一、系列回顾与本篇定位
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 依赖:
bash
<!-- 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:
bash
{
"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:
bash
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.json5
3.6 第五步:配置 ChatClient 集成 MCP 工具
修改SaaLLMConfig,将 MCP 工具集成到ChatClient中:
java
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 的功能:
java
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 生态,无需自行开发工具,大幅提升开发效率。