一、系列回顾与本篇定位
1.1 系列回顾
- 第一篇至第十篇:我们完整掌握了 Spring AI 的核心能力 —— 从基础集成、ChatClient、多模型共存、Prompt 工程、结构化输出、Tool Calling、Chat Memory、多模态能力、RAG 实战,到上一篇的 MCP 基础集成(本地工具暴露与 SSE 连接远程 Server)。
- 上一篇核心:我们实现了将本地 Spring 服务暴露为 MCP Server,并通过 SSE 方式连接远程 MCP Server。
1.2 本篇定位
上一篇我们提到,MCP 有两种主要的连接方式:
- SSE (Server-Sent Events):通过 HTTP 连接远程 MCP Server,适合跨网络、跨服务的场景。
- stdio (Standard Input/Output):通过标准输入输出流启动并连接本地 MCP Server 进程,适合接入社区丰富的 Node.js/Python 编写的 MCP 工具。
而社区中绝大多数现成的 MCP Server(如文件系统、浏览器、地图、数据库等)都是通过npm/pip分发,通过stdio方式启动的。
本篇是系列生态接入实战篇,我们将深度实战 Spring AI 通过 stdio 方式接入第三方 MCP 生态:
- 从核心原理出发,理解 MCP stdio 与 SSE 的区别与适用场景。
- 基于百度地图 MCP Server,完整实现 Spring AI 通过 stdio 连接第三方 MCP Server。
- 覆盖 Node.js 环境准备、MCP 配置、API Key 安全管理、功能测试全流程。
- 补充生产环境最佳实践与高频踩坑避坑指南。
二、核心概念:MCP stdio vs SSE
在开始实战之前,我们先明确 MCP 的两种主要连接方式的区别:
| 对比维度 | MCP stdio (标准输入输出) | MCP SSE (Server-Sent Events) |
|---|---|---|
| 连接方式 | 通过标准输入 (stdin) 和标准输出 (stdout) 与本地进程通信 | 通过 HTTP SSE 协议与远程服务通信 |
| 典型场景 | 接入本地运行的第三方 MCP Server(如 npm/pip 安装的工具) | 连接远程部署的 MCP Server(如自己开发的 Spring 服务) |
| 部署依赖 | 需要本地安装对应运行时(如 Node.js、Python) | 仅需网络连接 |
| 性能 | 本地进程通信,延迟极低 | 网络通信,延迟受网络影响 |
| Spring AI 支持 | 1.0 + 版本原生支持 | 1.0 + 版本原生支持 |
简单来说:
- 如果你想接入社区现成的 MCP 工具(如百度地图、文件系统、浏览器),用stdio。
- 如果你想连接自己开发的远程 MCP 服务,用SSE。
三、实战落地:Spring AI 接入百度地图 MCP Server
我们将以百度地图 MCP Server为例,完整实现 Spring AI 通过 stdio 方式接入第三方 MCP 生态,实现天气查询、IP 归属地查询、路线规划等功能。
3.1 环境前提
- JDK 17+、Spring Boot 3.2.x
- Node.js 18+:用于运行 npm 安装的 MCP Server(百度地图 MCP Server 是 Node.js 编写的)
- 阿里云百炼 API Key:配置到环境变量
DASHSCOPE_API_KEY - 百度地图API Key:百度地图
3.2 第一步:引入依赖
在pom.xml中引入 Spring AI Alibaba Starter 与 MCP Client 依赖:
<!-- Spring AI Alibaba Starter --> <dependency> <groupId>com.alibaba.cloud.ai</groupId> <artifactId>spring-ai-alibaba-starter-dashscope</artifactId> <version>1.0.0.2</version> </dependency> <!-- Spring AI MCP Client --> <dependency> <groupId>org.springframework.ai</groupId> <artifactId>spring-ai-mcp-client</artifactId> </dependency>3.3 第二步:准备 Node.js 环境
百度地图 MCP Server 是通过 npm 分发的,需要先安装 Node.js:
- 下载并安装 Node.js 18+
- 验证安装:在终端执行
node -v和npm -v,确保版本正常。
3.4 第三步:配置 MCP Client (stdio 方式)
在src/main/resources目录下创建mcp-server.json5配置文件,用于配置 stdio 方式的 MCP Server:
{ "mcpServers": { "baidu-map": { "command": "nodejs/bin/npx.cmd", "args": ["-y", "@baidumap/mcp-server-baidu-map"], "env": { "BAIDU_MAP_API_KEY": "你的百度地图API Key" } } } }关键配置说明:
command:Node.js 的 npx 命令路径(注意:Windows 和 Mac/Linux 路径不同)- Windows:通常是
"C:\\Program Files\\nodejs\\npx.cmd" - Mac/Linux:通过
which npx查看路径,例如"/usr/local/bin/npx"
- Windows:通常是
args:npx 的参数,-y表示自动确认,@baidumap/mcp-server-baidu-map是百度地图 MCP Server 的 npm 包名env:环境变量,这里需要配置百度地图 API Key
3.5 第四步:配置 application.properties
在application.properties中配置服务端口、Spring AI 和 MCP Client:
server.port=8001 # 编码格式配置 server.servlet.encoding.enabled=true server.servlet.encoding.force=true server.servlet.encoding.charset=UTF-8 spring.application.name=BaiduMcpServer # Spring AI Alibaba 配置 spring.ai.dashscope.api-key=${DASHSCOPE_API_KEY} # ==== MCP Client 配置 (stdio方式) ==== spring.ai.mcp.client.request-timeout=20s spring.ai.mcp.client.toolcallback.enabled=true # 指定MCP Server配置文件路径 spring.ai.mcp.client.stdio.servers-configuration=classpath:/mcp-server.json53.6 第五步:配置 ChatClient 集成 MCP 工具
修改SaaLLMConfig,将 MCP 工具集成到ChatClient中:
import org.springframework.ai.chat.client.ChatClient; import org.springframework.ai.chat.model.ChatModel; import org.springframework.ai.tool.ToolCallbackProvider; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; /** * ChatModel+ChatClient+MCP集成配置类 */ @Configuration public class LLMConfig { /** * 配置带MCP工具支持的ChatClient * ToolCallbackProvider会自动从mcp-server.json5中加载配置的MCP Server工具 */ @Bean public ChatClient chatClient(ChatModel chatModel, ToolCallbackProvider tools) { return ChatClient.builder(chatModel) // 核心:将MCP工具(包括stdio连接的百度地图工具)注册到ChatClient .defaultToolCallbacks(tools.getToolCallbacks()) .build(); } }3.7 第六步:编写测试接口
创建McpClientCallBaiDuMcpController,测试百度地图 MCP Server 的功能:
import jakarta.annotation.Resource; import org.springframework.ai.chat.client.ChatClient; import org.springframework.ai.chat.model.ChatModel; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.RequestParam; import org.springframework.web.bind.annotation.RestController; import reactor.core.publisher.Flux; /** * 百度地图MCP Server测试接口 */ @RestController public class McpClientCallBaiDuMcpController { // 带MCP工具支持的ChatClient(包括百度地图工具) @Resource private ChatClient chatClient; // 普通ChatModel(无MCP工具支持,用于对比) @Resource private ChatModel chatModel; /** * 带MCP支持的对话接口 * 测试示例3:http://localhost:8001/mcp/chat?msg=查询昌平到天安门的路线规划 */ @GetMapping("/mcp/chat") public Flux<String> chat(@RequestParam(name = "msg") String msg) { System.out.println("✅ 使用了MCP工具支持(百度地图)"); return chatClient.prompt(msg).stream().content(); } /** * 普通对话接口(无MCP支持,用于对比) * 测试示例:http://localhost:8001/mcp/chat2?msg=查询昌平到天安门的路线规划 */ @GetMapping("/mcp/chat2") public Flux<String> chat2(@RequestParam(name = "msg") String msg) { System.out.println("❌ 未使用MCP工具支持"); return chatModel.stream(msg); } }八、本篇总结
本篇我们深度实战了 Spring AI 通过 stdio 方式接入第三方 MCP 生态:
- 从核心原理出发,理解了 MCP stdio 与 SSE 的区别与适用场景。
- 基于百度地图 MCP Server,完整实现了 Spring AI 通过 stdio 连接第三方 MCP Server。
- 覆盖了 Node.js 环境准备、MCP 配置、API Key 安全管理、功能测试全流程。
- 补充了生产环境最佳实践与高频踩坑避坑指南。
通过 stdio 方式,我们可以接入社区丰富的 MCP 生态,无需自行开发工具,大幅提升开发效率。