MCP 协议设计与实现

前言:Agent 生态的 USB 标准

作者 杨艺韬 · 3,729 字 · 发布于 · 更新于

过去 40 年,网络、操作系统、Web 的每一次生态收敛,最后都收敛到一份开放协议上。这一次轮到 Agent 的工具层。

写作动机:Agent 生态的碎片化困境

MCP 出现之前,AI Agent 生态面临一个尴尬的现实:每个 Agent 框架都在重新发明工具集成的轮子。

Claude Code 有自己的工具系统,LangChain 有自己的 Tool 抽象,Cursor 有自己的集成方式,Windsurf 又有自己的规范。一个开发者写了一个"搜索 Jira 工单"的工具,想在 Claude Code 里用——得按 Claude Code 的格式实现一遍。想在 LangChain 里用——得按 LangChain 的 BaseTool 重写一遍。想在 Cursor 里用——又得再来一遍。

graph LR
    subgraph Before["MCP 之前的世界"]
        T1[Jira Tool] -->|"API 写法 A"| CC1[Claude Code]
        T1 -->|"API 写法 B"| LC1[LangChain]
        T1 -->|"API 写法 C"| CU1[Cursor]
        T1 -->|"API 写法 D"| WI1[Windsurf]
        T1 -->|"每个平台都要重写"| N[N 次重复劳动]
    end
    subgraph After["MCP 之后的世界"]
        T2[Jira MCP Server] -->|"只实现一次"| H[MCP 协议<br/>统一接口]
        H --> CC2[Claude Code]
        H --> LC2[LangChain]
        H --> CU2[Cursor]
        H --> WI2[Windsurf]
    end
    style N fill:#fee2e2,stroke:#ef4444
    style H fill:#dcfce7,stroke:#22c55e,stroke-width:2px

这就像 USB 标准出现之前的外设市场:每个厂商有自己的接口,买个鼠标还要看主板兼容性。每个外设厂商要为每个主板写一份驱动。最终的结果是:生态被分割,创新被锁死在各个孤岛内。

MCP(Model Context Protocol)就是 Agent 生态的 USB 标准。

它定义了一个开放的、标准化的协议,让任何工具只要实现一次 MCP Server,就能被所有支持 MCP 的 Client 调用——Claude Code、Claude Desktop、Cursor、Windsurf、Zed,以及未来更多的 Agent 平台。

MCP 的爆发式增长

2024 年 11 月 Anthropic 发布 MCP 的第一个版本时,社区的反应是"又一个协议?"。但短短半年内:

这种增长速度说明了一个事实:Agent 生态确实需要一个标准协议,MCP 来得正是时候。

为什么这次能成?

历史上有过很多"开放协议"试图统一 AI 生态——很多都失败了。MCP 能站住脚的关键因素有四个:

  1. Anthropic 作为主要客户率先验证——Claude Desktop 在协议发布时即原生支持,随后推出的 Claude Code 也内建了 MCP 客户端,给了生态信心
  2. 协议设计克制——核心原语只有三个(Tool/Resource/Prompt),不臃肿
  3. 基于 JSON-RPC——成熟、可调试、语言无关
  4. SDK 先行——TypeScript 和 Python SDK 开源,立刻能用

这四点共同造就了临界质量的生态启动。

这个专栏讲什么

本专栏不是 MCP 的使用教程——官方文档已经做得很好了。

本专栏关注的是协议的设计与实现:为什么这样设计?SDK 是怎么实现的?集成时会踩什么坑?如何自己开发一个生产级的 MCP Server?

核心问题清单

本专栏回答以下具体问题:

协议设计

传输层

安全与认证

高级能力

工程实现

每一章从设计意图出发,深入 TypeScript SDK 和 Python SDK 的源码实现,最后提炼可迁移的协议设计模式。

本专栏的方法论:协议 = 规范 + 实现 + 生态

理解一个协议需要三个视角:

graph TD
    Protocol[MCP 协议]
    Protocol --> Spec[规范层<br/>官方文档说了什么]
    Protocol --> Impl[实现层<br/>SDK 是怎么做的]
    Protocol --> Eco[生态层<br/>社区在怎么用]
    Spec --> S1[为什么这样设计]
    Spec --> S2[设计权衡]
    Spec --> S3[演进方向]
    Impl --> I1[TypeScript SDK]
    Impl --> I2[Python SDK]
    Impl --> I3[Claude Code 集成]
    Eco --> E1[主流 MCP Server]
    Eco --> E2[常见坑点]
    Eco --> E3[社区反馈]
    style Protocol fill:#dbeafe,stroke:#3b82f6,stroke-width:2px
    style Spec fill:#fef3c7,stroke:#f59e0b
    style Impl fill:#dcfce7,stroke:#22c55e
    style Eco fill:#f3e8ff,stroke:#a855f7

很多书只讲规范,读完你知道协议"是什么"但不知道"怎么用"。很多文档只讲实现,读完你会用但不理解"为什么"。本专栏三个视角同时推进——规范解释意图,实现展示机理,生态提供教训。

