MCP 协议设计与实现

第1章 为什么需要 MCP

作者 杨艺韬 · 7,173 字

第1章 为什么需要 MCP

"We shape our tools, and thereafter our tools shape us." —— Marshall McLuhan

本章要点

  1. 碎片化困局:每个 Agent 框架都在各自发明工具集成方案,导致生态严重割裂
  2. USB 类比:MCP 之于 AI Agent 工具生态,正如 USB 之于计算机外设生态
  3. 协议本质:MCP 是基于 JSON-RPC 2.0 的开放协议,定义了 Host-Client-Server 三层架构
  4. 三大原语:Tool(模型控制)、Resource(应用控制)、Prompt(用户控制)的分层设计是 MCP 的精髓
  5. 生态爆发:从 2024 年 11 月首次发布到 Claude Code、Cursor、VS Code 全面采用,MCP 正在成为事实标准

1.1 一个真实的痛点:工具集成的碎片化

假设你是一个全栈开发者,刚刚构建了一个连接 PostgreSQL 数据库的工具——它能执行 SQL 查询、分析表结构、生成数据报告。现在你希望把这个工具接入各种 AI 应用,让不同的 AI 助手都能使用它。

你很快会发现一个令人沮丧的现实:

同一个工具,五种接口。每增加一个 AI 应用,就要多写一套适配代码。每增加一个工具,就要为所有已接入的 AI 应用分别适配。这是一个典型的 M×N 问题

各框架工具接口的真实面貌

让我们看看这些不兼容的接口到底长什么样。

OpenAI Function Calling 格式:

{
  "type": "function",
  "function": {
    "name": "query_database",
    "description": "Execute SQL query on PostgreSQL",
    "parameters": {
      "type": "object",
      "properties": {
        "sql": { "type": "string", "description": "SQL statement" }
      },
      "required": ["sql"]
    }
  }
}

LangChain BaseTool:

from langchain.tools import BaseTool
from pydantic import Field

class DatabaseQueryTool(BaseTool):
    name: str = "query_database"
    description: str = "Execute SQL query on PostgreSQL"

    def _run(self, sql: str) -> str:
        # 执行查询逻辑
        return result

    async def _arun(self, sql: str) -> str:
        # 异步执行逻辑
        return result

Claude Code 内置工具格式:

const tool = {
  name: "query_database",
  description: "Execute SQL query on PostgreSQL",
  inputSchema: {
    type: "object" as const,
    properties: {
      sql: { type: "string", description: "SQL statement" }
    },
    required: ["sql"]
  },
  async call(input: { sql: string }) {
    // 执行查询逻辑
    return { result };
  }
};

表面上看,这些定义的核心信息是一样的:工具名、描述、参数 schema、执行逻辑。但包装方式完全不同——有的用 JSON,有的用类继承,有的用对象字面量。更关键的是,传输协议、生命周期管理、错误处理、安全模型都各不相同

M×N 问题的本质

graph TB
    subgraph "没有 MCP 的世界:M×N 适配"
        A1["Claude Desktop"] ---|"适配层 A1"| T1["数据库工具"]
        A1 ---|"适配层 A2"| T2["文件系统工具"]
        A1 ---|"适配层 A3"| T3["GitHub 工具"]

        A2["ChatGPT Plugin"] ---|"适配层 B1"| T1
        A2 ---|"适配层 B2"| T2
        A2 ---|"适配层 B3"| T3

        A3["Cursor"] ---|"适配层 C1"| T1
        A3 ---|"适配层 C2"| T2
        A3 ---|"适配层 C3"| T3
    end

    style A1 fill:#dbeafe,stroke:#3b82f6
    style A2 fill:#dbeafe,stroke:#3b82f6
    style A3 fill:#dbeafe,stroke:#3b82f6
    style T1 fill:#fef3c7,stroke:#f59e0b
    style T2 fill:#fef3c7,stroke:#f59e0b
    style T3 fill:#fef3c7,stroke:#f59e0b

3 个 AI 应用 × 3 个工具 = 9 个适配层。当应用和工具各增长到 100 个时,就需要 10,000 个适配层。这显然不可持续。

这不是一个新问题。计算机历史上每一次外设接口标准化都经历过同样的阶段——打印机、显示器、存储设备,在 USB 出现之前,每种设备都有自己的专用接口。

1.2 USB 类比:为什么标准协议改变一切

USB(Universal Serial Bus)在 1996 年发布时,PC 世界的外设接口是一团混乱:串口连调制解调器,并口连打印机,PS/2 连键盘鼠标,SCSI 连硬盘,游戏端口连手柄。每种设备需要专用的物理接口、专用的驱动程序、专用的通信协议。

USB 做了什么?它定义了:

  1. 统一的物理接口——一种接口连接所有设备
  2. 标准的通信协议——设备自描述,即插即用
  3. 清晰的角色分工——Host(主机)控制总线,Device(设备)响应请求
  4. 可扩展的设备类型——键盘、鼠标、存储、音频,都通过同一协议描述

