用 Spring Boot + Spring AI 接 MCP,我踩过的 6 个连接坑
MCP 这东西看介绍很顺。
标准协议、统一工具入口、还能直接接到 Spring AI 里。很多人第一眼看到时都会觉得:这不就是把外部工具统一接进模型吗?应该挺省事。
但真上手以后,MCP 最常见的问题不是“完全接不上”,而是这种半通不通的状态:
- 客户端起起来了
- 服务端也在跑
- Spring 容器里甚至能注入到 MCP client
- 但模型就是用不到工具
- 或者多连几个服务器以后,工具名、传输层、初始化过程开始互相打架
这篇不讲 MCP 原理,直接讲我认为最容易踩的 6 个连接坑。
先看一个最小配置
Spring AI MCP Client Boot Starter 官方文档给的 YAML 大致是这样:
spring:
ai:
mcp:
client:
enabled: true
name: my-mcp-client
version: 1.0.0
request-timeout: 30s
type: SYNC
sse:
connections:
server1:
url: http://localhost:8080
streamable-http:
connections:
server2:
url: http://localhost:8083
endpoint: /mcp
stdio:
connections:
local-tools:
command: /path/to/server
args:
- --mode=production
文档还说明了两点:
- MCP client bean 会自动配置并可注入
- 工具回调默认是开启的,MCP tools 会以
ToolCallbackProvider的形式提供出来
问题是,“能注入”不等于“这条链已经稳定可用”。
坑 1:传输层选错了,结果一开始就走偏
Spring AI 官方 MCP 文档写得很清楚,客户端支持多种 transport:
STDIOSSEStreamable-HTTPStateless Streamable-HTTP
另外还有一个容易忽略的点:spring-ai-starter-mcp-client 和 spring-ai-starter-mcp-client-webflux 不是一回事。
如果你的应用是同步风格、服务端就是本地进程,STDIO 往往更直接。
如果你是 HTTP 流式通信,就要认真区分 SSE 和 Streamable-HTTP。
如果项目本身已经是 reactive 栈,就别硬套同步 starter。
很多“连接坑”其实第一步就已经埋下了:不是协议坏了,而是 transport 选得不对。
坑 2:应用是 reactive 思路,MCP 却按同步类型在接
官方文档在 MCP Client Starter 里明确给了 type: SYNC 或 ASYNC 的配置入口。
这个配置别小看。它不是可有可无的装饰项,而是直接决定你拿到的是:
McpSyncClientMcpAsyncClient
如果你的项目后面整条链都是 reactive,但 MCP client 还按同步方式接,很容易在后面遇到这些问题:
- 调用时序不好看
- 线程模型别扭
- 某些延迟问题很难解释
所以这一步别偷懒。先决定你是同步应用还是异步应用,再决定 client 类型。
坑 3:你以为“连上了 MCP”就等于“模型能用这些工具”
这应该是 MCP 最容易造成误解的一点。
Spring AI 文档写得很明确:当 tool callbacks 开启时,所有注册过的 MCP tools 会以 ToolCallbackProvider 的方式提供出来。
也就是说,MCP 连接本身解决的是:
- 服务发现
- 工具发现
- 协议通信
但模型能不能真正调用这些工具,取决于这些工具有没有进入你的 ChatClient / ChatModel 工具链路。
最直观的例子是:
@Autowired
private SyncMcpToolCallbackProvider toolCallbackProvider;
ToolCallback[] toolCallbacks = toolCallbackProvider.getToolCallbacks();
如果你只是把 MCP client 配起来,却没把这些 tools 接进实际聊天调用链,那模型照样看不到它们。
这类问题最坑的地方在于:MCP client 明明能注入成功,日志也不报错,你就会下意识以为链路已经通了。
其实只通到了一半。
坑 4:多个 MCP 服务器一起接,工具名开始冲突
Spring AI 官方文档在 1.1 的 MCP Client Starter 里专门加了一块内容:tool name prefix generation。
这背后说明了一个很现实的问题:你只要连多个 MCP 服务器,就很容易出现工具重名。
官方文档给出的默认策略是:
- 自动追踪现有连接和工具名
- 发现重名时自动生成唯一名字
- 必要时加前缀,比如
alt_1_search
如果你没有意识到这件事,后面排障会非常迷:
- 你以为模型调的是 A 服务的
search - 实际上跑到了 B 服务的
search - 或者你看到的工具名已经被自动改写了,但你自己还在按原名排查
所以一旦进入多 MCP 服务场景,这件事最好提前想清楚:
- 要不要自定义前缀规则
- 要不要做工具过滤
- 哪些工具应该暴露给哪个 Agent
别等冲突出来了再补救。
坑 5:自动初始化很方便,但也会把问题提前到应用启动阶段
MCP Client Starter 文档里提到一个点:支持自动客户端初始化。
这件事本身没有问题,问题在于很多人把它当成“更省心”,结果忽略了它的副作用。
一旦你依赖自动初始化,MCP 服务端的这些问题就会更早暴露出来:
- 某个远端服务没起来
- 某个本地命令行 server 路径错了
- 某个 transport 地址写错了
- 某个 server 初始化协商失败
这些问题会直接影响启动期行为,而不是等到第一条请求进来时才暴露。
这不是坏事,但你要有心理准备:MCP 的错误有时不是“运行期某个接口失败”,而是“应用一启动就开始卡你”。
坑 6:你只验证了“能连”,没验证“工具是否真的被发现和暴露”
Spring AI MCP Overview 文档提到,MCP client 负责:
- 协议版本协商
- 能力协商
- 工具发现与执行
- 资源访问
- prompt 系统交互
这句话其实很关键。因为它说明 MCP 不只是“开个连接”。
很多人排查到这里就停了:
- URL 对
- 进程在跑
- Bean 能注入
但还少了一步:工具到底发现了没有?发现后名字是什么?最后有没有暴露成 ToolCallback?
如果这一层没确认,你所谓的“连通”其实只是 transport 级别连通,不是 Agent 真正可用。
我会怎么排 MCP 接入问题
如果是我自己排,我一般按这个顺序:
- 先确认 transport 选型是不是对的
- 再确认同步 / 异步 client 类型是不是和应用风格一致
- 再确认 MCP tools 有没有真正进入
ToolCallback链 - 如果是多 server,先看工具名是否冲突或被重写
- 最后再排自动初始化和启动期协商问题
这样查比一上来盯网络包更稳。
最后给一份速查清单
- 你到底该用
STDIO、SSE还是Streamable-HTTP? - 你的 starter 该是普通版还是
webflux版? type该是SYNC还是ASYNC?- MCP tools 发现后,是否真的进入了
ToolCallbackProvider? - 聊天链路有没有真正拿到这些
ToolCallback? - 多 MCP server 场景下,工具名是否冲突或被自动改写?
- 自动初始化是不是把问题提前到了启动阶段?
- 你现在验证的是“能连”,还是“模型真的能用”?
结尾
MCP 的坑不在于它复杂,而在于它层次很多。transport 通了、client 注入了、工具发现了、模型可用了,这四件事不是一回事。你如果把它们混成一个“接上了”,排障就会一直卡在半路。
下一篇我会写系列里唯一一篇偏选型的文章:Java 做 Agent,到底选 Spring AI、LangChain4j 还是 Spring AI Alibaba?
参考资料
- Spring AI MCP Overview: https://docs.spring.io/spring-ai/reference/api/mcp/mcp-overview.html
- Spring AI MCP Client Boot Starter: https://docs.spring.io/spring-ai/reference/api/mcp/mcp-client-boot-starter-docs.html
- Spring AI Getting Started with MCP: https://docs.spring.io/spring-ai/reference/guides/getting-started-mcp.html
说明
文中的以下结论直接来自 Spring AI 官方文档:
- MCP 客户端支持多种 transport,包括 STDIO、SSE、Streamable-HTTP
- 提供普通 starter 和 WebFlux starter
- 支持同步和异步 client
- MCP tools 默认会以
ToolCallbackProvider的形式暴露 - 支持多连接、工具过滤和工具名前缀生成
- MCP client 不只负责连接,还包括协商、工具发现与执行
文中的这些表述属于我的工程归纳,不是官方原句:
- “连上 MCP 不等于模型已经能用这些工具”
- “很多问题只是 transport 连通,不是 Agent 真可用”
- “自动初始化会把错误提前暴露到启动阶段”
AtomGit 是由开放原子开源基金会联合 CSDN 等生态伙伴共同推出的新一代开源与人工智能协作平台。平台坚持“开放、中立、公益”的理念,把代码托管、模型共享、数据集托管、智能体开发体验和算力服务整合在一起,为开发者提供从开发、训练到部署的一站式体验。
更多推荐



所有评论(0)