本专栏读者

前置知识

你需要:

你不需要:

本专栏组织:八个部分

graph TD
    P1[开篇<br/>Ch00-01<br/>为什么需要 MCP] --> P2[协议基础<br/>Ch02-04<br/>架构·消息·生命周期]
    P2 --> P3[三大原语<br/>Ch05-07<br/>Tool·Resource·Prompt]
    P3 --> P4[SDK 实现<br/>Ch08-11<br/>TS/Python Server/Client]
    P4 --> P5[传输层<br/>Ch12-14<br/>STDIO·HTTP·SSE·WS]
    P5 --> P6[认证安全<br/>Ch15-16<br/>OAuth·发现·注册]
    P6 --> P7[高级特性<br/>Ch17-19<br/>Sampling·Elicitation·Claude Code]
    P7 --> P8[总结<br/>Ch20-21<br/>构建 Server·设计模式]
    style P1 fill:#dbeafe,stroke:#3b82f6
    style P2 fill:#dbeafe,stroke:#3b82f6
    style P3 fill:#fef3c7,stroke:#f59e0b
    style P4 fill:#fef3c7,stroke:#f59e0b
    style P5 fill:#dcfce7,stroke:#22c55e
    style P6 fill:#fecaca,stroke:#dc2626
    style P7 fill:#f3e8ff,stroke:#a855f7
    style P8 fill:#fef9c3,stroke:#eab308

第一部分:开篇(前言与第 1 章)——MCP 存在的理由、生态位、和竞品的对比。读完建立全局认知。

第二部分:协议基础(第 2-4 章)——MCP 的架构层次(Host / Client / Server)、消息格式(JSON-RPC 2.0)、连接生命周期。这是后续所有章节的基础。

第三部分:三大原语(第 5-7 章)——Tool / Resource / Prompt 三个核心抽象的设计和使用。每一章深入到"为什么是这三个,而不是更多或更少"。

第四部分:SDK 实现(第 8-11 章)——TypeScript SDK 和 Python SDK 的内部实现。Server 和 Client 两个视角都有。这一部分看完,你能独立开发 MCP Server。

第五部分:传输层(第 12-14 章)——STDIO、Streamable HTTP、SSE、WebSocket 四种传输方式的实现和权衡(2025-11-25 规范只定义前两种;HTTP+SSE 是 2024-11-05 的遗留传输,WebSocket 从来不是规范定义的传输)。最务实的工程章节。

第六部分:认证安全(第 15-16 章)——OAuth 2.1、Discovery、Dynamic Client Registration。生产级 MCP Server 必读。

第七部分:高级特性(第 17-19 章)——Sampling(反向 LLM 调用)、Elicitation(向用户索要信息)、Claude Code 的实际集成方案。

第八部分:总结(第 20-21 章)——从零构建一个生产级 MCP Server 的完整流程;协议设计的可迁移模式。

每一章的写作节奏

  1. 问题域:这一章解决的具体问题是什么?
  2. 规范要点:MCP 官方文档对这一块怎么规定?
  3. 设计意图:为什么这样规定?替代方案是什么?
  4. 实现细节:TS SDK / Python SDK 怎么实现?
  5. 踩坑与最佳实践:真实生态里遇到的坑和对策
  6. 可迁移方法论:这个设计模式能应用到其他协议设计中吗?

一条核心论断:协议窗口期

每一代计算平台都有一个"协议窗口期":

计算时代 关键协议窗口 抓住窗口的一方
1980s PC 操作系统 API(DOS/Windows, POSIX) Microsoft
1990s 网络 TCP/IP、HTTP Cisco, Netscape(败给 IE)
2000s Web DOM、XHR、HTML5 Google, Mozilla
2010s Mobile iOS/Android SDK Apple, Google
2010s-2020s 云原生 Kubernetes API CNCF
2025+ AI Agent MCP ?

协议窗口期往往只有短短几年。过了窗口期,生态往往就锁定了,新进入者很难撼动。在作者看来,MCP 正处在这样一个窗口期内。

源码版本与环境

本专栏基于以下版本分析:

组件 版本 获取方式
MCP 协议规范 2025-11-25 git clone https://github.com/modelcontextprotocol/modelcontextprotocol.git
TypeScript SDK b8886e7(2026-04-16,@modelcontextprotocol/client@2.0.0-alpha.2 之后 13 个提交) git clone https://github.com/modelcontextprotocol/typescript-sdk.git && git checkout b8886e7
Python SDK 3d7b311(2026-04-15,v1.25.0 之后 156 个提交) git clone https://github.com/modelcontextprotocol/python-sdk.git && git checkout 3d7b311
MCP Inspector 随 npx 取最新 npx @modelcontextprotocol/inspector

表里两个 SDK 的日期是 git 记录的作者日期(按作者本地时区);3d7b311 换算成 UTC 是 2026-04-14 21:41,是同一个提交。

2025-11-25 已不是最新规范