USB 把 M×N 问题变成了 M+N 问题:设备厂商只需实现一次 USB 协议,计算机厂商也只需实现一次 USB 主控,两边独立发展,互不干扰。

MCP 在 AI Agent 领域做的,正是同样的事情。

graph TB
    subgraph "有 MCP 的世界:M+N 标准化"
        A1["Claude Desktop"] --- P["MCP 协议"]
        A2["Cursor"] --- P
        A3["VS Code"] --- P
        A4["自定义 Agent"] --- P

        P --- T1["数据库 Server"]
        P --- T2["文件系统 Server"]
        P --- T3["GitHub Server"]
        P --- T4["Slack Server"]
    end

    style P fill:#dcfce7,stroke:#22c55e,stroke-width:3px
    style A1 fill:#dbeafe,stroke:#3b82f6
    style A2 fill:#dbeafe,stroke:#3b82f6
    style A3 fill:#dbeafe,stroke:#3b82f6
    style A4 fill:#dbeafe,stroke:#3b82f6
    style T1 fill:#fef3c7,stroke:#f59e0b
    style T2 fill:#fef3c7,stroke:#f59e0b
    style T3 fill:#fef3c7,stroke:#f59e0b
    style T4 fill:#fef3c7,stroke:#f59e0b

4 个应用 + 4 个工具 = 只需要 8 次实现,而不是 16 次。当两边各增长到 100 个时,只需要 200 次实现,而不是 10,000 次。

这个类比不只是修辞手法。USB 的成功有三个关键因素,MCP 同样具备:

特征 USB MCP
统一接口 标准物理插口 + 电气协议 JSON-RPC 2.0 + 标准消息格式
设备自描述 USB 描述符(Device Descriptor) 能力协商(Capability Negotiation)
角色分工 Host / Device Host / Client / Server
即插即用 热插拔 + 自动驱动 动态发现 + 运行时注册
开放标准 USB-IF 组织维护 Anthropic 开源 + 社区共建

1.3 MCP 到底是什么

让我们给 MCP 一个精确的定义。

Model Context Protocol(MCP)是一个开放协议,它标准化了 AI 应用(如 Claude Desktop、Cursor、IDE 插件)与外部数据源和工具之间的通信方式。

这个定义来自 MCP 规范的官方描述:

"Model Context Protocol (MCP) is an open protocol that enables seamless integration between LLM applications and external data sources and tools."

让我们拆解这个定义中的每一个关键词:

技术基础:JSON-RPC 2.0

MCP 建立在 JSON-RPC 2.0 之上。这不是随意的选择,而是经过深思熟虑的技术决策。

JSON-RPC 2.0 是一个轻量级的远程过程调用协议,它的消息格式极其简洁:

请求(Request):

{
  "jsonrpc": "2.0",
  "id": 1,
  "method": "tools/list",
  "params": {}
}

响应(Response):

{
  "jsonrpc": "2.0",
  "id": 1,
  "result": {
    "tools": [
      {
        "name": "query_database",
        "description": "Execute SQL query",
        "inputSchema": {
          "type": "object",
          "properties": {
            "sql": { "type": "string" }
          },
          "required": ["sql"]
        }
      }
    ]
  }
}

通知(Notification)——没有 id 字段,不需要响应:

{
  "jsonrpc": "2.0",
  "method": "notifications/tools/list_changed"
}

为什么选择 JSON-RPC 而不是其他协议?这个问题的答案与 MCP 的设计哲学密切相关,我们将在 1.6 节详细讨论。

MCP 的灵感来源

MCP 规范明确提到了它的灵感来源:

"MCP takes some inspiration from the Language Server Protocol (LSP), which standardizes how to add support for programming languages across a whole ecosystem of development tools."

LSP 解决的问题和 MCP 几乎完全对称:在 LSP 出现之前,每个编辑器(VS Code、Vim、Emacs、Sublime)要单独实现每种编程语言的支持(语法高亮、自动补全、跳转定义),这也是一个 M×N 问题。LSP 通过定义一个标准的 Language Server 协议,把问题变成了 M+N——编辑器只需要实现 LSP 客户端,语言工具只需要实现 LSP 服务端。

MCP 在 AI 领域做了同样的事,但它面对的挑战更复杂:

维度 LSP MCP
通信发起方 人类输入触发 模型自主决策触发
安全模型 相对简单(读代码) 复杂(可能执行任意操作)
状态管理 文件系统为中心 多数据源、多工具
结果类型 结构化(补全列表、诊断) 非结构化(文本、图片、音频)

1.4 Host-Client-Server:三层架构的精妙设计

理解 MCP 的架构是理解整个协议的钥匙。MCP 采用的不是简单的客户端-服务端两层模型,而是 Host-Client-Server 三层架构

