记录一下那天晚上的排查过程。自建 MCP server 用 Python 写,调试时加了一行 print,客户端立刻报 Unexpected token d is not valid JSON 并断开连接,删掉 print 后恢复。

刚开始盯着「日志库默认 handler 指向 stdout」,折腾了半个多小时,排掉了。

这类报错背后常见的原因有几处,逐个排除就行。stdio 传输把 stdout 当作 JSON-RPC 通道。还有一种是print 的输出直接混进了消息流。

另外,未捕获异常的栈也打到了 stdout。

搜一遍代码里的 print 调用

python -c "import re;[print(i+1,l) for i,l in enumerate(open('server.py',encoding='utf-8')) if 'print(' in l]"

再往下把日志 handler 统一指向 stderr

python -c "import logging,sys;logging.basicConfig(stream=sys.stderr,level=logging.INFO)"

随后加一层保护,禁止向 stdout 写非协议内容

python -c "import sys;print('guard stdout',file=sys.stderr)"

剩下的就是用官方 inspector 连一次确认消息可解析

python -c "print('npx @modelcontextprotocol/inspector')"

命令输出我都留了记录,免得改完记不清原来的值。

改之前先确认了最近有没有人动过配置,避免白查一遍。

别只看报错消失,验证要多做一步。客户端能持续收到 tools/list 与调用结果,日志出现在 stderr 一侧,连接不再断开。

这里还有个坑。stdio 模式下 stdout 只有协议能用,所有调试输出走 stderr,这条规则要写进项目的开发约定。如果同一现象隔几天又出现,说明根因没找到,别当偶发处理。

作者 9823189