目錄
一、前言
二、MCP 介紹
2.1 MCP是什么
2.2 MCP 核心特點
2.3 Spring AI MCP 介紹
2.3.1 Spring AI MCP架構
2.3.2 Spring AI MCP分層說明
2.4 兩種模式介紹
三、本地開發SSE模式
3.1 搭建mcp-server
3.1.1 導入工程核心依賴
3.1.2 添加配置文件
3.1.3 提供兩個Tool
3.1.4 注冊Tool
3.2 搭建mcp-client
3.2.1 導入核心依賴
3.2.2 添加配置文件
3.2.3 增加測試接口
3.2.4 效果測試
四、本地開發stdio模式
4.1 server 端開發
4.1.1 導入核心依賴
4.1.2 調整配置文件
4.1.3 提供Tool工具方法
4.1.4 注冊工具方法
4.1.5 添加日志文件
4.1.6 構建jar包
4.2 mcp-client 開發
4.2.1 pom文件中導入下面核心依賴
4.2.2 添加下面的配置文件
4.2.3 接口改造
4.2.4 效果測試
五、Spring AI 對接第三方MCP服務
5.1 高德MCP服務前置說明
5.1.2 獲取apikey
5.2 代碼集成
5.2.1 配置文件信息
5.2.2 增加配置類
5.2.3 增加測試接口
六、寫在文末
一、前言
MCP(Model Context Protocol) 是一種由 Anthropic 于 2024 年 11 月發布的開源協議,旨在標準化大型語言模型(LLM)與外部數據源和工具的交互。它像“AI的USB-C接口”,通過統一接口讓 AI 模型無縫連接數據庫、文件、API 等外部資源。隨著人工智能技術的發展,越來越多的框架和工具被開發出來,以幫助開發者快速構建智能化的應用程序。Spring AI 是 Spring 家族的一員,它提供了豐富的機器學習和人工智能相關的支持。同時,Spring AI也適應時代的發展,快速跟進,于近期開始了對MCP生態的能力整合,本篇將詳細介紹下如何在Spring AI中集成和使用MCP能力。
二、MCP 介紹
2.1 MCP是什么
模型上下文協議(即 Model Context Protocol,MCP)是一個開放協議,它規范了應用程序如何向大型語言模型(LLM)提供上下文。MCP 提供了一種統一的方式將 AI 模型連接到不同的數據源和工具,它定義了統一的集成方式。在開發智能體(Agent)的過程中,我們經常需要將將智能體與數據和工具集成,MCP 以標準的方式規范了智能體與數據及工具的集成方式,可以幫助您在 LLM 之上構建智能體(Agent)和復雜的工作流。目前已經有大量的服務接入并提供了 MCP server 實現,當前這個生態正在以非常快的速度不斷的豐富中。
2.2 MCP 核心特點
MCP 具備如下核心特點:
-
標準化集成
-
MCP統一了不同AI模型(如Claude、GPT等)與外部工具(如數據庫、API、瀏覽器等)的交互方式,避免了傳統定制化API開發的重復勞動
-
-
雙向通信
-
不同于傳統AI只能被動接收數據,MCP支持AI主動檢索信息并執行操作(如更新數據庫、觸發工作流),實現真正的“代理式AI”
-
-
動態上下文管理
-
MCP允許AI在會話中持續攜帶上下文信息(如用戶偏好、歷史記錄),使多步驟任務(如“查詢天氣→推薦行程→預訂酒店”)能自動串聯執行
-
-
安全與靈活性
-
MCP支持本地或云端部署,通過OAuth 2.1認證和數據沙箱機制保障敏感信息的安全訪問
-
2.3 Spring AI MCP 介紹
官網入口:Model Context Protocol (MCP) :: Spring AI Reference
2.3.1 Spring AI MCP架構
Spring 官網對于MCP給出了下面的架構圖
從上面的架構圖不難看出,Spring AI MCP 采用模塊化架構,包括以下組件:
-
Spring AI 應用程序:使用 Spring AI 框架構建想要通過 MCP 訪問數據的生成式 AI 應用程序
-
Spring MCP 客戶端:MCP 協議的 Spring AI 實現,與服務器保持 1:1 連接
-
MCP 服務器:輕量級程序,每個程序都通過標準化的模型上下文協議公開特定的功能
-
本地數據源:MCP 服務器可以安全訪問的計算機文件、數據庫和服務
-
遠程服務:MCP 服務器可以通過互聯網(例如,通過 API)連接到的外部系統
2.3.2 Spring AI MCP分層說明
Spring AI?MCP實現遵循三層架構:
三層架構實現說明
Java MCP 實現遵循三層架構:
-
客戶端/服務器層:McpClient 處理客戶端操作,McpServer 管理服務器端協議操作
-
會話層(McpSession):管理通信模式和狀態
-
傳輸層(McpTransport):處理 JSON-RPC 消息的序列化和反序列化,支持多種傳輸方式
2.4 兩種模式介紹
在Spring AI MCP模式下,目前主要提供了2種的通信協議的模式,即SSE和STDIO
STDIO傳輸協議:
-
STDIO方式是基于進程間通信,MCP Client和MCP Server運行在同一主機,主要用于本地集成、命令行工具等場景。
-
優點:
-
簡單可靠,無需網絡配置;適合本地部署場景;進程隔離,安全性好。
-
-
缺點:
-
僅支持單機部署;不支持跨網絡訪問;每個客戶端需要獨立啟動服務器進程。
-
SSE傳輸協議:
-
SSE(Server-Sent Events)傳輸層是基于HTTP的單向通信機制,專門用于服務器向客戶端推送數據。MCP Client遠程調用MCP Server提供的SSE服務。實現客戶端和服務端遠程通信。
-
優點:
-
支持分布式部署;可跨網絡訪問;支持多客戶端連接;輕量級,使用標準HTTP協議。
-
-
缺點:
-
需要額外的網絡配置;相比stdio實現略微復雜;需要考慮網絡安全性。
-
三、本地開發SSE模式
3.1 搭建mcp-server
分別搭建mcp-server 和 mcp-client兩個工程,下面依次說明。
3.1.1 導入工程核心依賴
在pom文件中導入下面的核心依賴
<properties><maven.compiler.source>17</maven.compiler.source><maven.compiler.target>17</maven.compiler.target><project.build.sourceEncoding>UTF-8</project.build.sourceEncoding><spring-ai.version>1.0.0-M7</spring-ai.version>
</properties><parent><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-parent</artifactId><version>3.4.4</version><relativePath/>
</parent><dependencyManagement><dependencies><dependency><groupId>org.springframework.ai</groupId><artifactId>spring-ai-bom</artifactId><version>1.0.0-M7</version><type>pom</type><scope>import</scope></dependency></dependencies>
</dependencyManagement><dependencies><dependency><groupId>org.springframework.ai</groupId><artifactId>spring-ai-starter-mcp-server-webflux</artifactId></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-test</artifactId></dependency>
</dependencies><build><plugins><plugin><groupId>org.springframework.boot</groupId><artifactId>spring-boot-maven-plugin</artifactId></plugin></plugins>
</build><repositories><repository><id>central</id><url>https://maven.aliyun.com/repository/central</url><releases><enabled>true</enabled></releases><snapshots><enabled>true</enabled></snapshots></repository><repository><name>Central Portal Snapshots</name><id>central-portal-snapshots</id><url>https://central.sonatype.com/repository/maven-snapshots/</url><releases><enabled>false</enabled></releases><snapshots><enabled>true</enabled></snapshots></repository><repository><id>spring-milestones</id><name>Spring Milestones</name><url>https://repo.spring.io/milestone</url><snapshots><enabled>false</enabled></snapshots></repository><repository><id>spring-snapshots</id><name>Spring Snapshots</name><url>https://repo.spring.io/snapshot</url><releases><enabled>false</enabled></releases></repository>
</repositories>
3.1.2 添加配置文件
在配置文件中添加下面的配置信息
spring:ai:mcp:server:name: mcp-serverversion: 1.0.0type: ASYNCsse-message-endpoint: /mcp/messages
3.1.3 提供兩個Tool
自定義一個類,增加兩個Tool方法,參考下面的代碼
package com.congge.tool;import org.springframework.ai.tool.annotation.Tool;
import org.springframework.context.i18n.LocaleContextHolder;
import org.springframework.stereotype.Component;
import org.springframework.stereotype.Service;import java.time.LocalDateTime;@Service("weatherServiceTool")
public class WeatherServiceTool {@Tool(description = "獲取指定城市的天氣")public String getWeather(String cityName){if(cityName.equals("北京")){return "晴天";}else if(cityName.equals("上海")){return "陰天";}else {return "未知";}}@Tool(description = "獲取當前用戶所在的時區時間")String getCurrentDateTime() {return LocalDateTime.now().atZone(LocaleContextHolder.getTimeZone().toZoneId()).toString();}}
3.1.4 注冊Tool
提供一個配置類,將上面的Tool方法進行注冊
package com.congge.config;import com.congge.tool.WeatherServiceTool;
import org.springframework.ai.tool.ToolCallbackProvider;
import org.springframework.ai.tool.method.MethodToolCallbackProvider;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;@Configuration
public class ToolCallbackProviderConfig {@Beanpublic ToolCallbackProvider toolCallbackProvider(WeatherServiceTool weatherServiceTool) {return MethodToolCallbackProvider.builder().toolObjects(weatherServiceTool).build();}
}
以上做完之后,啟動項目,通過控制臺的輸出可以看到,注冊了2個Tool方法
3.2 搭建mcp-client
mcp-client , 即調用server端提供的大模型工具的客戶端,在實際業務中,可以有多個客戶端都需要server端提供的各類Tool能力,統稱為客戶端。
3.2.1 導入核心依賴
在pom文件中導入下面的核心依賴
<properties><maven.compiler.source>17</maven.compiler.source><maven.compiler.target>17</maven.compiler.target><project.build.sourceEncoding>UTF-8</project.build.sourceEncoding><spring-ai.version>1.0.0-M7</spring-ai.version></properties><parent><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-parent</artifactId><version>3.4.4</version><relativePath/></parent><dependencies><dependency><groupId>com.alibaba.cloud.ai</groupId><artifactId>spring-ai-alibaba-starter</artifactId><version>1.0.0-M6.1</version></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId></dependency><dependency><groupId>org.springframework.ai</groupId><artifactId>spring-ai-starter-mcp-client</artifactId></dependency></dependencies><repositories><repository><id>spring-snapshots</id><name>Spring Snapshots</name><url>https://repo.spring.io/snapshot</url><releases><enabled>false</enabled></releases></repository><repository><name>Central Portal Snapshots</name><id>central-portal-snapshots</id><url>https://central.sonatype.com/repository/maven-snapshots/</url><releases><enabled>false</enabled></releases><snapshots><enabled>true</enabled></snapshots></repository><repository><id>spring-milestones</id><name>Spring Milestones</name><url>https://repo.spring.io/milestone</url><snapshots><enabled>false</enabled></snapshots></repository><repository><id>spring-snapshots</id><name>Spring Snapshots</name><url>https://repo.spring.io/snapshot</url><releases><enabled>false</enabled></releases></repository></repositories><dependencyManagement><dependencies><dependency><groupId>org.springframework.ai</groupId><artifactId>spring-ai-bom</artifactId><version>1.0.0-M7</version><type>pom</type><scope>import</scope></dependency></dependencies></dependencyManagement><build><plugins><plugin><groupId>org.springframework.boot</groupId><artifactId>spring-boot-maven-plugin</artifactId></plugin></plugins></build>
3.2.2 添加配置文件
在配置文件中添加如下信息
spring:ai:dashscope:api-key: 你的apikeymcp:client:sse:connections:server1:url: http://localhost:8080toolcallback:enabled: true
3.2.3 增加測試接口
增加一個測試接口,用于測試調用server端的Tool能力
package com.congge.web;import jakarta.annotation.Resource;
import org.springframework.ai.chat.client.ChatClient;
import org.springframework.ai.tool.ToolCallbackProvider;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;@RestController
@RequestMapping("/client/ai")
public class ChatController {private final ChatClient chatClient;public ChatController(ChatClient.Builder chatClientBuilder) {this.chatClient = chatClientBuilder.build();}@Resourceprivate ToolCallbackProvider toolCallbackProvider;//localhost:8082/client/ai/chat?message=今天北京的天氣如何//localhost:8082/client/ai/chat?message=你是誰//localhost:8082/client/ai/chat?message=當前時間是多少@GetMapping("/chat")public String chat(String message){return chatClient.prompt().user(message).tools(toolCallbackProvider.getToolCallbacks()).call().content();}
}
3.2.4 效果測試
下面通過幾個不同的測試場景分別驗證下server端提供的工具能力是否生效
1)測試效果一
調用接口:localhost:8082/client/ai/chat?message=今天北京的天氣如何 , 問題是Tool工具中相關的,可以給出預期的結果
2)測試效果二
調用接口:localhost:8082/client/ai/chat?message=你是誰 , 問題是Tool工具中非相關的
3)測試效果三
調用接口:localhost:8082/client/ai/chat?message=當前時間是多少, 問題是Tool工具中相關的,可以給出預期的結果
四、本地開發stdio模式
基于stdio的MCP服務端通過標準輸入輸出流與客戶端通信,適用于作為子進程被客戶端啟動和管理的場景,非常適合嵌入式應用。
通過Java開發工具創建一個springboot工程,模擬開發一個算術計算器服務,通過stdio傳輸協議發布為MCP Server。
4.1 server 端開發
4.1.1 導入核心依賴
在pom中導入如下核心的依賴
<dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId></dependency><dependency><groupId>org.springframework.ai</groupId><artifactId>spring-ai-mcp-server-webflux-spring-boot-starter</artifactId></dependency>
4.1.2 調整配置文件
在配置文件中添加下面的配置信息
server:port: 8088spring:ai:mcp:server:name: mcp-stdio-serverversion: 1.0.0
4.1.3 提供Tool工具方法
可以復用上一個案例中的工具方法
4.1.4 注冊工具方法
同上一個案例
4.1.5 添加日志文件
為了方便后續查看運行過程中的日志,在resources目錄下增加一個日志配置文件logback-spring.xml
<configuration><appender name="FILE" class="ch.qos.logback.core.FileAppender"><file>mcp-server.log</file><encoder><pattern>%d{yyyy-MM-dd HH:mm:ss} [%thread] %-5level %logger{36} - %msg%n</pattern></encoder></appender><root level="INFO"><appender-ref ref="FILE" /></root>
</configuration>
4.1.6 構建jar包
到這里,一個通過Spring AI創建的MCP Server完成了。stdio方式是server和client通過進程通信,所以需要把server打包成jar,以便client命令啟動執行。
jar包的完整路徑:E:\code-self\517\server\mcp-server\target\mcp-server-1.0-SNAPSHOT.jar
測試該服務是否發布成功,在cmd命令行窗口里輸入如下命令:
java -Dspring.ai.mcp.server.stdio=true -Dspring.main.web-application-type=none -Dspring.main.banner-mode=off -jar E:/code-self/517/server/mcp-server/target/mcp-server-1.0-SNAPSHOT.jar
至此,我們通過spring ai框架開發完成了2個MCP Server服務,一個通過sse協議發布,另一個通過stdio協議發布,接下來,開發一個MCP Client端,調用這兩個MCP Server服務。
4.2 mcp-client 開發
4.2.1 pom文件中導入下面核心依賴
導入下面核心依賴,之前的可以保持不變
<dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId>
</dependency><dependency><groupId>org.springframework.ai</groupId><artifactId>spring-ai-mcp-client-webflux-spring-boot-starter</artifactId><version>1.0.0-M6</version>
</dependency>
4.2.2 添加下面的配置文件
配置文件中添加下面的配置信息
-
args參數中根據你的包的實際路徑填寫
server:port: 8082spring:ai:dashscope:api-key: 你的apikeychat:options:#model: qwen-maxmodel: qwen-plusmcp:client:connection-timeout: 60stype: ASYNCstdio:connections:server2:command: javaargs:- -Dspring.ai.mcp.server.stdio=true- -Dspring.main.web-application-type=none- -Dspring.main.banner-mode=off- -jar- D:/self-code/0522/mcp-server/target/mcp-server.jar
另一種方式是在resource目錄下增加一個配置文件,比如叫做:mcp-servers-config.json ,然后將上述的args里面的參數放到該json文件中,如下:
{"mcpServers": {"weather": {"command": "java","args": ["-Dspring.ai.mcp.server.stdio=true","-Dspring.main.web-application-type=none","-Dspring.main.banner-mode=off","-jar","E:/code-self/517/集成/mcp-server/target/mcp-server.jar"],"env": {}}}
}
最后,再重新調整下原始的配置文件,改為對該json文件的引用即可
server:port: 8082spring:ai:mcp:client:stdio:servers-configuration: classpath:/mcp-servers-config.json
# connections:
# server2:
# command: java
# args:
# - -Dspring.ai.mcp.server.stdio=true
# - -Dspring.main.web-application-type=none
# - -Dspring.main.banner-mode=off
# - -jar
# - D:/self-code/0522/mcp-server/target/mcp-server.jardashscope:api-key: 你的apikeychat:options:#模型名稱: qwen-plus deepseek-v3 deepseek-r1model: qwen-plus
以上這兩種方式任選其一即可,更推薦引用json文件的方式,這樣方便全局管理
4.2.3 接口改造
在原來的測試接口中做一些調整,參考下面的代碼 , 主要是把ToolCallbackProvider 配置到ChatClient 中
package com.congge.web;import jakarta.annotation.Resource;
import org.springframework.ai.chat.client.ChatClient;
import org.springframework.ai.tool.ToolCallbackProvider;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;@RestController
@RequestMapping("/client/ai")
public class ChatController {private final ChatClient chatClient;public ChatController(ChatClient.Builder chatClientBuilder,ToolCallbackProvider tools) {this.chatClient = chatClientBuilder.defaultTools(tools).build();}@Resourceprivate ToolCallbackProvider toolCallbackProvider;//localhost:8082/client/ai/chat?message=今天北京的天氣如何//localhost:8082/client/ai/chat?message=你是誰//localhost:8082/client/ai/chat?message=當前時間是多少@GetMapping("/chat")public String chat(String message){return chatClient.prompt().user(message).tools(toolCallbackProvider.getToolCallbacks()).call().content();}
}
4.2.4 效果測試
仿照上面的案例測試,問一個與Tool中無關的問題,和一個相關的問題
1)測試效果一
調用接口:localhost:8082/client/ai/chat?message=你是誰 , 問題是Tool工具中非相關的
2)測試效果二
調用接口:http://localhost:8082/client/ai/chat?message=當前時間是多少
五、Spring AI 對接第三方MCP服務
隨著MCP的概念火了之后,也有很多平臺開始逐步開放自己的MCP,利用這些平臺的能力即可快速對接各類特定場景下的MCP服務,從而為自身的應用賦能,下面介紹一下如何在自己的Spring AI應用中對接第三方的MCP服務。下面的案例中以高德地圖提供的MCP服務為例進行說明。
5.1 高德MCP服務前置說明
使用高德MCP服務有多個渠道,第一種是直接通過高德開放平臺本身進行對接,第二種是通過第三方平臺對接高德MCP服務,比如阿里云百煉平臺。
入口地址一:概述-MCP Server | 高德地圖API
入口地址二:百煉控制臺
5.1.2 獲取apikey
在后文的代碼中,為了集成并使用高德的mcp服務時,需要用到apikey,因此需要提前在高德開放平臺注冊賬號并獲取apikey,參考該文檔即可完成apikey 的獲取:創建應用和 Key-MCP Server | 高德地圖API
最后在控制臺,我的應用這里就能看到你創建的這個應用的apikey信息了
5.2 代碼集成
在代碼中集成高德MCP也很簡單,官方提供的參考文檔地址:快速接入-MCP Server | 高德地圖API,下面看代碼中的集成過程。
5.2.1 配置文件信息
在工程配置文件中,增加下面的配置信息
spring:ai:dashscope:api-key: 你的apikeychat:options:model: qwen-maxmcp:client:connection-timeout: 60stype: ASYNC
5.2.2 增加配置類
在工程中增加如下配置類
package com.congge.tool;import com.fasterxml.jackson.databind.ObjectMapper;
import io.modelcontextprotocol.client.transport.HttpClientSseClientTransport;
import io.modelcontextprotocol.spec.McpClientTransport;
import org.springframework.ai.mcp.client.autoconfigure.NamedClientMcpTransport;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;import java.util.Collections;
import java.util.List;@Configuration
public class McpConfig {@Beanpublic List<NamedClientMcpTransport> mcpClientTransport() {McpClientTransport transport = HttpClientSseClientTransport.builder("https://mcp.amap.com").sseEndpoint("/sse?key=你的高德的apikey").objectMapper(new ObjectMapper()).build();return Collections.singletonList(new NamedClientMcpTransport("amap", transport));}}
5.2.3 增加測試接口
添加如下測試接口,用于測試效果
package com.congge.web;import io.modelcontextprotocol.client.McpAsyncClient;
import io.modelcontextprotocol.spec.McpSchema;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import reactor.core.publisher.Mono;import java.util.List;
import java.util.Map;@RestController
@RequestMapping("/client/mcp")
public class McpController {@AutowiredList<McpAsyncClient> mcpAsyncClients;//localhost:8082/client/mcp/test@RequestMapping("/test")public Mono<McpSchema.CallToolResult> test() {var mcpClient = mcpAsyncClients.get(0);return mcpClient.listTools().flatMap(tools -> {//logger.info("tools: {}", tools);System.out.println(tools);return mcpClient.callTool(new McpSchema.CallToolRequest("maps_weather",Map.of("city", "北京")));});}}
啟動工程后,調用一下上述的接口,成功返回了數據,實際應用時,可以進一步參考官方API對相應的字段進行解析使用
六、寫在文末
本文通過較大的篇幅詳細介紹了基于Spring AI使用MCP的常用幾種開發模式,細節部分還有待進一步的完善,希望對看到的同學有用,本篇到此結束,感謝觀看。