Appearance
从 MCP 到 LSP:好协议都在消灭重复的胶水
上一篇我从一个 AWS 服务一路问到了状态机。这一篇是它的续集,因为同一串追问还有后半截——我顺手问了一句"MCP 到底是什么",结果又拽出来一条线。等我把这条线和上一条并在一起看,发现它们指向同一个东西。
先把结论放这:
好的协议都在干同一件事——把 M×N 的重复集成爆炸,收敛成 M+N 的标准接口。
先说 MCP 是什么
MCP(Model Context Protocol,模型上下文协议)是 Anthropic 在 2024 年 11 月发布并开源的标准。一句话:它是 AI 模型和外部世界(数据、工具、系统)之间的标准接口,官方那个比喻很贴切——它是 AI 的 USB-C 口。
它解决的真问题,是一个集成爆炸。在 MCP 之前,你想让一个 AI 接入外部能力,得为每一对"模型 × 工具"单独写一遍集成:
Claude ←自定义代码→ GitHub
Claude ←自定义代码→ Slack
GPT ←自定义代码→ GitHub ← 又重写一遍
GPT ←自定义代码→ Slack ← 又重写一遍M 个模型 × N 个工具 = M×N 套胶水代码。每出一个新模型或新工具,集成量翻倍。
MCP 把它拆成 M+N:工具方只要实现一次 MCP Server,模型方只要实现一次 MCP Client,两边照同一个协议对话就行。
┌─ MCP Server (GitHub)
模型 ─MCP─┼─ MCP Server (Slack)
(Client) └─ MCP Server (你的内部系统)协议里具体有什么
MCP 本质是一套建立在 JSON-RPC 2.0 之上的约定:
- 地基:JSON-RPC 2.0,有状态连接。
- 握手:连上先发
initialize,双方互相声明支持哪些能力(capability negotiation)。 - Server 给 Client 三样:Tools(模型可调用的函数)、Resources(可读的数据)、Prompts(预设模板)。
- Client 给 Server 三样:Sampling(让 server 反过来用模型)、Roots(操作边界)、Elicitation(向用户要补充信息)。
- 传输:stdio(本地子进程)、Streamable HTTP(远程)。
- 安全:工具等于任意代码执行,所以协议层强制"用户同意"——这就是为什么我的 AI 助手每次帮我 git push、发消息前都要我确认。
其中最关键的一点:工具用 JSON Schema 自描述。模型问一句"你有哪些工具",server 就用 JSON Schema 加自然语言描述告诉它"我有这些能力、每个要什么参数、是干嘛的"。机器不用人帮忙读文档,自己就懂了。 这正是它能跨模型通用的技术底座。
这套打法不是新的:LSP 早来了八年
写到这我意识到,这个"用标准协议消灭 M×N"的招式特别眼熟。一查,MCP 的官方规范自己点名了模板:LSP(Language Server Protocol)。
LSP 是微软 2016 年随 VS Code 推出并开源的。它解决的是另一个一模一样的爆炸——M 个编辑器 × N 种语言:
在 LSP 之前,"代码补全、跳转定义、报错"这些智能功能,是每个编辑器为每种语言单独实现一遍的。VS Code 的 Python 支持、Vim 的 Python 支持、IDEA 的 Python 支持……各写各的。这就是为什么以前小众语言在大多数编辑器里没有智能提示。
LSP 的解法和 MCP 是同一张图:语言方实现一次 Language Server(pyright、gopls、rust-analyzer),所有编辑器都能用上。一门新语言只要出一个 server,所有编辑器立刻支持。
| LSP(2016) | MCP(2024) | |
|---|---|---|
| 标准化谁和谁 | 编辑器 ↔ 语言 | AI 模型 ↔ 工具 |
| Client 侧 | VS Code / Vim / IDEA | Claude / GPT / 各种 agent |
| Server 侧 | pyright / gopls / rust-analyzer | 各种 MCP server |
| 消除的爆炸 | M 编辑器 × N 语言 | M 模型 × N 工具 |
| 底层消息格式 | JSON-RPC | JSON-RPC(直接继承) |
连底层消息格式都一样——MCP 用 JSON-RPC,正是因为它照着 LSP 抄的。
那 MCP 像 HTTP 吗?
我一开始的直觉是:MCP 是不是就像 HTTP,定义了"系统对外提供服务的协议"?
方向对,但磨细之后更有意思。HTTP 确实是"对外服务协议",但它少干了一件大事:只规定怎么传(GET/POST、状态码),不告诉你有什么服务。你访问一个陌生 API,光靠 HTTP 啥也不知道,得去翻文档、看 OpenAPI,人类读懂了再写代码去调。HTTP 把"语义"这层完全留给了人。
而 MCP 把"自描述"焊进了协议本身。所以更精确的说法是:
MCP ≈ HTTP + OpenAPI + 一套专为 AI 消费者设计的固定语义词汇(tools / resources / prompts)。
最关键的差别在最后一层:HTTP/OpenAPI 的自描述是给人看的;MCP 的自描述是给模型看的。它把人类原本要做的"读文档 → 懂语义 → 写调用代码"那一步,直接编进了协议。
一个隐藏的成本,和一个反直觉的活儿
天下没有白来的抽象。MCP 降低了客户端集成成本(M+N),但把另一个成本集中了起来:底层 API 一变,MCP server 就得跟着改。 server 本质是个适配器,它就是吸收 API 变更的那块缓冲垫。
好处是这个变更被"困"在 server 一侧,不会扩散——server 作者改一次,所有接它的模型自动跟上。这也是为什么 GitHub、Notion、Linear 这些都开始自己出官方 server:只有 API 提供方自己维护,才能保证零延迟同步,生态才稳。
还有个反直觉的细节:模型决定调不调一个工具,主要看 description 那段自然语言,不只看 schema。所以维护 MCP server,很多时候不是在维护接口,是在维护"对模型的说明书"。一段话写得好不好,直接决定模型用得对不对。
收束:把两条线并起来看
上一篇那条线是:Step Functions → 状态机 → 1936 年的图灵机。 这一篇这条线是:MCP → LSP → HTTP。
并在一起,是同一句话的两个例子:
- Step Functions 消灭的是"流程编排"的重复胶水(每个项目重写一遍的状态管理、重试、等待)。
- LSP / MCP 消灭的是"集成对接"的重复胶水(每对编辑器×语言、每对模型×工具重写一遍的适配)。
每一代基础设施,都在用一个更聪明的协议,替我们消灭上一代人反复手搓的胶水。而 MCP 比所有前辈更进了一步——连"读懂接口"这件事,都不再留给人了。
这大概就是"好基础设施"的定义:它消灭的不是某个具体的活,而是某一类"本不该由人反复做"的活。