为什么你的 MCP Server 老是连接失败?深度拆解 JSON-RPC Parse Error 的“物理级”原因

1 阅读2分钟

「起因:被一行 Print 毁掉的连接」 最近在调优 MCP Server 时,我遇到了一个最经典的“玄学”问题:代码逻辑全对,但在 Cursor 里一连就报 JSON-RPC parse error 或者 Tool list failed。

在折腾了 3 个小时后,我发现原因竟然是启动脚本里的一行: console.log("MCP server started successfully");

「物理诊断:Stdio 通道污染」 在 MCP 的 stdio 传输模式下,stdout 是唯一的协议通道。 这意味着,你的 print、console.log、甚至是启动时的 Banner 艺术字,都会被客户端(如 Claude Desktop)当成 JSON 报文去解析。

  • 现象:客户端读到了字符串而不是 { 开头的 JSON。
  • 后果:解析器瞬间崩溃,连接直接切断。

「JSON-RPC 错误码深度速查」 别看到报错就慌,看懂错误码能让你少掉一半头发:

  • -32700 (Parse error):
    • 物理诱因:stdout 被业务日志污染,或者 JSON 被系统缓冲区截断。
    • 修复:所有非协议日志强制通过 sys.stderr 输出。
  • -32601 (Method not found):
    • 物理诱因:客户端调用的 tools/list 或业务方法你没实现。
    • 修复:检查方法名拼写,补全协议映射。
  • -32603 (Internal error):
    • 物理诱因:你本地的 Python/Node 脚本崩溃了,直接喷出了异常堆栈。
    • 修复:查看 stderr 里的错误栈,修你的业务逻辑。

「小白的 MCP 排错 Checklist」

  1. 脱离黑盒调试:先不要在 Cursor 里跑,直接在终端里裸跑 Server 脚本。如果第一行输出不是 {,直接去修日志模块。
  2. 强制分流:Node 环境全局替换为 console.error;Python 环境强制使用 file=sys.stderr。
  3. UTF-8 校验:确保报文没有非法字符。
  4. 缓冲区 Flush:大消息返回时,确保 JSON 已经完全 Flush,防止输出半截数据。

「对比:MCP vs Function Calling」 MCP 的调试难度高于传统的 HTTP API,因为它涉及到本地进程的 IO 监听。在 HTTP 下你顶多收到一个 500 报错,而在 MCP 下,一个字符的侧漏就能让整个通道报废。

「总结」 精准识别错误码,做到有的放矢。我把 5 类常见错误码的触发原因和修复方向整理成了一篇详细的排坑指南,希望能帮你在构建 AI Agent 的路上少踩坑。

👇 物理级排坑指南全量内容: www.xbstack.com/ai/mcp-json…