跳到主要内容
版本:1.1.0

MCP

MCP(Model Context Protocol)是 AI 模型与外部工具服务器的标准通信协议。Spring AI 的 MCP 集成让 ChatClient 能够调用任何实现了 MCP 协议的工具服务器——无论使用何种编程语言或运行环境——就像调用本地的 @Tool 方法一样。

Spring AI 1.1.0 内置 MCP SDK 0.16.0。1.1.0 对 MCP 架构进行了全面重构,从单模块拆分为六模块:

客户端:common → httpclient / webflux
服务端:common → webmvc / webflux

新增 Streamable HTTP 传输和 SSE HTTP Client 传输,支持工具回调缓存和客户端注解扫描。

ChatClient → ToolCallback → McpClient → 传输层(STDIO / SSE / Streamable HTTP) → MCP Server → 实际工具

1. 客户端:调用外部 MCP 工具

1.1 自动配置(YAML)

引入 spring-ai-starter-mcp-client 后,通过 YAML 配置 MCP 服务器连接,工具会自动注册到 ChatClient。

pom.xml
<dependency>
<groupId>org.springframework.ai</groupId>
<artifactId>spring-ai-starter-mcp-client</artifactId>
</dependency>
application.yml
spring:
ai:
mcp:
client:
enabled: true
type: SYNC
stdio:
connections:
weather-server:
command: python
args: ["/opt/mcp-servers/weather-server.py"]

客户端配置项:

配置项默认值说明
spring.ai.mcp.client.enabledtrue是否启用 MCP 客户端
spring.ai.mcp.client.typeSYNC客户端类型,SYNCASYNC
spring.ai.mcp.client.namespring-ai-mcp-client向服务器报告的客户端名称
spring.ai.mcp.client.version1.0.0客户端版本
spring.ai.mcp.client.request-timeout20s请求超时时间
spring.ai.mcp.client.toolcallback.enabledtrue是否自动注册为 ToolCallback
spring.ai.mcp.client.stdio.connections.<name>.command-STDIO 模式下执行的命令
spring.ai.mcp.client.stdio.connections.<name>.args-命令行参数列表
spring.ai.mcp.client.sse.connections.<name>.url-SSE 服务端点 URL
spring.ai.mcp.client.streamable-http.connections.<name>.url-Streamable HTTP 端点 URL

配置完成后无需任何 Java 代码——MCP 服务器的工具自动出现在 ChatClient 中:

@Bean
public ChatClient chatClient(ChatClient.Builder builder) {
return builder.build();
}

// MCP 服务器的工具会自动可用
String response = chatClient.prompt()
.user("北京今天天气怎么样?")
.call()
.content();

1.2 编程式创建

适合需要动态管理连接或细粒度控制的场景:

// 创建 STDIO 传输
var transport = new StdioClientTransport(
ServerParameters.builder("python")
.args(List.of("/opt/mcp-servers/weather-server.py"))
.build());

// 创建 MCP 客户端
McpSyncClient mcpClient = McpClient.sync(transport)
.clientInfo(new Implementation("my-app", "1.0.0"))
.requestTimeout(Duration.ofSeconds(20))
.build();
mcpClient.initialize();

// 包装为 ToolCallbackProvider
ToolCallbackProvider provider = new SyncMcpToolCallbackProvider(mcpClient);

// 注册到 ChatClient
ChatClient chatClient = ChatClient.builder(chatModel)
.defaultToolCallbacks(provider)
.build();

2. 工具过滤

当 MCP 服务器提供的工具较多时,可按名称过滤只需部分工具:

// 仅保留以 "weather_" 开头的工具
BiPredicate<McpSyncClient, Tool> weatherOnly =
(client, tool) -> tool.name().startsWith("weather_");

ToolCallbackProvider provider = new SyncMcpToolCallbackProvider(weatherOnly, mcpClient);

2.1 工具回调缓存(1.1.0 新增)

MCP 工具列表通过事件驱动缓存机制(McpAsyncToolsChangeEventEmmiter / McpSyncToolsChangeEventEmmiter)管理,避免每次请求都重复获取工具列表,减少通信开销。


2.2 客户端注解扫描(1.1.0 新增)

McpClientAnnotationScannerAutoConfiguration 自动扫描 @McpTool 注解的方法并注册为工具回调,简化客户端工具接入流程。


3. 自定义客户端

通过实现 McpSyncClientCustomizer 在客户端创建前注入自定义配置:

@Component
public class WeatherClientCustomizer implements McpSyncClientCustomizer {

@Override
public void customize(String serverName, McpClient.SyncSpec spec) {
if ("weather-server".equals(serverName)) {
spec.requestTimeout(Duration.ofSeconds(30));
}
}
}

4. 服务端:将 Spring AI 工具暴露为 MCP 工具

Spring AI 也可以作为 MCP 服务器,将 @Tool 方法暴露给外部 MCP 客户端调用。

pom.xml
<dependency>
<groupId>org.springframework.ai</groupId>
<artifactId>spring-ai-starter-mcp-server</artifactId>
</dependency>
application.yml
spring:
ai:
mcp:
server:
enabled: true
name: "spring-ai-tools"
version: "1.0.0"
instructions: "提供天气查询、计算等工具"

