MCP 传输层:stdio 与 Streamable HTTP
搞清楚 MCP 的两种消息传输方式——本地用 stdio、远程用 Streamable HTTP,以及怎么选。
零基础认识 MCP——让 AI 应用安全、统一地连上外部工具和数据的开放标准协议。
内容摘要
MCP 全称 **Model Context Protocol(模型上下文协议)**,是 Anthropic 在 **2024 年 11 月 25 日** 发布的一个开放标准。它干的事情其实很简单一句话就能说清:**让 AI 应用有一个统一的方式,去连接外部的工具、数据和工作流**。
MCP 全称 Model Context Protocol(模型上下文协议),是 Anthropic 在 2024 年 11 月 25 日 发布的一个开放标准。它干的事情其实很简单一句话就能说清:让 AI 应用有一个统一的方式,去连接外部的工具、数据和工作流。
要理解它为什么存在,得先说清楚它解决了什么痛点。在 MCP 出现之前,如果你想让 Claude 读你电脑上的文件,得写一份专门给 Claude 的对接代码;想让它读数据库,又得写一份;换成 ChatGPT,前面那两份代码基本上还得再重写一遍。M 个 AI 应用 × N 种数据源 = M × N 份对接代码,这就是业内常说的"N×M 集成难题"。每加一个数据源、每换一个 AI 客户端,工程量都要翻倍。
MCP 官方自己打的比方非常形象:MCP 之于 AI,就像 USB-C 之于电子设备。在 USB-C 普及之前,手机、相机、硬盘、耳机都有自己的专用接口,买一根新线换一台设备就得重来;USB-C 出现之后,只要两边都是 USB-C,插上就能用。MCP 想做的就是 AI 世界的 USB-C——只要客户端(AI 应用)和服务端(工具/数据源)都遵守同一个协议,任意两边都能直接对接,不用再各写各的胶水代码。
发布之初,Anthropic 就顺手给了六个开箱即用的官方 Server:Google Drive、Slack、GitHub、Git、PostgreSQL、Puppeteer。这一点很关键,它不只是抛出一份纸面协议,而是附带了"能让你马上跑起来"的参考实现。
| 要素 | 作用 |
|---|---|
| 开放标准 | 协议和 SDK 全部开源,任何人、任何厂商都可以实现自己的客户端或服务端 |
| 客户端-服务端架构 | AI 应用充当 Host,内部为每个外部服务建一个 Client,Client 一对一地连到一个 Server |
| JSON-RPC 2.0 | 底层消息格式使用业界通用的 JSON-RPC 2.0,不是 Anthropic 自己发明的新语言 |
| 能力协商 | 连接建立时,客户端和服务端互相声明"我支持哪些能力",避免调用对方不支持的功能 |
| 双向通信 | 不只是客户端调服务端,服务端也可以反向请求客户端采样 LLM、向用户提问 |
这是理解 MCP 最重要的一张图。Host、Client、Server 三个词经常被混用,但它们是三个不同的东西:
很多新手一看到 "Server" 就以为要部署到云上、要有域名——完全不是。大多数日常用的 MCP Server 只是一个运行在你自己电脑上的本地小程序,启动后和 Host 之间用标准输入输出(stdio)交换 JSON 消息,简单到不可思议。
MCP 规范把协议划分成两层,理解这个划分有助于你之后读源码和文档不被搞晕:
这是 MCP 给 Server 开发者的"三块积木",几乎所有 MCP Server 都是在这三种原语里挑组合:
| 原语 | 中文 | 本质 | 典型例子 |
|---|---|---|---|
| Tools | 工具 | 可被 AI 调用的函数,会产生副作用 | 查询数据库、发送邮件、修改文件 |
| Resources | 资源 | 可被 AI 读取的上下文数据 | 文件内容、数据库表结构、API 返回体 |
| Prompts | 提示词模板 | 预定义的提示词模板,用户可手动调用 | 代码评审模板、翻译润色模板 |
一个记法:Tools 是"做",Resources 是"读",Prompts 是"模板"。绝大多数初学者一开始只会用到 Tools,其他两个可以暂时放一边。
MCP 作为一个协议本身没有"跑一下看看"的命令,但最快感受它的办法是:在 Claude Desktop 里挂一个官方 Filesystem Server,让 Claude 能读写你电脑上的某个文件夹。下面这段就是 Claude Desktop 的配置文件 claude_desktop_config.json 的最小示例:
{
"mcpServers": {
"filesystem": {
"command": "npx",
"args": [
"-y",
"@modelcontextprotocol/server-filesystem",
"/Users/your-name/Desktop"
]
}
}
}
这几行 JSON 翻译成人话:
mcpServers 下每一项就是一个你想挂载的 Server,名字(这里是 filesystem)自己起,方便识别就行。command + args 告诉 Host "要启动这个 Server,请执行 npx -y @modelcontextprotocol/server-filesystem /Users/your-name/Desktop"。保存配置、重启 Claude Desktop,在对话框的附件区域就会多出一个锤子图标,点开能看到 Filesystem Server 暴露出来的工具,比如 read_file、write_file、list_directory。接下来你对 Claude 说"把我桌面上的 README.md 总结一下",它就会自己调用 read_file 把文件内容读进来再回答——这就是 MCP 在干的事情。
预期行为:
你:帮我看一下桌面上 notes.md 里写了什么,顺便总结成三句话。
Claude:[调用工具:read_file,参数:/Users/your-name/Desktop/notes.md]
Claude:文件里主要讲了三件事:……
MCP 不是第一个"让 AI 调外部服务"的方案,它的独特价值只有对比了才看得清楚:
| 维度 | MCP | Function Calling(OpenAI / Anthropic 原生) | ChatGPT Plugins(已退场) | LangChain Tools |
|---|---|---|---|---|
| 开放标准 | ✅ 开源开放,多厂商支持 | ❌ 各家 API 格式不同 | ❌ 仅 OpenAI 生态 | 半开放,但绑定在 Python 框架里 |
| 谁写一次谁就能复用 | ✅ 写一个 Server,所有兼容客户端都能用 | ❌ 工具函数和特定 SDK 绑定 | ❌ 绑定 OpenAI 平台 | ❌ 绑定 LangChain |
| 跨进程/跨语言 | ✅ 服务端语言任意,客户端通过 stdio/HTTP 对接 | ❌ 通常在同一进程内 | ✅ | ❌ 主要在 Python 内 |
| 支持远程托管 | ✅ Streamable HTTP + OAuth | — | ✅ | 需自己搭 |
| 学习曲线 | 中(要理解协议三原语) | 低 | 低 | 中 |
核心区别用一句话说:
| 误区 | 准确理解 |
|---|---|
| 以为 MCP 是 Anthropic 私有的、只能给 Claude 用 | MCP 是开放标准,目前 Claude、ChatGPT、VS Code、Cursor、Windsurf、Zed 等都已支持;写一个 Server 可以喂给所有这些客户端 |
| 以为 MCP Server 一定要部署到云上 | 大多数常用 Server 就是跑在你电脑上的本地小程序,通过 stdio 和 Host 交换消息,根本不需要公网地址 |
| 把 MCP 和 Function Calling 对立起来 | 两者是互补关系:Host 收到 Server 声明的 Tools 后,最终还是用大模型原生的 Function Calling 能力让模型决定调哪个工具 |
| 认为 MCP 只能提供工具调用 | Server 端有三种原语:Tools(做动作)、Resources(提供只读上下文)、Prompts(提供提示词模板);客户端还可以暴露 Sampling、Elicitation、Logging 三种原语供 Server 反向调用 |
| 以为学 MCP 要先啃 JSON-RPC 规范 | 官方 Python / TypeScript SDK 已经把 JSON-RPC 封装好了,日常开发几乎见不到原始协议消息,只要理解三原语和生命周期即可 |
| 以为 "Server" 和 "Client" 是独立的两台机器 | MCP 里的 Host、Client、Server 是逻辑角色——Client 是 Host 内部的一个组件,而不是一个独立的程序 |
| 优势 | 劣势 |
|---|---|
| 写一次,到处可用:一个 Filesystem Server 同时适配多个 AI 客户端,彻底打破 N×M 集成困境 | 协议仍在快速迭代:目前规范版本为 2025-06-18,字段、能力、鉴权方案半年内还会变,早期写的 Server 可能要跟着升级 |
| 本地优先 + 远程可扩:stdio 让本地开发零网络负担,Streamable HTTP 又支持 OAuth 接企业远端服务 | 生态质量参差:社区 Server 数量暴涨,但安全性和稳定性差异很大,下载陌生 Server 前需要自己审代码 |
| 语言无关:服务端用 Python/Go/Rust/Node 都行,只要说 JSON-RPC 就能接 | 调试门槛略高:出问题时要同时排查 Host、Client、Server 三方,初学者容易定位不到哪一层出错,好在有 MCP Inspector 可视化工具 |
能力协商机制健全:生命周期明确、listChanged 通知能让工具列表动态更新,适合做企业级长连接 | 安全模型依赖客户端实现:MCP 规范只定义协议,真正的权限控制、沙箱隔离要靠 Host 去做,不同客户端的安全等级差异很大 |
| 官方 + 社区双轮驱动:reference server 保证协议真的能跑,社区 Server 覆盖速度极快(GitHub、Notion、Slack、Figma 等主流 SaaS 都已有) | 不适合做"薄"的一次性集成:如果你只是想在自己 App 内部接一个固定的 API,直接用原生 Function Calling 成本更低 |
参考答案:
N×M 指的是 "M 个 AI 应用 × N 种数据源"。没有统一协议之前,每一对组合都要单独写对接代码——Claude 对接 GitHub 要写一次,Cursor 对接 GitHub 又得写一次,换成 Notion 还得再来一遍。集成工作量随两边数量相乘增长。
一个很直观的身边例子:USB-C 普及前的充电线抽屉。一个家庭里常备 Micro USB(旧安卓)、Lightning(旧 iPhone)、Mini USB(某些相机)、Type-C(新设备)四五种线,每加一台新设备就要买一根对应线,或者多带一根旅行。USB-C 统一之后,一根线走天下,这就是 MCP 想让 AI 工具生态达到的状态——写一个 Server,对所有客户端有效。
参考答案:
Function Calling 是模型层面的能力:你告诉模型"有这么几个函数可以调,参数是什么",模型在生成时会选择要不要调其中一个函数。它解决了"模型如何表达想调工具"的问题。
但 Function Calling 本身不管工具的发现、分发、复用、跨客户端共享——这些函数是你在自己代码里硬编码进去的,换一个 AI 应用就要再写一遍,而且工具函数的业务逻辑和模型 SDK 混在一起,很难独立演进。
MCP 是工具生态层面的协议,它站在 Function Calling 上一层:一个 MCP Server 把自己能提供的 Tools 通过 tools/list 暴露出来,Host 拿到这个列表后,再用大模型原生的 Function Calling 能力把这些工具描述喂给模型,让模型选工具。模型选好之后,Host 再把调用转发给对应的 Server。
所以两者是嵌套关系:MCP 负责工具的跨进程、跨客户端共享;Function Calling 负责让模型在一堆工具里做选择。你可以把 MCP 理解成一个"可插拔的工具菜单",Function Calling 是"点菜"的动作,菜谁做、怎么做由 Server 决定。
参考答案:
分层的本质是把"消息长什么样"和"消息怎么送到对方"解耦。
数据层固定采用 JSON-RPC 2.0,定义了握手、能力协商、三大原语的方法名和字段结构——这些是不会随运行环境变化的"语义"。传输层则可以按场景替换:本地进程间直接用 stdio 最省事、零网络开销;远程服务用 Streamable HTTP 则能享受到 HTTP 生态成熟的鉴权、代理、CDN、负载均衡等能力。
工程上的好处有三点:
这种"内外分层"的做法和 HTTP vs TCP、邮件内容 vs SMTP 是同一个哲学:语义稳定,通道可换。
优先展示同分类且标签更接近的内容,方便继续串联学习。
搞清楚 MCP 的两种消息传输方式——本地用 stdio、远程用 Streamable HTTP,以及怎么选。
搞清楚 MCP 里 Host、Client、Server 各自干什么、怎么连接、消息怎么流转。
搞清楚 MCP Server 能暴露的三种能力——工具、资源、提示词模板,以及什么时候该用哪个。