总结一篇关于 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 服务的实际运行模式:

  1. Stdio(标准输入输出)模式:
  • 多数本地开源 MCP 服务(如官方 SQLite、Filesystem 适配器)的默认运行方式。
  • 服务通过标准输入/输出流通过管道传递 JSON-RPC 消息,完全不开放 HTTP 端口。
  • 排查结论:若服务运行于此模式,使用 curl 请求任何 HTTP 端口均会直接返回连接拒绝或 404。必须使用官方的 MCP Inspector(npx @modelcontextprotocol/inspector)进行管道注入与可视化调试。
  1. 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),便于排查字段类型匹配错误或协议违规。