专栏名称: 阿里云开发者
阿里巴巴官方技术号,关于阿里的技术创新均将呈现于此
目录
相关文章推荐
阿里云开发者  ·  浅析 rust 大明星 Tokio ·  17 小时前  
阿里云开发者  ·  基于 Spring AI 的 MCP ... ·  昨天  
白鲸出海  ·  中国互联网出海一周头条 ... ·  昨天  
白鲸出海  ·  半年冲刺500万美元ARR,华裔00后打造永 ... ·  3 天前  
51好读  ›  专栏  ›  阿里云开发者

从原理到示例:Java开发玩转MCP

阿里云开发者  · 公众号  · 科技公司  · 2025-04-25 18:00

主要观点总结

文章介绍了如何在Java开发者中使用Spring AI Alibaba框架玩转MCP(Model Context Protocol)的详细流程,包括MCP基础、发布Spring应用为MCP Server、调用MCP Server、在Spring AI Alibaba OpenManus中使用MCP服务、存量应用如何转为MCP服务被智能体调用等。文章还提到了MCP的架构、Spring AI中的MCP支持,并给出了代码示例和源码地址。

关键观点总结

关键观点1: MCP基础与体验

文章介绍了MCP的基础知识、快速体验以及如何发布Spring应用为MCP Server。

关键观点2: 调用MCP Server

介绍了如何调用自己发布的Java MCP Server和市面上的通用MCP Server。

关键观点3: 在Spring AI Alibaba OpenManus中使用MCP

展示了如何在Spring AI Alibaba OpenManus中使用MCP服务,实现智能化。

关键观点4: 存量应用转为MCP服务

提到了存量应用如何转为MCP服务被智能体调用,并给出了后续解决方案。

关键观点5: Spring AI Alibaba中的MCP支持

说明了Spring AI Alibaba框架如何支持MCP,让Java开发者轻松集成MCP服务。


正文

请到「今天看啥」查看全文


在 Spring AI 中使用 Mcp Server

2.1 Spring AI MCP 的介绍

Spring AI MCP 为模型上下文协议提供 Java 和 Spring 框架集成。它使 Spring AI 应用程序能够通过标准化的接口与不同的数据源和工具进行交互,支持同步和异步通信模式。整体架构如下:


图片


S pr ing AI MCP 采用模块化架构,包括以下组件:

  • Spring AI 应用程序:使用 Spring AI 框架构建想要通过 MCP 访问数据的生成式 AI 应用程序

  • Spring MCP 客户端:MCP 协议的 Spring AI 实现,与服务器保持 1:1 连接

通过 Spring AI MCP,可以快速搭建 MCP 客户端和服务端程序。

2.2 使用 Spring AI MCP 快速搭建 MCP Server

Spring AI 提供了两种机制快速搭建 MCP Server,通过这两种方式开发者可以快速向 AI 应用开放自身的能力,这两种机制如下:

  • 基于 stdio 的进程间通信传输,以独立的进程运行在 AI 应用本地,适用于比较轻量级的工具。

  • 基于 SSE(Server-Sent Events) 进行远程服务访问,需要将服务单独部署,客户端通过服务端的 URL 进行远程访问,适用于比较重量级的工具。

接下来逐一介绍一下这两种方式的实现,示例代码可以通过如下链接获取:

https://github.com/springaialibaba/spring-ai-alibaba-examples/tree/main/spring-ai-alibaba-mcp-example/starter-example/server


2.2.1 基于 stdio 的 MCP 服务端实现


基于 stdio 的 MCP 服务端通过标准输入输出流与客户端通信,适用于作为子进程被客户端启动和管理的场景。


添加依赖


首先,在项目中添加 Spring AI MCP Server Starter 依赖:

<dependency>   <groupId>org.springframework.aigroupId>   <artifactId>spring-ai-mcp-server-spring-boot-starterartifactId>dependency>


配置 MCP 服务端


application.yml 中配置 MCP 服务端,这次要实现的是一个天气服务:

spring:  main:    web-application-type: none  # 必须禁用web应用类型    banner-mode: off           # 禁用banner  ai:    mcp:      server:        stdio: true            # 启用stdio模式        name: my-weather-server # 服务器名称        version: 0.0.1         # 服务器版本


实现 MCP 工具


使用 @Tool 注解标记方法,使其可以被 MCP 客户端发现和调用,通过 @ToolParameter 注解工具的具体参数:


@Service
publicclassOpenMeteoService {    privatefinal WebClient webClient;    publicOpenMeteoService(WebClient.Builder webClientBuilder){        this.webClient = webClientBuilder                .baseUrl("https://api.open-meteo.com/v1")                .build();    }    @Tool(description = "根据经纬度获取天气预报")    public String getWeatherForecastByLocation(            @ToolParameter(description = "纬度,例如:39.9042"String latitude,            @ToolParameter(description = "经度,例如:116.4074"String longitude) {        try {            String response = webClient.get()                    .uri(uriBuilder -> uriBuilder                            .path("/forecast")                            .queryParam("latitude", latitude)                            .queryParam("longitude", longitude)                            .queryParam("current""temperature_2m,wind_speed_10m")                            .queryParam("timezone""auto")                            .build())                    .retrieve()                    .bodyToMono(String.class)                    .block();            // 解析响应并返回格式化的天气信息            // 这里简化处理,实际应用中应该解析JSON            return"当前位置(纬度:" + latitude + ",经度:" + longitude + ")的天气信息:\n" + response;        } catch (Exception e) {            return"获取天气信息失败:" + e.getMessage();        }    }    @Tool(description = "根据经纬度获取空气质量信息")    public String getAirQuality(            @ToolParameter(description = "纬度,例如:39.9042"String latitude,            @ToolParameter(description = "经度,例如:116.4074"String longitude) {        // 模拟数据,实际应用中应调用真实API        return"当前位置(纬度:" + latitude + ",经度:" + longitude + ")的空气质量:\n" +                "- PM2.5: 15 μg/m³ (优)\n" +                "- PM10: 28 μg/m³ (良)\n" +                "- 空气质量指数(AQI): 42 (优)\n" +                "- 主要污染物: 无";    }
}

这里使用了 OpenMeteo, OpenMeteo 是一个开源的天气 API,为非商业用途提供免费访问,无需 API 密钥。


注册 MCP 工具


在应用程序入口类中注册工具:


@SpringBootApplicationpublicclassMcpServerApplication {    publicstaticvoidmain(String[] args){        SpringApplication.run(McpServerApplication.class, args);    }
    @Bean
    public ToolCallbackProvider weatherTools(OpenMeteoService openMeteoService){        return MethodToolCallbackProvider.builder()                .toolObjects(openMeteoService)                .build();    }}

运行服务端


在控制台中执行如下命令,编译并打包应用:


Terminal window

mvn clean package -DskipTests

2.2.2 基于 SSE 的 MCP 服务端实现


基于 SSE 的 MCP 服务端通过 HTTP 协议与客户端通信,适用于作为独立服务部署的场景,可以被多个客户端远程调用,具体做法与 stdio 非常类似。


添加依赖


首先,在您的项目中添加依赖:

<dependency>   <groupId>org.springframework.aigroupId>   <artifactId>spring-ai-mcp-server-webflux-spring-boot-starterartifactId>dependency>

配置 MCP 服务端


application.yml 中配置 MCP 服务端:

server:  port: 8080  # 服务器端口配置spring:  ai:    mcp:      server:        name: my-weather-server    # MCP服务器名称        version: 0.0.1            # 服务器版本号

实现 MCP 工具


与基于 stdio 的实现完全相同:

@Service
publicclassOpenMeteoService {    privatefinal WebClient webClient;    publicOpenMeteoService(WebClient.Builder webClientBuilder){        this.webClient = webClientBuilder                .baseUrl("https://api.open-meteo.com/v1")                .build();    }    @Tool(description = "根据经纬度获取天气预报")    public String getWeatherForecastByLocation(            @ToolParameter(description = "纬度,例如:39.9042"String latitude,            @ToolParameter(description = "经度,例如:116.4074"String longitude) {        try {            String response = webClient.get()                    .uri(uriBuilder -> uriBuilder                            .path("/forecast")                            .queryParam("latitude", latitude)                            .queryParam("longitude", longitude)                            .queryParam("current""temperature_2m,wind_speed_10m")                            .queryParam("timezone""auto")                            .build())                    .retrieve()                    .bodyToMono(String.class)                    .block();            // 解析响应并返回格式化的天气信息            return"当前位置(纬度:" + latitude + ",经度:" + longitude + ")的天气信息:\n" + response;        } catch (Exception e) {            return"获取天气信息失败:" + e.getMessage();        }    }    @Tool(description = "根据经纬度获取空气质量信息")    public String getAirQuality(            @ToolParameter(description = "纬度,例如:39.9042"String latitude,            @ToolParameter(description = "经度,例如:116.4074"String longitude) {        // 模拟数据,实际应用中应调用真实API        return"当前位置(纬度:" + latitude + ",经度:" + longitude + ")的空气质量:\n" +                "- PM2.5: 15 μg/m³ (优)\n" +                "- PM10: 28 μg/m³ (良)\n"






请到「今天看啥」查看全文