规范仓库在 2026-07-28 发布了新一版,改动很大:去掉 initialize 握手与 Mcp-Session-Id 会话,协议版本与客户端能力改由每个请求的 _meta 携带;Server 向 Client 索要 Sampling / Elicitation / Roots 改为 Multi Round-Trip Requests(结果里返回 input_required,Client 带着答复重试原请求);Tasks 移出核心协议成为扩展;Roots、Sampling、Logging 与 HTTP+SSE 传输、动态客户端注册(RFC 7591)标为 Deprecated(见该版 changelog.mdx)。本专栏锚定的两个 SDK 提交早于这一版,LATEST_PROTOCOL_VERSION 都是 2025-11-25。本专栏讲的是 2025-11-25 的形态,涉及生命周期、会话与反向通道时,读新规范要以 2026-07-28 为准。

规范仓库已改名

规范仓库原名 modelcontextprotocol/specification,现已重命名为 modelcontextprotocol/modelcontextprotocol。旧地址靠 GitHub 重定向仍能 clone, 但本专栏一律使用改名后的规范地址。

关于 SDK 的版本:本专栏不写 "latest"。"latest" 不是一个版本——它随时间变化,读者拿到的树和写作时的树可能不是同一棵。两个 SDK 都还在快速演进(TypeScript SDK 此时仍处在 2.0.0-alpha 阶段),文件会搬家:例如 ModelPreferences 原先在单文件模块 mcp/types.py 里,现在 types 已经拆成包,它落在 src/mcp/types/_types.py(本专栏锚定的 3d7b311 上实测)。本专栏引用的行号取自上表那两个精确提交——照着上面的 git checkout 命令拿到的就是核对时用的那棵树,行号逐条对得上(本专栏带行号的引用都在这几棵树上逐条复核过,没有越界的行号)。如果你用的是更新的版本而某处行号对不上,以符号名为准检索(rg "class ModelPreferences" -n)。

这条承诺是无条件的:本专栏凡是带行号的引用,一律指向上表锚定的那几棵树,你照着 git checkout 就能逐条复核。第 19 章 §19.10.1 讲的是 Claude Code 自身的内部实现(闭源,读者拿不到),所以那一小节刻意不给行号——给一份打不开的源码标行号,比不给行号更糟,它带着可复核的外观却没有可复核的实质。该小节开头有单独说明。

核心源码目录:

modelcontextprotocol/            # 规范仓库
├── docs/specification/2025-11-25/    # 本专栏基准的协议规范
└── schema/2025-11-25/schema.ts       # TypeScript 形式的 schema
    # 同级目录还并存 2024-11-05 / 2025-03-26 / 2025-06-18 / 2026-07-28 / draft

typescript-sdk/                  # b8886e7 上 packages/ 下四个目录、七个 package
├── packages/
│   ├── core/           # 协议核心:shared/(protocol、transport、stdio、uriTemplate)+ types/ + auth/
│   ├── client/         # Client 实现(client/、stdio、sse、streamableHttp)
│   ├── server/         # Server 实现(server/、mcp、stdio、streamableHttp)
│   └── middleware/     # 框架适配层(express / fastify / hono / node)

python-sdk/
├── src/mcp/
│   ├── client/        # Client 实现
│   ├── server/        # Server 实现(含 lowlevel/ 与 mcpserver/)
│   ├── shared/        # 共享组件(session、message、auth、memory 等)
│   └── types/         # Pydantic 类型定义(__init__.py / jsonrpc.py / _types.py)

目录结构随版本漂移

上面这棵树是 b8886e7 / 3d7b311 上的实际形态,两个 SDK 之后都还在搬家: TypeScript SDK 后来又拆出了 packages/core-internal、packages/server-legacy、 packages/codemod;Python SDK 的 src/mcp/shared/session.py 后来被 peer.py + dispatcher.py 取代,types/ 下的 _types.py 也拆成了 methods.py / version.py。 后续章节引用源码路径时,若你 clone 的是更新的版本,按符号名检索换算即可。

实战工具推荐

读本专栏的时候,强烈推荐装这些工具:

# MCP Inspector - 可视化调试 MCP Server
npx @modelcontextprotocol/inspector <你的 server 命令>

# 官方参考 Server(modelcontextprotocol/servers 仓库现存七个:
# everything / fetch / filesystem / git / memory / sequentialthinking / time)
npx @modelcontextprotocol/server-filesystem /tmp   # TypeScript 实现,走 npm
uvx mcp-server-git --repository /path/to/repo      # Python 实现,走 PyPI

# Claude Code CLI(用于测试 MCP 集成)
# 参考官方文档安装

阅读路径

根据不同目标,推荐的阅读顺序:


本专栏基于 2026 年 4 月时间点的 MCP 规范(2025-11-25)与对应 SDK 版本;此后规范已于 2026-07-28 发布新一版(见上文《源码版本与环境》)。协议仍在演进,但设计原则比具体规定更持久——读懂 MCP 为什么这样设计,也能迁移到下一代协议上。

杨艺韬 2026 年 4 月 · 于北京


延伸阅读的推荐起点