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..."
- 发现阶段 (Discovery):Host 启动时,Client 会询问 Server:"你有什么本事?" Server 返回一份工具清单(Schema)。
- 决策阶段:用户提问后,LLM 根据工具清单,判断需要调用哪个工具,并生成参数。
- 执行阶段:Client 将调用请求发送给 Server。Server 执行真正的业务逻辑(查库、调 API)。
- 反馈阶段: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 开发,你会发现以下模式非常熟悉:
-
Tool Registry (工具注册中心) :
在我的系统中,我维护了一个统一的工具注册表。每个工具都有标准的 Schema 描述(输入参数、输出格式)。这与 MCP Server 暴露
tools/list的逻辑一致。 -
Structured Output (结构化输出) :
强制 LLM 输出 JSON 格式的工具调用指令,而不是自由文本。这对应了 MCP 中标准化的通信格式。
-
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 能力的生态化。
-
API 经济的 AI 延伸 :
过去十年,我们建立了庞大的 API 经济(Stripe, Twilio, AWS)。未来,这些 API 不会直接暴露给 LLM,而是通过 MCP Server 包装一层。这意味着,现有的数百万个 API 可以快速转化为 AI 可用的能力。
-
打破数据孤岛 :
企业内部有大量的私有数据(飞书文档、内部 ERP、Git 代码库)。通过编写轻量级的 MCP Server,这些数据可以安全、标准化地暴露给 AI 助手,而无需修改 AI 模型本身。
-
互操作性 :
想象一下,你在 Cursor 里写的一个数据库查询 MCP Server,可以直接在 Claude Desktop 中使用,也可以集成到你公司内部的自研 AI 平台中。一次开发,处处运行。
八、 总结与建议
MCP 是大模型从"聊天机器人"走向"操作系统级 Agent"的关键基础设施。
对于开发者,我的建议是:
- 不要等待,现在就开始思考"标准化":即使你不直接使用官方 MCP SDK,也要在你的 Agent 项目中采用"工具描述与执行分离"、"标准化 Schema"的设计模式。
- 关注 MCP Server 的开发:尝试为你常用的数据源(如 Notion、GitHub、本地文件夹)编写简单的 MCP Server。这是未来连接 AI 与现实世界的桥梁。
- 理解协议细节 :深入了解 JSON-RPC 在 MCP 中的应用,理解
resources、tools、prompts三大核心原语的区别。
MCP 正在重新定义 AI 应用的边界。它让 AI 不再是一个孤立的智力大脑,而是一个能够手脚并用、操作整个数字世界的超级智能体。
希望这篇文章能帮你理清 MCP 的脉络。如果你在实践过程中遇到问题,欢迎在评论区交流!
参考资料: