MCP通信与传输
3917 字约 13 分钟
AIAgentMCP通信
2026-07-24
MCP 传输层(Transport)定义了协议消息在 Client 与 Server 之间如何物理传递。它是 MCP架构总览 中 Client-Server 连接的实际载体,决定了 MCP 系统的部署拓扑、安全边界和运维复杂度。
一、基本定义
Transport(传输层) 是 MCP 协议栈中最底层的基础设施,负责将 MCP基础 中定义的 JSON-RPC 2.0 消息从一端可靠地传递到另一端。
MCP 协议本身是 传输无关的(transport-agnostic)——协议层定义了消息的格式和语义,但不关心消息如何物理传递。传输层解决的就是"消息怎么走"的问题。
当前 MCP 规范定义了两种传输方式:
- stdio 传输:通过标准输入/输出管道通信,适用于本地进程
- Streamable HTTP 传输:通过 HTTP 请求/响应通信,适用于远程服务化部署
二、为什么传输层设计重要
传输层的选择直接影响:
| 维度 | 影响 |
|---|---|
| 部署拓扑 | 本地进程 or 远程服务 |
| 安全模型 | 进程隔离 or 网络安全 |
| 生命周期管理 | 子进程绑定 or 独立服务 |
| 可扩展性 | 单用户 or 多客户端共享 |
| 运维复杂度 | 零配置 or 需网络治理 |
一个常见的错误是:协议能力完全相同的情况下,仅仅因为传输方式选错,导致系统无法扩展或引入不必要的安全风险。
三、在 MCP 体系中的位置
协议层定义消息"说什么",传输层定义消息"怎么送"。同一个 MCP Server 可以支持多种传输方式,客户端根据部署场景选择。
四、协议消息与传输方式的区别
这是理解 MCP 通信的关键区分:
| 层级 | 职责 | 举例 |
|---|---|---|
| 协议层 | 定义消息格式和语义 | tools/list 请求、resources/read 通知 |
| 传输层 | 定义消息如何物理传递 | stdio 管道、HTTP POST |
类比:协议层是"信封里的信件格式",传输层是"快递公司怎么送信"。同一封信可以通过不同的快递公司投递,信件格式不变。
所有传输方式承载的 JSON-RPC 2.0 消息格式完全一致,区别仅在于消息的编码和传递机制。
五、stdio 传输
工作原理
stdio 传输通过子进程的 stdin 和 stdout 管道进行通信。Host 应用启动 Server 进程后:
- Client 通过 Server 的 stdin 发送请求
- Server 通过 stdout 返回响应
- 双向管道,消息实时传递
消息帧格式
stdio 传输使用 Content-Length header 进行消息分帧,与 Language Server Protocol(LSP)的方式一致:
Content-Length: 73\r\n
\r\n
{"jsonrpc":"2.0","method":"tools/list","id":1}- 每条消息前必须有
Content-Lengthheader,声明 JSON body 的字节长度 - Header 与 body 之间用空行(
\r\n\r\n)分隔 - 这种机制解决了 TCP/管道流中的消息边界问题——接收方可以准确知道一条消息在哪里结束、下一条在哪里开始
适用场景
- 本地命令行工具(如文件系统 MCP Server)
- 桌面客户端(如 Claude Desktop、IDE 插件)
- 开发调试阶段
- 对安全性要求高、不需要远程访问的场景
优势
- 零网络配置:不需要端口、不需要防火墙规则
- 低暴露面:通信局限在进程间管道,不经过网络栈
- 简单可靠:无需处理认证、TLS、超时重连等网络问题
- 生命周期清晰:Server 随 Host 启动,随 Host 退出终止
局限
- 生命周期绑定:Server 必须作为 Host 的子进程存在,无法独立运行
- 不支持远程访问:只能在同一台机器上使用
- 单进程约束:一个 Client 对应一个 Server 进程,无法多客户端共享
- 日志污染风险:Server 如果将日志输出到 stdout,会破坏消息帧。所有非协议输出必须写到 stderr
日志污染问题
这是 stdio 传输最常见的踩坑点:
- stdout 是协议通道,任何非 JSON-RPC 内容都会导致解析失败
- Server 的调试日志、警告信息必须输出到 stderr
- Host 应用通常需要捕获 Server 的 stderr 用于诊断
- 部分不成熟的 Server 实现会将日志直接 print 到 stdout,导致 Client 崩溃
六、Streamable HTTP 传输
背景
MCP 早期版本定义了基于 Server-Sent Events(SSE)的 HTTP 传输。2025 年规范更新引入了 Streamable HTTP transport,取代了原有的 SSE 传输,成为 MCP 远程通信的标准方式。
工作原理
Streamable HTTP 基于标准 HTTP 请求/响应模型:
- Client 通过 HTTP POST 向 Server 端点发送 JSON-RPC 消息
- Server 可以在同一个 HTTP 响应中:
- 直接返回 JSON 响应(适用于普通请求-响应)
- 返回 SSE 流(适用于需要持续推送的场景)
- 返回空响应(适用于通知类消息)
- Server 也可以通过独立的 HTTP POST 向 Client 推送消息(如通知)
关键特性:
- 单一端点:Client 和 Server 各有一个 HTTP 端点
- 请求灵活性:每个 HTTP 请求可以携带一个 JSON-RPC 消息(或批处理消息)
- 响应灵活性:Server 根据场景选择响应方式,不需要客户端提前声明
Session 管理
Streamable HTTP 引入了可选的 Session 概念:
- Server 可以在响应中返回
Mcp-Session-Idheader,标识会话 - Session 用于关联同一 Client 的多次请求(如状态管理、资源清理)
- Session 是 Server 端的实现选择,不是所有 Server 都需要 Session
- Client 在后续请求中应携带 Server 分配的 Session ID
适用场景
- 远程 MCP Server(跨机器、跨数据中心)
- 多客户端共享的公共服务
- 云端部署的 AI 工具服务
- 需要通过网关/代理访问的环境
优势
- 无需进程管理:Server 独立运行,不依赖 Host 生命周期
- 多客户端共享:多个 Client 可以连接同一个 Server
- 穿越网络边界:标准 HTTP 可以通过代理、防火墙、NAT
- 易部署:可以部署在云服务器、容器、Kubernetes 上
- 负载均衡友好:标准 HTTP 可以接入 LB
局限
- 需要认证:必须实现认证机制(API Key、OAuth 等),防止未授权访问
- 需要网络治理:需要处理 TLS、超时、重试、限流等
- 需要 TLS:生产环境必须使用 HTTPS,明文 HTTP 只适用于本地开发
- 状态管理复杂:Session 需要 Server 端维护状态或使用无状态设计
七、传输方式对比
| 维度 | stdio | Streamable HTTP |
|---|---|---|
| 通信介质 | stdin/stdout 管道 | HTTP 请求/响应 |
| 部署位置 | 本地同机 | 本地或远程 |
| 消息帧 | Content-Length header | HTTP body(JSON 或 SSE 流) |
| 生命周期 | 绑定子进程 | 独立服务 |
| 多客户端 | 不支持 | 支持 |
| 安全模型 | 进程隔离 | 网络认证 + TLS |
| 运维成本 | 极低 | 中等 |
| 适用场景 | 本地工具、桌面客户端 | 远程服务、云端部署 |
| 调试难度 | 低(直接看管道) | 中(需 HTTP 工具) |
| 穿透代理 | 不适用 | 支持 |
八、消息格式
JSON-RPC 2.0 消息结构
所有传输方式承载的都是 JSON-RPC 2.0 消息,分为三种类型:
请求(Request)——需要对方响应:
{
"jsonrpc": "2.0",
"id": 1,
"method": "tools/list",
"params": {}
}响应(Response)——对请求的回复:
{
"jsonrpc": "2.0",
"id": 1,
"result": {
"tools": []
}
}通知(Notification)——不需要响应,单向推送:
{
"jsonrpc": "2.0",
"method": "notifications/initialized"
}通知与请求的区别:通知没有 id 字段,接收方不需要回复。
Content-Length 编码
stdio 传输使用 Content-Length 编码解决消息边界问题:
Content-Length: 52\r\n
\r\n
{"jsonrpc":"2.0","method":"initialize","id":1}接收方读取流程:
- 按行读取直到空行,提取
Content-Length值 - 精确读取指定字节数的 body
- 解析 body 为 JSON-RPC 消息
- 回到步骤 1 处理下一条消息
九、连接生命周期管理
MCP 连接的生命周期包含以下阶段:
关键点:
- 初始化握手是必须的:Client 和 Server 先交换能力声明(capabilities),再开始工作
- 协议版本协商:initialize 阶段确定双方支持的最高协议版本
- 优雅关闭:Client 应等待进行中的请求完成后再关闭连接
十、超时与心跳
超时策略
- initialize 超时:Client 等待 Server 初始化响应应有超时(建议 30-60 秒)
- 请求超时:每个请求应有合理的超时时间,避免无限等待
- 工具调用超时:长时间运行的工具调用需要单独的超时机制
心跳
- stdio 传输:进程存活即连接存活,通常不需要额外心跳
- Streamable HTTP:可以通过定期发送轻量请求或利用 HTTP 连接保活机制检测连接状态
- Server 可以在 SSE 流中发送心跳事件保持连接活跃
十一、断线重连策略
| 传输方式 | 断线含义 | 恢复策略 |
|---|---|---|
| stdio | 子进程退出 | 重新创建子进程,重新初始化 |
| Streamable HTTP | 网络中断或 Server 不可达 | 指数退避重试,重连后可能需要重新初始化 |
Streamable HTTP 的重连注意事项:
- 重连后应重新发送
initialize请求 - 如果之前有 Session ID,重连时仍应携带
- 使用指数退避(exponential backoff) 避免雪崩式重连
- 建议设置最大重试次数,超过后通知用户
十二、大消息处理
MCP 消息可能包含大量数据(如读取大文件资源)。处理原则:
- stdio 传输:Content-Length 机制天然支持大消息,但要注意内存分配
- Streamable HTTP:HTTP 协议本身支持大 body,但需要设置合理的 body 大小限制
- 对于超大资源,应考虑分页或使用 Resource 的 URI 引用而非内联内容
- Server 实现应有消息大小上限,防止内存耗尽
十三、背压(Backpressure)
当消息生产速度超过消费速度时,需要背压机制:
- stdio 管道:操作系统管道本身有背压——管道缓冲区满时,写入方自动阻塞
- Streamable HTTP:需要应用层实现背压
- Server 端:限制并发请求数、队列深度
- Client 端:控制请求发送速率
- SSE 流:通过流的暂停/恢复控制推送速度
背压不足会导致内存持续增长,最终 OOM。
十四、代理和防火墙
stdio 传输
- 不涉及网络,不受代理和防火墙影响
- 但受操作系统文件描述符限制和管道缓冲区大小约束
Streamable HTTP 传输
- 标准 HTTP/HTTPS 通常可以通过企业代理和防火墙
- 需要注意:
- 代理的超时设置(长时间 SSE 流可能被代理切断)
- WebSocket 升级可能被代理阻止(Streamable HTTP 使用 SSE 而非 WebSocket,规避了这个问题)
- 请求体大小限制
- 连接数限制
十五、TLS 和网络安全
Streamable HTTP 传输的安全要求:
- 生产环境必须使用 TLS:所有 HTTP 通信应加密
- 证书验证:Client 必须验证 Server 的 TLS 证书
- 认证机制:MCP 规范建议通过 HTTP header 传递认证信息(如 API Key、Bearer Token)
- 本地开发:可以使用
http://localhost,但生产环境禁止明文传输
安全架构建议:
Client ──TLS──▶ API Gateway ──内网──▶ MCP Server
│
├─ 认证(OAuth / API Key)
├─ 限流
└─ 审计日志十六、设计原则
- 传输无关:协议逻辑不依赖特定传输方式,便于扩展新的传输
- 渐进复杂:stdio 零配置即可工作,Streamable HTTP 按需引入网络复杂度
- 安全默认:远程传输默认要求 TLS,不鼓励明文通信
- 简单帧协议:Content-Length 帧格式简单可靠,避免复杂的分帧逻辑
- 优雅降级:连接失败时有明确的重试和恢复路径
十七、常见误区
| 误区 | 实际情况 |
|---|---|
| "MCP 只支持 HTTP" | MCP 支持 stdio 和 Streamable HTTP,场景不同选择不同 |
| "stdio 传输不安全" | stdio 通过进程间管道通信,天然隔离,安全性很高 |
| "传输层决定了协议能力" | 协议能力与传输方式无关,两种传输承载相同的 JSON-RPC 消息 |
| "Server 可以把日志写到 stdout" | stdio 传输下 stdout 是协议通道,日志必须写到 stderr |
| "Streamable HTTP 就是 WebSocket" | Streamable HTTP 基于 HTTP POST + SSE,不使用 WebSocket |
| "远程传输不需要认证" | 任何暴露在网络上的 MCP Server 都必须实现认证 |
| "SSE 传输是最新的远程方案" | SSE 传输已被 Streamable HTTP 取代(2025 年规范更新) |
十八、实践检查清单
选择传输方式时
stdio 传输开发时
Streamable HTTP 部署时
十九、与其他概念的关系
- MCP基础:传输层承载的是 MCP基础 中定义的 JSON-RPC 消息
- MCP架构总览:传输是 MCP架构总览 中 Client-Server 连接的实际实现
- MCP Server设计:Server 必须选择并实现至少一种传输方式
- MCP Client设计:Client 需要支持目标 Server 使用的传输方式
- MCP安全边界:传输方式直接影响安全边界的划定
- MCP协议生命周期:传输连接的建立、初始化、运行、关闭流程
- MCP错误处理:传输层的错误分类和恢复策略
二十、适用边界
本文档覆盖:
- MCP 传输层的两种标准方式(stdio、Streamable HTTP)
- 消息帧格式和编码
- 连接生命周期、超时、重连
- 安全和运维考量
本文档不覆盖:
- 具体的 SDK 实现细节(参考各语言 SDK 文档)
- 自定义传输的实现方法(需要深入协议规范)
- 特定部署平台(如 Kubernetes、AWS)的具体配置
- HTTP/2 或 HTTP/3 的底层优化细节