MCP stdio 传输详解:消息帧、进程生命周期与向后兼容(2026-07-28 规范版)
MCP stdio 传输的规范级拆解:一行一个 JSON-RPC 的消息帧、stdout/stderr 的硬性边界、取消与优雅关停的进程生命周期规则、崩溃重启语义,以及 server/discover 探测向后兼容的三种结果。
操作步骤
关闭 stdin
客户端关闭到子进程的输入流——stdin EOF 是规范认定的主要且唯一可移植的优雅关停信号,服务器收到后应立即退出。
等待退出
给服务器一个合理的宽限时间;服务器也可主动关闭自己的 stdout 并退出。
超时强制终止
仍未退出时按平台强制终止:POSIX 从 SIGTERM 升级到 SIGKILL;Windows 使用 TerminateProcess 或 Job Objects。重启后记得重建订阅类流。
MCP 的两种标准传输里,stdio 是本地场景的默认选择:客户端把服务器作为子进程启动,在标准流上对话。它的规则看起来简单——"往 stdin 写 JSON-RPC、从 stdout 读 JSON-RPC"——但规范在消息帧、流边界、取消、关停与向后兼容上有一整套精确约束(本文全部规则引自 2026-07-28 规范版 stdio 传输页,2026-09-04 核对)。本文按实现者视角拆解这些规则,并给出与调试、安全两篇的衔接点。
1. 基本模型:子进程与三条流的分工
stdio 传输中,客户端把 MCP 服务器作为子进程启动,双方在子进程的标准流上通信:
| 流 | 方向 | 用途 | 硬性规则 |
|---|---|---|---|
| stdin | 客户端 → 服务器 | 传 JSON-RPC 请求与通知 | 客户端不得写入非 MCP 消息;客户端不得向其写 JSON-RPC 响应 |
| stdout | 服务器 → 客户端 | 传 JSON-RPC 响应、通知与请求 | 服务器不得写入任何非合法 MCP 消息的内容 |
| stderr | 服务器 → 客户端 | 仅日志 | 可写 UTF-8 字符串(信息/调试/错误);客户端可捕获、转发或忽略,且不应视为错误信号 |
三条流各司其职,任何越界——往 stdout 打印一行调试日志、往 stdin 回写响应——都会破坏协议。
2. 消息帧:一行一条,行内无换行
每条消息是单个 JSON-RPC 请求、通知或响应,以换行分隔,行内不得内嵌换行。客户端从 stdout 逐行读取;所有消息共享这一条通道,没有按请求划分的流。
帧格式还有一个重要的可移植性结论(引自规范):这套"可靠双向字节流上的换行分隔 JSON-RPC"不依赖标准流本身——Unix 域套接字、TCP 等通道可原样复用。自定义传输是允许的(MAY),但必须保留 JSON-RPC 消息格式、消息模式与按请求元数据模型,并应文档化连接建立、消息帧与取消模式;基于字节流的自定义传输 SHOULD 直接复用 stdio 帧,只有子进程特有的部分(启动、stderr、关流关停、进程重启)需要等价替代。
# 消息帧示意(每行一条完整的 JSON-RPC)
{"jsonrpc":"2.0","id":1,"method":"tools/call","params":{"name":"fetch_report","arguments":{"report_id":"r-42"}}}
{"jsonrpc":"2.0","id":2,"method":"ping"}
# 反例:pretty-print 把一条消息拆成多行 —— 每行都成了非法帧
{"jsonrpc":"2.0",
"id":3,
"method":"tools/list"}
3. 取消与关停:进程生命周期规则
取消:stdio 是单条共享双向通道,没有按请求的流可关。规范要求服务器在请求被取消后尽快停止相关工作,且不再为该请求发送任何消息。
关停的规范顺序:
- 客户端关闭到子进程的输入流(stdin);
- 等待服务器退出;
- 超时未退出则按平台强制终止——POSIX 上从 SIGTERM 升级到 SIGKILL;Windows 无 POSIX 信号,可用 TerminateProcess 或 Job Objects。
服务器侧的对应义务:stdin 关闭或读到 EOF 时应立即退出——规范称这是主要且唯一可移植的优雅关停信号,遵守它可以免去强制终止。服务器也可主动关停:关闭到客户端的 stdout 并退出。
崩溃重启:服务器进程意外退出时,客户端应重启它。协议是无状态的——进行中的请求直接丢失,可对新进程重试;但活动的订阅/监听流必须重启后重建。
# 优雅关停顺序(规范语义)
1. client: close(server stdin) ← 主信号:EOF
2. wait(server exit) ← 服务器应在 stdin EOF 后尽快退出
3. force: SIGTERM → SIGKILL ← 仅在超时后(Windows: TerminateProcess / Job Objects)
4. 向后兼容:server/discover 探测的三种结果
规范允许同一传输上共存"现代"与"遗留"两个时代的服务器,客户端用探测区分:发送 server/discover(把偏好的现代版本放进 _meta),结果三选一:
| 探测结果 | 判定 | 客户端动作 |
|---|---|---|
| 返回 DiscoverResult | 现代服务器 | 从 supportedVersions 选共同支持版本继续 |
| 返回 UnsupportedProtocolVersionError 等现代 JSON-RPC 错误 | 现代服务器,但不支持请求版本 | 改用其广告的版本列表;不要回退 initialize |
| 其他错误,或合理超时内无响应 | 遗留服务器 | 回退 initialize 握手 |
两条硬规则:回退判定 MUST NOT 绑定单一错误码(遗留服务器对未知请求常用 -32601 / -32602,也可能不应答);只支持现代版本的客户端可以不探测,但规范建议依然探测——部分遗留服务器不校验"请求必须发生在 initialize 之后",会把 tools/call 这类时代歧义方法按遗留语义处理,探测能让失败确定化。
# server/discover 探测的三种结果
DiscoverResult → 现代服务器:选共同版本继续
UnsupportedProtocolVersionError → 现代但版本不匹配:改用其广告版本列表
其他错误 / 超时 → 遗留服务器:回退 initialize 握手
5. 常见错误与排查
- 往 stdout 打日志:最高频的 stdio 自伤——stdout 是纯协议通道,日志一律走 stderr(排查细节见《MCP 调试实战:Inspector、日志规范与连接问题排查链》)。
- pretty-print JSON:多行 JSON 会把一条消息拆成多条非法帧;序列化必须压成单行。
- 把 stderr 输出当错误:规范明确客户端不应如此假设——stderr 是日志流,不是错误信号。
- 强制终止前不关 stdin:跳过 EOF 信号直接 SIGKILL,会失去优雅退出的机会;按"关 stdin → 等待 → 强制"的顺序来。
- 崩溃重启后忘记重建订阅:协议无状态,重启即重置——订阅/监听流是调用方责任。
- 用单一错误码判定遗留服务器:-32601/-32602 都可能是"其他实现定义的错误",按规范用"现代错误形态 vs 其他/超时"来分类。
6. 下一步
- HTTP 场景的授权流程(stdio 不走 OAuth,凭据走环境变量):《MCP 授权机制拆解:OAuth 2.1 落进 MCP 的完整流程(2026-07-28 规范版)》。
- stdio 服务器的日志与调试:《MCP 调试实战:Inspector、日志规范与连接问题排查链》。
- 从零写一个 stdio 服务器:《自己搭一个 MCP Server:从零到发布的完整指南》。
关键要点
- 基本模型:客户端把服务器作为子进程启动;stdin/stdout 交换 JSON-RPC;每行一条消息,行内 MUST NOT 内嵌换行
- 流的硬边界:stdout 只允许合法 MCP 消息(MUST NOT 写任何其他内容);stderr 可写 UTF-8 日志,客户端不应把 stderr 输出当作错误信号
- 帧格式可移植:换行分隔 JSON-RPC 的帧在 Unix 域套接字、TCP 等可靠双向字节流上原样可用,自定义传输 SHOULD 复用该帧;自定义传输 MUST 保留 JSON-RPC 消息格式、消息模式与按请求元数据模型
- 取消:stdio 是单条共享双向通道,没有按请求的流可关;服务器 SHOULD 尽快停止被取消请求的工作,且不再为其发送任何消息
- 关停:客户端应先关 stdin、等待退出、超时再强制终止(POSIX 上 SIGTERM 升级到 SIGKILL);服务器见 stdin EOF 即应退出——这是主要且唯一可移植的优雅关停信号
- 崩溃重启:协议无状态,进行中请求直接丢失、可对新进程重试;活动订阅/监听流需重建
- 向后兼容:先用 server/discover 探测(把偏好版本放 _meta),三种结果——DiscoverResult=现代服务器、UnsupportedProtocolVersionError=现代但版本不匹配、其他错误或超时=遗留服务器回退 initialize 握手;回退 MUST NOT 绑定单一错误码(遗留服务器常见 -32601 / -32602 或干脆不应答)
常见问题
官方参考
相关文章
MCP 授权机制拆解:OAuth 2.1 落进 MCP 的完整流程(2026-07-28 规范版)
MCP 授权规范逐条拆解:角色映射(服务器=资源服务器、客户端=OAuth 客户端)、RFC9728 发现、三种客户端注册方式、iss 响应校验表、resource 参数与 canonical URI、token 使用红线与 step-up 授权流。
阅读全文MCP 调试实战:Inspector、日志规范与连接问题排查链
MCP 集成调试的官方方法:Inspector 交互式测试 UI 为什么是第一站、stdio 与 Streamable HTTP 的日志怎么打(notifications/message 已在 2026-07-28 规范版弃用)、启动失败三类根因与连接失败五步排查链。
阅读全文MCP 安全指南:官方 8 类攻击面与缓解清单
MCP 官方安全最佳实践拆解:Confused Deputy、Token Passthrough、SSRF、会话劫持、本地 Server 攻击、OAuth URL 校验、stdio 代理安全、权限最小化——每类攻击的原理与官方缓解要求。
阅读全文订阅 GPTMap Weekly
每周一封邮件,精选 OpenAI 重要更新、深度解读与最佳实践。无广告,可随时退订。