MCP服务器开发避坑:从能跑到能上线的七个细节

📅 2026/4/26 ✍️ 小文 📖 约 1 分钟

写完一个MCP server只要半天,让它稳定被别人使用要两周。本文总结七个最常踩的坑:工具描述、参数校验、超时、幂等、错误信息、权限、日志。

MCP(Model Context Protocol)现在已经是 Agent 工具接入的事实标准。写一个 MCP server 的门槛极低——一个周末就能跑通”hello world”和几个演示工具。

但把它交给别人(其他团队、其他模型、生产环境)使用,问题会集中爆发。下面七点是我在多个 MCP server 项目里反复踩到的坑。

一、工具描述是给模型看的,不是给人看的

最常见的问题:工具描述写成文档口吻——“该接口用于查询订单信息,支持分页和筛选”。

模型不需要这种概述,它需要什么时候该调用、什么时候不该调用。好的描述长这样:

按订单号精确查询订单状态。仅在用户提供了明确的订单号时调用;
若用户只提供姓名或日期,请先调用 search_orders。
返回:状态、金额、发货时间。不返回商品明细。

说清楚触发条件、不适用场景、返回内容边界,模型选错工具的概率会明显下降。

二、参数校验要在服务端做,不能只写 schema

JSON Schema 是建议,不是约束。模型可能传 "page": "3"(字符串)或 "limit": 0。

服务端必须做类型转换和边界检查,并在校验失败时返回可理解的错误。一个返回 500 Internal Error 的 MCP server,会让模型陷入无意义的重试循环——它不知道错在哪,只能猜。

三、超时必须显式设置,且要短

MCP 工具调用挂住三十秒,整个 Agent 对话就卡住三十秒。默认超时不要设成平台的默认值,按业务设定:查询类 5~10 秒,写操作 15~30 秒。

更重要的是超时后返回结构化提示,让模型知道可以换个方式重试,而不是以为工具不存在。

四、写操作必须幂等

模型重试是常态。同一笔订单被创建两次、同一封邮件被发送两次,这类事故在早期项目中屡见不鲜。

方案:写操作接受一个幂等键(用会话 ID + 操作语义生成),服务端对重复键直接返回首次结果。这是花二十分钟就能加上的保护。

五、错误信息要包含”下一步做什么”

对比两类错误:

  • Error: invalid status
  • Error: status 必须是 pending/shipped/delivered 之一,当前收到 "完成"

第二种错误模型能自己修正,第一种只能瞎试。错误信息是给模型的提示词,这个观念要建立起来。

六、权限要在工具层收敛,不要暴露”万能工具”

反面教材是做一个 execute_sql 工具,让模型自己写查询。方便,但等于把数据库交给模型。

更好的设计是把高频需求封装成窄工具:get_order_by_id、list_recent_refunds,SQL 在服务端固定。工具越窄,越可审计、越安全。

七、日志要记录”模型推理链路上能用到的东西”

生产排障时,你需要的不是完整请求体,而是:调用时间、工具名、参数摘要、耗时、是否成功、失败原因、会话 ID。

有了会话 ID,才能把一个 Agent 的多次工具调用串成一条链路,看清它为什么在第 4 步开始跑偏。

上线条目清单

动手前花五分钟过一遍:

  • 每个工具的描述包含触发条件与不适用场景
  • 所有参数服务端校验,错误信息可操作
  • 每个工具都有显式超时
  • 所有写操作支持幂等键
  • 无万能执行类工具
  • 日志含会话 ID 与耗时
  • 有一个最小的集成测试,模拟真实模型调用

MCP 的价值在于”一次开发、多处复用”。但复用的前提是可靠——一个行为不可预测的工具,会污染每一个接它的 Agent。把上面七点做扎实,你的 MCP server 才能真正被信任。

📤 分享到