一、MCP 是什么:从"胶水代码"困境说起

如果你用过大模型做过工具调用(Function Calling),大概率经历过这样的痛苦:每接入一个新的数据源——数据库、文件系统、Slack、GitHub——都要写一堆胶水代码,把该数据源的 API 翻译成大模型能理解的工具描述格式。更糟糕的是,换个模型(比如从 GPT-4 换到 Claude),这些胶水可能还得重写一遍。

MCP(Model Context Protocol) 就是为了解决这个问题而生的。它的定位可以类比为"AI 应用的 USB-C 接口":不管你的大模型是哪家的、工具是哪来的,只要双方都遵守 MCP 这套协议,就能即插即用。它由 Anthropic 在 2024 年底开源提出,目前已经逐渐成为业界连接 LLM 与外部工具的事实标准。

提示:MCP 解决的不是"模型能力"问题,而是"模型与外部世界之间的连接标准化"问题。它的本质是一个通信协议 + 接口约定,本身不涉及任何模型推理逻辑。

二、MCP 的核心架构:Host、Client、Server 三方角色

MCP 的架构里有三个关键角色,理解它们的分工是读懂协议的前提:

这三者的关系可以简单理解为:Host 拿着用户的请求,通过 Client 去"问"某个 Server 能提供什么;Server 告诉 Client 自己有哪些工具和资源;最终 Host 把这些信息组合后交给大模型决策调用。值得注意的是,一个 Host 可以同时连接多个 Server,这就是 MCP 生态可扩展性的来源——你装一个新的 MCP Server,就像给系统插了一个新外设。

三、协议的三大能力:Tools、Resources、Prompts

MCP 定义了三类核心原语(Primitives),分别服务于不同场景:

  1. Tools(工具):由模型主动调用的可执行操作,比如"查询数据库""发送邮件"。这是最常用的能力,对应 Function Calling 的场景。
  2. Resources(资源):由应用程序按需读取的数据,比如文件内容、API 返回的 JSON。模型不直接"调用"资源,而是 Host 决定何时注入。
  3. Prompts(提示模板):预定义的提示词模板,用户在客户端中可以主动选择使用,比如一个"代码审查"模板。

很多初学者容易混淆 Tools 和 Resources。一个简单的判断标准是:这个操作会不会改变外部状态?如果会(写文件、发消息),就是 Tool;如果只是读取已有数据,通常用 Resource。不过实际开发中,绝大多数 Server 只实现了 Tools,因为它的交互模型最直观。

提示:MCP 还支持 Sampling(Server 反向请求 Host 调用 LLM)和 Roots(客户端告知 Server 工作目录)等高级能力,但初学阶段可以先聚焦 Tools 这一条主线。

四、一次完整的 MCP 交互流程

理解协议最好的方式是跟踪一次完整的调用。假设用户在 Host 中说"帮我查一下今天北京的天气",而你有一个 weather-server:

  1. 连接建立:Host 通过 Client 启动 Server(通常是 stdio 子进程或 SSE 远程连接),双方进行 initialize 握手,交换协议版本和能力声明。
  2. 能力发现:Client 发送 tools/list 请求,Server 返回它支持的工具列表(含名称、参数 JSON Schema)。
  3. 模型决策:Host 把工具描述注入 LLM 的 system prompt 或 tool 定义中,LLM 决定调用 get_weather(city="北京")。
  4. 工具执行:Client 发送 tools/call 请求,Server 执行真实逻辑,返回结果(文本或结构化内容)。
  5. 结果回填:Host 把结果拼入对话上下文,LLM 生成最终回答。

整个流程中,MCP 只负责第 1、2、4 步的通信格式,模型的决策逻辑完全在 Host 端完成。这种"协议管传输、Host 管智能"的分层设计,是 MCP 能适配多种模型的原因。

五、动手写一个最小 MCP Server

官方的 Python SDK(mcp 包)把协议细节封装得很好,几行代码就能跑起来一个 Server。下面是一个最小可运行的示例:

# server.py — 一个极简 MCP Server
from mcp.server.fastmcp import FastMCP

mcp = FastMCP("demo-server")

@mcp.tool()
def add(a: int, b: int) -> int:
    """将两个整数相加并返回结果。"""
    return a + b

@mcp.tool()
def greet(name: str) -> str:
    """向指定的人打招呼。"""
    return f"你好,{name}!欢迎使用 MCP。"

if __name__ == "__main__":
    mcp.run()  # 默认通过 stdio 传输

启动后,在 Host(比如 Claude Desktop)的配置文件中注册这个 Server 即可:

{
  "mcpServers": {
    "demo": {
      "command": "python",
      "args": ["server.py"]
    }
  }
}

配置完成后,你对 Claude 说"帮我算 3 加 5",它就会自动调用 add 工具。整个过程中你没有写任何 Function Calling 的胶水代码——SDK 自动生成了工具描述、序列化了请求响应、管理了连接生命周期,这正是 MCP 的价值所在。

提示:FastMCP 是高层封装,适合快速原型;如果你需要精细控制协议细节(比如自定义 resources、prompts),可以使用底层的 mcp.server.Server 类手动注册 handler。

六、MCP 的现实意义与当前局限

MCP 最大的现实意义在于生态复用。开发者写一个 MCP Server,就能被所有支持 MCP 的 Host 使用;反过来,一个 Host 支持 MCP,就能接入社区中成百上千的现成 Server。这种双向的网络效应,让 MCP 迅速从"一个协议"演变为"一个生态"。目前 VS Code、Cursor、Claude Desktop、甚至一些 Agent 框架(如 LangChain)都已支持 MCP。

但也要清醒地看到它目前的局限:

总的来说,MCP 是一次用协议统一 AI 工具生态的尝试,它的设计哲学和 HTTP 之于 Web、LSP 之于编辑器非常相似——不发明新轮子,只定义轮子之间的接口。对于想深入 AI 应用开发的同学,花一两个小时跑通一个 MCP Server,比读十篇解读文章更有收获。