graph LR
    subgraph "Application Host Process"
        H["Host<br>(如 Claude Desktop)"]
        C1["Client 1"]
        C2["Client 2"]
        C3["Client 3"]
        H --> C1
        H --> C2
        H --> C3
    end

    subgraph "Local Machine"
        S1["Server 1<br>文件系统"]
        S2["Server 2<br>数据库"]
        R1[("本地<br>文件")]
        R2[("本地<br>数据库")]

        C1 --> S1
        C2 --> S2
        S1 <--> R1
        S2 <--> R2
    end

    subgraph "Internet"
        S3["Server 3<br>GitHub API"]
        R3[("远程<br>仓库")]

        C3 --> S3
        S3 <--> R3
    end

    style H fill:#dcfce7,stroke:#22c55e,stroke-width:2px
    style C1 fill:#dbeafe,stroke:#3b82f6
    style C2 fill:#dbeafe,stroke:#3b82f6
    style C3 fill:#dbeafe,stroke:#3b82f6
    style S1 fill:#fef3c7,stroke:#f59e0b
    style S2 fill:#fef3c7,stroke:#f59e0b
    style S3 fill:#fef3c7,stroke:#f59e0b

为什么是三层而不是两层?

这是 MCP 最容易被误解的设计决策之一。直觉上,似乎"应用直接连服务器"更简单。但三层架构解决了几个关键问题:

Host(宿主) 是用户直接交互的应用程序,比如 Claude Desktop、Cursor、VS Code。它的职责是:

Client(客户端) 是 Host 内部的连接器,每个 Client 与一个 Server 保持一对一的连接:

Server(服务端) 提供具体的工具和数据:

安全隔离:为什么每个 Server 看不到其他 Server

这是三层架构最重要的设计意图之一。MCP 规范的设计原则明确指出:

"Servers should not be able to read the whole conversation, nor 'see into' other servers."

这意味着:

这种设计直接源于安全考量。想象一下:如果你同时连接了一个"公司内部数据库"Server 和一个"第三方天气查询"Server,你绝对不希望天气 Server 能看到你的数据库查询内容。三层架构通过 Client 的隔离确保了这一点。

能力协商:渐进式功能发现

MCP 的另一个精妙设计是**能力协商(Capability Negotiation)**机制。在连接建立时,Client 和 Server 会交换各自支持的功能列表:

// Client 发送 initialize 请求
{
  "jsonrpc": "2.0",
  "id": 1,
  "method": "initialize",
  "params": {
    "protocolVersion": "2025-03-26",
    "capabilities": {
      "roots": { "listChanged": true },
      "sampling": {}
    },
    "clientInfo": {
      "name": "claude-desktop",
      "version": "1.0.0"
    }
  }
}

// Server 响应,声明自己支持的能力
{
  "jsonrpc": "2.0",
  "id": 1,
  "result": {
    "protocolVersion": "2025-03-26",
    "capabilities": {
      "tools": { "listChanged": true },
      "resources": { "subscribe": true }
    },
    "serverInfo": {
      "name": "database-server",
      "version": "2.1.0"
    }
  }
}

这种设计的好处是渐进式兼容——旧版本的 Client 遇到新版本的 Server 不会崩溃,它只是看不到新功能。MCP 规范对此的设计原则是:

"Features can be added to servers and clients progressively. Core protocol provides minimal required functionality. Additional capabilities can be negotiated as needed."

这和 USB 的设备描述符机制如出一辙:你把一个 USB 3.0 设备插到 USB 2.0 端口,它不会报错,只是降级到 USB 2.0 速度运行。

1.5 三大原语:Tool、Resource、Prompt

MCP 定义了三种核心原语,这是理解整个协议最关键的概念。它们不是按"功能类型"划分的,而是按**"谁来控制调用"**划分的。

原语 控制方 类比 典型用例
Tool 模型控制(Model-controlled) 函数 执行 SQL、调用 API、文件操作
Resource 应用控制(Application-controlled) 数据源 读取文件内容、获取数据库 schema
Prompt 用户控制(User-controlled) 模板 代码审查模板、SQL 生成模板

这个三分法看似简单,实则蕴含深意。

Tool:模型自主决策的执行能力

Tool 是最容易理解的原语。MCP 规范对 Tool 的定义是:

"Tools in MCP are designed to be model-controlled, meaning that the language model can discover and invoke tools automatically based on its contextual understanding and the user's prompts."

当你对 Claude 说"帮我查一下数据库中用户表有多少条记录",模型会自主决定调用数据库查询工具。模型发现可用工具列表、选择合适的工具、构造参数、发起调用——整个过程都是模型驱动的。

一个 MCP Tool 的定义包含以下关键字段:

{
  "name": "query_database",
  "description": "Execute a read-only SQL query on the PostgreSQL database",
  "inputSchema": {
    "type": "object",
    "properties": {
      "sql": {
        "type": "string",
        "description": "The SQL query to execute (SELECT only)"
      }
    },
    "required": ["sql"]
  },
  "annotations": {
    "readOnlyHint": true,
    "openWorldHint": false
  }
}

注意 annotations 字段——它提供了关于工具行为的元数据提示,比如这个工具是否只读、是否会产生副作用。但规范特别提醒:

