第十一章 MCP:为什么 AI 世界需要统一的工具协议?
目录
零基础认识大语言模型(LLM)工作原理目录 - GuZhenYin - 博客园
本章导读
上一章,我们介绍了 Tool Calling(工具调用)。
它让大语言模型第一次拥有了与现实世界交互的能力。
例如:
- 查询天气;
- 搜索互联网;
- 执行 Python;
- 查询数据库;
- 控制浏览器。
这些能力让 AI 从一个"只会聊天"的模型,逐渐变成一个能够完成任务的 Agent。
但是,当社区中越来越多工具出现之后,一个新的问题开始暴露出来。
如果每个 AI 平台都要重新开发一套工具接口,会发生什么?
这正是 MCP(Model Context Protocol)诞生的原因。
11.1 Tool Calling 已经很好了,为什么还需要 MCP?
我们还是以一个例子作为开始。
假设你开发了一个天气查询工具。(其实也是大多数兄弟tool calling的开始..)
它提供一个简单的接口:
查询天气(城市)
现在,你希望它能够被不同的大模型使用。
例如:
- ChatGPT
- Claude
- Gemini
- MinMax
- Qwen
理论上,它们都可以调用这个天气接口。
但是现实却不是这样。
每个平台都有自己的工具调用格式。
例如(以下仅为示意,不代表最新的交互协议):
ChatGPT
↓
Function Calling
↓
你的天气工具
Claude
↓
Tool Use
↓
你的天气工具
Gemini
↓
Function Declaration
↓
你的天气工具
虽然最终调用的是同一个天气 API,但每个平台都有自己的接口规范、参数格式和通信方式。
于是,一个非常尴尬的问题出现了。
如果你想同时支持五个平台,就需要分别适配五套接口。
这就像我们前些年的手机充电器一样:
- 安卓一种接口;
- 苹果一种接口;
- Micro USB 一种接口;
- Type-C 又是一种接口。
明明都是充电,却没有统一标准。
11.2 Tool Calling 的局限在哪里?
上一章我们提到:
Tool Calling 的本质是:模型告诉程序:"我需要调用这个工具。"
例如:
{
"tool": "weather",
"city": "北京"
}
程序收到之后会按下面的流程进行操作
调用天气 API
↓
获得天气数据
↓
再交给 LLM
整个流程没有任何问题。
但是问题在于 Tool Calling 更像是模型厂商提供的一种能力,而不是一种统一标准。
例如:
OpenAI:有自己的 Function Calling。
Anthropic:有自己的 Tool Use。
Google:有自己的 Function Declaration。
不同平台之间:
- Tool 定义不同;
- 参数格式不同;
- 返回格式不同;
- 通信方式不同。
这意味着:
工具开发者需要不断重复开发适配层。
11.3 MCP 想解决什么问题?
MCP 并没有发明一种新的工具,它只是定义了一套协议。
它真正解决的是:如何让工具只开发一次,就能够被所有支持 MCP 的 AI 使用。
可以把 MCP 理解成:AI 与工具之间的一种通用语言。
注意,这里的"语言"并不是自然语言,而是一套约定好的通信协议。
只要:
- Agent 能按照 MCP调用;
- 工具也能按照 MCP实现;
那么它们就可以互相通信,而不需要关心对方是谁。
11.4 MCP 是 AI 世界的 USB?
还是举个例子.
假设你买了一把无线鼠标。
以前不同品牌都有自己的接收器。
后来USB 成为了统一标准。
于是无论罗技、雷蛇、戴尔、都可以直接插在你的电脑上。
电脑并不需要知道,这是哪家公司生产的鼠标。
因为 USB 已经规定好了通信方式。
不过,这里有一点需要特别强调。
网上很多文章都会说:
MCP 是 AI 世界的 USB。
这个比喻虽然便于理解,但并不完全准确。
USB 是一种硬件接口标准,解决的是设备之间的物理连接问题。
而 MCP 是一种应用层通信协议,解决的是 AI 与工具之间如何交换能力、请求和结果的问题。
因此,更准确的类比应该是:MCP 其实更像 HTTP协议或者数据库连接协议,而不是 USB 接口。
11.5 MCP 架构长什么样?
我们来看一张简化后的架构图。
AI Agent
│
▼
MCP Client(客户端)
│
MCP 通信协议
│
▼
MCP Server(服务端)
┌────────┼────────┐
▼ ▼ ▼
浏览器 数据库 Git
这里第一次出现了两个新的角色, MCP Client 和MCP Server.
最早,我们很容易混淆它们。
但是,其实它们的职责其实非常明确。
11.6 MCP Client 是什么?
Client其实就是:主动发起请求的一方。
它通常是LLM或者Agent,比如
Claude Desktop;
OpenClaw;
Cursor;
Claude Code;
Codex;
这些 AI 应用,都可以充当 MCP Client。
它们负责:
- 连接 MCP Server;
- 获取工具列表;
- 调用工具;
- 获取返回结果。
可以理解为Client 等于使用工具的人。
11.7 MCP Server 是什么?
Server 则相反。
它负责提供能力。
比如,一个 Git MCP Server。
它可以提供:
- 查看 Commit;
- 创建 Branch;
- 提交代码。
一个数据库 MCP Server。
它可以提供:
- 查询数据;
- 修改数据;
- 执行 SQL。
一个浏览器 MCP Server。
它可以提供:
- 打开网页;
- 点击按钮;
- 获取页面内容。
所以Server则是提供工具能力的一方。
一个 Server 可以提供多个 Tool,而一个 Client 也可以同时连接多个 Server。
11.8 MCP 的一次完整调用流程
简单了解了 MCP 的整体架构之后,我们再来看一次真实的调用过程。
很多人第一次接触 MCP 时,会有一种误解:
是不是 Claude 或 ChatGPT 直接调用了我的 C# 方法?
实际上并不是。
整个调用过程始终遵循"模型负责决策,程序负责执行"的原则。
下面以一个天气查询工具为例,看看一次完整的 MCP 调用过程。
假设我们开发了一个 MCP Server,其中提供了一个查询天气的 Tool:
QueryWeather(city)
用户向 AI 提出问题:
武汉今天的天气怎么样?
整个系统会经历下面几个步骤。
┌──────────────────────────────────────────┐
│ 用户输入 │
│ "武汉今天的天气怎么样?" │
└──────────────────┬───────────────────────┘
│
▼
┌──────────────────────────────────────────┐
│ LLM 分析用户意图 │
│ 判断需要调用 QueryWeather Tool │
└──────────────────┬───────────────────────┘
│
▼
┌──────────────────────────────────────────┐
│ MCP Client │
│ 向 MCP Server 发送 tools/call 请求 │
└──────────────────┬───────────────────────┘
│
▼
┌──────────────────────────────────────────┐
│ MCP Server │
│ 执行 QueryWeather("武汉") │
└──────────────────┬───────────────────────┘
│
▼
┌──────────────────────────────────────────┐
│ 返回结果 │
│ 晴天,30℃,东南风三级 │
└──────────────────┬───────────────────────┘
│
▼
┌──────────────────────────────────────────┐
│ LLM 根据工具结果组织自然语言 │
└──────────────────┬───────────────────────┘
│
▼
回复最终答案
整个过程中,大模型始终没有直接执行任何代码。
它只完成了两件事情:
- 判断是否需要调用工具;
- 根据工具返回的数据生成最终回复。
真正执行查询天气的是 MCP Server。
因此可以说:
MCP 负责连接工具,LLM 负责理解语言,两者各司其职。
MCP 初始化过程
很多兄弟可能还会有一个疑问:
LLM 是怎么知道有哪些 Tool 可以调用的?
答案其实就在 MCP 的初始化过程中。
当 Client 第一次连接 MCP Server 时,就会自动获取 Server 所提供的能力。
整个过程可以简化为下面几个步骤:
Client
│
│ initialize
▼
Server
│
│ 返回协议版本、Server 信息
▼
Client
│
│ tools/list
▼
Server
│
├── QueryWeather
├── SearchOrder
├── GetInventory
└── GenerateReport
完成这一步之后,其实这些能力就已经在LLM的上下文对话中了,这时候LLM 就已经知道:当前有哪些 Tool 可以使用。
之后,当用户提出问题时,模型会根据 Tool 的名称、说明以及参数定义,自主决定是否调用某个 Tool。
整个过程并不需要开发人员编写任何"如果用户问天气,就调用天气接口"这样的业务代码。
这也是 MCP 与传统 API 最大的不同之处。
11.9 使用 .NET 开发一个简单的 MCP Server
理解了 MCP 的工作原理之后,我们再来看一个最简单的 .NET 示例。
对于 .NET 开发者来说,一个好消息是:目前已经有官方的 MCP C# SDK,开发者无需自己实现 JSON-RPC 协议、Tool 注册或通信逻辑,只需要关注业务代码即可。
目前推荐使用 ModelContextProtocol 官方 C# SDK ,它由 Anthropic 与 Microsoft 共同推动维护,是 MCP 官方组织提供的 .NET 实现,也是目前 .NET 平台开发 MCP 应用的推荐方案。
官方地址:
- GitHub:modelcontextprotocol/csharp-sdk
- 官方文档:https://modelcontextprotocol.io/
- API 文档:https://csharp.sdk.modelcontextprotocol.io/
整个 SDK 已经与 Microsoft.Extensions.DependencyInjection 、Microsoft.Extensions.Hosting 等 .NET 基础设施深度集成,因此开发体验与 ASP.NET Core 十分相似。
对于绝大多数项目,只需要安装下面这两个 NuGet 包即可:
dotnet add package ModelContextProtocol
dotnet add package Microsoft.Extensions.Hosting
安装完成之后,就可以开始开发自己的 MCP Server。
第一步:注册 MCP Server
Program.cs:
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
using ModelContextProtocol.Server;
var builder = Host.CreateApplicationBuilder(args);
builder.Services
.AddMcpServer()
.WithStdioServerTransport()
.WithToolsFromAssembly();
await builder.Build().RunAsync();
这段代码与 ASP.NET Core 十分相似。
整个 MCP Server 可以理解成一个普通的 Host 应用。
其中几个扩展方法分别承担不同职责:
| 方法 | 作用 |
|---|---|
AddMcpServer() |
注册 MCP Server 服务。 |
WithStdioServerTransport() |
使用 STDIO(标准输入/输出)作为通信方式,适用于 Claude Desktop、OpenClaw、Claude Code 等本地 Agent。 |
WithToolsFromAssembly() |
自动扫描程序集中的 Tool,并完成注册,无需手工维护 Tool 列表。 |
可以看到,开发者几乎不用关心 MCP 协议本身,而是通过 SDK 提供的扩展方法快速完成整个 Server 的初始化。
第二步:编写一个 Tool
完成 Server 注册之后,只需要编写一个普通的 C# 方法即可将其暴露给 AI Agent 调用。
下面我们定义一个最简单的天气查询工具:
using ModelContextProtocol.Server;
[McpServerToolType]
public class WeatherTool
{
[McpServerTool, Description("查询各地区天气,可以调用这个接口")]
public string QueryWeather(string city)
{
return $"{city}:晴天,30℃";
}
}
对于开发者来说,一个 MCP Tool 本质上就是一个普通的方法。
SDK 会自动完成下面一系列操作:
- Tool 注册;
- 参数解析;
- JSON 序列化;
- MCP 协议通信;
- 返回结果封装。
开发者只需要关注业务逻辑,而无需处理协议细节。
MCP Tool 的调用过程
假设用户在 Claude Desktop 中输入:
武汉今天的天气怎么样?
整个调用过程如下图所示:
Claude Desktop
│
▼
LLM 判断需要调用 QueryWeather
│
▼
MCP Client
│
▼
MCP Server
│
▼
WeatherTool.QueryWeather("武汉")
│
▼
返回:"武汉:晴天,30℃"
│
▼
LLM 根据结果组织自然语言
│
▼
回复用户
整个过程中,大模型始终没有直接执行任何 C# 代码。
真正执行代码的是 MCP Server。
LLM 负责理解用户意图,并决定何时调用 Tool;MCP Server 负责完成具体业务逻辑,两者共同协作完成一次完整的任务。
知识拓展:MCP SDK 与 Semantic Kernel 是什么关系?
很多 .NET 开发者第一次接触 MCP 时都会问:
既然已经有 Semantic Kernel,为什么还需要 MCP SDK?
实际上,两者并不是竞争关系,而是位于不同层次。
| 技术 | 主要职责 |
|---|---|
| Semantic Kernel | AI 应用开发框架,负责 Prompt、Chat、Memory、Planner、Workflow 等 AI 能力编排。 |
| Microsoft.Extensions.AI | 对不同大模型提供统一抽象,屏蔽 OpenAI、Azure OpenAI、Ollama 等模型接口差异。 |
| ModelContextProtocol C# SDK | 实现 MCP 协议,负责 AI Agent 与 MCP Server 之间的通信。 |
它们之间的关系可以理解为:
Semantic Kernel
│
▼
Microsoft.Extensions.AI
│
▼
ModelContextProtocol C# SDK
│
▼
MCP Server
│
▼
企业系统 / 数据库 / Web API
三者分别解决不同层次的问题:
- Semantic Kernel 负责组织 AI 的工作流程;
- Microsoft.Extensions.AI 负责统一模型调用接口;
- MCP SDK 则负责让 AI 能够安全、标准地访问外部工具和企业系统。
因此,在企业级 AI 应用中,这三者往往是协同工作的,而不是相互替代。
11.10 为什么越来越多Agent产品开始支持 MCP?
因为对于产品平台来说,它解决了一个长期存在的问题:
过去,每接入一种工具,都要做一次适配。
现在,只要工具实现了 MCP Server,平台实现了 MCP Client,它们就可以按照统一协议进行通信。
这意味着:
- 工具开发者只需要维护一套接口;
- AI 平台可以快速接入大量已有工具;
- 企业内部也可以把自己的系统封装成 MCP Server,对外提供能力。
因此,MCP 的价值不仅在于"方便开发",更在于降低生态之间的连接成本。
11.11 以 OpenClaw 为例
以今年以来比较火的 OpenClaw 为例,它本身并不会直接内置所有工具。
相反,它可以作为一个 MCP Client,连接多个 MCP Server。
例如:
OpenClaw
│
├──────── 文件系统 MCP Server
│
├──────── Git MCP Server
│
├──────── PostgreSQL MCP Server
│
├──────── Browser MCP Server
│
└──────── 企业内部 ERP MCP Server
对于 OpenClaw 来说,它并不需要知道这些工具是谁开发的,只需要知道:
它们都遵循 MCP 协议。
这样,当模型需要某种能力时,就可以通过 MCP 调用对应的工具。
这也是为什么近一年来,越来越多 Agent 框架开始支持 MCP。
本章总结
这一章,我们回答了四个问题:
- 为什么 Tool Calling 还不够?
- 因为各个平台都有自己的工具调用方式,生态彼此割裂。
- MCP 想解决什么问题?
- 为 AI 与工具之间建立一套统一的通信协议。
- MCP Client 和 MCP Server 分别是什么?
- Client 发起调用,Server 提供能力,它们通过 MCP 协议进行通信。
- 为什么 MCP 越来越重要?
- 它降低了工具接入成本,使不同平台能够共享同一套工具生态。