文章目录
- 引言
- 一、MCP协议概念:标准化的工具连接
-
- [1.1 为什么需要MCP?](#1.1 为什么需要MCP?)
- [1.2 MCP的三大核心概念](#1.2 MCP的三大核心概念)
- 工具(Tools)
- 资源(Resources)
- 提示词(Prompts)
- [1.3 MCP的设计哲学](#1.3 MCP的设计哲学)
- 二、MCP架构设计:Client-Server通信模式
-
- [2.1 整体架构图](#2.1 整体架构图)
- [2.2 通信流程](#2.2 通信流程)
- 阶段1:初始化与发现(Startup)
- [阶段2:工具调用(Tool Calling)](#阶段2:工具调用(Tool Calling))
- [2.3 ToolCallbackProvider的职责](#2.3 ToolCallbackProvider的职责)
- 三、依赖引入与项目配置
-
- [3.1 添加MCP Client依赖](#3.1 添加MCP Client依赖)
- [3.2 MCP Server端配置](#3.2 MCP Server端配置)
- [3.3 MCP Client端配置](#3.3 MCP Client端配置)
- [四、MCP Server端实现详解](#四、MCP Server端实现详解)
-
- [4.1 WeatherService:工具提供者](#4.1 WeatherService:工具提供者)
- [@McpTool - 可调用的函数工具](#@McpTool - 可调用的函数工具)
- [@McpResource - 只读数据资源](#@McpResource - 只读数据资源)
- [@McpPrompt - 预设提示词模板](#@McpPrompt - 预设提示词模板)
- [4.2 MCP Server的启动配置](#4.2 MCP Server的启动配置)
- [五、MCP Client端实现详解](#五、MCP Client端实现详解)
-
- [5.1 McpController:工具调用的入口](#5.1 McpController:工具调用的入口)
- [5.2 实际测试](#5.2 实际测试)
- [六、MCP vs 直接Tool Calling:架构对比](#六、MCP vs 直接Tool Calling:架构对比)
-
- [6.1 直接Tool Calling方式(之前的做法)](#6.1 直接Tool Calling方式(之前的做法))
- [6.2 MCP Client方式(新做法)](#6.2 MCP Client方式(新做法))
- [6.3 对比表](#6.3 对比表)
- [6.4 选择策略](#6.4 选择策略)
- 七、MCP协议深度探讨
-
- [7.1 MCP的Request-Response模式](#7.1 MCP的Request-Response模式)
- Request格式
- Response格式
- [7.2 参数自动映射](#7.2 参数自动映射)
- [7.3 连接池与健康检查](#7.3 连接池与健康检查)
- 八、生产环保的最佳实践
- 九、实战案例:多Agent系统架构
- 十、常见问题与故障排查
-
- [10.1 "Tool not found" 错误](#10.1 "Tool not found" 错误)
- [10.2 网络延迟](#10.2 网络延迟)
- [10.3 Server宕机处理](#10.3 Server宕机处理)
- 十一、总结与展望
-
- [11.1 MCP Client的核心价值](#11.1 MCP Client的核心价值)
- [11.2 MCP的未来](#11.2 MCP的未来)
- [11.3 学习路线](#11.3 学习路线)
- [11.4 与我们之前学到的内容的联系](#11.4 与我们之前学到的内容的联系)
- 总结

引言
当我们的AI Agent功能足够丰富时,一个新的问题浮现出来:如何让多个独立的Agent系统共享工具能力?
考虑这样的场景:
- 一个天气查询服务单独部署在8082端口,提供"获取天气"工具
- 一个医疗咨询Agent部署在8081端口,需要调用天气工具
- 两个系统怎样才能优雅地协作,而不是把工具代码重复写一遍?
MCP(Model Context Protocol)协议 应运而生。它是Anthropic定义的一套标准化协议,用于AI模型与外部工具服务进行通信。Spring AI从1.1.0版本开始原生支持MCP Client,让我们可以:
- 动态发现远程MCP Server提供的所有工具
- 跨进程调用这些工具,就像本地工具一样自然
- 简化部署------工具无需重复编码,可以被多个Agent共享
本文将深入讲解MCP协议的设计理念、Spring AI的实现方式,以及如何通过仅仅几行配置,让你的Agent获得访问远程工具服务的能力。
一、MCP协议概念:标准化的工具连接
1.1 为什么需要MCP?
在MCP出现之前,工具调用是这样的:
java
┌─────────────────────────┐
│ Agent 1 (8081) │
│ ├─ Tool A │
│ ├─ Tool B │
│ └─ Tool C │
└─────────────────────────┘
┌─────────────────────────┐
│ Agent 2 (8082) │
│ ├─ Tool A (重复) │
│ ├─ Tool B (重复) │
│ └─ Tool D │
└─────────────────────────┘
问题多多:
- 工具代码重复维护
- 工具版本不一致
- 扩展新工具需要修改多处代码
- 微服务之间缺乏标准的工具调用协议
MCP的出现改变了这一切:
java
┌──────────────────────┐
│ Agent Client │
│ (8081) │
│ ToolCallbackProvider│────┐
└──────────────────────┘ │
│ MCP Protocol
│ (HTTP/WebSocket)
▼
┌──────────────────────┐
│ MCP Server │
│ (8082) │
│ ├─ Weather Tool │
│ ├─ Config Resource │
│ └─ Greeting Prompt │
└──────────────────────┘
1.2 MCP的三大核心概念
工具(Tools)
MCP Server暴露的可执行函数,Client可以通过标准协议调用。
比如WeatherService的getWeather方法:
java
@McpTool(description = "获取指定城市的天气")
public String getWeather(String cityName) {
// ... 实现
}
资源(Resources)
MCP Server暴露的数据资源,可以被Client读取。用于传输静态配置、模板等。
java
@McpResource(uri = "config://{key}", name = "configuration")
public String getConfig(String key) {
return environment.getProperty(key, "123");
}
提示词(Prompts)
MCP Server定义的预设提示模板,Client可以请求并使用这些模板。
java
@McpPrompt(name = "greeting", description = "欢迎语")
public McpSchema.GetPromptResult greeting(@McpArg(name = "name") String name) {
String message = "你好, " + name + "! 有什么可以帮您?";
return new McpSchema.GetPromptResult(...);
}
1.3 MCP的设计哲学
标准化:所有MCP Server都遵循同一套接口规范,Client无需关心具体实现。
解耦:Server和Client独立部署、独立升级,通过协议通信。
动态发现:Client启动时自动探测Server的所有能力(tools、resources、prompts),不需要硬编码工具列表。
协议中立:MCP本身与传输层无关,可以用HTTP、WebSocket、stdio等多种方式实现。
二、MCP架构设计:Client-Server通信模式
2.1 整体架构图
java
┌─────────────────────────────────────────────────────────────┐
│ Spring AI Application │
│ │
│ ┌──────────────────────────────────────────────────────┐ │
│ │ ChatClient │ │
│ │ (负责与大模型交互) │ │
│ └──────────────────────────────────────────────────────┘ │
│ ▲ │
│ │ │
│ ┌──────────────────────┴──────────────────────────────┐ │
│ │ │ │
│ │ ToolCallbackProvider.getToolCallbacks() │ │
│ │ (动态加载MCP Server的工具) │ │
│ │ │ │
│ └──────────────────────┬──────────────────────────────┘ │
└─────────────────────────┼──────────────────────────────────┘
│
┌─────────┴─────────┐
│ MCP HTTP Client │
│ Connection Pool │
└─────────┬─────────┘
│
MCP Protocol (HTTP)
streamable-http://
│
┌─────────▼─────────┐
│ MCP Server │
│ (8082) │
│ │
│ ┌──────────────┐ │
│ │ WeatherTool │ │
│ │ ConfigResource │
│ │ GreetingPrompt │
│ └──────────────┘ │
└───────────────────┘
2.2 通信流程
阶段1:初始化与发现(Startup)
- MCP Client启动时,连接到Server
- 发送initialize请求,告诉Server客户端信息
- Server响应,返回自己支持的协议版本
- Client发送list-tools请求,获取所有可用工具
- Server返回工具列表,包含工具名、描述、参数schema
java
Client Server
│ │
├──────── initialize ─────────►│
│ │
│◄─── initialize response ─────┤
│ │
├──────── list-tools ─────────►│
│ │
│◄─── [getWeather, ...] ───────┤
阶段2:工具调用(Tool Calling)
当大模型决定调用工具时:
java
┌─ ChatClient ──────────────────────────────┐
│ prompt: "上海天气怎样?" │
│ tools: [getWeather, ...] │
│ (tools来自MCP Server) │
└────────────┬──────────────────────────────┘
│
▼
┌─ LLM Response ────────────────┐
│ { │
│ "tool_calls": [ │
│ { │
│ "id": "call_123", │
│ "function": { │
│ "name": "getWeather", │
│ "arguments": { │
│ "cityName": "上海" │
│ } │
│ } │
│ } │
│ ] │
│ } │
└────────────┬──────────────────┘
│
▼
┌─ ToolCallbackProvider ────────────────────┐
│ 1. 识别工具名: getWeather │
│ 2. 从MCP Server动态调用 │
│ 3. 返回结果: "天晴" │
└────────────┬──────────────────────────────┘
│
▼
┌─ ChatClient ──────────────────────────────┐
│ 添加tool message到memory │
│ 继续与LLM交互 │
└────────────────────────────────────────────┘
2.3 ToolCallbackProvider的职责
ToolCallbackProvider是Spring AI中的关键接口,负责:
- 工具发现:启动时连接MCP Server,获取所有工具定义
- 生成Callbacks:为每个工具创建可调用的Callback对象
- 动态绑定:大模型调用工具时,动态找到对应Callback并执行
伪代码如下:
java
public class McpToolCallbackProvider implements ToolCallbackProvider {
private final MCP_CLIENT mcpClient; // MCP HTTP客户端
public List<ToolCallback> getToolCallbacks() {
// 1. 从MCP Server发送list-tools请求
List<Tool> tools = mcpClient.listTools();
// 2. 为每个工具创建动态Callback
return tools.stream()
.map(tool -> createCallback(tool))
.toList();
}
private ToolCallback createCallback(Tool tool) {
return new ToolCallback() {
@Override
public String getName() {
return tool.getName();
}
@Override
public String getDescription() {
return tool.getDescription();
}
@Override
public String call(String arguments) {
// 3. 实际调用:远程调用MCP Server的工具
return mcpClient.callTool(tool.getName(), arguments);
}
};
}
}
三、依赖引入与项目配置
3.1 添加MCP Client依赖
在spring-ai-demo/pom.xml中,与其他Spring AI依赖并列添加:
xml
<dependencies>
<!-- 现有依赖... -->
<dependency>
<groupId>org.springframework.ai</groupId>
<artifactId>spring-ai-starter-mcp-client</artifactId>
</dependency>
</dependencies>
这个依赖包含:
MCP Client核心库HTTP连接器(streamable-http)ToolCallbackProvider实现
3.2 MCP Server端配置
在spring-ai-mcp-server-demo/src/main/resources/application.yml中:
yaml
spring:
ai:
mcp:
server:
name: weather-mcp-server # Server名称
protocol: streamable # 使用HTTP协议
server:
port: 8082 # 独立端口
关键点:
protocol: streamable表示使用HTTP SSE(Server-Sent Events)方式- 端口8082与Client的配置相对应
3.3 MCP Client端配置
在spring-ai-demo/src/main/resources/application.yml中:
yaml
spring:
ai:
mcp:
client:
name: spring-ai-mcp-client-demo # Client名称,标识自己
streamable-http: # HTTP连接方式
connections:
server1: # 连接名(任意)
url: http://localhost:8082 # MCP Server地址
重要参数说明:
| 参数 | 说明 | 示例 |
|---|---|---|
name |
当前应用在MCP中的标识 | spring-ai-mcp-client-demo |
connections |
可以连接多个MCP Server | 下例支持多Server |
url |
MCP Server的HTTP入口 | http://localhost:8082 |
多Server配置示例:
yaml
spring:
ai:
mcp:
client:
streamable-http:
connections:
weather-server:
url: http://localhost:8082
config-server:
url: http://config-server:9000
search-server:
url: http://search-server:9001
此时Client会自动发现三个Server的所有工具。
四、MCP Server端实现详解
4.1 WeatherService:工具提供者
MCP Server通过@McpTool注解声明工具:
java
@Service
@Log4j2
public class WeatherService {
@Autowired
private Environment environment;
// 工具1:获取天气
@McpTool(description = "获取指定城市的天气")
public String getWeather(String cityName) {
log.info("正在获取天气信息...");
if (cityName.equals("上海")) {
return "天晴";
} else if (cityName.equals("北京")) {
return "下雨";
}
return "不知道";
}
// 工具2:问候提示词
@McpPrompt(name = "greeting", description = "欢迎语")
public McpSchema.GetPromptResult greeting(@McpArg(name = "name") String name) {
String message = "你好, " + name + "! 有什么可以帮您?";
return new McpSchema.GetPromptResult(
"Greeting",
List.of(new McpSchema.PromptMessage(
McpSchema.Role.ASSISTANT,
new McpSchema.TextContent(message)
))
);
}
// 工具3:配置资源
@McpResource(uri = "config://{key}", name = "configuration")
public String getConfig(String key) {
return environment.getProperty(key, "123");
}
}
三种能力详解:
@McpTool - 可调用的函数工具
java
@McpTool(description = "获取指定城市的天气")
public String getWeather(String cityName) { ... }
- 可被Client动态调用
- 参数自动序列化为JSON Schema
- 返回值作为工具执行结果
当Client调用时,MCP协议自动处理:
json
{
"jsonrpc": "2.0",
"method": "tools/call",
"params": {
"name": "getWeather",
"arguments": {
"cityName": "上海"
}
}
}
@McpResource - 只读数据资源
java
@McpResource(uri = "config://{key}", name = "configuration")
public String getConfig(String key) { ... }
- URI模板:支持参数化读取
- 读取示例 :
config://spring.datasource.url→ 返回数据库地址 - 用途:共享配置、常量、模板等静态资源
@McpPrompt - 预设提示词模板
java
@McpPrompt(name = "greeting", description = "欢迎语")
public McpSchema.GetPromptResult greeting(@McpArg(name = "name") String name) { ... }
- 提供预编写的提示词
- 支持参数化(如用户名)
- 用途:系统级别的提示词模板共享
4.2 MCP Server的启动配置
java
@SpringBootApplication
public class McpServerApplication {
// 注意:不需要手动配置ToolCallbackProvider
// Spring AI会自动扫描@McpTool @McpResource @McpPrompt注解
// 并通过MCP协议暴露这些能力
public static void main(String[] args) {
SpringApplication.run(McpServerApplication.class, args);
}
}
重要:Spring AI自动检测并注册所有带MCP注解的Bean,无需手动配置。
五、MCP Client端实现详解
5.1 McpController:工具调用的入口
java
@RestController
public class McpController {
@Autowired
private ChatClient chatClient;
@Autowired
private ToolCallbackProvider toolCallbackProvider;
@GetMapping("/mcp")
public String mcp(String message) {
return chatClient
.prompt()
.user(message)
.toolCallbacks(toolCallbackProvider.getToolCallbacks())
.call()
.content();
}
}
逐行解析:
-
ToolCallbackProvider toolCallbackProvider- Spring AI自动注入
- 负责从MCP Server动态加载工具
-
toolCallbackProvider.getToolCallbacks()- 返回所有可用工具的Callback列表
- 这些Callback会被传给大模型
- 大模型可以选择调用其中任何一个
-
.toolCallbacks(...)- 将MCP Server的工具注入到ChatClient
- 大模型现在可以使用这些工具
-
完整执行流:
java
GET /mcp?message=上海天气怎样?
│
▼
User: "上海天气怎样?"
Tools: [getWeather (from MCP Server)] ◄── 动态加载
│
▼
LLM Response: tool_calls=[getWeather(cityName="上海")]
│
▼
ToolCallbackProvider.call("getWeather", {...})
│
▼
MCP Client → HTTP → MCP Server
tools/call getWeather
│
▼
MCP Server: "天晴"
│
▼
LLM: "根据天气工具的反馈,上海天晴"
│
▼
返回给用户
5.2 实际测试
启动两个应用后,测试MCP调用:
bash
# MCP Server启动在8082
cd spring-ai-mcp-server-demo
mvn spring-boot:run
# MCP Client启动在8081
cd spring-ai-demo
mvn spring-boot:run
# 测试调用
curl "http://localhost:8081/mcp?message=上海天气怎样?"
预期输出:
java
根据我获取的天气信息,上海天晴。
背后的调用链:
- Client的ChatClient收到请求
- 向大模型提交用户问题 + MCP Server暴露的工具列表
- 大模型选择调用
getWeather("上海") - ToolCallbackProvider通过MCP协议远程调用
- 得到"天晴"的结果
- 反馈给大模型继续推理
- 大模型生成最终回复
六、MCP vs 直接Tool Calling:架构对比
6.1 直接Tool Calling方式(之前的做法)
java
@Configuration
public class ToolConfig {
@Bean
public ToolCallbackProvider localTools(WeatherService weatherService) {
// 把WeatherService的方法注册为本地工具
return MethodToolCallbackProvider.builder()
.toolObjects(weatherService)
.build();
}
}
@RestController
public class ChatController {
@GetMapping("/chat")
public String chat(String message) {
return chatClient.prompt()
.user(message)
.toolCallbacks(localTools.getToolCallbacks()) // 本地工具
.call()
.content();
}
}
特点:
- 工具与Agent紧密耦合
- 工具代码必须与Agent在同一进程
- 工具更新需要重启Agent应用
6.2 MCP Client方式(新做法)
yaml
# 仅需配置,无需代码
spring:
ai:
mcp:
client:
streamable-http:
connections:
server1:
url: http://localhost:8082
java
@RestController
public class McpController {
@GetMapping("/mcp")
public String mcp(String message) {
return chatClient.prompt()
.user(message)
.toolCallbacks(toolCallbackProvider.getToolCallbacks()) // 远程工具
.call()
.content();
}
}
特点:
- 工具独立部署
- Agent与工具解耦
- 动态发现,无需硬编码
- 工具更新无需重启Agent
6.3 对比表
| 维度 | 直接Tool Calling | MCP Client |
|---|---|---|
| 部署方式 | 单一进程 | 多进程 |
| 通信方式 | 方法调用 | HTTP/WebSocket RPC |
| 工具发现 | 硬编码注册 | 动态发现 |
| 工具复用 | 重复编码 | 一次部署,多处使用 |
| 更新影响 | 需重启Agent | 仅Server重启 |
| 网络延迟 | 无 | 有(毫秒级) |
| 扩展性 | 中等 | 高 |
| 适用场景 | 小型单体应用 | 微服务、多Agent系统 |
6.4 选择策略
选用直接Tool Calling:
- Agent数量少(1-2个)
- 工具相对稳定,不常更新
- 工具逻辑简单,计算量小
- 无网络延迟要求
选用MCP Client:
- Agent数量多(3个以上)
- 工具经常更新迭代
- 多个Agent共享相同工具
- 工具可能部署在不同机器/容器
- 需要微服务架构
七、MCP协议深度探讨
7.1 MCP的Request-Response模式
所有通信都遵循JSON-RPC 2.0标准:
Request格式
json
{
"jsonrpc": "2.0",
"id": "1",
"method": "tools/call",
"params": {
"name": "getWeather",
"arguments": {
"cityName": "上海"
}
}
}
Response格式
json
{
"jsonrpc": "2.0",
"id": "1",
"result": {
"content": [
{
"type": "text",
"text": "天晴"
}
]
}
}
或错误响应:
json
{
"jsonrpc": "2.0",
"id": "1",
"error": {
"code": -32600,
"message": "Invalid Request",
"data": {
"details": "city not found"
}
}
}
7.2 参数自动映射
MCP Server会自动将Java方法签名转换为JSON Schema,供Client理解:
java
@McpTool(description = "获取指定城市的天气")
public String getWeather(String cityName) { ... }
自动生成的Schema:
json
{
"name": "getWeather",
"description": "获取指定城市的天气",
"inputSchema": {
"type": "object",
"properties": {
"cityName": {
"type": "string",
"description": "城市名称"
}
},
"required": ["cityName"]
}
}
LLM看到这个Schema,就知道如何调用这个工具。
7.3 连接池与健康检查
Spring AI MCP Client维护HTTP连接池,定期检查Server健康状态:
yaml
spring:
ai:
mcp:
client:
streamable-http:
connections:
server1:
url: http://localhost:8082
# 可选:配置连接超时
timeout: 30s
# 可选:配置心跳间隔
heartbeat-interval: 60s
如果Server不可用,Client会:
- 记录日志
- 标记连接为"不可用"
- 继续尝试重连
- 大模型无法使用该Server的工具(但不会崩溃)
八、生产环保的最佳实践
8.1 错误处理
MCP工具执行失败时,大模型应该收到错误信息:
java
@McpTool(description = "获取指定城市的天气")
public String getWeather(String cityName) {
try {
// 调用天气API
WeatherData data = weatherApi.fetch(cityName);
return data.getDescription();
} catch (CityNotFoundException e) {
// 返回有意义的错误信息
return "Error: 城市 " + cityName + " 不存在";
} catch (ApiTimeoutException e) {
return "Error: 天气服务暂时不可用,请稍后重试";
}
}
大模型会收到这个错误信息,并可能:
- 重新尝试
- 使用备选方案
- 向用户解释为什么无法获取信息
8.2 日志与监控
在Server端详细记录所有工具调用:
java
@McpTool(description = "获取指定城市的天气")
public String getWeather(String cityName) {
log.info("MCP Tool called: getWeather, cityName={}", cityName);
long startTime = System.currentTimeMillis();
try {
String result = fetchWeather(cityName);
long elapsed = System.currentTimeMillis() - startTime;
log.info("MCP Tool success: getWeather, cityName={}, elapsed={}ms",
cityName, elapsed);
return result;
} catch (Exception e) {
log.error("MCP Tool error: getWeather, cityName={}", cityName, e);
throw e;
}
}
关键指标:
- 工具调用次数
- 调用延迟(网络+执行)
- 错误率
- Server连接状态
8.3 版本兼容性
Server和Client的版本可以不同步,但要保持兼容:
java
// Server更新添加新参数时
@McpTool(description = "获取天气")
public String getWeather(
String cityName,
@McpArg(required = false) String timestamp // 新参数,但可选
) {
// 旧Client发送的请求不包含timestamp,也能正常工作
}
8.4 安全性考虑
认证与授权
yaml
spring:
ai:
mcp:
client:
streamable-http:
connections:
secure-server:
url: https://secure-server:8082
auth:
type: bearer
token: ${MCP_SERVER_TOKEN} # 环境变量
速率限制
java
@McpTool(description = "获取天气")
@RateLimit(requestsPerMinute = 60)
public String getWeather(String cityName) { ... }
九、实战案例:多Agent系统架构
假设你要构建一个企业级AI系统,包含三个独立Agent:
java
┌─────────────────────┐
│ ChatBot Agent │ 8081
│ (对话机器人) │
└──────────┬──────────┘
│ MCP
├─────────┬─────────┬──────────┐
│ │ │ │
┌──────▼───┐ ┌───▼────┐ ┌─▼──────┐ ┌▼────────┐
│ Weather │ │ Config │ │ Search │ │Database │
│ Service │ │Service │ │Service │ │Service │
│ 8082 │ │ 8083 │ │ 8084 │ │ 8085 │
└──────────┘ └────────┘ └────────┘ └─────────┘
在ChatBot Agent的配置中:
yaml
spring:
ai:
mcp:
client:
name: chatbot-mcp-client
streamable-http:
connections:
weather:
url: http://localhost:8082
config:
url: http://localhost:8083
search:
url: http://localhost:8084
database:
url: http://localhost:8085
现在ChatBot Agent可以:
- 调用WeatherService获取天气
- 调用ConfigService查询配置
- 调用SearchService搜索网络
- 调用DatabaseService查询数据库
这些服务可以独立部署、独立更新、独立扩展,ChatBot完全无感知。
十、常见问题与故障排查
10.1 "Tool not found" 错误
现象:大模型要调用某个工具,但系统报错"Tool not found"
原因:
- MCP Server未启动
- Server地址配置错误
- 工具定义有问题
排查步骤:
bash
# 1. 检查Server是否在线
curl http://localhost:8082/health # 如果有health endpoint
# 2. 检查Client日志
# 查看是否有"Connected to MCP Server"的日志
# 3. 手动测试工具列表
# 在Client启动日志中应该看到工具列表被加载
# 4. 验证工具名称拼写
# 确保Client请求的工具名与Server定义的完全相同
10.2 网络延迟
现象:工具调用很慢
原因:
- HTTP连接开销
- 网络距离远
- Server处理慢
优化方案:
yaml
# 1. 启用连接复用
spring:
ai:
mcp:
client:
streamable-http:
connections:
server1:
url: http://localhost:8082
keep-alive: true
connection-timeout: 5s
# 2. 部署Server靠近Client
# 使用容器编排工具(Docker, K8s)确保网络延迟<10ms
# 3. 考虑使用WebSocket而非HTTP
# WebSocket长连接开销更小(未来版本)
10.3 Server宕机处理
现象:Server无响应,Client应用停滞
原因:Client等待Server响应超时
解决方案:
yaml
spring:
ai:
mcp:
client:
streamable-http:
connections:
server1:
url: http://localhost:8082
timeout: 10s # 设置合理超时
retry:
max-attempts: 3
backoff: exponential
此时大模型仍可用,只是无法调用该Server的工具。
十一、总结与展望
11.1 MCP Client的核心价值
| 能力 | 收益 |
|---|---|
| 动态工具发现 | 无需硬编码工具列表 |
| 工具共享 | 一个工具,多个Agent使用 |
| 独立演进 | Server和Client独立开发 |
| 微服务支持 | 适配容器化部署 |
| 协议标准化 | 与Anthropic官方工具无缝对接 |
11.2 MCP的未来
Anthropic宣布MCP成为AI Agent的通用标准:
- 语言无关:Java、Python、Node.js都有SDK
- AI模型无关:Claude、GPT、开源模型都支持
- 工具市场:未来可能出现MCP工具市场,类似npm
- IDE集成:开发工具将内置MCP支持
11.3 学习路线
java
基础 → 进阶 → 生产
│ │ │
├─────┴──────┴──────────────────────┐
│ │
▼ ▼
单Server工具调用 多Server容器化部署
↓ ↓
本地测试 Kubernetes编排
↓ ↓
性能优化 工具市场集成
11.4 与我们之前学到的内容的联系
java
Spring AI学习路线:
第1步: Tool Calling基础 (直接调用本地工具)
↓
第2步: RAG + Memory (增强知识库与记忆)
↓
第3步: MCP Client(本文) (远程工具调用)
↓
第4步: 多Agent系统 (多个Agent协作)
↓
第5步: 生产化部署 (容器、监控、高可用)
本文介绍的MCP Client正是从单Agent应用到多Agent系统的关键桥梁。
总结
通过MCP(Model Context Protocol),我们打破了Agent与工具的紧耦合关系:
- 工具变成了独立服务,可以单独部署和演进
- 大模型获得了远程工具调用的能力,就像使用本地工具一样自然
- 多个Agent可以共享同一套工具,避免代码重复
- 系统整体的扩展性和灵活性得到了质的提升
MCP的出现,标志着AI Agent从"单体应用"走向"分布式系统"的开始。
在下一篇文章中,我们将深入多Agent系统的设计与实现------如何让多个Agent之间互相通信、协作完成复杂任务。