"For trust & safety and security, clients MUST consider tool annotations to be untrusted unless they come from trusted servers."

这意味着工具的 annotations 仅供参考,Host 不应该盲目信任它们来做安全决策。

Resource:应用程序控制的上下文数据

Resource 的控制逻辑与 Tool 完全不同。MCP 规范明确说:

"Resources in MCP are designed to be application-driven, with host applications determining how to incorporate context based on their needs."

Resource 不是模型自主去取的,而是应用程序决定什么时候、以什么方式把数据提供给模型。典型的场景包括:

每个 Resource 由一个 URI 唯一标识,支持订阅和变更通知:

{
  "uri": "file:///project/src/main.rs",
  "name": "main.rs",
  "description": "Primary application entry point",
  "mimeType": "text/x-rust"
}

Resource 还支持模板化的 URI,这意味着服务端可以暴露动态的资源空间。比如一个数据库 Server 可以暴露 db://{schema}/{table} 模板,让应用程序根据需要查询任意表的结构。

Prompt:用户显式选择的交互模板

Prompt 是三个原语中最"人性化"的一个。MCP 规范说:

"Prompts are designed to be user-controlled, meaning they are exposed from servers to clients with the intention of the user being able to explicitly select them for use."

Prompt 通常以斜杠命令(slash command)的形式暴露给用户。比如在 Claude Desktop 中,数据库 Server 可能提供一个 /analyze-table 提示模板:

{
  "name": "analyze-table",
  "description": "Generate a comprehensive analysis of a database table",
  "arguments": [
    {
      "name": "table_name",
      "description": "Name of the table to analyze",
      "required": true
    }
  ]
}

当用户选择这个命令时,Server 返回一组预构造的消息,引导模型按照特定的方式分析数据。

为什么这个三分法很重要?

你可能会想:Tool、Resource、Prompt 的底层不都是"向 Server 请求数据或执行操作"吗?为什么要分成三种?

关键在于安全模型和用户体验

Tool 涉及执行(execution)。模型调用工具可能产生副作用——修改文件、发送邮件、删除数据。因此 MCP 规范要求:

"There SHOULD always be a human in the loop with the ability to deny tool invocations."

Host 必须在工具执行前展示确认对话框,让用户审批。

Resource 涉及读取(reading)。读取操作通常是安全的,不会修改外部状态。应用程序可以自动、静默地把相关资源注入上下文,不需要每次都征求用户同意。

Prompt 涉及引导(guidance)。它改变的不是外部世界,而是模型的行为方式。用户需要显式选择使用哪个 Prompt 模板,因为不同的模板会导致完全不同的分析视角和输出格式。

这三种控制层级构成了一个安全梯度:

用户控制(Prompt)→ 应用控制(Resource)→ 模型控制(Tool)
   安全性最高            中等              需要人工审批

这种分层与操作系统的权限设计有异曲同工之妙。读取文件不需要特殊权限,执行程序需要执行权限,修改系统配置需要管理员权限——MCP 的三大原语用类似的逻辑把 AI Agent 的操作按风险等级分层。

1.6 MCP vs 替代方案:为什么不用已有的协议?

在 MCP 出现之前,已经有很多成熟的通信协议和工具集成方案。一个自然的问题是:为什么不直接用它们?

为什么不用 REST API?

REST API 是 Web 开发的基石,几乎所有后端服务都暴露 REST 接口。但它不适合做 AI 工具协议,原因有三:

第一,REST 是无状态的,MCP 需要有状态的会话。 MCP 的会话从 initialize 开始,经过能力协商,到 shutdown 结束。在整个会话期间,Client 和 Server 维持着共享状态——哪些能力已协商、哪些资源已订阅、哪些工具可用。REST 的每个请求都是独立的,无法优雅地管理这种有状态的交互。

第二,REST 缺少双向通信。 REST 是请求-响应模式,Server 无法主动向 Client 推送消息。但 MCP 需要 Server 主动发送通知,比如"工具列表发生了变化"(notifications/tools/list_changed)或"资源内容更新了"(notifications/resources/updated)。

第三,REST 没有标准的能力协商机制。 每个 REST API 都自定义自己的认证方式、版本管理、错误格式。MCP 通过 initialize 请求统一解决了这些问题。

为什么不用 gRPC?

gRPC 是 Google 开发的高性能 RPC 框架,支持双向流、Protocol Buffers 序列化、强类型。它看起来很适合 MCP 的场景。

但 gRPC 的门槛太高了。 MCP 规范的第一条设计原则是:

"Servers should be extremely easy to build."

gRPC 需要预定义 .proto 文件,需要代码生成步骤,需要 HTTP/2 服务器。而 MCP 的 stdio 传输模式只需要从标准输入读 JSON、向标准输出写 JSON——一个 Python 初学者用 json.loads()print() 就能实现一个最简 MCP Server。

