目录
为什么要了解 MCP 与 stdio?
过去一年,大模型从“会聊天”进化到“会动手”:读文件、调 API、跑脚本。然而各家厂商的插件接口五花八门,开发者必须写 N 套适配器。
Anthropic 在 2024 年 11 月发布的 Model Context Protocol(MCP) 把“插件”抽象成了统一的 资源 / 工具 / 提示 三大概念,并提供 stdio、HTTP+SSE(后来改成了Streamable HTTP) 两种传输机制。
其中 stdio 传输 最简单——只需启动一个子进程,用标准输入/输出就能完成所有 JSON-RPC 通信,非常适合本地 CLI 工具、脚本或嵌入式 Agent。
MCP 协议全景图
MCP 架构图如下:

- Client:AI Agent、IDE、聊天机器人……
- Server:暴露文件、数据库、REST API 等能力的轻量进程
- Transport:本文主角 —— stdio(标准输入/输出)
- Message:JSON-RPC 2.0 规范,分 Request / Response / Notification 三类
stdio 传输规则速查表
| 维度 | 约定 |
|---|---|
| 编码 | UTF-8 |
| 每条消息 | 单行 JSON,以 \n 结尾 |
| 方向 | Client→Server 走 stdin |
| 错误 | stderr 可打印日志,但不参与协议 |
| 并发 | 支持多请求并行,靠 id 字段匹配响应 |
传输过程入下图所示:
实战:手动握手 + 拉取工具列表
下面用“纯终端”方式演示一次完整会话,不依赖任何 SDK。
启动服务器
我们采用Cangjie Magic所提供的官方示例,有关详情参考:调试基于Cangjie Magic的MCP服务器指南-优快云博客
启动Cangjie Magic的MCP服务器的命令行是:
cjpm run --skip-build --name magic.examples.mcp_server
此时进程阻塞,等待 stdin输入
发送 initialize 请求
在终端(或 使用echo)向该进程 stdin 写入:
{"jsonrpc":"2.0","id":1,"method":"initialize","params":{"protocolVersion":"2024-11-05","capabilities":{},"clientInfo":{"name":"demo-cli","version":"1.0"}}}
注意:必须带换行符 `\n`。
接收握手响应
服务器立即在 stdout 返回:
{"jsonrpc":"2.0","id":0,"result":{"protocolVersion":"2024-11-05","capabilities":{"prompts":{"listChanged":false},"resources":{"subscribe":false,"listChanged":false},"tools":{"listChanged":false}},"serverInfo":{"name":"Cangjie Magic Agent Server","version":"0.1"}}}
发送 initialized 通知
客户端必须再发一条“我已初始化完毕”的无回复通知:
{"jsonrpc":"2.0","method":"notifications/initialized"}
查询工具列表
接着就可以拉取工具:
{"jsonrpc":"2.0","id":2,"method":"tools/list","params":{}}
服务器返回(示例):
{"jsonrpc":"2.0","id":2,"result":{"tools":[{"name":"add","description":"Add two numbers","inputSchema":{"type":"object","properties":{"a":{"type":"integer"},"b":{"type":"integer"}},"required":["a","b"]}},{"name":"multiply","description":"Multiply two numbers","inputSchema":{"type":"object","properties":{"a":{"type":"integer"},"b":{"type":"integer"}},"required":["a","b"]}},{"name":"Calculator","description":"小学算术计算器","inputSchema":{"type":"object","properties":{"question":{"type":"string","description":"The input question"}},"required":["question"]}}]}}
至此,stdio 通道已完全可用,后续可继续发送 `tools/call`、`resources/list` 等请求。
stdio vs SSE 传输对比
| 场景 | stdio | HTTP+SSE |
|---|---|---|
| 启动方式 | 本地子进程 | 远端 URL |
| 防火墙 | 无要求 | 需开放端口 |
| 并发连接 | 单进程单连接 | 可多客户端 |
| 适用对象 | CLI、桌面插件 | SaaS、云函数 |
| 演示难度 | ⭐(简单) | ⭐⭐⭐(需 CORS、鉴权) |
常见问题 FAQ
1. 一定要发 `initialized` 吗?
是的,否则服务器不会接受后续业务请求。
2. 可以一次发送多条请求吗?
可以,只要每条 JSON 独占一行,服务器按 `id` 异步回复。
延伸阅读与工具
结束语
如果本文帮到你,欢迎转发/收藏,也欢迎在评论区贴出你用 MCP 做出的酷炫 Agent!
5216

被折叠的 条评论
为什么被折叠?



