目录:
- [一、为什么需要 MCP?](#一、为什么需要 MCP?)
- [二、MCP 的两种通信方式](#二、MCP 的两种通信方式)
- [三、STDIO 方式详解](#三、STDIO 方式详解)
-
- [1. MCP Server(服务端)](#1. MCP Server(服务端))
-
- [① 使用现成的公共 MCP Server](#① 使用现成的公共 MCP Server)
- [② 自定义 STDIO MCP Server](#② 自定义 STDIO MCP Server)
- [2. MCP Client(客户端)调用 STDIO](#2. MCP Client(客户端)调用 STDIO)
一、为什么需要 MCP?
在 AI 应用爆发式增长的今天,我们常常面临两个痛点:
- 服务商想开放工具:比如高德地图提供位置查询、百度提供联网搜索,但每个服务商都有自己的 API 格式,调用方式千差万别。
- 企业内部多应用共享工具:多个智能应用都想使用同一套内部工具(如订单查询、用户画像),如果每个应用各自接入,重复造轮子且维护成本极高。
解决方案很简单:把 Tools 单独抽取出来,由应用程序统一读取外部 Tools。
但问题随之而来------怎么读?怎么解析?
如果每个提供商各用一套规则,想象一下对接几十个不同 API 的混乱场面......
于是 MCP(Model Context Protocol) 应运而生。
MCP 指定了 标准通信规则,以 JSON‑RPC 2.0 格式进行交互,彻底统一了 Tools 的暴露与调用方式。

二、MCP 的两种通信方式
MCP 官方提供了两种主流传输方式:


三、STDIO 方式详解
1. MCP Server(服务端)
① 使用现成的公共 MCP Server
网上已有大量现成的 MCP 服务,例如:
- MCP Server 聚合站 提供了百度地图、文件系统、天气查询等众多 MCP Server。

② 自定义 STDIO MCP Server
下面我们用 Spring AI 创建一个自定义的 STDIO MCP Server。
第一步:添加依赖(pom.xml)
yaml
<!-- MCP Server 依赖 -->
<dependency>
<groupId>org.springframework.ai</groupId>
<artifactId>spring-ai-starter-mcp-server</artifactId>
</dependency>
<!-- Spring AI BOM 管理 -->
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.ai</groupId>
<artifactId>spring-ai-bom</artifactId>
<version>${spring-ai.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
<!-- 打包插件(用于生成可执行 jar) -->
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<executions>
<execution>
<goals>
<goal>repackage</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
第二步:编写 Tool 服务
java
@Service
public class UserToolService {
Map<String, Double> userScore = Map.of(
"xushu", 99.0,
"zhangsan", 2.0,
"lisi", 3.0
);
@Tool(description = "获取用户分数")
public String getScore(String username) {
if (userScore.containsKey(username)) {
return userScore.get(username).toString();
}
return "未检索到当前用户 " + username;
}
}
第三步:暴露 Tool
java
@Bean
public ToolCallbackProvider weatherTools(UserToolService userToolService) {
return MethodToolCallbackProvider.builder()
.toolObjects(userToolService)
.build();
}
第四步:配置文件(application.yml)
yaml
spring:
main:
banner-mode: off # 必须关闭横幅,否则影响 STDIO 通信
ai:
mcp:
server:
name: my-weather-server
version: 0.0.1
⚠️ 注意:必须禁用横幅和控制台日志,否则会污染标准输入输出流,导致 MCP 通信失败。
第五步:打包
执行 mvn package,在 target/ 下生成可执行 jar 包。
2. MCP Client(客户端)调用 STDIO
第一步:依赖
yaml
<dependency>
<groupId>org.springframework.ai</groupId>
<artifactId>spring-ai-starter-mcp-client-webflux</artifactId>
</dependency>
第二步:配置 application.yml
yaml
spring:
ai:
mcp:
client:
request-timeout: 60000
stdio:
servers-configuration: classpath:/mcp-servers-config.json
connections:
server1:
command: /path/to/server
args:
- --port=8080
- --mode=production
env:
API_KEY: your-api-key
DEBUG: "true"
第三步:mcp-servers-config.json(放在 resources 下)
yaml
{
"mcpServers": {
"baidu-map": {
"command": "cmd",
"args": ["/c", "npx", "-y", "@baidumap/mcp-server-baidu-map"],
"env": {
"BAIDU_MAP_API_KEY": "你的百度地图Key"
}
},
"mcp-server-weather": {
"command": "java",
"args": [
"-Dspring.ai.mcp.server.stdio=true",
"-Dlogging.pattern.console=",
"-jar",
"D:\\xxx\\target\\mcp-stdio-server.jar"
]
}
}
}
第四步:绑定到 ChatClient
java
@RestController
public class OpenAiController {
private final ChatClient chatClient;
public OpenAiController(DashScopeChatModel dashScopeChatModel,
ToolCallbackProvider mcpTools) {
this.chatClient = ChatClient.builder(dashScopeChatModel)
.defaultToolCallbacks(mcpTools)
.build();
}
@GetMapping(value = "/ai/generateStream", produces = MediaType.TEXT_EVENT_STREAM_VALUE)
public Flux<String> generateStream(@RequestParam String message) {
return chatClient.prompt()
.user(message)
.stream()
.content();
}
}
待完善。。。。。。