gRPC 的 Protocol Buffers 虽然高效,但牺牲了可读性。当你在调试 MCP 通信问题时,JSON 可以直接用肉眼阅读,而 protobuf 的二进制格式需要专用工具解码。对于一个主要传输文本(代码、文档、SQL 查询结果)的协议来说,JSON 的序列化开销并不是瓶颈。

为什么不用 OpenAI Function Calling 格式?

OpenAI 的 function calling 格式已经是事实上的行业标准——很多框架都兼容或参考了它。为什么 MCP 不直接采用?

因为 function calling 不是协议,它只是一种消息格式。 function calling 定义了"工具长什么样"和"调用参数是什么",但没有定义:

MCP 在消息层面与 function calling 是兼容的(工具定义的 inputSchema 格式一致),但它在此基础上增加了完整的协议层——传输、会话、能力协商、安全模型。

为什么不用 LSP 直接扩展?

LSP 是 MCP 的直接灵感来源,为什么不直接扩展 LSP 而是另起炉灶?

因为 LSP 的假设是"一个语言服务器对应一种编程语言",它的消息类型都围绕代码编辑场景设计:textDocument/completiontextDocument/definitiontextDocument/diagnostic。AI Agent 的工具生态远超代码编辑——数据库查询、API 调用、文件操作、网络搜索——这些用例需要不同的抽象模型。

MCP 借鉴了 LSP 的协议设计思路(JSON-RPC、能力协商、渐进式功能),但定义了全新的消息类型和原语体系

对比总结

维度 REST API gRPC Function Calling LSP MCP
传输 HTTP HTTP/2 嵌入 LLM API JSON-RPC JSON-RPC
状态 无状态 有状态 无状态 有状态 有状态
双向通信
能力协商
易于实现
序列化 JSON Protobuf JSON JSON JSON
安全模型 自定义 自定义 依赖平台 有限 完整
工具发现 无标准 反射 静态 静态 动态
场景覆盖 通用 Web 微服务 LLM 调用 代码编辑 AI Agent

MCP 不是要替代这些协议,而是在 AI Agent 工具集成这个特定领域,填补了一个空白。

1.7 从发布到生态爆发:MCP 的发展时间线

MCP 的发展速度超出了大多数人的预期。以下是关键里程碑:

2024 年 11 月:首次发布

Anthropic 在 2024 年 11 月 25 日发布了 MCP 的第一个版本(协议版本 2024-11-05),同步开源了:

首版协议定义了核心架构(Host-Client-Server)、三大原语(Tool/Resource/Prompt)、两种传输方式(stdio 和 HTTP+SSE),以及完整的生命周期管理。

2025 年 3 月:重大版本更新

协议版本 2025-03-26 带来了多项重要改进:

2025 年中:生态爆发

多个主流 AI 开发工具宣布支持 MCP:

2025 年底至 2026 年:持续演进

协议版本 2025-06-182025-11-25 继续推进:

MCP 的规范仓库中维护着完整的版本历史,每个版本的 Schema 定义都保存在 schema/ 目录下,从 2024-11-05 到最新的 draft,清晰地记录了协议的演进轨迹。

schema/
├── 2024-11-05/    # 首版
├── 2025-03-26/    # 重大更新
├── 2025-06-18/    # 持续演进
├── 2025-11-25/    # 最新稳定版
└── draft/         # 开发中的下一版
    ├── schema.json
    ├── schema.ts   # TypeScript 类型定义(权威源)
    └── schema.mdx

值得注意的是,MCP 规范明确指出 TypeScript Schema(schema.ts)是权威定义源:

"This specification defines the authoritative protocol requirements, based on the TypeScript schema in schema.ts."

这意味着所有语言的 SDK 实现都以这个 TypeScript 定义为准。

1.8 本书的范围:教什么,不教什么

你将学到什么

本书将从协议规范和 SDK 源码出发,系统地教你:

协议层面(第 2-7 章):

实现层面(第 8-11 章):

传输与安全(第 12-16 章):

高级特性(第 17-18 章):

实战(第 19-21 章):

不教什么

阅读前提

1.8.1 实测:MCP "M+N" 在两个官方 SDK 里的真实工程量

§1.1 抽象提到"M×N → M+N" 的协议价值——本书 ch03-ch19 已对两个官方 SDK 做了11 处具体实测——把这些数字汇总成 MCP 的 "M+N 真实账本"——

TS SDK 全家桶(mcp-typescript-sdk)——

模块 章节实测出处
packages/core 10871 ch08 §8.8.1
packages/server 3989 ch08 §8.8.1
packages/client 5937 ch08 §8.8.1
packages/middleware 703 ch08 §8.8.1
其中 OAuth (client+core) 2888 ch15 §15.9.4
其中 STDIO (server+client) 398 ch12 §12.11.1
其中 Streamable HTTP 2003 ch13 §13.9.1
其中 Discovery (auth.ts 内联) ~700 ch16 §16.9.1
其中 Prompt ~120 ch07 §7.11.1
其中 Resource ~420 ch06 §6.9.1
合计 49370

