本文主要方便用户了解MCP 的通信机制
模型上下文协议 (MCP) 中的传输协议为客户端和服务器之间的通信提供了基础。传输协议负责处理消息发送和接收的底层机制。
消息格式
MCP 使用JSON-RPC 2.0 作为其传输格式。传输层负责将 MCP 协议消息转换为 JSON-RPC 格式进行传输,并将接收到的 JSON-RPC 消息转换回 MCP 协议消息。
使用的 JSON-RPC 消息有三种类型:
请求
v
回应
{
jsonrpc: "2.0",
id: number | string,
result?: object,
error?: {
code: number,
message: string,
data?: unknown
}
}
通知
{
jsonrpc: "2.0",
method: string,
params?: object
}
内置传输类型
MCP 目前定义了两种标准传输机制:
标准输入/输出(stdio)
stdio 传输支持通过标准输入和输出流进行通信。这对于本地集成和命令行工具尤其有用。
在以下情况下使用 stdio:
构建命令行工具
实施本地整合
需要简单的流程沟通
使用 Shell 脚本
可流式传输的 HTTP
SSE 传输已被更灵活的Streamable HTTP传输所取代。请参阅规范 和最新的 SDK 以获取最新信息。
SSE 传输通过 HTTP POST 请求实现服务器到客户端的流式传输,从而实现客户端到服务器的通信。
在以下情况下使用 Streamable HTTP:
构建基于 Web 的集成
需要通过 HTTP 进行客户端-服务器通信
需要有状态会话
支持多个并发客户端
实现可恢复连接
工作原理
客户端到服务器通信:从客户端到服务器的每个 JSON-RPC 消息都作为新的 HTTP POST 请求发送到 MCP 端点
服务器响应:服务器可以采用以下方式响应:
单个 JSON 响应(
Content-Type: application/json
)Content-Type: text/event-stream
用于多条消息的SSE 流 ( )
服务器到客户端通信:服务器可以通过以下方式向客户端发送请求/通知:
由客户端请求发起的 SSE 流
SSE 将 HTTP GET 请求流式传输到 MCP 端点
会话管理
可流式 HTTP 支持有状态会话以跨多个请求维护上下文:
会话初始化:服务器可以在初始化期间分配会话 ID,方法是将其包含在
Mcp-Session-Id
标头中会话持久性
Mcp-Session-Id
:客户端必须在所有后续请求中使用标头包含会话 ID会话终止:可以通过发送带有会话 ID 的 HTTP DELETE 请求来明确终止会话
会话流程示例:
// Server assigns session ID during initialization
app.post("/mcp", (req, res) => {
if (req.body.method === "initialize") {
const sessionId = generateSecureId();
res.setHeader("Mcp-Session-Id", sessionId);
// Store session state...
}
// Handle request...
});
// Client includes session ID in subsequent requests
fetch("/mcp", {
method: "POST",
headers: {
"Content-Type": "application/json",
"Mcp-Session-Id": sessionId,
},
body: JSON.stringify(request),
});
可恢复性和重新交付
为了支持恢复断开的连接,Streamable HTTP 提供:
事件 ID:服务器可以将唯一 ID 附加到 SSE 事件以便跟踪
从上一个事件恢复:客户端可以通过发送
Last-Event-ID
标题来恢复消息重播:服务器可以从断开点重播错过的消息
即使在网络连接不稳定的情况下,这也确保了可靠的消息传递。
安全注意事项
实施 Streamable HTTP 传输时,请遵循以下安全最佳实践:
验证来源标头:始终验证
Origin
所有传入连接上的标头,以防止 DNS 重新绑定攻击绑定到本地主机:在本地运行时,仅绑定到本地主机(127.0.0.1),而不是所有网络接口(0.0.0.0)
实施身份验证:对所有连接使用适当的身份验证
使用 HTTPS:始终使用 TLS/HTTPS 进行生产部署
验证会话 ID:确保会话 ID 加密安全且经过正确验证
如果没有这些保护措施,攻击者可以使用 DNS 重新绑定从远程网站与本地 MCP 服务器进行交互。
定制运输
MCP 可以轻松实现针对特定需求的自定义传输。任何传输实现只需遵循 Transport 接口即可:
您可以为以下对象实现自定义传输:
自定义网络协议
专业沟通渠道
与现有系统集成
性能优化
interface Transport {
// Start processing messages
start(): Promise<void>;
// Send a JSON-RPC message
send(message: JSONRPCMessage): Promise<void>;
// Close the connection
close(): Promise<void>;
// Callbacks
onclose?: () => void;
onerror?: (error: Error) => void;
onmessage?: (message: JSONRPCMessage) => void;
}
错误处理
传输实现应该处理各种错误情况:
连接错误
消息解析错误
协议错误
网络超时
资源清理
最佳实践
实施或使用 MCP 传输时:
正确处理连接生命周期
实施适当的错误处理
连接关闭时清理资源
使用适当的超时
发送前验证消息
记录传输事件以进行调试
在适当的时候实现重新连接逻辑
处理消息队列中的背压
监控连接健康状况
实施适当的安全措施
安全注意事项
实施运输时:
身份验证和授权
实施适当的身份验证机制
验证客户端凭据
使用安全令牌处理
实施授权检查
数据安全
使用 TLS 进行网络传输
加密敏感数据
验证消息完整性
实施邮件大小限制
净化输入数据
网络安全
实施速率限制
使用适当的超时
处理拒绝服务情况
监控异常模式
实施适当的防火墙规则
对于基于 HTTP 的传输(包括 Streamable HTTP),验证 Origin 标头以防止 DNS 重新绑定攻击
对于本地服务器,仅绑定到本地主机(127.0.0.1),而不是所有接口(0.0.0.0)
调试传输
调试传输问题的提示:
启用调试日志记录
监控消息流
检查连接状态
验证消息格式
测试错误场景
使用网络分析工具
实施健康检查
监视资源使用情况
测试边缘情况
使用适当的错误跟踪
评论区