传输层

数据层的 JSON-RPC 消息在每一种传输上 语义相同。传输只规定:消息怎么成帧、元数据怎么附带、取消与断开怎么表达。现行规范的标准绑定是 stdioStreamable HTTP。早期的 HTTP+SSE 已被取代,但仍会在部分客户端(包括 Cursor 的部分配置)里以遗留方式出现。


对照表

传输怎么走典型场景新项目?
StdioHost 拉起子进程,换行分隔的 JSON-RPC 走 stdin/stdout本机工具、开发调试本地首选
Streamable HTTP客户端对 同一个 MCP 端点 发 HTTP POST;响应可以是 JSON 或请求范围内的 SSE 流远程、多客户端、可部署远程首选
SSE(遗留)旧版「HTTP + 长连接事件流」尚未迁移的客户端不要新建

官方 Python SDK 的态度很明确:mcp.run() 默认 stdio;部署用 transport="streamable-http"transport="sse" 仅为兼容。


Stdio:本地、零网络开销

Host 的配置通常是一条 命令 + 参数,而不是 URL:

{
  "command": "python",
  "args": ["D:\\mcp-demo\\server.py"]
}

进程起来之后:

  • Client 往 stdin 写请求
  • Server 往 stdout 写响应
  • stderr 才是日志该去的地方

因此:

# 危险:可能污染协议流(尤其在 run() 之前或缓冲刷新时)
print("server starting")

# 正确:打到 stderr
import logging
logging.basicConfig(level=logging.INFO)  # 官方 SDK 默认把日志落到 stderr

自己在终端里运行 python server.py 时,什么也不打印、也不退出 是正常的——它在等 stdin 上的第一条协议消息。用 Inspector 或 Host 启动,而不是盯着这个窗口「看有没有输出」。

Windows PowerShell 启动检查(应阻塞,用 Ctrl+C 结束):

python .\server.py

Unix:

python ./server.py

取消:Client 发送 notifications/cancelled。进程退出即连接结束。


Streamable HTTP:远程默认

客户端对单一端点(常见 /mcp)发 POST。规范要求请求带上可被网关阅读的头(如 Mcp-MethodMcp-Name、协议版本),便于路由与限流,而不必先解析 JSON 体。鉴权走标准 HTTP:Bearer、API Key、自定义头;官方建议用 OAuth 获取令牌

用官方 SDK 监听本机:

if __name__ == "__main__":
    mcp.run(transport="streamable-http", host="127.0.0.1", port=8000)

默认端点是 http://127.0.0.1:8000/mcphost / port / streamable_http_pathrun() 的参数,不要传给 MCPServer(...)

PowerShell 快速探活(仅确认端口在听;完整协议请用 Inspector):

Invoke-WebRequest -Uri "http://127.0.0.1:8000/mcp" -Method POST -ContentType "application/json" -Body '{"jsonrpc":"2.0","id":1,"method":"server/discover","params":{}}'

Unix:

curl -sS -X POST "http://127.0.0.1:8000/mcp" \
  -H "Content-Type: application/json" \
  -d '{"jsonrpc":"2.0","id":1,"method":"server/discover","params":{}}'

取消:Client 关闭这一次请求的响应流。现行规范下,不必再依赖长期会话 ID 才能水平扩展。

绑定 0.0.0.0 之前,先想清楚鉴权与防火墙;本机学习保持 127.0.0.1


遗留 SSE:知道即可

2025-03-26 规范用 Streamable HTTP 取代了旧的 HTTP+SSE。部分客户端(文档与 UI 里仍写 SSE 的,Cursor 是常见例子)还能填一个事件流 URL。那是兼容通道,不是新接口。

若必须对接只懂 SSE 的旧 Client:用对方文档里的字段(有的叫 url + transport: sse),同时规划迁到 Streamable HTTP。新 Server 不要把 SSE 当主路径。


如何选择

flowchart TD
    A[这台 Server 给谁用?] --> B{只有本机这一个 Host?}
    B -->|是| C[Stdio]
    B -->|否 / 要部署] --> D[Streamable HTTP]
    D --> E{对方是否只认旧 SSE?}
    E -->|是| F[临时兼容 SSE,并记录迁移]
    E -->|否| G[只提供 /mcp POST]

同一套 Tools / Resources / Prompts 可以先用 stdio 开发,再改一行 run(transport=...) 发布。传输变了,原语不变。


下一步

评论