MCP:大模型时代的“USB-C”接口,彻底打通 AI 与外部世界

MCP:大模型时代的"USB-C"接口,彻底打通 AI 与外部世界

大家好,我是你们的老朋友,一名在代码世界里摸爬滚打多年的程序员。

最近,如果你关注 AI 领域的动态,一定频繁听到一个词:MCP (Model Context Protocol)

很多开发者朋友问我:"这不就是换个名字的 Function Calling 吗?为什么 Anthropic 要大力推它?它到底解决了什么痛点?"

今天,我们就抛开晦涩的术语,用大白话聊聊 MCP 是什么,它的核心原理,以及作为开发者,我们该如何看待这场"协议革命"。

一、 什么是 MCP?

MCP 的全称是 Model Context Protocol(模型上下文协议)。

如果要用一句话定义它,我会说:它是大模型时代的标准化工具协议,相当于 AI 领域的 "USB-C" 或 "HTTP"。

在 Web 1.0/2.0 时代,HTTP 协议统一了浏览器和服务器的通信方式,无论后端是 Java、Python 还是 Go,前端是 Chrome 还是 Safari,只要遵循 HTTP,就能互联互通。

而在 AI Agent(智能体)时代,MCP 试图解决同样的问题:如何让 LLM(大语言模型)以统一、标准化的方式访问外部能力?

这些能力包括:

  • 工具 (Tools):查数据库、调 API、执行代码。
  • 数据源 (Resources):文件系统、IDE 代码库、网页内容、企业知识库。
  • 提示词 (Prompts):预定义的交互模板。

二、 为什么我们需要 MCP?(痛点分析)

在 MCP 出现之前,AI 应用开发处于一种"巴别塔"式的混乱状态。

1. 生态割裂,重复造轮子

假设你想让 AI 助手读取你的本地文件并查询 PostgreSQL 数据库:

  • 如果你用 OpenAI 的 Function Calling,你需要写一套适配代码。
  • 如果你切换到 Claude,你可能需要调整 Tool Use 的格式。
  • 如果你用 LangChain,又有另一套 Tool 定义标准。

每接入一个新模型或新框架,开发者都要重新写一遍"适配器"。这导致生态极度割裂,工具无法复用。

2. 上下文获取困难

LLM 本身是"无知"的,它不知道你的本地文件结构,也不知道你公司内部的 Jira 状态。以前,我们只能通过 Prompt 硬编码少量信息,或者为每个数据源编写复杂的提取脚本。

MCP 的目标 :统一 模型 ↔ 工具/数据 之间的通信协议。让开发者只需编写一次 MCP Server,就可以被任何支持 MCP 的 Client(如 Claude Desktop、Cursor、IDE Agent)直接使用。

三、 MCP 的核心架构

