MCP 半小时跑通和敢上生产之间,隔着这 5 个坑
明人不说暗话:这篇和前 3 篇不一样。前 3 篇的东西我全部亲手验证过------41 条规则跑了五个月、demo 是我一行行敲出来的。这篇讲的是"上生产",我们自己的 MCP 还没接真实业务(接了会写 +1 封顶篇),所以这篇里一部分坑是别人公开分享的实战,凡是别人的,我都注明出处;凡是能自己验证的,我都先跑了一遍再写。哪种都不能信的文章我不会让它进这个系列。
老规矩三十秒背景:四人 Java 团队,AI 全职写代码,人审代码拍板。五个月 bug 月均 3→11→2,PR 周期 32h→9h,41 条审查规则开源在 github.com/wangheng19901021/skills(MIT 协议)。第 2 篇我们用 Spring Boot 4.1.1 + Spring AI 2.0.1 手写了一个 MCP Server,半小时跑通。
半小时跑通和上生产之间,隔着下面这五个坑。
坑一:Tool 的 description 不是注释,是写给模型读的 prompt
第 2 篇埋过这个点:@Tool 里的 description,我写得比 JavaDoc 还认真。为什么?因为模型根本看不到你的方法签名,它看到的只有一段文本。
腾讯云团队在给内部数据平台做 Agent 插件的公开分享里把这层窗户纸捅得很透:Agent 启动时向 MCP Server 发 tools/list,拿到的每个工具是 name、description、inputSchema 三件套,全部注入 system prompt。也就是说,模型决定"调不调你的工具、参数填什么",依据就是那段描述文本。description 写得烂,调用率就烂------工具不存在一样。
我们自己的对照实验很小但说明问题:demo 里三个工具,description 写清了"什么时候该调我"(按规则 id 取全文 / 按关键词模糊搜 / 列全量目录),客户端 listTools 回来的定义直接就能看懂每个工具的分工。要是偷懒写个"查询规则",模型在真场景里就只能瞎猜。
上生产的动作:把 description 当接口契约评审,review 工具定义和 review 代码同级。
坑二:写操作想靠 prompt 拦住?拦不住的
MCP 工具里一旦有了"建工单""改配置""删数据"这类写操作,事情性质就变了。在 system prompt 里写"删除前必须先确认"------模型大多数时候会照做,但"大多数时候"在生产环境等于裸奔。
腾讯云团队的做法值得抄(还是那篇公开分享):他们不靠 prompt,靠 Hook 在调用链路上做硬拦截 ------Agent 构造完工具调用、框架真正发起之前,执行流暂停,把工具名和参数交给一个脚本裁决:放行、弹窗确认、还是直接拒绝。Agent 绕不开,因为工具调用到执行的路径被框架独占,Hook 是这条路上唯一的道闸。他们给 72 个工具做了四级安全分级(静默放行 / 记审计 / 弹窗确认 / 硬阻断),光 PreToolUse 一个拦截脚本就写了 60KB,规则全部外化在配置文件里。
他们原文里有句话我建议抄在墙上:"prompt 约束是软的,安全边界要靠工程架构来保障。"
上生产的动作:先给工具分级。只读查询放绿灯;写操作至少弹窗确认;不可逆的删除类,没有护栏就别暴露。
坑三:自建 Server 直调 Service 层?一个 Java 团队的真实教训
这是标题里那个"真实教训",来自腾讯云团队的同一篇分享(他们是 Java 技术栈,Spring Boot 自建 MCP Server)。
他们最初的方案很直觉:Agent 和后端之间架一层自建的 MCP Server,新建一套 AiController 直接调 Service 层。上手之后两个坑暴露:
- 横切逻辑全部要重做。原 Controller 上挂着的 AOP 切面、并发控制、异常处理,AiController 绕开原层之后全得在新层重新实现一遍------不是"调用转发",是整套横切关注点的二次开发。
- 多一个独立服务,多一整层运维。构建、部署、监控、扩缩容、版本同步、线上排错,全链路多一份。
他们最后的解法:不自建了,改用部门内已有的 MCP 市场------上传一份 Swagger/OpenAPI 规范,平台自动把 REST 接口解析注册成 MCP 工具,一行适配代码不写。原话的大意是:这不是"做不出来"的问题,是"值不值得单独维护一个中间代理层"的问题。
这个教训对我们 Java 团队的提示很直接:真要接内部系统,先盘一下自己有没有现成的 OpenAPI 文档。有,优先考虑自动注册这条路;没有,自建时别把"绕过 Controller 直调 Service"当捷径------那是把坑挖在了地基里。
坑四:别笼统说"MCP 费 token",Tools 和 Resources 是两种活法
"MCP 费 token"这句话流传很广,但它粗糙得没法指导决策。拆开看(腾讯云那篇里有张很清楚的对比表):
- Tools :启动时批量注册,定义全部注入 system prompt------常驻占 token,工具越多越贵
- Resources :只读数据,惰性拉取,用到才取,不占 prompt------他们把一个 150+ 张表的 schema 库做成 Resources,Agent 启动时一张表都不拉,用户问了才按 URI 取
- Prompts:预定义提示词模板,无副作用,纯复用
所以正确的姿势不是"怕费 token 不敢用 MCP",而是按加载策略选型:要动手改状态的,只能 Tools;纯查询的结构化参考数据(表结构、数据字典、配置文档),做成 Resources 比 Tools 便宜得多。第 3 篇那个反向案例(MCP 接三个月一变的文档、每次 3000+ token、改回 Skill 省 60%)本质也是这个账:静态的东西用了最贵的通道。
上生产的动作:盘点工具清单时顺手问一句"这里面哪些是只读查询",只读的优先考虑 Resources。
坑五:协议口径在换代,学资料先看日期
这个坑第 1、2 篇都提过,放这里收个尾,因为它对"上生产"影响最大:SSE 传输在 Spring AI 2.0 里已经 deprecated,官方推荐 Streamable HTTP,端点 POST /mcp。协议官方 2026 年 7 月 28 日发的候选版还在往无状态连接演进------无状态对生产部署是大利好(负载均衡、水平扩缩都好做了),但意味着你照着旧教程搭出来的有状态服务,架构红利吃不到。
我们的 demo 为了配合经典客户端写法显式用的 SSE,那是练手的选择,不是生产的推荐。新工程直接上 Streamable HTTP。 老规矩:看到通篇教你配 SSE 的教程,先看发表日期。
上生产的动作:技术选型文档里把"传输协议 = Streamable HTTP"写死,别让 SSE 混进新服务。
收尾
系列三到这里,四篇正篇齐了:第 1 篇分清概念,第 2 篇动手跑通,第 3 篇管住手别乱升,第 4 篇(这篇)上生产前的五条护栏。我自己的那张检查单其实就三行:description 当契约审、写操作走工程护栏、只读数据别用 Tools。
按规划,这个系列还剩一篇 +1 封顶篇------等我们的 MCP 真接上内部系统,把实战复盘写出来,前四篇就全成了预告。到那天再见真章。
仓库里 41 条规则和 demo 工程都在 github.com/wangheng19901021/skills(demo 在 demo/mcp-review-rules-server,含一键复跑脚本),MIT 协议,拿去改成你们团队自己的。
你们团队 MCP 上生产踩过什么坑?评论区聊聊,我看到会回。觉得有用就点个赞收个藏,关注账号,封顶篇发出来你能收到。
------ 硅基书斋主理人,十年 Java 后端