总结一篇关于 Model Context Protocol (MCP) 传输层机制、协议演进及 curl 联调排错。
一、 关于MCP传输层Streamable HTTP
在 MCP 协议中,客户端与服务器的通信高度依赖底层传输协议。去年2025版本的协议标准从旧版的 Legacy SSE 演进为现代的 Streamable HTTP。
1. Legacy SSE (HTTP + SSE 双端点模式)
- 架构特征:采用双端点设计。客户端首先通过
GET /sse建立长连接,用于单向接收服务器推送的事件;服务器在初始连接事件中动态返回一个专用的消息接收地址(通常形如/messages?sessionId=uuid)。 - 状态管理:会话标识(Session ID)紧密绑定在 URL 查询参数(Query Parameter)中。
- 致命缺陷:若用于监听的
GET长连接因网络抖动或超时中断,整个 Session 即告失效,缺乏内建的断线重连与状态恢复能力。
2. Streamable HTTP (现代单端点标准)
- 架构特征:统一收敛至单一 HTTP 端点(例如
/mcp)。无论是建立初始连接、发送 JSON-RPC 指令还是接收流式响应,均通过该统一路径处理。 - 状态传递机制:剥离了动态 URL 参数,改由标准的 HTTP 请求头(Header) 承载会话上下文(如
Mcp-Session-Id),完美适配现代 API 网关、反向代理(Nginx)与负载均衡器。 - 可靠性与断点续传:支持基于事件 ID(如
Last-Event-ID)的消息重放机制,允许客户端在网络重连后拉取断开期间遗漏的事件。
传输模式对比矩阵
| 对比维度 | Legacy SSE (HTTP+SSE) | Streamable HTTP (Modern) |
|---|---|---|
| 端点设计 | 双端点(分离的 GET /sse 与 POST /messages) |
单端点(统一的 /mcp 路径) |
| 会话传递 | URL 查询参数 (?sessionId=...) |
HTTP 请求头 (Mcp-Session-Id) |
| 重连机制 | 不支持,中断即会话销毁 | 支持(依托 Last-Event-ID 恢复) |
| 代理友好度 | 较低(URL 动态多变,不利于网关路由) | 高(标准 RESTful 风格 Header 路由) |
二、 运行模式识别:Stdio vs. HTTP
在排查连接问题前,必须先确认 MCP 服务的实际运行模式:
- Stdio(标准输入输出)模式:
- 多数本地开源 MCP 服务(如官方 SQLite、Filesystem 适配器)的默认运行方式。
- 服务通过标准输入/输出流通过管道传递 JSON-RPC 消息,完全不开放 HTTP 端口。
- 排查结论:若服务运行于此模式,使用
curl请求任何 HTTP 端口均会直接返回连接拒绝或 404。必须使用官方的 MCP Inspector(npx @modelcontextprotocol/inspector)进行管道注入与可视化调试。
- HTTP / Streamable HTTP 模式:
- 运行独立的服务进程,监听特定 TCP 端口(如
3000)。 - 支持通过标准 HTTP 客户端(如
curl、Postman)进行交互。
三、 基于 curl 的 Streamable HTTP 联调
当确认服务运行于 Streamable HTTP 模式时,标准的交互流程分为建立长连接流与发送 JSON-RPC 指令两个阶段。
步骤 1:建立持久监听流 (GET)
在终端中发起长连接请求,禁用缓冲区(-N),以实时监听服务器推送的事件流:
curl -N -v -H "Accept: text/event-stream" http://localhost:3000/mcp
- 运行表现:连接成功后,终端会保持挂起状态并持续接收事件。服务器会在初始化阶段下发会话标识(
Mcp-Session-Id),需将其记录用于后续的POST请求。
步骤 2:通过 Header 发送 JSON-RPC 请求 (POST)
保持上述 GET 终端不关闭,另起终端发送具体的 JSON-RPC 2.0 请求。必须严格指定 Content-Type 与 Mcp-Session-Id。
1. 查询可用工具列表 (tools/list)
curl -X POST http://localhost:3000/mcp \
-H "Content-Type: application/json" \
-H "Mcp-Session-Id: <your-session-id>" \
-d '{
"jsonrpc": "2.0",
"id": 1,
"method": "tools/list",
"params": {}
}'
2. 执行具体工具调用 (tools/call)
curl -X POST http://localhost:3000/mcp \
-H "Content-Type: application/json" \
-H "Mcp-Session-Id: <your-session-id>" \
-d '{
"jsonrpc": "2.0",
"id": 2,
"method": "tools/call",
"params": {
"name": "execute_query",
"arguments": {
"sql": "SELECT 1;"
}
}
}'
四、 使用官方 Model Context Protocol Inspector 工具进行调试
另外可以直接使用官方提供的 MCP Inspector 是最高效的黄金调试工具。对于 Stdio 模式 的服务,或者在不想编写繁琐的 curl 时,它能够自动托管 Stdio 管道并向开发者提供直观的 Web UI,非常方便。
1. 启动命令
通过 npx 直接加载 Inspector 并包装你的服务启动命令:
# 针对 Node.js / TypeScript 服务
npx @modelcontextprotocol/inspector node server.js
# 针对 Python 服务(如基于 FastMCP 的脚本)
npx @modelcontextprotocol/inspector python server.py
2. 核心功能与使用收益
- 自动分配 Web UI:启动后,终端会输出一个本地调试面板地址(通常为
http://localhost:5173或类似端口)。 - 可视化交互:在浏览器中可以直接查看服务器声明的 Tools、Resources 与 Prompts 列表。
- 参数表单生成:针对每个工具,Inspector 会根据 JSON Schema 自动生成对应的输入参数表单,点击即可直接触发
tools/call并实时查看结构化返回结果。 - Raw 报文透传:提供实时的 JSON-RPC 消息收发日志(Inspector Logs),便于排查字段类型匹配错误或协议违规。