服务端会自动收集所有 ToolCallbackToolCallbackProvider Bean,转换为 MCP 工具规格。

服务端配置项:

配置项默认值说明
spring.ai.mcp.server.enabledtrue是否启用 MCP 服务器
spring.ai.mcp.server.typeSYNC服务器类型
spring.ai.mcp.server.namemcp-server服务器名称
spring.ai.mcp.server.version1.0.0服务器版本
spring.ai.mcp.server.instructions-客户端可见的说明文本
spring.ai.mcp.server.stdiofalse启用 STDIO 传输(有 Web 框架时默认禁用以使用 SSE)

4.1 MCP Server ObjectMapper

Spring AI 1.0.7 新增 McpServerObjectMapperAutoConfiguration,自动注册名为 mcpServerObjectMapperObjectMapper Bean,配置为符合 MCP 协议规范的 JSON 序列化:

  • 禁止将日期写为时间戳(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS
  • 忽略未知属性(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES
  • 序列化时排除 null 值(JsonInclude.Include.NON_NULL

如需自定义序列化行为,提供同名的 mcpServerObjectMapper Bean 即可覆盖。

@Bean("mcpServerObjectMapper")
public ObjectMapper customMcpServerObjectMapper() {
return JsonMapper.builder()
.serializationInclusion(JsonInclude.Include.NON_EMPTY)
.build();
}

5. 完整示例:服务端 + 客户端

以下示例展示一个完整的 MCP 调用链路——服务端通过 STDIO 暴露天气工具,客户端连接后由 ChatClient 自动发现并调用。

5.1 服务端(天气 MCP Server)

独立 Spring Boot 应用,使用 @Tool 注解定义工具方法,通过 MCP Server 暴露。

server/pom.xml
<dependency>
<groupId>org.springframework.ai</groupId>
<artifactId>spring-ai-starter-mcp-server</artifactId>
</dependency>
server/application.yml
spring:
ai:
mcp:
server:
enabled: true
name: "weather-mcp-server"
version: "1.0.0"
instructions: "提供全球城市天气查询服务"
stdio: true
server/WeatherMcpServerApplication.java
@SpringBootApplication
public class WeatherMcpServerApplication {

public static void main(String[] args) {
SpringApplication.run(WeatherMcpServerApplication.class, args);
}

@Bean
public WeatherTools weatherTools() {
return new WeatherTools();
}

static class WeatherTools {

@Tool(description = "获取指定城市的实时天气信息")
public String getWeather(
@ToolParam(description = "城市名称,如 Beijing、Shanghai") String city) {
return city + ":晴,25°C,湿度 60%,风力 3 级";
}

@Tool(description = "获取指定城市未来 N 天的天气预报")
public String getForecast(
@ToolParam(description = "城市名称") String city,
@ToolParam(description = "预报天数") int days) {
return city + "未来" + days + "天天气:以晴为主,22-28°C";
}
}
}

服务端启动后通过 STDIO 监听,等待客户端连接并调用工具。

5.2 客户端(ChatClient + MCP Client)

另一个 Spring Boot 应用,通过 MCP Client 连接上述天气服务器,ChatClient 自动发现并调用天气工具。

client/pom.xml
<dependency>
<groupId>org.springframework.ai</groupId>
<artifactId>spring-ai-starter-mcp-client</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.ai</groupId>
<artifactId>spring-ai-ollama-spring-boot-starter</artifactId>
</dependency>
client/application.yml
spring:
ai:
mcp:
client:
enabled: true
stdio:
connections:
weather-server:
command: java
args: ["-jar", "/path/to/weather-mcp-server.jar"]
ollama:
base-url: http://localhost:11434
chat:
options:
model: qwen3:8b
client/WeatherClientApplication.java
@SpringBootApplication
public class WeatherClientApplication {

public static void main(String[] args) {
var ctx = SpringApplication.run(WeatherClientApplication.class, args);
ChatClient chatClient = ctx.getBean(ChatClient.class);

// MCP 工具已自动注册,直接使用
System.out.println("=== 单工具调用 ===");
String response1 = chatClient.prompt()
.user("北京今天天气怎么样?")
.call()
.content();
System.out.println(response1);

System.out.println("=== 多工具调用 ===");
String response2 = chatClient.prompt()
.user("查询上海今天天气和未来3天的预报")
.call()
.content();
System.out.println(response2);
}
}

5.3 执行流程

1. 启动 weather-mcp-server.jar → STDIO 监听
2. 启动 WeatherClientApplication → McpClientAutoConfiguration 自动创建 McpSyncClient
→ McpToolCallbackAutoConfiguration 自动发现服务端工具并注册为 ToolCallback
3. chatClient.prompt("北京今天天气怎么样?").call()
→ ChatModel 识别到需要调用 getWeather 工具
→ DefaultToolCallingManager 通过 McpSyncClient 向服务端发起调用
→ 服务端执行 getWeather("北京"),返回 "北京:晴,25°C..."
→ ChatModel 基于结果生成最终回复