Python SDK 全家桶(mcp-python-sdk)——

模块 章节实测出处
OAuth (client + server + utils) 3313 ch15 §15.9.4
Streamable HTTP 1940 ch13 §13.9.1
STDIO + os/win32 740 ch12 §12.11.1
Discovery utils 339 ch16 §16.9.1
Prompt ~302 ch07 §7.11.1
Resource 513 ch06 §6.9.1
Core (shared/auth.py + types/_types.py + ...) 余下

两条值得记住的"M+N"物理证据——

  1. "M+N 一次实现、所有用户共享"在 MCP 里就是这两个 SDK ~50K + ~30K ≈ 80K 行——支撑全球数百个 MCP Server + 几十个 Client 集成——按 GitHub 上 1000+ MCP Server 项目估算,M+N 路线节省的总工程量是 80K 的几个数量级——和 §1.4 抽象描述对上号;这是 ch01 §1.9.1 测得的 Serde "26000 行基础设施 vs M=50/N=8 全部用户算 30 倍代码减少" 在 MCP 协议层的同款论证
  2. 两个 SDK 实现一致性"按功能模块决定"(本书 7 处实测确认:§13.9.1 Streamable HTTP 双 SDK 严格对称 / §15.9.4 OAuth 服务端 Python 1572 vs TS 0 / §16.9.1 Discovery Python 多文件 vs TS 单文件 / §17.10.1 Sampling 双 SDK 对称 / §12.11.1 STDIO Windows Python 333 vs TS 0 / §7.11.1 Prompt Python 2.5x / §6.9.1 Resource 1.22x)——印证 §1.6.4 提到的 "MCP 不是 Anthropic 私有、而是开放规范" 在工程现实层面:两个 SDK 各自演进、各按语言生态做最适合的取舍、不强求一致——这正是开放治理的真实样貌

对照本书 ch01 §1.4.1 测得的 Claude Code Harness 379K TypeScript——MCP 两 SDK 加起来只占 Claude Code 的 ~21%——印证 §1.5.1 "MCP 是协议、不是产品"——一个 MCP 协议层只占典型生产 Agent 1/5 的工程量、其余 4/5 是产品特定的 Harness。

1.9 本章小结

本章从一个真实的工程痛点出发——AI 工具集成的碎片化——引出了 MCP 协议存在的意义。我们看到:

  1. 碎片化是真实存在的。每个 Agent 框架的工具接口互不兼容,导致工具开发者面临 M×N 的适配困境
  2. MCP 是 AI 领域的 USB。它通过定义标准协议,把 M×N 问题降维为 M+N 问题
  3. MCP 建立在 JSON-RPC 2.0 之上,这是一个深思熟虑的技术选择——简单、可读、易于实现
  4. 三层架构(Host-Client-Server) 不是过度设计,而是安全隔离和可组合性的必然要求
  5. 三大原语(Tool/Resource/Prompt) 按控制方而非功能类型划分,构成了清晰的安全梯度
  6. MCP 不是要替代 REST、gRPC 或 function calling,而是在 AI Agent 工具集成这个特定领域填补空白
  7. MCP 的生态增长速度远超预期,正在成为 AI 工具集成的事实标准

从下一章开始,我们将深入 MCP 的架构设计,逐层拆解协议的每一个组成部分。在那之前,建议你先尝试一件事:打开 Claude Desktop 或 Claude Code,配置一个简单的 MCP Server(比如官方的 filesystem server),亲身体验一下"即插即用"的工具集成是什么感觉。这个体验会让后续章节的每一个技术细节都变得更加生动。


延伸阅读:MCP 为什么能快速成为标准

MCP 从 2024 年 11 月由 Anthropic 发布、到 2025-2026 年被 OpenAI、Google、Microsoft 等大厂广泛采纳——用了不到一年时间这种"标准化速度"在计算机历史上很罕见——HTTP 标准化用了 5 年、REST 成为事实标准用了 10 年为什么 MCP 这么快?有几个原因第一、"痛点明确且普遍"——每个 AI 应用都在重复造轮子做工具集成、大家都在寻找统一方案第二、"Anthropic 的中立性和权威性"——不像某个创业公司出的提议、Anthropic 作为头部 LLM 公司的提案有足够分量第三、"开放治理"——MCP 不是 Anthropic 私有、而是建立在开放规范之上、让其他公司能平等参与第四、"技术选型简单务实"——基于 JSON-RPC 这种成熟协议、门槛低、容易实现

这四个条件缺一不可——缺了"痛点"、再好的标准也没人用;缺了"权威性"、没人信任;缺了"开放治理"、大厂不愿意加入;缺了"技术简单"、小团队没资源实现MCP 的成功、是天时地利人和对读者的启示是——如果你希望推动某个标准、先看看这四个条件是否都具备——缺一个、成功概率就大打折扣

延伸阅读:MCP 与 USB 类比的深层含义

"MCP 是 AI 时代的 USB"——这个类比在社区广为流传、很贴切USB 之前、外设连接是"每家厂商一套接口"——鼠标有 PS/2、键盘有 DIN、打印机有并口、扫描仪有 SCSI——用户要配一堆转接线USB 统一之后、所有外设用同一个接口——插上就用、换设备不用改配置MCP 解决的是同类问题——不同 LLM 连不同工具、之前要各自适配、现在一套接口搞定

但 USB 的类比还有更深层含义——"USB 催生了一个庞大的外设生态"USB 之前、外设是"专业硬件厂商"的领域;USB 之后、任何小公司都能做 USB 设备(因为接口统一、门槛低)——催生了 U 盘、USB 音箱、USB 摄像头、USB 灯等海量消费级产品MCP 可能也会催生类似的"长尾 Agent 工具"——个人开发者可以做小众工具(比如"查北京天气"的 MCP Server)、放到市场、被全世界用户用这种"长尾创新"、是 MCP 最令人激动的未来

延伸阅读:MCP 之前的几次失败尝试

工具集成标准化、在 MCP 之前有过几次尝试——都没成OpenAI 的 Plugins(2023)——想建立"ChatGPT 插件市场"——因为只能在 OpenAI 生态用、没被其他公司接受;LangChain 的 Tool 抽象——是库层面的抽象、不是协议、无法跨框架使用;Agent Protocol(2023 由 AI Engineer Foundation 推动)——太早了、生态没跟上、逐渐淡化这些失败尝试、都积累了经验——让 MCP 避开了他们踩过的坑

MCP 的设计、明显吸收了前辈教训——不绑定 Anthropic 的生态(任何 LLM 都能用)、不只是库(有正式协议规范)、不过度设计(一开始只做最核心的三原语、慢慢扩展)这种"站在前辈失败肩膀上"的智慧、让 MCP 能成为第一个真正成功的 AI 工具标准对有志推动标准化的读者——了解前人的失败、比了解前人的成功更有价值——失败告诉你"不能这样"、成功告诉你"这样能行"——两者结合、你才能找到自己的路

延伸阅读:MCP 三原语的设计智慧

本章提到 MCP 的三原语(Tool / Resource / Prompt)——这个划分有深层的设计智慧Tool 是"Agent 可以主动调用的能力"(读文件、查询 API);Resource 是"Agent 可以读取的内容"(文件内容、数据库记录);Prompt 是"用户或开发者提供的指令模板"三者的区别、不是"功能类别"、而是"谁控制、谁调用"

Tool 由 Agent 主动决定调用(高自由度、需要权限控制);Resource 由 Agent 按需读取(低风险、主要是数据);Prompt 由用户显式选择(完全可控、无隐藏行为)这种"按安全梯度划分"的设计、让权限管理变得自然——Tool 需要严格权限控制、Resource 需要轻度控制、Prompt 基本不需要控制这比"按功能划分"(比如"文件工具、网络工具、数据库工具")更有智慧——因为安全性是跨功能的横切关注点、按安全划分能统一权限模型

延伸阅读:MCP 的未来:双向 MCP

2026 年 MCP 的发展方向之一——"双向 MCP"(Bidirectional MCP)当前 MCP 是单向的——LLM 调用 Server、Server 提供工具双向 MCP 的愿景——Server 也能调用 LLM——比如一个 MCP Server 想在特定条件下问 LLM 一个问题、或者让 LLM 生成某段文本这种双向流动、会让 MCP 更像"真正的协议"(双方对等)而不是"客户端-服务端模式"

双向 MCP 的挑战——"安全和信任"如果 Server 能调 LLM、怎么防止恶意 Server 消耗大量 token?怎么防止 Server 通过调 LLM 进行 prompt injection?这些问题的答案可能要靠更严格的权限模型、更细粒度的 rate limiting、更完整的审计日志双向 MCP 目前还在 RFC 阶段、未来 1-2 年可能会有初步方案读者如果对协议演化感兴趣、可以关注 MCP GitHub 的 proposals 目录——那里是协议未来的第一现场——能看到不同公司的工程师在讨论、辩论、妥协

延伸阅读:MCP 对个人开发者的机会

MCP 生态的开放性——对个人开发者是一个罕见的机会窗口写一个 MCP Server、比写一个独立的 AI 产品容易得多——不用做前端、不用做计费、不用做用户系统——只要把"一个有用的能力"包装成 MCP Server、发布到 MCP Registry、就能被全世界用户接入这种"低门槛高杠杆"的分发模式、让个人开发者能触达以前只有大公司才能触达的用户群

好的 MCP Server 机会——"领域专家的能力"(法律检索、医疗查询、财务分析)、"垂直工具"(SEO 分析、社交媒体发布、海关查询)、"特定地区的服务"(中国的各种政务数据、电商数据)——这些都是大公司不容易覆盖、个人开发者有机会深耕的领域2026 年是 MCP 生态的"淘金期"——早入场的开发者、有机会在某个细分领域建立不可替代的地位《LangChain 源码》第 17 章讨论的 Partner 包生态、也是类似机会——AI 时代、"做生态基础设施"比"做终端产品"门槛更低、回报更高

延伸阅读:MCP 与微服务的相似性

MCP Server 的概念、和微服务有深度相似性——每个 Server 提供一个或几个相关功能、通过标准协议对外服务、可以独立部署和演化这种相似性不是偶然——MCP 借鉴了微服务架构 15 年的成熟经验微服务的服务发现、负载均衡、版本管理、健康检查、监控告警——这些概念都可以迁移到 MCP Server 生态

但 MCP 和微服务也有关键差异——"调用方"不同微服务的调用方是"其他服务"(确定的、可预测的);MCP Server 的调用方是"LLM"(概率性的、可能调也可能不调)这个差异让 MCP Server 的设计要考虑"LLM 友好"——描述清楚、参数简单、错误消息可解释——让 LLM 能理解怎么用懂微服务架构的工程师、学 MCP 会很快——只需要再学"怎么让接口对 LLM 友好"这一个维度——这种"迁移式学习"、让老工程师在 AI 时代有巨大优势

延伸阅读:MCP 与 GraphQL 的对比

做工具集成、除了 MCP、还有 GraphQL 这种选择——能不能用 GraphQL 解决 AI 工具集成?理论上可以、实际上不合适GraphQL 面向"前端开发者显式写查询"——查询由开发者写、执行计划由 GraphQL 服务器优化、返回精确的字段组合AI 工具集成面向"LLM 自动生成调用"——调用由 LLM 根据自然语言生成、执行没有优化空间(就是调用一个函数)、返回的是完整结果两者的目标用户和使用方式完全不同

MCP 针对"LLM 调用"这个新场景、做了专门设计——简单的 JSON-RPC 格式(LLM 容易生成)、清晰的 tool description(LLM 容易理解)、结构化的 output schema(LLM 容易解析)这些设计让 MCP 在 AI 工具集成场景比 GraphQL 更合适不同协议、不同场景——没有银弹——这是协议设计的基本真理

延伸阅读:MCP 的文化意义

MCP 不只是一个技术协议、更是一个文化符号——它代表 AI 时代的"开放 vs 封闭"之争里、开放阵营的一次胜利在 MCP 之前、AI 工具集成的主流是各家 LLM 公司封闭生态——OpenAI 的 Plugins 只能在 ChatGPT 里用、Claude 的 MCP 只能和 Claude 用——用户被锁定MCP 打破了这种封闭——让工具能跨 LLM 使用——用户有了真正的选择权

这种"开放胜过封闭"的价值观、在互联网历史上反复上演——HTTP 胜过各种专有协议、HTML 胜过 Flash/Silverlight、Linux 胜过各种 Unix 变种——开放总是最终获胜MCP 的成功、延续了这个传统——AI 时代的基础设施、依然遵循"开放胜过封闭"的规律作为工程师、选择开放标准而非封闭方案、不只是技术选择、更是对"用户自由"的支持——这种价值观、值得每个技术决策者铭记——技术人的选择、塑造了技术世界的形态

延伸阅读:MCP 与国内生态

MCP 在国内的落地、正在快速推进几大国产 LLM 厂商(通义、文心、智谱、Kimi)都在或已经支持 MCP——让国产 LLM 也能享受 MCP 生态的工具国内社区也在快速搭建 MCP Server——有做微信公众号发布、飞书文档管理、企业微信自动化、钉钉办公、小红书分析——各种国内特有工具的 MCP Server这让国内开发者能在国产 LLM + 国产工具的全栈下、享受 MCP 带来的便利

这种"国产 + 国产"的生态、在合规、支付、本地化方面有独特优势——企业客户不用担心数据出境、不用操心外币付费、文档和客服都是中文对服务国内企业市场的 AI 创业公司——基于国产 LLM + MCP 搭建方案、可能是比"OpenAI + LangChain"更务实的选择《LangChain 源码》第 17 章提到的本土化 Partner 包、也是类似思路——用开放标准 + 本土适配、服务本土市场

延伸阅读:MCP Server 的开发者体验

好的 MCP Server、除了"LLM 友好"、还要"开发者友好"——让其他开发者能快速理解、部署、扩展"开发者友好"的几个维度——"文档清晰"(README 能让人 5 分钟上手)、"配置简单"(环境变量或 YAML、不要复杂的初始化脚本)、"错误信息友好"(报错时告诉用户怎么修)、"有示例"(提供典型用法的示例代码)、"维护活跃"(issues 及时回复、PR 及时 review)

这些看起来和普通开源项目一样——确实一样——MCP Server 本质上就是一个开源库但在 MCP 生态刚起步的阶段、"开发者友好"尤其重要——因为用户在比较"这个 MCP 还是那个 MCP"时、文档质量、社区活跃度往往比功能本身更有决定作用对有志做 MCP Server 的开发者——投入 30% 精力写代码、70% 精力做文档和社区——这个比例可能更有回报、也更符合开源项目的成功规律