MCP 的架构设计非常清晰,主要包含三个角色。理解这三个角色,就理解了 MCP 的一半。
#mermaid-svg-V8ogoTVTvLqEJm0w{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-V8ogoTVTvLqEJm0w .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-V8ogoTVTvLqEJm0w .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-V8ogoTVTvLqEJm0w .error-icon{fill:#552222;}#mermaid-svg-V8ogoTVTvLqEJm0w .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-V8ogoTVTvLqEJm0w .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-V8ogoTVTvLqEJm0w .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-V8ogoTVTvLqEJm0w .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-V8ogoTVTvLqEJm0w .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-V8ogoTVTvLqEJm0w .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-V8ogoTVTvLqEJm0w .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-V8ogoTVTvLqEJm0w .marker{fill:#333333;stroke:#333333;}#mermaid-svg-V8ogoTVTvLqEJm0w .marker.cross{stroke:#333333;}#mermaid-svg-V8ogoTVTvLqEJm0w svg{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-V8ogoTVTvLqEJm0w p{margin:0;}#mermaid-svg-V8ogoTVTvLqEJm0w .label{font-family:"trebuchet ms",verdana,arial,sans-serif;color:#333;}#mermaid-svg-V8ogoTVTvLqEJm0w .cluster-label text{fill:#333;}#mermaid-svg-V8ogoTVTvLqEJm0w .cluster-label span{color:#333;}#mermaid-svg-V8ogoTVTvLqEJm0w .cluster-label span p{background-color:transparent;}#mermaid-svg-V8ogoTVTvLqEJm0w .label text,#mermaid-svg-V8ogoTVTvLqEJm0w span{fill:#333;color:#333;}#mermaid-svg-V8ogoTVTvLqEJm0w .node rect,#mermaid-svg-V8ogoTVTvLqEJm0w .node circle,#mermaid-svg-V8ogoTVTvLqEJm0w .node ellipse,#mermaid-svg-V8ogoTVTvLqEJm0w .node polygon,#mermaid-svg-V8ogoTVTvLqEJm0w .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-V8ogoTVTvLqEJm0w .rough-node .label text,#mermaid-svg-V8ogoTVTvLqEJm0w .node .label text,#mermaid-svg-V8ogoTVTvLqEJm0w .image-shape .label,#mermaid-svg-V8ogoTVTvLqEJm0w .icon-shape .label{text-anchor:middle;}#mermaid-svg-V8ogoTVTvLqEJm0w .node .katex path{fill:#000;stroke:#000;stroke-width:1px;}#mermaid-svg-V8ogoTVTvLqEJm0w .rough-node .label,#mermaid-svg-V8ogoTVTvLqEJm0w .node .label,#mermaid-svg-V8ogoTVTvLqEJm0w .image-shape .label,#mermaid-svg-V8ogoTVTvLqEJm0w .icon-shape .label{text-align:center;}#mermaid-svg-V8ogoTVTvLqEJm0w .node.clickable{cursor:pointer;}#mermaid-svg-V8ogoTVTvLqEJm0w .root .anchor path{fill:#333333!important;stroke-width:0;stroke:#333333;}#mermaid-svg-V8ogoTVTvLqEJm0w .arrowheadPath{fill:#333333;}#mermaid-svg-V8ogoTVTvLqEJm0w .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-V8ogoTVTvLqEJm0w .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-V8ogoTVTvLqEJm0w .edgeLabel{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-V8ogoTVTvLqEJm0w .edgeLabel p{background-color:rgba(232,232,232, 0.8);}#mermaid-svg-V8ogoTVTvLqEJm0w .edgeLabel rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-V8ogoTVTvLqEJm0w .labelBkg{background-color:rgba(232, 232, 232, 0.5);}#mermaid-svg-V8ogoTVTvLqEJm0w .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-V8ogoTVTvLqEJm0w .cluster text{fill:#333;}#mermaid-svg-V8ogoTVTvLqEJm0w .cluster span{color:#333;}#mermaid-svg-V8ogoTVTvLqEJm0w div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-V8ogoTVTvLqEJm0w .flowchartTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-svg-V8ogoTVTvLqEJm0w rect.text{fill:none;stroke-width:0;}#mermaid-svg-V8ogoTVTvLqEJm0w .icon-shape,#mermaid-svg-V8ogoTVTvLqEJm0w .image-shape{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-V8ogoTVTvLqEJm0w .icon-shape p,#mermaid-svg-V8ogoTVTvLqEJm0w .image-shape p{background-color:rgba(232,232,232, 0.8);padding:2px;}#mermaid-svg-V8ogoTVTvLqEJm0w .icon-shape .label rect,#mermaid-svg-V8ogoTVTvLqEJm0w .image-shape .label rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-V8ogoTVTvLqEJm0w .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#mermaid-svg-V8ogoTVTvLqEJm0w .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#mermaid-svg-V8ogoTVTvLqEJm0w :root{--mermaid-font-family:"trebuchet ms",verdana,arial,sans-serif;} 服务侧 (Server Side)
用户侧 (Client Side)
运行
JSON-RPC / Stdio or SSE
读取/写入
读取/写入
调用
MCP Host

例如: Claude Desktop, Cursor
MCP Client

负责协议通信
MCP Server

能力提供方
PostgreSQL
File System
External APIs

1. MCP Host(宿主)

这是运行 LLM 的客户端应用程序。

  • 例子:Claude Desktop App、Cursor IDE、Zed Editor。
  • 作用:它拥有智能核心(LLM),负责理解用户意图,并决定何时调用工具。

2. MCP Client(客户端)

嵌入在 Host 中,负责具体的协议通信。

  • 作用:它不关心业务逻辑,只负责按照 MCP 协议标准,向 Server 发送请求(如"列出所有可用工具"、"执行某个工具"),并接收结果。

3. MCP Server(服务端)------ 最核心部分

这是能力的实际提供方,也是开发者主要编写的部分。

  • 例子:GitHub MCP Server、PostgreSQL MCP Server、Filesystem MCP Server。
  • 作用
    • 暴露能力:告诉 Client 我有哪些工具(Tools)和资源(Resources)。
    • 执行操作:真正去连接数据库、读取文件或调用第三方 API。
    • 返回结果:将执行结果标准化后返回给 Client。

四、 MCP 的工作流程

让我们通过一个具体场景:"用户询问:帮我查询数据库中 ID 为 123 的用户信息",来看看 MCP 是如何工作的。
数据库 MCP Server (PostgreSQL) MCP Client MCP Host (Claude/Cursor) 用户 数据库 MCP Server (PostgreSQL) MCP Client MCP Host (Claude/Cursor) 用户 #mermaid-svg-qc4HzxHWmletVl13{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-qc4HzxHWmletVl13 .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-qc4HzxHWmletVl13 .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-qc4HzxHWmletVl13 .error-icon{fill:#552222;}#mermaid-svg-qc4HzxHWmletVl13 .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-qc4HzxHWmletVl13 .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-qc4HzxHWmletVl13 .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-qc4HzxHWmletVl13 .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-qc4HzxHWmletVl13 .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-qc4HzxHWmletVl13 .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-qc4HzxHWmletVl13 .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-qc4HzxHWmletVl13 .marker{fill:#333333;stroke:#333333;}#mermaid-svg-qc4HzxHWmletVl13 .marker.cross{stroke:#333333;}#mermaid-svg-qc4HzxHWmletVl13 svg{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-qc4HzxHWmletVl13 p{margin:0;}#mermaid-svg-qc4HzxHWmletVl13 .actor{stroke:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);fill:#ECECFF;}#mermaid-svg-qc4HzxHWmletVl13 text.actor>tspan{fill:black;stroke:none;}#mermaid-svg-qc4HzxHWmletVl13 .actor-line{stroke:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);}#mermaid-svg-qc4HzxHWmletVl13 .innerArc{stroke-width:1.5;stroke-dasharray:none;}#mermaid-svg-qc4HzxHWmletVl13 .messageLine0{stroke-width:1.5;stroke-dasharray:none;stroke:#333;}#mermaid-svg-qc4HzxHWmletVl13 .messageLine1{stroke-width:1.5;stroke-dasharray:2,2;stroke:#333;}#mermaid-svg-qc4HzxHWmletVl13 #arrowhead path{fill:#333;stroke:#333;}#mermaid-svg-qc4HzxHWmletVl13 .sequenceNumber{fill:white;}#mermaid-svg-qc4HzxHWmletVl13 #sequencenumber{fill:#333;}#mermaid-svg-qc4HzxHWmletVl13 #crosshead path{fill:#333;stroke:#333;}#mermaid-svg-qc4HzxHWmletVl13 .messageText{fill:#333;stroke:none;}#mermaid-svg-qc4HzxHWmletVl13 .labelBox{stroke:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);fill:#ECECFF;}#mermaid-svg-qc4HzxHWmletVl13 .labelText,#mermaid-svg-qc4HzxHWmletVl13 .labelText>tspan{fill:black;stroke:none;}#mermaid-svg-qc4HzxHWmletVl13 .loopText,#mermaid-svg-qc4HzxHWmletVl13 .loopText>tspan{fill:black;stroke:none;}#mermaid-svg-qc4HzxHWmletVl13 .loopLine{stroke-width:2px;stroke-dasharray:2,2;stroke:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);fill:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);}#mermaid-svg-qc4HzxHWmletVl13 .note{stroke:#aaaa33;fill:#fff5ad;}#mermaid-svg-qc4HzxHWmletVl13 .noteText,#mermaid-svg-qc4HzxHWmletVl13 .noteText>tspan{fill:black;stroke:none;}#mermaid-svg-qc4HzxHWmletVl13 .activation0{fill:#f4f4f4;stroke:#666;}#mermaid-svg-qc4HzxHWmletVl13 .activation1{fill:#f4f4f4;stroke:#666;}#mermaid-svg-qc4HzxHWmletVl13 .activation2{fill:#f4f4f4;stroke:#666;}#mermaid-svg-qc4HzxHWmletVl13 .actorPopupMenu{position:absolute;}#mermaid-svg-qc4HzxHWmletVl13 .actorPopupMenuPanel{position:absolute;fill:#ECECFF;box-shadow:0px 8px 16px 0px rgba(0,0,0,0.2);filter:drop-shadow(3px 5px 2px rgb(0 0 0 / 0.4));}#mermaid-svg-qc4HzxHWmletVl13 .actor-man line{stroke:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);fill:#ECECFF;}#mermaid-svg-qc4HzxHWmletVl13 .actor-man circle,#mermaid-svg-qc4HzxHWmletVl13 line{stroke:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);fill:#ECECFF;stroke-width:2px;}#mermaid-svg-qc4HzxHWmletVl13 :root{--mermaid-font-family:"trebuchet ms",verdana,arial,sans-serif;} "查询用户 ID 123" 请求可用工具列表 (List Tools) List Tools Request 返回工具定义: query_user(id) 收到工具定义 LLM 推理:需要调用 query_user 调用工具: query_user(id=123) Call Tool Request SELECT * FROM users WHERE id=123 返回数据 {name: "Alice", ...} 返回工具结果 收到结果 LLM 结合结果生成最终回答 "用户 ID 123 的名字是 Alice..."

  1. 发现阶段 (Discovery):Host 启动时,Client 会询问 Server:"你有什么本事?" Server 返回一份工具清单(Schema)。
  2. 决策阶段:用户提问后,LLM 根据工具清单,判断需要调用哪个工具,并生成参数。
  3. 执行阶段:Client 将调用请求发送给 Server。Server 执行真正的业务逻辑(查库、调 API)。
  4. 反馈阶段:Server 将结果返回给 Host,LLM 结合结果生成自然语言回答给用户。

五、 MCP vs Function Calling:有什么区别?

这是面试和日常讨论中最高频的问题。简单来说,Function Calling 是"功能",MCP 是"协议"

对比维度 Function Calling (传统) MCP (Model Context Protocol)
本质 模型的一种内置能力 跨系统的通信协议标准
范围 单次、单模型的工具调用 整个生态系统的互联
标准化程度 弱(各厂商格式不一) (统一 JSON-RPC 标准)
动态发现 通常需在代码中静态注册 支持 (Client 可动态查询 Server 能力)
跨平台性 较弱(绑定特定 SDK) (Server 可被任何 MCP Client 使用)
适用场景 小型、封闭的 Agent 应用 开放、可扩展的企业级 Agent 生态

比喻

  • Function Calling 像是你给手机装了一个专属 APP,只能在这个手机系统里用。
  • MCP 像是 USB-C 接口,只要你符合这个标准,你的充电器、数据线、硬盘可以在任何支持 USB-C 的设备上即插即用。

六、 实践分享:虽然没有"官方" MCP,但我早已践行其思想

在很多技术交流中,大家常问:"你项目中用过 MCP 吗?"

坦白说,MCP 是一个较新的开源标准(由 Anthropic 主导),目前许多企业内部系统尚未完全迁移到官方 MCP 协议。但是,我在构建 Multi-Agent 系统时,已经深度实践了 MCP 的核心思想。

如果你也在做 Agent 开发,你会发现以下模式非常熟悉:

  1. Tool Registry (工具注册中心)

    在我的系统中,我维护了一个统一的工具注册表。每个工具都有标准的 Schema 描述(输入参数、输出格式)。这与 MCP Server 暴露 tools/list 的逻辑一致。

  2. Structured Output (结构化输出)

    强制 LLM 输出 JSON 格式的工具调用指令,而不是自由文本。这对应了 MCP 中标准化的通信格式。

  3. Tool Routing (工具路由)

    Agent 根据用户意图,动态选择调用哪个工具模块。这类似于 MCP Client 根据 Server 提供的能力进行分发。

我的代码实践示例(伪代码):

python 复制代码
# 这是一个简化的 Agent 工具管理结构,体现了 MCP 的思想

class ToolInterface:
    """所有工具必须遵循的标准接口"""
    def get_schema(self) -> dict:
        """返回工具的描述和参数结构,类似 MCP 的 tools/list"""
        pass
    
    def execute(self, params: dict) -> any:
        """执行工具逻辑,类似 MCP 的 tools/call"""
        pass

class DatabaseTool(ToolInterface):
    def get_schema(self):
        return {
            "name": "query_db",
            "description": "查询用户数据",
            "parameters": {"user_id": "string"}
        }
    
    def execute(self, params):
        # 真正连接数据库
        return db.query(params['user_id'])

# Agent 核心逻辑
class Agent:
    def __init__(self):
        self.tools = [DatabaseTool()] # 注册工具
        
    def run(self, user_input):
        # 1. 获取所有可用工具的 Schema
        available_tools = [t.get_schema() for t in self.tools]
        
        # 2. LLM 决定调用哪个工具
        tool_call = llm.decide(user_input, available_tools)
        
        # 3. 执行工具
        if tool_call:
            target_tool = self.find_tool(tool_call.name)
            result = target_tool.execute(tool_call.params)
            return llm.generate_final_answer(result)

这段代码的价值在于 :它将"工具调用"从硬编码的逻辑中解耦出来,变成了标准化的插件。这正是 MCP 想要在整个行业层面做的事情。

七、 为什么 MCP 是未来的趋势?

我认为 MCP 的最大价值不在于"多了一种调用工具的方法",而在于实现了 Agent 能力的生态化

  1. API 经济的 AI 延伸

    过去十年,我们建立了庞大的 API 经济(Stripe, Twilio, AWS)。未来,这些 API 不会直接暴露给 LLM,而是通过 MCP Server 包装一层。这意味着,现有的数百万个 API 可以快速转化为 AI 可用的能力。

  2. 打破数据孤岛

    企业内部有大量的私有数据(飞书文档、内部 ERP、Git 代码库)。通过编写轻量级的 MCP Server,这些数据可以安全、标准化地暴露给 AI 助手,而无需修改 AI 模型本身。

  3. 互操作性

    想象一下,你在 Cursor 里写的一个数据库查询 MCP Server,可以直接在 Claude Desktop 中使用,也可以集成到你公司内部的自研 AI 平台中。一次开发,处处运行。

八、 总结与建议

MCP 是大模型从"聊天机器人"走向"操作系统级 Agent"的关键基础设施。

对于开发者,我的建议是:

  1. 不要等待,现在就开始思考"标准化":即使你不直接使用官方 MCP SDK,也要在你的 Agent 项目中采用"工具描述与执行分离"、"标准化 Schema"的设计模式。
  2. 关注 MCP Server 的开发:尝试为你常用的数据源(如 Notion、GitHub、本地文件夹)编写简单的 MCP Server。这是未来连接 AI 与现实世界的桥梁。
  3. 理解协议细节 :深入了解 JSON-RPC 在 MCP 中的应用,理解 resourcestoolsprompts 三大核心原语的区别。

MCP 正在重新定义 AI 应用的边界。它让 AI 不再是一个孤立的智力大脑,而是一个能够手脚并用、操作整个数字世界的超级智能体。

希望这篇文章能帮你理清 MCP 的脉络。如果你在实践过程中遇到问题,欢迎在评论区交流!


参考资料: