Skip to content
MCP 文档版本 2026-07-28 更新于 2026-10-14

stdio

在 stdio 传输中,客户端将 MCP 服务端作为子进程启动。 两端通过子进程的标准流进行通信:

  • 服务端从 stdin 读取 JSON-RPC 消息,并向 stdout 写入 JSON-RPC 消息。
  • 每条消息都是一个单独的 JSON-RPC 请求、通知或响应。
  • 消息以换行符分隔,且 MUST NOT(不得)包含内嵌换行符。
  • 服务端 MAY(可以)向 stderr 写入 UTF-8 字符串,用于任何日志记录目的, 包括信息性、调试和错误消息。
  • 客户端 MAY(可以)捕获、转发或忽略服务端的 stderr 输出,并且 SHOULD NOT(不应)假定 stderr 输出表示错误状况。
  • 服务端 MUST NOT(不得)向其 stdout 写入任何不是有效 MCP 消息的内容。
  • 客户端 MUST NOT(不得)向服务端的 stdin 写入任何不是有效 MCP 消息的内容。

标准流是规范通道,但除进程生命周期外,此绑定不依赖它们。 线上格式(在可靠的双向字节流上,每行一条以换行符分隔的 JSON-RPC 消息) 在 Unix 域套接字、TCP 连接或任何类似通道上均可原样工作。 基于此类流构建的自定义传输SHOULD(应)复用本页的分帧和消息规则;只有子进程特有的方面 (启动、stderr、通过关闭流进行关闭、进程重启)需要特定于通道的等价实现。

发送消息

客户端通过向服务端的 stdin 写入 JSON-RPC 请求和通知来发送消息, 每行一条消息。客户端 MUST NOT(不得)写入 JSON-RPC 响应。

接收消息

客户端从 stdout 读取服务端消息,每行一条消息。所有 消息共享这一单一通道;不存在按请求划分的流。

服务端写入三类消息:

  1. 对客户端请求的响应,通过 JSON-RPC id 进行关联。
  2. 与进行中请求相关的通知,例如 notifications/progress 和 notifications/message。
  3. 为活动的 subscriptions/listen 请求投递的通知。客户端 MUST 使用 _meta 中的 io.modelcontextprotocol/subscriptionId 字段 对这些通知进行关联;参见 SubscriptionsListenRequest。

服务端 MUST NOT(不得)向 stdout 写入 JSON-RPC 请求。 服务端到客户端的交互承载于 InputRequiredResult 回复中;参见 多轮往返请求。

请求元数据

stdio 传输的所有请求元数据都内联承载于 JSON-RPC 消息体中。协议版本、逐请求能力和 可选的客户端身份位于 _meta.io.modelcontextprotocol/*; 方法名和参数位于 JSON-RPC 规定的位置。不存在 头部层。

取消

要取消进行中的请求,客户端 MUST(必须)发送一个 引用该请求 ID 的 notifications/cancelled 通知。由于 stdio 是单一共享的双向通道,不存在可按请求关闭的流。 服务端 SHOULD(应)在切实可行的情况下尽快停止已取消请求的工作, 并且 MUST NOT(不得)为其发送任何进一步的消息。完整规则参见 取消。

关闭

客户端 SHOULD(应)通过以下方式发起关闭:

  1. 关闭指向子进程(服务端)的输入流。
  2. 等待服务端退出。
  3. 如果服务端未在合理时间内退出,则使用适合操作系统的 机制强制终止该进程。

在 POSIX 系统上,强制终止通常从 SIGTERM 升级到 SIGKILL。在 Windows 上,由于没有 POSIX 信号,客户端可以 使用 TerminateProcess 或 Job Objects。

服务端 SHOULD(应)在其标准输入被关闭或读取返回文件结尾时 及时退出。这是主要的优雅关闭信号,也是唯一可移植的信号, 因此遵循该信号可减少强制终止的需要。

服务端 MAY(可以)通过关闭其指向客户端的输出流并退出来 发起关闭。

意外终止

如果服务端进程意外退出,客户端 SHOULD(应)重启它。 由于协议是无状态的,任何进行中的请求只会丢失, 客户端可以针对新进程重试这些请求。活动的 subscriptions/listen 流也必须在重启后 重新建立。

向后兼容

同时支持现代(逐请求元数据)MCP 版本和需要 initialize 握手的 传统版本的客户端,SHOULD(应)在发送任何其他请求之前 使用 server/discover 进行探测, 并在 _meta 中设置其偏好的现代版本。该探测有三种 可能结果:

  • 服务端返回 DiscoverResult:服务端为现代版本。从 supportedVersions 中选择一个双方都支持的版本并继续。
  • 服务端返回一个可识别的现代 JSON-RPC 错误,例如 UnsupportedProtocolVersionError:服务端为 现代版本,但不支持所请求的版本。使用其通告的 supported 列表中的 某个版本。不要回退到 initialize。
  • 服务端返回任何其他错误,或未在合理超时内响应:服务端为传统版本。 回退到 initialize 握手。

回退机制 MUST NOT(不得)绑定到某个特定的错误码:传统服务端对 initialize 之前的未知请求会以实现自定义的错误(通常是 -32601 或 -32602)响应,或者根本不响应。

仅支持现代版本的客户端无需探测,但仍 RECOMMENDED(建议)进行探测:某些传统服务端不会校验请求是否在 initialize 之后到达,并会按传统语义处理一个时代归属不明确的方法(例如 tools/call)。探测则会得到确定性的失败。

关于时代模型以及面向实现者的兼容性矩阵,参见 Versioning: Backward Compatibility。

BytesRouter 是社区翻译站点,所有译文仅供参考,一切以官方英文原文为准。