MCP 实现
MCP(Model Context Protocol)是一种标准化的大语言模型工具调用交互协议,旨在实现AI工具安全高效地调用本地/远程资源。该协议定义了5个核心角色(主机、客户端、服务器、本地/远程数据源),支持两种实现方式:基于stdio的嵌入式本地调用和基于SSE的远程服务调用。MCP通过@Tool注解封装工具方法,实现与FunctionCall类似但更标准化的功能,特别强调通信协议标准化和
MCP(Model Context Protocol)本质是标准化的 LLM 工具调用交互规范,核心目标是让 AI 工具(如 Claude Desktop、IDE 插件)安全、高效地调用封装了本地 / 远程资源的 “能力服务”,其实现逻辑与 Function Call 一致,但更强调 “通信协议标准化” 和 “多场景适配(本地 / 远程)”。
MCP 是一个开放协议,它标准化了应用程序如何向大语言模型(LLMs)提供上下文。
MCP 核心角色
MCP 的实现依赖 5 个核心角色,各角色分工明确,共同完成 “工具调用” 闭环:
|
角色 |
核心职责 |
示例 |
|
MCP 主机(Host) |
发起工具调用需求的 “业务方”,即 MCP 能力的使用者 |
Trae、Claude Desktop、IDE 插件、AI 问答工具 |
|
MCP 客户端(Client) |
遵循 MCP 协议的 “通信代理”,负责与 MCP 服务器建立连接、传递调用请求、接收结果 |
基于 stdio/SSE 的 Spring AI 客户端 |
|
MCP 服务器(Server) |
封装 “工具能力” 的 “服务提供方”,暴露可调用的工具(如天气查询、数据库访问) |
本地嵌入式服务、远程 HTTP 服务 |
|
本地数据源 |
MCP 服务器可安全访问的本地资源(避免 Host 直接操作) |
本地文件、MySQL 数据库、本地 API |
|
远程服务 |
MCP 服务器可调用的外部互联网服务 |
天气 API(OpenMeteo)、支付接口 |
MCP 两种实现方式
- 基于 stdio(标准输入输出)
-
- 适用场景:嵌入式、单机部署,客户端直接启动服务端子进程。
- 特点:轻量、无网络依赖,适合本地工具(如文件读取、系统命令)。
- 实现关键:
-
-
- 服务端需设置
spring.main.web-application-type=none - 启动参数包含
-Dspring.ai.mcp.server.stdio=true - 客户端通过
StdioClientTransport管理子进程 。
- 服务端需设置
-
- 基于 SSE(Server-Sent Events)
-
- 适用场景:远程服务、多客户端共享、云原生部署。
- 特点:基于 HTTP/HTTPS,可跨网络调用,支持负载均衡。
- 实现关键:
-
-
- 服务端作为 WebFlux 应用运行在指定端口(如 8080)
- 客户端通过
WebFluxSseClientTransport连接
-
两种方式在业务逻辑层完全一致——都通过 @Tool 注解暴露方法

MCP 客户端实现
客户端的核心是 “按协议与服务器通信”,分为本地 stdio 模式(同一机器,子进程交互)和远程 SSE 模式(跨机器,HTTP 交互),两者实现差异集中在 “连接方式” 和 “配置”。
本地 stdio 模式(适合嵌入式场景)
核心特点
客户端与服务器在同一台机器,客户端通过 “启动服务器子进程”,用标准输入输出流(stdio)通信,无需网络,延迟低。
实现步骤
- 添加依赖(Spring AI MCP 客户端 starter)
<!-- 本地stdio模式依赖 -->
<dependency>
<groupId>org.springframework.ai</groupId>
<artifactId>spring-ai-mcp-client-spring-boot-starter</artifactId>
</dependency>
- 配置服务器(application.yml + JSON 配置文件)
-
- application.yml:指定服务器配置文件路径,或直接配置启动命令
spring:
ai:
dashscope: # 若调用远程LLM(如通义千问),配置API密钥
api-key: ${DASH_SCOPE_API_KEY}
mcp:
client:
stdio:
# 方式1:指定服务器配置文件(推荐,分离配置)
servers-configuration: classpath:/mcp-servers-config.json
# 方式2:直接配置(适合简单场景)
# connections:
# server1:
# command: java
# args: [-jar, /path/to/mcp-server.jar]
-
- mcp-servers-config.json:定义服务器启动参数(如命令、JVM 参数)
{
"mcpServers": {
"weather-server": { # 服务器名称(自定义)
"command": "java", # 启动命令
"args": [
"-Dspring.ai.mcp.server.stdio=true", # 启用stdio模式
"-Dspring.main.web-application-type=none", # 禁用Web服务(本地子进程)
"-jar",
"/path/to/weather-mcp-server.jar" # 服务器Jar包路径
],
"env": {} # 可选:环境变量(如数据库密码)
}
}
}
- 代码实现:构建 ChatClient,注入 MCP 工具
@SpringBootApplication
public class McpStdioClientApplication {
public static void main(String[] args) {
SpringApplication.run(McpStdioClientApplication.class, args);
}
// 注入工具和ChatClient,执行查询
@Bean
public CommandLineRunner runTool(
ChatClient.Builder chatClientBuilder,
ToolCallbackProvider tools, // MCP工具自动注入
ConfigurableApplicationContext context) {
return args -> {
// 1. 构建支持MCP工具的ChatClient
ChatClient chatClient = chatClientBuilder
.defaultTools(tools) // 注入MCP服务器的工具(如天气查询)
.build();
// 2. 调用工具:查询北京天气(触发MCP客户端向服务器发请求)
String userQuery = "北京的天气如何?";
System.out.println(">>> 问题:" + userQuery);
String result = chatClient.prompt(userQuery).call().content();
System.out.println(">>> 结果:" + result);
context.close();
};
}
}
远程 SSE 模式(适合多客户端共享场景)
核心特点
服务器独立部署(如远程服务器、云服务),客户端通过Server-Sent Events(SSE) 协议(HTTP 长连接)与服务器通信,支持多客户端同时调用。
实现步骤
- 添加依赖(支持 SSE 的 MCP 客户端 starter)
<!-- 远程SSE模式依赖 -->
<dependency>
<groupId>org.springframework.ai</groupId>
<artifactId>spring-ai-starter-mcp-client</artifactId>
</dependency>
- 配置服务器(仅需指定远程 URL)
spring:
ai:
dashscope:
api-key: ${DASH_SCOPE_API_KEY}
mcp:
client:
sse:
connections:
weather-server: # 服务器名称
url: http://localhost:8080 # 远程MCP服务器地址(SSE服务端口)
- 代码实现:与 stdio 模式完全一致(协议透明化)
@SpringBootApplication
public class McpSseClientApplication {
public static void main(String[] args) {
SpringApplication.run(McpSseClientApplication.class, args);
}
@Bean
public CommandLineRunner runTool(
ChatClient.Builder chatClientBuilder,
ToolCallbackProvider tools,
ConfigurableApplicationContext context) {
return args -> {
// 代码与stdio模式完全相同,Spring AI自动处理SSE通信
ChatClient chatClient = chatClientBuilder.defaultTools(tools).build();
String result = chatClient.prompt("北京天气?").call().content();
System.out.println(">>> SSE模式结果:" + result);
context.close();
};
}
}
MCP 服务器实现
服务器的核心是 “将能力封装为可调用的工具”,通过@Tool注解标记方法,让客户端自动发现并调用,同样支持 stdio 和 SSE 两种部署模式。
本地 stdio 模式(嵌入式服务器)
核心特点
作为客户端的 “子进程” 启动,无独立端口,禁用 Web 服务,适合本地资源访问(如本地文件、数据库)。
实现步骤:
- 添加依赖(stdio 模式服务器 starter)
<dependency>
<groupId>org.springframework.ai</groupId>
<artifactId>spring-ai-starter-mcp-server-webflux</artifactId>
</dependency>
- 配置服务器(禁用 Web,启用 stdio)
spring:
main:
web-application-type: none # 关键:禁用Web服务(嵌入式子进程)
banner-mode: off # 关闭启动日志(减少干扰)
ai:
mcp:
server:
stdio: true # 启用stdio模式
name: weather-stdio-server # 服务器名称(客户端需匹配)
version: 0.0.1 # 版本号(用于兼容性判断)
- 封装工具:用
@Tool标记可调用方法
// 服务类:封装天气查询能力(调用远程天气API)
@Service
public class WeatherToolService {
private final WebClient webClient;
// 注入WebClient,用于调用远程天气API
public WeatherToolService(WebClient.Builder webClientBuilder) {
this.webClient = webClientBuilder.baseUrl("https://api.open-meteo.com/v1").build();
}
/**
* 工具1:根据经纬度查天气预报
* @Tool:标记为MCP工具,description供客户端识别功能
* @ToolParameter:描述参数,帮助客户端传递正确值
*/
@Tool(description = "根据经纬度获取实时天气预报(温度、风速)")
public String getWeather(
@ToolParameter(description = "纬度,示例:39.9042(北京)") String latitude,
@ToolParameter(description = "经度,示例:116.4074(北京)") String longitude) {
try {
// 调用远程天气API
String apiResult = webClient.get()
.uri(uri -> uri.path("/forecast")
.queryParam("latitude", latitude)
.queryParam("longitude", longitude)
.queryParam("current", "temperature_2m,wind_speed_10m")
.build())
.retrieve()
.bodyToMono(String.class)
.block();
// 格式化结果(实际项目需解析JSON)
return "北京天气:\n" + apiResult;
} catch (Exception e) {
return "查询失败:" + e.getMessage();
}
}
/** 工具2:根据经纬度查空气质量(模拟数据) */
@Tool(description = "根据经纬度获取空气质量(PM2.5、AQI)")
public String getAirQuality(
@ToolParameter(description = "纬度") String latitude,
@ToolParameter(description = "经度") String longitude) {
return "北京空气质量:\nPM2.5: 15 μg/m³(优)\nAQI: 42";
}
}
- 注册工具:让服务器识别并暴露工具
@SpringBootApplication
public class McpStdioServerApplication {
public static void main(String[] args) {
SpringApplication.run(McpStdioServerApplication.class, args);
}
// 注册工具:将WeatherToolService中的@Tool方法暴露给客户端
@Bean
public ToolCallbackProvider weatherTools(WeatherToolService weatherToolService) {
return MethodToolCallbackProvider.builder()
.toolObjects(weatherToolService) // 传入工具类实例
.build();
}
}
远程 SSE 模式(独立服务器)
核心特点
作为独立 Web 服务启动(有端口),支持多客户端远程调用,适合共享能力(如团队内共用的数据库查询工具)。
实现步骤
- 添加依赖(同 stdio 模式,需 WebFlux 支持 SSE)
<dependency>
<groupId>org.springframework.ai</groupId>
<artifactId>spring-ai-starter-mcp-server-webflux</artifactId>
</dependency>
- 配置服务器(指定端口,启用 SSE)
server:
port: 8080 # 独立服务端口(客户端需配置此地址)
spring:
ai:
mcp:
server:
name: weather-sse-server # 服务器名称
version: 0.0.1
# 无需配置stdio=true(默认启用SSE)
- 工具封装与注册:与 stdio 模式完全一致
工具类(WeatherToolService)和注册代码(ToolCallbackProvider)与 stdio 模式相同,Spring AI 自动通过 SSE 协议暴露工具。
- 启动服务器:独立运行
# 打包
mvn clean package -DskipTests
# 启动(独立进程)
java -jar target/weather-sse-server.jar
MCP 客户端与服务器交互流程
两种模式的交互逻辑差异集中在 “连接建立方式”,核心工具调用流程一致(请求→处理→响应)。
stdio 模式交互(本地子进程)
- 客户端启动时,读取
mcp-servers-config.json,执行java -jar命令启动服务器子进程; - 客户端通过 “标准输入流” 向服务器发送工具调用请求(如
getWeather(latitude=39.9042, longitude=116.4074)); - 服务器执行
@Tool方法,通过 “标准输出流” 将结果返回给客户端; - 客户端将结果传递给 Host(如 AI 工具),生成最终回答。
SSE 模式交互(远程 HTTP)
- 客户端启动时,通过配置的
http://localhost:8080建立 SSE 长连接; - 客户端通过 HTTP 请求发送工具调用参数,服务器接收后执行
@Tool方法; - 服务器通过 SSE 流将结果推送给客户端(无需客户端轮询);
- 客户端接收结果,传递给 Host。
MCP 的本质
MCP 与 LLM 的 Function Call 核心目标一致(让 AI 调用外部工具),但 MCP 是更具象的 “交互协议规范”,两者差异如下:
|
维度 |
Function Call(如 OpenAI 函数调用) |
MCP(模型上下文协议) |
|
核心定位 |
工具调用能力(LLM 侧定义) |
工具调用的 “通信 + 封装” 标准化规范 |
|
通信方式 |
依赖 LLM API(如 OpenAI API) |
支持 stdio(本地)、SSE(远程)两种模式 |
|
能力封装 |
需手动定义函数 Schema |
用 注解自动封装,无需手动写 Schema |
|
部署场景 |
多为远程 API 调用 |
支持本地嵌入式、远程共享两种场景 |
|
安全隔离 |
无明确隔离(Host 直接调用工具) |
服务器隔离 Host 与数据源(Host 不直接操作本地资源) |
结论:MCP 是 Function Call 的 “工业化实现”—— 它将 Function Call 的 “工具调用逻辑”,通过标准化协议(stdio/SSE)、注解式工具封装、多场景部署,变成可落地的工程方案。
Function Calling 是‘模型自己会用的工具’,MCP 是‘让模型安全、标准地连接万物的协议’
MCP 核心价值
- 标准化:终结了各家 Function Calling 的碎片化,提供统一接口。
- 解耦:LLM 应用与工具服务完全分离,便于独立开发、部署、升级。
- 安全可控:通过独立服务进程隔离敏感操作(如数据库访问)。
- 生态友好:任何人可开发 MCP Server,形成“AI 工具市场”。
MCP 落地最佳实践
- 工具设计:
-
- 每个
@Tool方法仅做一件事(如 “查天气”“查空气质量” 分开),避免参数过多; - 用
@ToolParameter详细描述参数(含示例),帮助 LLM 生成正确参数。
- 每个
- 错误处理:
-
- 服务器工具方法必须捕获异常,返回 “用户可理解的错误信息”(如 “纬度格式错误,示例:39.9042”)。
- 部署选择:
-
- 本地资源访问(如本地文件、数据库)→ 选 stdio 模式(低延迟、安全);
- 多客户端共享能力(如团队共用工具)→ 选 SSE 模式(方便部署、可扩展)
更多推荐




所有评论(0)