MCP 这东西,刚开始看很容易觉得:不就是让大模型调用外部工具吗?OpenAI 的 Function Call、Claude 的 Tool Use,不也能干这个?
表面看确实像。
但你多往下想一层就会发现,它们要解决的问题不是一个层级。Function Call 解决的是“模型怎么表达一次工具调用”,MCP 解决的是“智能体应用怎么安全、统一、可复用地连接外部世界”。
这也是理解 MCP 最关键的起点。
一、先把 MCP 的定位说清楚
MCP 到底是什么
MCP,全称是 Model Context Protocol,中文一般叫“模型上下文协议”。它最早由 Anthropic 开源出来,目标很明确:让大模型应用能用统一方式连接外部工具、数据源和上下文。
但是别被名字绕进去。MCP 不是一个具体框架,也不是某个 SDK,更不是某个模型独有的功能。它是一套开放协议,规定了 AI 应用和外部能力之间怎么通信、怎么发现能力、怎么调用工具、怎么返回结果。
用大白话说,MCP 更像 AI 时代的 USB 接口。

USB 不关心你插的是鼠标、键盘、U 盘还是摄像头,它只规定一套统一的连接方式。MCP 也是类似的思路:数据库、文件系统、GitHub、Slack、内部文档、业务接口,都可以包装成 MCP Server。只要客户端支持 MCP,就能按同一套协议接入。
以前你想让一个智能体读取数据库,通常要在这个智能体里写一套专门的 Function Call 逻辑。换一个智能体,可能又要重新适配一遍。今天 Cursor 写一套,明天 Claude Desktop 再写一套,后天自己的 Agent 框架还得继续写。
MCP 想干的事情就是:别每家都重复造轮子了。工具能力独立出来,大家按协议连接。
所以 MCP 的重点不是“让模型会调用工具”,而是让工具能力变成可以被不同智能体复用的标准服务。
下面这张图是来自 MCP 官网的架构图,可以直观地感受到 MCP 协议的”枢纽”作用:中间的 MCP 协议层作为统一标准,连接了左侧的智能体客户端(如 Claude、IDE)和右侧的工具(如数据库、文件系统等)。它将原本没有复用性的点对点连接,简化为了统一的接口调用,意味着只要支持 MCP 标准,左侧的任意客户端应用都能”即插即用”地连接右侧的任意工具,真正实现了智能体和工具的功能解耦。

