纵横中文网手机客户端
42.26MB · 2025-10-18
MCP (Model Context Protocol) 是一个用于 AI 模型与外部工具通信的协议。很多开发者在接触 MCP 时,常常对其传输方式感到困惑:为什么有的配置是一个命令行,有的是一个 HTTP 地址?今天我们就来深入探讨 MCP 的三种传输方式及其区别。
MCP 目前支持三种传输方式:
stdio 是最常用的本地集成方式。它的核心特点是:客户端负责启动服务器进程,而不是连接到一个已经运行的进程。
{
"mcpServers": {
"filesystem": {
"command": "npx",
"args": ["-y", "@modelcontextprotocol/server-filesystem", "/home/user"],
"transport": "stdio"
}
}
}
┌─────────────┐
│ 客户端 │
│ (Claude等) │
└──────┬──────┘
│
│ 1. 执行命令启动子进程
▼
┌─────────────┐
│ MCP Server │
│ (子进程) │
└──────┬──────┘
│
│ 2. 建立 stdin/stdout 管道
│
┌──┴──┐
│stdin│ ← 客户端写入请求
│stdout│ → 服务器返回响应
└─────┘
// 客户端侧
cmd := exec.Command("node", "/path/to/server.js")
stdin, _ := cmd.StdinPipe()
stdout, _ := cmd.StdoutPipe()
cmd.Start()
// 发送请求
stdin.Write([]byte(`{"jsonrpc":"2.0","method":"tools/list","id":1}n`))
// 读取响应
scanner := bufio.NewScanner(stdout)
scanner.Scan()
response := scanner.Text()
// 服务器侧
func main() {
server := mcp.NewServer(...)
// 从 stdin 读取
scanner := bufio.NewScanner(os.Stdin)
for scanner.Scan() {
message := scanner.Text()
response := server.Handle(message)
// 通过 stdout 返回
fmt.Println(response)
}
}
优点:
缺点:
SSE 是早期的 HTTP 传输方式,从 2024-11-05 版本开始已被弃用,但为了向后兼容仍被支持。
SSE 方式需要两个独立的端点:
// 需要两个处理器
router.GET("/sse", handleSSE) // 服务器推送
router.POST("/message", handleMsg) // 客户端发送
客户端 → 服务器:POST /message (发送请求)
服务器 → 客户端:GET /sse (长连接接收推送)
客户端需要同时维护两个连接:
{
"url": "http://localhost:3000/sse",
"messageEndpoint": "http://localhost:3000/message",
"transport": "sse"
}
Streamable HTTP 是在 2025 年 3 月引入的新传输方法,它简化了 SSE 的复杂性。
只需要一个统一的端点,处理所有通信:
mcpHandler := mcp.NewStreamableHTTPHandler(
func(r *http.Request) *mcp.Server {
return appServer.mcpServer
},
&mcp.StreamableHTTPOptions{
JSONResponse: true, // 支持 JSON 响应
},
)
// 单一端点处理所有请求
router.Any("/mcp", gin.WrapH(mcpHandler))
router.Any("/mcp/*path", gin.WrapH(mcpHandler))
Streamable HTTP 支持两种响应模式:
POST /mcp
↓
立即返回 JSON 响应
POST /mcp
↓
返回 SSE 流,持续推送消息
{
"url": "http://localhost:8080/mcp",
"transport": "http"
}
特性 | stdio | SSE(已弃用) | Streamable HTTP |
---|---|---|---|
端点数量 | N/A | 2个独立端点 | 1个统一端点 |
通信方式 | 进程间通信 | HTTP 双端点 | HTTP 单端点 |
部署位置 | 本地 | 远程 | 远程 |
会话管理 | 自动 | 复杂 | 内置支持 |
响应灵活性 | N/A | 仅 SSE | JSON + SSE |
配置复杂度 | 简单 | 中等 | 简单 |
使用场景 | 本地工具、插件 | 遗留系统 | 现代 Web 服务 |
状态 | 推荐 | ️ 已弃用 | 推荐 |
推荐使用 stdio
{
"mcpServers": {
"file-system": {
"command": "npx",
"args": ["-y", "@modelcontextprotocol/server-filesystem", "/workspace"],
"transport": "stdio"
},
"git": {
"command": "npx",
"args": ["-y", "@modelcontextprotocol/server-git"],
"transport": "stdio"
}
}
}
原因:
推荐使用 Streamable HTTP
func main() {
mcpServer := mcp.NewServer(...)
mcpHandler := mcp.NewStreamableHTTPHandler(
func(r *http.Request) *mcp.Server {
return mcpServer
},
&mcp.StreamableHTTPOptions{
JSONResponse: true,
},
)
http.Handle("/mcp", mcpHandler)
http.ListenAndServe(":8080", nil)
}
客户端配置:
{
"url": "https://mcp.example.com/mcp",
"transport": "http"
}
原因:
可能需要支持 SSE
如果你的系统已经使用了 SSE 方式,可以继续使用以保持兼容性,但建议逐步迁移到 Streamable HTTP。
新项目优先选择:
安全考虑:
性能优化:
错误处理:
// stdio 方式
if err := cmd.Start(); err != nil {
log.Fatal("Failed to start MCP server:", err)
}
// HTTP 方式
if resp.StatusCode != 200 {
log.Error("MCP request failed:", resp.Status)
}
MCP 的三种传输方式各有特点,选择合适的传输方式能够让你的应用更加高效和可靠:
参考资源: