最近在折腾 Agent 的时候,又一次被「MCP」这三个字母刷屏。从 Claude Desktop 到 Cursor,再到一堆 Agent 框架,几乎都在拥抱它。一开始我也以为它就是「另一个 Function Calling 套壳」,直到真正动手写了一个 MCP Server 之后,才发现自己理解得太浅了。

这篇文章把我对 MCP 的理解整理一下,算是给自己的学习留个备忘,也希望对同样在 AI 工程化路上摸索的朋友有点帮助。

MCP 的定位:给 AI 工具调用定一套统一标准

一、MCP 不是框架,是协议

如果把 MCP 翻译成中文,叫「模型上下文协议」(Model Context Protocol)。注意关键词是「协议」,不是「框架」,更不是「Anthropic 的私有 API」。

它由 Anthropic 在 2024 年底提出并开源,目标只有一个:

解决「模型怎么接工具」这件事的碎片化问题。

这一点很重要。它和 Function Calling 不在同一层

  • Function Calling 解决的是「模型怎么把'我要调用工具'这个意图,结构化地输出出来」——这是模型层的能力。
  • MCP 解决的是「这个工具本身,怎么被 AI 应用以一种统一的方式接进来」——这是工程层的协议。

一个偏「说话」,一个偏「接线」。混为一谈就尴尬了。

二、没有 MCP 之前,接工具有多难受

举个例子。我之前给 Claude 接一个 GitHub 工具,需要:

  1. 在 GitHub 注册一个 OAuth App,拿 token;
  2. 自己写一段封装代码,把 GitHub API 包成 Claude 能识别的 Function Schema;
  3. 处理 token 刷新、错误重试、权限边界;
  4. 想换到 GPT 用?再写一遍。
  5. 想加一个新工具?继续重复 1–4。

每个工具是一个孤岛,每个模型也是一个孤岛。N 个工具 × M 个模型 = N×M 份重复劳动

有 MCP 之前 vs 之后:从「面条线」到「集线器」

这事儿其实在 IT 历史上反复出现过。USB 出现之前,每种外设都有自己的接口;HTTP 出现之前,每个服务都有自己的协议。最后都是靠「定一套大家都遵守的标准」收敛的。MCP 想做的,正是 AI 工具接入这一层的标准化。

三、Client–Server 架构:USB 类比

MCP 的架构其实很朴素:

  • MCP Server:工具的实现方。比如 GitHub 官方写一个 GitHub MCP Server,负责把 issue、PR、仓库这些能力暴露出来。
  • MCP Client:AI 应用方。比如 Claude Desktop、Cursor、Windsurf,或者你自己写的 Agent。
  • 一个 Client 可以同时连多个 Server,就像一台电脑通过 USB 同时接键盘、鼠标、U 盘。
┌──────────────────┐
│   Claude Desktop │  ← MCP Client
└────────┬─────────┘
         │ 标准 MCP 协议
   ┌─────┼──────────────┬───────────┐
   ▼     ▼              ▼           ▼
[FileSystem]  [GitHub Server]   [Postgres]   [Slack]
   ↑              ↑                  ↑           ↑
   └──── 各自实现 MCP Server,互不干扰 ────┘

用户视角,从「写一段 200 行的对接代码」变成了「在配置文件里加一行」。

四、三类核心能力:Tools / Resources / Prompts

MCP 把 Server 能提供的东西,分成了三类。这三类不是随便分的,背后有「有没有副作用」的考量。

三类核心能力:Tools / Resources / Prompts

Tools — 有副作用的「动作」

可以改变外部世界的操作,比如:

  • 在 GitHub 提交一个 PR
  • 往 Slack 发一条消息
  • 创建/修改文件

因为是「改东西」,所以协议里要求调用前需要用户授权——这是一种安全设计上的边界。

Resources — 只读的「数据」

只读的、无副作用的资源,比如:

  • 读取一份日志
  • 查询数据库的某张表
  • 获取一份文档内容

因为没有副作用,授权策略可以宽松一些。Resource 更像「让模型有上下文可以读」。

Prompts — 可复用的「模板」

带参数占位符的提示词模板,团队可以共享。例子:「给我 review 这段代码」「翻译这段文档为英文」。本质是把那些反复要写的提示词工程化、版本化。

我自己理解:Tools 是手,Resources 是眼,Prompts 是嘴。一个 Agent 该有的器官,MCP 都给规定了接入方式。

五、底层通信:JSON-RPC 2.0

往底下扒一层,MCP 的消息格式用的是 JSON-RPC 2.0——一个非常老牌、轻量的远程调用协议。一次调用大概长这样:

{
  "jsonrpc": "2.0",
  "id": 1,
  "method": "tools/call",
  "params": {
    "name": "create_issue",
    "arguments": {
      "repo": "anthropics/anthropic-sdk-python",
      "title": "..."
    }
  }
}

返回也是结构化 JSON。好处是:易读、易调试、语言无关。我用 Python 写 Server,对端用 TypeScript 写 Client,没问题。

两种传输方式

JSON-RPC 是「消息长什么样」,传输是「消息怎么送过去」。MCP 给了两种:

  1. stdio(标准输入输出) Client 把 Server 当成本地子进程拉起来,通过管道收发消息。适合本地工具。Claude Desktop 的桌面端集成就用这种。优点是简单,没网络栈,启动即用。

  2. Streamable HTTP 通过 HTTP + SSE 暴露一个 /mcp 端点,Client 拿 URL 直接连。适合远程部署或者多个 Client 共享同一个 Server。Serverless 部署也很友好。

顺便说一下时间线:早期(2024-11-05 规范)用的是 HTTP + SSE 双端点的方案,2025 年 3 月规范更新合并成了 Streamable HTTP 单端点 /mcp,老方案被标记为 deprecated 但仍兼容。如果你看了一些早期教程发现配置不一样,多半是这个原因。

六、为什么生态起得这么快

我观察了一下,MCP 在不到一年时间里能形成现在的局面,主要是两件事:

一是实现门槛被压到了几乎为零。 官方有 Python、TypeScript 的 SDK,写一个最小可用的 MCP Server 真的不到 30 行:

from mcp.server.fastmcp import FastMCP

mcp = FastMCP("demo")

@mcp.tool()
def add(a: int, b: int) -> int:
    """两个数相加"""
    return a + b

if __name__ == "__main__":
    mcp.run()

跑起来就是个能被 Claude 调用的工具。这个体验非常顺手。

二是头部工具厂商用脚投了票。 GitHub、Slack、PostgreSQL、Puppeteer、Google Maps、Notion……一票主流工具的 MCP Server 在短期内集中冒出来。Claude Desktop、Cursor、Windsurf 等主流 AI 应用纷纷支持。

正反馈一旦建立——「工具方写一份,所有 AI 都能用;Client 方支持一次,所有工具都能接」——加速度就拉开了。

七、一些个人思考

写了一阵子 MCP Server 之后,我的感受是:

  • 它把「Agent 接工具」这件事从一个工程问题变成了配置问题。 这非常关键。让更多非全栈背景的同学也能拼出自己的 Agent。
  • 它不会取代 Function Calling。 模型层面把意图结构化输出的能力依然必需,MCP 只是让「这个意图最终落到哪里、怎么落」更标准化。
  • 协议本身还在演进。 比如鉴权、长任务、流式返回这些细节,每个版本都在打磨。所以遇到坑别慌,去看最新规范。
  • 生态层面,MCP、A2A、各家 Agent 协议会逐渐分化与融合。 现在押注 MCP 看起来是性价比最高的选择,但保持对其他协议的关注也很重要。

总的来说,MCP 让我对「协议优于框架」这件事又多了一份信心。框架解决的是「我怎么用得快」,协议解决的是「大家怎么一起用」。后者的天花板高得多。


如果你也在做 Agent,强烈建议花一个晚上把 MCP 的官方 Quickstart 跑一遍,比看十篇文章都管用。

—— Smian