为什么它必须是协议,而不是框架
理解 MCP 的第一原则是:真正的复用,一定发生在框架之外。
如果一个工具只能挂在某个 SDK 里,那它就天然被这个 SDK 绑定住了。你写了一个 Java SDK,Python 智能体怎么用?你接进某个 Agent 框架,换到另一个框架是不是又要重写?
工具要可移植、可组合、可复用,最干净的方式就是把它做成独立能力端点。智能体不需要知道工具是 Java 写的、Python 写的,还是跑在本地、容器里、远程服务器上。智能体只需要知道:这个 Server 暴露了哪些能力,每个能力怎么调用,结果会按什么格式返回。
这就是 MCP 为什么更像“HTTP 之于 Web”,而不是“MyBatis 之于数据库”。
框架解决的是某个生态里的开发效率,协议解决的是不同系统之间的协作边界。MCP 的价值就在这里:它把工具从智能体内部拆出来,变成外部可协商、可发现、可调用、可复用的能力服务。
二、MCP 的架构先看明白
MCP 的架构里有三个核心角色:Host、Client、Server。
- Host 是宿主应用,也就是承载智能体能力的产品,比如 Cursor、Claude Desktop、Cline,或者你自己写的 Agent 应用。用户真正交互的是 Host。
- Client 通常运行在 Host 里面,负责和某个 MCP Server 建立连接。一个 Host 可以连接多个 MCP Server,因此通常也会有多个 Client。可以把 Client 理解成 Host 里的“协议适配器”。
- Server 则是独立的能力提供方。它把文件读取、代码搜索、数据库查询、GitHub 操作、内部系统调用等能力暴露出来,并按 MCP 协议响应 Client 的请求。
这个 Client-Server 结构看起来朴素,但它解决了以前工具和智能体强耦合的问题。工具代码不再放在智能体内部,而是独立运行。智能体只负责发现、选择和调度工具,不需要理解工具内部怎么实现。
这也是 MCP 能让工具标准化的前提。
三、MCP VS Function Call
在理解了 MCP 的整体架构之后,我们再回到一个核心问题:MCP 与传统的 Function Call 有什么区别?从表面上看,二者似乎都是为了让智能体调用工具,但实际上,它们在抽象层级、复用能力和工程复杂度上有着本质差异。
Function Call 流程痛点
在传统的 Function Call 模式中,整个流程本质上是一种“硬编码式集成“。每次的工具集成都是一次完整的开发,不可避免的就回重复造轮子、强耦合。所有环节都要由开发者自己实现。
并目这些逻辑全部都必须得在智能体内部“写死”。如果智能体数量增加,则每个智能体的接入代码都要重复书写。随着工具规模扩大,系统的耦合度越来越高,智能体的扩展成本也会急剧上升。
MCP 通过清晰的 Client-Server 分层架构解决了传统 Function Call 的“强耦合、难扩展、难管理”问题。工具不再需要嵌入到智能体内部,而是以独立的 MCP Sever 暴露能力;Client 负责通过 JSON-RPC 协议与 Sever 进行能力协商与通信;智能体则统一管理权限、上下文整合与大模型的调用。这样一来,工具接入不再需要在智能体中硬编码逻辑,功能边界更清晰,智能体也能通过工具的组合与复用轻松扩展。
graph TD
subgraph "Your Computer"
Host["Hoest with MCP Client<br/>(Claude, IDEs, Tools)"]
ServerA["MCP Server A"]
ServerB["MCP Server B"]
ServerC["MCP Server C"]
LocalA["Local Data Source A"]
LocalB["Local Data Source B"]
end
subgraph "Internet"
RemoteC["Remote Service C"]
end
%% 主机与服务器的连接
Host -- "MCP Protocol" --> ServerA
Host -- "MCP Protocol" --> ServerB
Host -- "MCP Protocol" --> ServerC
%% 服务器与数据源的连接
ServerA <--> LocalA
ServerB <--> LocalB
ServerC -- "Web APIs" --> RemoteC通俗来讲,Function Call 是“智能体直接带着自制的工具去工作”,而 MCP 则通过一套标准的协议与架构,把工具变成独立服务,由智能体统一调度,就像“在工具商店,挑选专业制造商制造的工具去工作”。智能体只需通过协议查询和调用,无需了解工具的内部实现即可直接使用,从而真正实现了工具的模块化、标准化和可插拔化。
四、MCP 的工作流程
下面用一张图,描述一下智能体通过 MCP 是如何来工作的。

第一阶段:初始化(工具说明获取)智能体初始化的时候,会通过 MCP 协议向所有连接的 MCP Senver 使用 JSON-RPC 协议请求工具说明书。MCP Server 负责提供并确保这些说明书是标准化的 JSON 格式。
第二阶段:决策(大模型规划)智能体将用户的原始问题和获取到的所有标准化工具说明,一同发送给大模型,大模型根据这些信息进行规划,并返回一个清晰的工具调用指令。
第三阶段:调用(执行与结果回传)智能体接收到指令后,立即通过 MCP 协议请求对应的 MCP Sever 执行工具操作。MCP Server 完成实际的工具逻辑(如数据库查询),并将原始执行结果返回给智能体。
看到这里你应该就明白了:模型不直接碰你的文件系统、数据库或内部服务。模型只是做决策,真正动手的是 MCP Server。
也正因为如此,MCP Server 的权限边界、参数校验、审计日志和执行安全都非常重要。
五、大模型在工具调用里到底负责什么
这里有个边界一定要想清楚:不管是 Function Call,还是 MCP,大模型本身都不是那个真正执行动作的人。
大模型负责的是决策和规划。它看用户问题、上下文、工具说明,然后判断要不要调用工具、调用哪个工具、参数怎么填。
真正执行动作的是应用系统,或者更具体一点,是 Host 通过 Client 请求到的 MCP Server。
这个边界很重要。因为文件读取、数据库查询、退款、删除数据、发邮件这些动作都有真实副作用,不能把权限、安全、异常处理全部交给模型。模型可以建议执行动作,但不能成为权限系统本身。
工程上更稳的做法是:让模型在“你允许的工具集合里”做选择。当前页面、当前用户、当前业务状态能用代码确定的,就不要让模型猜。模型擅长理解意图和补全语义,确定性上下文应该交给工程系统。
六、MCP 是怎么做到把工具从智能体里拆出来的
要让工具不再绑定某个智能体,首先必须让工具的和智能体分离。
MCP 之所以能够做到这一点,正是因为它设计了 “client-server“ 的结构:
智能体作为客户端,向外部的 MCP Server 去请求能力;工具不再属于智能体,而属于独立的 Server。这种结构看似简单,却解决了此前所有工具耦合在智能体中的问题。
工具的代码不再放在智能体内部,也不再依赖于智能体的开发语言和运行环境,而是被包装为一个能够独立运行的能力端点。智能体只是与它进行通信,也不用关心工具是用 Java 写的、Python 写的,还是运行在什么平台上。这样工具就被从智能体内部拆到了系统外面,成为独立服务。
下面这个就是 MCP 官网提供的架构图。
graph TD
subgraph "MCP Host (AI Application)"
C1["MCP Client 1"]
C2["MCP Client 2"]
C3["MCP Client 3"]
C4["MCP Client 4"]
end
%% 本地服务器连接
C1 -- "Dedicated connection" --> SA["MCP Server A - Local<br/>(e.g. Filesystem)"]
C2 -- "Dedicated connection" --> SB["MCP Server B - Local<br/>(e.g. Database)"]
%% 远程服务器连接
C3 -- "Dedicated connection" --> SC["MCP Server C - Remote<br/>(e.g. Sentry)"]
C4 -- "Dedicated connection" --> SCMCP HOST 其实就是我们的智能体应用,MCP Client 就是安装在 HOST 中的一段代码,用于与 MCP Server 交互获取工具信息的组件,而 MCP server 就是独立的工具服务,用于提供说明书和具体执行逻辑。
从图中也可以看出,client 和 server 是一对一的,而 host 中则可以接入多个 client 用于实现智能体的能力扩展。
七、MCP 如何把工具调用标准化
数据层和传输层分别解决什么
工具从智能体里拆出来之后,接下来要解决的是标准化。
如果每个 Server 都按自己的格式描述工具、自己的格式接收参数、自己的格式返回结果,Client 还是要为每个工具写适配逻辑,那就又回到了老路。
MCP 的标准化主要分两层:数据层和传输层。
- 数据层规定大家交换什么消息。MCP 使用 JSON-RPC 2.0 作为核心消息格式,围绕初始化、能力发现、工具调用、资源读取、通知等动作定义了一组标准方法。
- 传输层规定消息怎么传。定义了客户端和服务器之间进行数据交换的通信机制和通道,包括特定于传输的连接建立、消息帧和授权。MCP 支持本地 stdio,也支持远程 HTTP 方式。老版本里有 SSE,新方案里更推荐 Streamable HTTP。
你可以把它理解成两件事:JSON-RPC 解决“大家说什么语言”,传输层解决“用什么通道说话”。
JSON-RPC:MCP 的通用语言
所有工具都必须用统一的格式描述自己 —— 包括工具名、使用说明、参数结构、返回格式等。
这种描述不是随意写的,而是采用严格的 JSON 格式。智能体在连接 MCP Server 的第一步,就是向其索要所有工具的说明书。这一步在 MCP 中被称为“初始化”,对应一次标准的 JSON-RPC 请求。智能体无需关心工具是谁写的,也无需去理解其内部逻辑,只需要根据“说明书”就能让大模型进行决策判断,并最终发起调用。另外,工具的执行返回也遵循同样的标准格式,因此智能体无需适配不同工具的返回值,也不需要写任何特殊逻辑。
只要按标准写了工具说明书,任何工具就能被任何智能体直接使用,不需要额外的集成成本。
JSON-RPC 就是两个服务之间通过发送 JSON 数据来进行沟通的一种”通用语言”。
- RPC(Remote Procedure Call):就是指远程过程调用。它的核心思想是:我在 A 服务上调用一个函数(比如 getWeather()),但实际上这个函数是在 B 服务上运行的,B 把结果运行完再传回给 A。
- JSON:所有的数据传输都使用最通用的 JSON 格式,这意味着无论你的智能体是用什么编程语言写的,大家都能看懂对方发来的信息,而且这样的请求是非常简洁高效的。
- 无状态(Stateless):每一次请求都是独立的,就像寄信一样,寄出去一封,收回来一封,协议本身不记忆之前的状态。
相比于复杂的 RESTful API(需要关心 HTTP 方法、URL 路径、Header),JSON-RPC 极其简单粗暴:只关心“需要调用的方法名”和“参数”。这与大模型调用工具的逻辑完美契合。
MCP 中的每一次请求,本质上都是在交换 JSON-RPC 2.0 标准的数据包。我们来看一下它的结构是什么样的。
请求体:
{
"jsonrpc": "2.0", // JSON-RPC 协议版本,MCP 固定使用 2.0
"method": "tools/call", // 调用方法:tools/call 表示调用外部工具/函数
"params": { // 请求参数体
"name": "get_weather", // 工具名称:要调用的具体工具名
"arguments": {
"city": "Beijing" // 工具入参:传给工具的实际参数(键值对形式)
}
},
"id": 1 // 请求唯一标识,用于匹配请求和响应
}
响应体:
{
"jsonrpc": "2.0",
"result": { // 结果:成功时的返回数据
"content": [
{
"type": "text",
"text": "北京今天晴,气温 25 度"
}
]
},
"id": 1 // 对应请求的 ID
}
错误结构:
{
"jsonrpc": "2.0",
"error": { // 错误对象
"code": -32601, // 标准错误码
"message": "Method not found" // 错误信息
},
"id": 1
}
MCP 如何利用 JSON-RPC 工作
在 MCP 架构中,JSON-RPC 并不是简单的数据传输工具,而是整个工具调用、状态管理和决策执行的核心标准语言。MCP 将智能体(MCP Host)、客户端(MCP Client)和工具服务(MCP Server)的交互完全规范化,使得每一次调用都遵循相同的流程。
初始化阶段:建立连接与能力协商
当 MCP Host 启动时,MCP Client 会向 MCP Server 发起 JSON-RPC 请求,进行初始化。
- 能力协商:客户端和服务端会确认协议版本、功能支持等信息。
- 准备就绪通知:初始化完成后,客户端会发送
notifications/initialized告知服务器自己已准备好。 - 意义:这一阶段保证双方在同一协议下通信,建立通信基础,为后续工具发现和调用做好准备。
示例请求:
{
"jsonrpc": "2.0",
"id": 1,
"method": "initialize",
"params": {
"protocolVersion": "2024-11-05",
"capabilities": {
"roots": {
"listChanged": true
},
"sampling": {},
"elicitation": {}
},
"clientInfo": {
"name": "ExampleClient",
"title": "Example Client Display Name",
"version": "1.0.0"
}
}
}
初始化成功后,客户端必须发送 initialized 通知,表明其已准备好开始正常运行:
这是 MCP 协议的强制步骤,没有这一步,服务端会认为客户端未就绪,直接禁止后续所有操作(如工具调用、资源访问等)。
{
"jsonrpc": "2.0",
"method": "notifications/initialized"
}
工具发现阶段:获取工具说明书
初始化完成后,客户端需要知道服务器上“有哪些工具”可以使用。
- 标准化描述:每个工具都以 JSON 格式描述方法名、参数类型、返回格式和使用说明。
- 无需理解内部逻辑:智能体只需知道工具能做什么、需要哪些参数、返回什么结果,无需关心内部实现。
- 动态发现:工具可能随时变化,每次获取的都是最新工具列表。
MCP Server 对外暴露三类核心能力:
- Resources(资源):可供客户端直接读取的外部数据,如文件内容、API 返回结果等。
- Tools(工具):具体执行的工具服务。(核心能力)
- Prompts(提示):预定义的提示词模板。
示例请求:
{
"jsonrpc": "2.0", // JSON-RPC 协议版本,固定为 "2.0"
"method": "tools/list", // MCP 工具发现阶段的请求方法,用于获取服务器支持的所有工具列表
"params": {}, // 请求参数,此处为空对象,表示无额外参数
"id": 100 // 请求ID,用于匹配服务器返回的响应
}
响应返回所有工具的说明信息。智能体在拿到这些说明后,就可以利用大模型构建调用策略和决策逻辑。
调用阶段:执行具体工具
当智能体通过大模型决策需要调用某个工具(如 get_weather)时,通过 MCP Client 构建标准 JSON-RPC 请求发送给 MCP Server。
{
"jsonrpc": "2.0", // JSON-RPC 协议版本,固定为 "2.0"
"method": "tools/call", // MCP 工具调用请求方法,用于执行指定工具
"params": {
"name": "get_weather", // 要调用的工具名称
"arguments": { // 工具所需的参数(键值对形式)
"city": "Beijing" // 工具入参:查询天气的城市
}
},
"id": 101 // 请求ID,用于匹配服务器返回的响应
}
服务器收到请求后:
- 解析工具名和参数:根据
name找到对应工具执行。 - 执行工具:独立运行工具逻辑,无需 Host 参与内部过程。
- 返回结果:按照 JSON-RPC 的
result或error返回数据。 智能体接收到返回值后,可以直接处理输出、组合多个工具结果,或者继续做下一步决策。整个流程完全无需针对每个工具写不同的适配逻辑。
工具变更阶段:处理工具列表更新
在运行过程中,服务器上的工具可能会发生变更(新增、下线或修改)。MCP 支持客户端实时获知变更:
- 变更通知:服务端通过
notifications/tools/list_changed通知客户端工具列表已更新。 - 重新获取列表:客户端收到通知后会重新请求
tools/list,更新内部工具注册表。 - 保证一致性:智能体始终知道最新的可用工具,实现动态适应和高扩展性。
示例通知:
{
"jsonrpc": "2.0",
"method": "notifications/tools/list_changed",
"params": {}
}
MCP 通过 JSON-RPC 的各阶段的调用,从而实现了工具的数据层的标准化、模块化和动态扩展能力。
MCP 传输层的标准化
JSON-RPC 搞定了 MCP 的数据层标准化。如果把 MCP 比作两个人的沟通,那么 JSON-RPC 就解决了“大家说什么语言(比如都说中文)”的问题。
那么接下来,我们必须解决“用什么工具通话”的问题。是面对面说话?打电话?还是发传真?这就是第二层标准:传输层。
MCP 官方前后共定义了三种主流的标准通信管道,分别对应不同的应用场景:Stdio、SSE(旧)和 Streamable HTTP(新)。
Stdio(标准输入输出)
也就是本地直连,这是 MCP 最原始、最高效的传输方式,也是 Claude、Cursor 等本地客户端智能体的首选集成方式。
Stdio 传输不涉及任何网络协议(TCP/HTTP),它的本质其实是进程间通信。当 MCP Host 启动一个 MCP Server 时,它实际上是在操作系统中 fork 了一个子进程。
- 下行通道(Host -> Server):Host 将 JSON-RPC 请求序列化为字符串,写入子进程的 stdin(标准输入流)。
- 上行通道(Server -> Host):Server 处理完后,将结果写入自己的 stdout(标准输出流),Host 监听这个流来获取响应。
- 错误通道:日志信息通常写入 stderr,这样不会干扰正常的 JSON 数据流。
这个模式有两个明显优点。
第一,生命周期简单。Server 进程由 Host 管理,Host 关闭,Server 也跟着结束。
第二,没有网络开销。数据在本机进程间流转,延迟很低,很适合文件系统、本地项目、本地数据库这类场景。
所以你在本地开发工具里看到的大量 MCP Server,都会优先采用 stdio。
sequenceDiagram
participant Client
participant ServerProcess as Server Process
Client->>ServerProcess: Launch subprocess
loop [Message Exchange]
Client->>ServerProcess: Write to stdin
ServerProcess->>Client: Write to stdout
ServerProcess-->>Client: Optional logs on stderr
end
Client->>ServerProcess: Close stdin, terminate subprocessSSE(Server-Sent Events)
当工具部署在远程服务器上时,就不能再靠本地 stdin/stdout 了,需要走 HTTP。但在 HTTP/1.1 时代,服务器无法主动发消息给客户端。
所以早期 MCP 使用过 SSE,也就是 Server-Sent Events。SSE 的特点是服务器可以通过 HTTP 长连接持续向客户端推消息,但客户端不能通过这条连接反向发送消息。
于是 MCP 在 SSE 模式下通常要维护两条通道:Client 通过 GET /sse 建立一个长连接,用来接收 Server 推送;Client 如果要发送工具调用请求,则再通过另一个端点,比如 /messages,发起 HTTP POST。
- 接收通道(Events Channel):
- Client 发起一个
GET /sse请求。 - Server 保持连接不关闭(Keep-Alive),并设置
Content-Type: text/event-stream。 - 一旦有消息(如工具执行结果、日志),Server 就通过这个长连接推送给 Client。
- Client 发起一个
- 发送通道(Post Channel):
- 当 Client 需要调用工具时,它无法通过 SSE 连接发送。
- Client 必须向 Server 的另一个端点(如
/messages)发起一个新的 HTTPPOST请求。
这样的模式下的痛点有两个。
首先是状态维护比较麻烦,Client 必须同时维护一个长连接(听)和一个短连接(说)。
其次重连机制无法自动断点重连,需要双方自己实现定时心跳检测来维护长连接。
打个比方,就像用收音机听指挥(单向接收 Server 消息),但要汇报工作时,却必须另外跑去邮局寄信(独立发送)。虽然能通,但整个过程很笨重。
sequenceDiagram
participant Client
participant Server
Client->>Server: Open SSE connection
Server-->>Client: endpoint event
loop [Message Exchange]
Client->>Server: HTTP POST messages
Server-->>Client: SSE message events
end
Client->>Server: Close SSE connectionStreamable HTTP
Streamable HTTP 的出现,就是为了解决 SSE 模式中读写分离带来的架构复杂度和传统 HTTP 的一次性交互无法满足 MCP 双向异步通知、以及无法断点重连等问题。
Streamable HTTP 的核心是统一和流式化。它将所有交互都汇集到一个标准的 HTTP POST 请求中,并利用 HTTP 的流式能力来承载 MCP 的 JSON-RPC 协议。
- 单一连接:Client 只需要连接一个统一的端点(
/mcp),无需维护两个分离的通道。 - 请求发送:Client 将 JSON-RPC 报文放在 POST 请求的 Body 中发送给 Server。
- 流式响应:Server 接收请求后,并不会立即关闭连接。它会利用 HTTP 协议的分块传输编码(Chunked Encoding),将响应(包括结果、日志、通知)分批次、实时地写入 POST 响应的 Body 中。
核心优势
- 简化架构:只需要一个 HTTP 端点,不再读写分离即可实现双向异步通信。
- 灵活性强:可以根据场景选择是否使用流式 SSE 响应,不必每次都保持长连接,支持无状态模式。
- 资源效率更高:不用一直维持 SSE 长连接时,节省资源;需要流式时也能按需开启。
- 更可靠的恢复机制:支持断点重连,可恢复会话(通过 Session ID + Last-Event-ID),通信更稳定。
- 基础设施更友好:与标准 HTTP 基础设施(API 网关、负载均衡、云服务)兼容性更好。
- 向后兼容:既可以支持新的 Streamable HTTP,也可以保留旧 SSE 通道,方便平滑升级。
sequenceDiagram
participant Client
participant Server
%% 初始化阶段
rect rgb(255, 248, 181)
note over Client, Server: initialization
Client->>Server: POST InitializeRequest
Server-->>Client: InitializeResponse<br/>MCP-Session-Id: 1868a90c...
Client->>Server: POST InitializedNotification<br/>MCP-Session-Id: 1868a90c...
Server-->>Client: 202 Accepted
end
%% 客户端请求阶段
rect rgb(255, 248, 181)
note over Client, Server: client requests
Client->>Server: POST ... request ...<br/>MCP-Session-Id: 1868a90c...
alt [single HTTP response]
Server-->>Client: ... response ...
else [server opens SSE stream]
loop [while connection remains open]
Server-->>Client: ... SSE messages from server ...
end
Server-->>Client: SSE event: ... response ...
end
end
%% 客户端通知/响应阶段
rect rgb(255, 248, 181)
note over Client, Server: client notifications/responses
Client->>Server: POST ... notification/response ...<br/>MCP-Session-Id: 1868a90c...
Server-->>Client: 202 Accepted
end
%% 服务器请求阶段
rect rgb(255, 248, 181)
note over Client, Server: server requests
Client->>Server: GET<br/>MCP-Session-Id: 1868a90c...
loop [while connection remains open]
Server-->>Client: ... SSE messages from server ...
end
end八、工程落地时真正要注意什么
MCP 能解决什么,不能解决什么
MCP 很重要,但它不是银弹。
它解决的是接入标准化问题:工具如何被发现,如何描述,如何调用,如何返回,如何被不同智能体复用。
但它不会自动解决所有工程问题。
一个 MCP Server 如果权限开太大,照样危险。一个工具描述写得很烂,模型照样可能误用。一个返回结果不可靠的内部系统,接上 MCP 之后也不会自动变可靠。协议把路铺好了,但不能保证路上的车都开得稳。
所以落地 MCP 时,仍然要回到工程基本功。
工具不要一股脑全暴露给模型。当前用户、当前页面、当前业务流程允许什么,就只给它什么。参数要做 schema 约束,也要在服务端二次校验。涉及副作用的工具,比如退款、删除、发消息,要有权限判断、二次确认、审计日志和幂等控制。
工具描述也要认真写。名字要清楚,描述要明确告诉模型什么时候该用、什么时候不该用。参数尽量扁平,能用枚举就不要让模型自由发挥。返回值要让模型看得懂,不要只返回内部错误码或晦涩字段。
这点和 Function Call 的工程经验是相通的:模型输出是输入源,不是可信边界。
为什么 MCP 现在会变得重要
原因很简单:Agent 应用越来越多了。
以前我们用大模型,更多是聊天。你问一句,它答一句。最多帮你写段代码、总结一篇文章。
但 Agent 不一样。Agent 要做事。
它要读文件、改代码、跑测试、查日志、搜文档、访问数据库、调用 SaaS、操作浏览器。只要它开始做事,就必然需要连接外部世界。
如果每个产品都自己接一遍数据库、GitHub、文件系统、Slack、内部接口,很快就会变成一堆重复、混乱、不可维护的适配层。
MCP 的出现,本质上是在给 Agent 时代补一层基础设施。
就像早期互联网需要 HTTP,服务之间需要 REST 或 gRPC,编辑器和语言服务之间需要 LSP。AI 应用要连接外部上下文和工具,也需要一个大家都能遵守的协议。
它真正改变的不是某一次工具调用,而是工具生态的组织方式。
一个 GitHub MCP Server 不应该只服务某一个 AI 应用。一个数据库 MCP Server 也不应该每接一个 Agent 框架就重写一遍。工具能力应该像基础设施一样,被多个支持协议的客户端复用。
最后
MCP 不是 Function Call 的换皮。
Function Call 的核心价值,是把自然语言意图变成结构化工具调用。它让模型能表达“我要调用哪个函数,参数是什么”。
MCP 的核心价值,是把外部能力包装成模型应用可以发现、可以理解、可以调用的标准服务。它通过 Host、Client、Server 的分层,把工具从智能体内部拆出来;通过 JSON-RPC 统一数据层;通过 stdio、SSE、Streamable HTTP 这些传输方式适配本地和远程场景。
说白了,Function Call 解决的是模型怎么点菜,MCP 解决的是厨房、菜单、传菜口和后厨系统怎么标准化。
等你从这个角度看 MCP,就不会再把它简单理解成“又一个工具调用方案”了。
它真正想做的,是给 Agent 连接真实世界这件事,定一套更通用的规矩。