核心概念
MCP 是什么
MCP (Model Context Protocol) 标准化数据总线 是 Anthropic 开源的一套标准化协议
用于建立客户端、主机和服务器之间的通用对话方式
核心特征:
- 统一接口:任何支持 MCP 的 AI 都能访问遵循 MCP 标准的数据源
- 即插即用:实现一次,到处通用
- 标准化通信:基于 JSON-RPC 协议
理解”标准化”问题
每个数据源都说”方言”
| 因素 | 说明 |
|---|---|
| 没有通用标准 | GitHub、Slack、Google Drive 由不同公司在不同年份开发 |
| 各自的设计目标 | 每个服务解决的是不同的问题 |
| 通信方式差异 | API 设计完全不同:请求格式、认证方式、返回数据结构都不一样 |
| 数据源 | 需要做的事情 |
|---|---|
| GitHub | GET /commits + Authentication 头 + 读 message 字段 |
| Slack | POST /conversations.history + Bot Token + 读 text 字段 |
| Google Drive | GET /drive/files + OAuth2 认证 + 读 name 字段 |
关键点:指令完全不同,数据格式也不同
为 GitHub 写的代码对 Slack 完全无用
AI 也说”方言”
1
2
3
4
5
6
7
8
9
10
11
OpenAI (GPT-4):
└─ 数据必须包装成 messages 列表
└─ Function Calling 需要特定的 JSON Schema 格式
Anthropic (Claude):
└─ API 结构不同
└─ System Prompt 位置要求不同
└─ 工具定义格式在细节字段上不兼容
本地模型 (Llama 3):
└─ 需要特定的提示词模板格式
N × M 复杂度问题
场景:
- 数据源:3 个(GitHub、Slack、本地数据库)
- AI 客户端:3 个(Claude Desktop、Cursor、Dify)
旧模式的工作量:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
总工作量 = 数据源数量 × AI 数量
= 3 × 3 = 9 组适配器代码
GitHub ──┬─→ Claude 适配器
├─→ Cursor 适配器
└─→ Dify 适配器
Slack ───┬─→ Claude 适配器
├─→ Cursor 适配器
└─→ Dify 适配器
DB ──────┬─→ Claude 适配器
├─→ Cursor 适配器
└─→ Dify 适配器
MCP 模式的工作量:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
总工作量 = 数据源数量 + AI 数量
= 3 + 3 = 6 次标准适配
数据源方(Server):
└─ GitHub 实现一个 MCP Server
└─ Slack 实现一个 MCP Server
└─ DB 实现一个 MCP Server
AI 方(Client):
└─ Claude 学会 MCP 协议
└─ Cursor 学会 MCP 协议
└─ Dify 学会 MCP 协议
结果:任何组合都能自动工作
理解”解耦”的价值
MCP 出现前的紧耦合
假设你开发了一个 AI 助手来查看 GitHub 仓库:
1
2
3
4
5
6
7
8
9
// 你的 AI 应用代码(紧耦合)
func fetchGitHubData() {
// GitHub API 的细节被硬编码在这里
response := http.Get("https://github.com/api/v3/repos/...")
// 特定的鉴权方式
req.Header.Set("Authorization", "token " + token)
// 特定的数据解析逻辑
data := response.JSON["items"][0]["message"]
}
后果:
- 你的 AI 软件和 GitHub 绑死了
- 如果 GitHub 改了接口 → 你的 AI 软件就挂了
- 如果你想换成 GitLab → 代码得完全重写
MCP 如何解耦
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
┌─────────────────────────────────────────────────┐
│ AI 客户端 │
│ (Claude Desktop / Cursor / Dify) │
│ └─ 只说"普通话"(标准 MCP 指令) │
└─────────────┬───────────────────────────────────┘
│ (标准 MCP 协议)
│
┌─────────────▼───────────────────────────────────┐
│ MCP Server(翻译官) │
│ ┌──────────────────────────────────────────┐ │
│ │ 左侧:听 AI 说普通话 │ │
│ │ 右侧:跟 GitHub 说"方言" │ │
│ │ 作用:隔离变化,防止数据源变动影响客户端 │ │
│ └──────────────────────────────────────────┘ │
└─────────────┬───────────────────────────────────┘
│ (GitHub 特定 API)
│
┌─────────────▼───────────────────────────────────┐
│ GitHub API(数据源) │
└─────────────────────────────────────────────────┘
| 维度 | 前 | 后 |
|---|---|---|
| 耦合方式 | 点对点紧耦合 | 通过标准协议解耦 |
| 变化隔离 | GitHub 改 API → AI 挂了 | GitHub 改 API → 只改 Server |
| AI 端影响 | 需要改代码 | 无需改代码 |
| 防腐效果 | ❌ 无防护 | ✅ 完全隔离 |
维护成本对比
场景:GitHub 修改了底层 API
旧模式(没有 MCP):
1
2
3
4
5
6
7
GitHub API 变更通知 ↓
Claude Desktop 里的连接器 → 坏了 → 需要修 1 次
Cursor 编辑器 里的插件 → 坏了 → 需要修 1 次
Dify 平台 里的模块 → 坏了 → 需要修 1 次
总修改次数:3 次
维护成本:高
新模式(有 MCP):
1
2
3
4
5
6
7
8
GitHub API 变更通知 ↓
git-mcp-server 代码 → 修改 1 处
↓
所有 AI 客户端自动获得修复
总修改次数:1 次
维护成本:✅ 低
所有客户端是否需要改代码?❌ 都不需要
三大原语
MCP 定义了三种原语来实现标准化对话:
1
2
3
Resources (资源) ──→ 被动读取数据,提供上下文(看)
Tools (工具) ──→ 主动执行操作,改变状态(做)
Prompts (提示词) ──→ 预定义交互模板(想)
Resources
作用:被动获取信息
但它在服务端不必是静态的
MCP 的 Resource 支持 resource templates(资源模板)
例如:postgres://tables/{table_name}/schema
这意味着 Client 请求 Resource 时,Server 端是可以运行一段代码(比如查询数据库 Schema)并动态返回结果的
所以 Resource 不仅仅是“读文件”,它是“无副作用的动态获取”
这点在设计时非常重要,因为它意味着 Resource 的获取也可能有延迟(数据库查询时间)
虽然没有 LLM 思考的延迟,但系统侧延迟依然存在
特征: ✓ 只读,不改变状态
✓ 提供上下文背景
✓ 可以被多次访问
✓ 像 RAG(检索增强生成)的数据源
| 场景 | 描述 | 类型 |
|---|---|---|
| 代码审查 | 读取 main.go 的当前内容 | ✅ Resources |
| 查看日志 | 读取 error.log 找出错误 | ✅ Resources |
| 实时数据 | 查看冰箱当前温度 (5℃) | ✅ Resources |
| 数据库结构 | 了解表的当前字段 | ✅ Resources |
Tools
作用:主动执行操作,改变系统状态
特征: ✓ 改变状态
✓ 执行具体操作
✓ 可能有返回值或副作用
| 场景 | 描述 | 类型 |
|---|---|---|
| 删除数据 | 删除一条错误的测试数据 | ✅ Tools |
| 调节温度 | 调节冰箱温度从 5℃ 到 -18℃ | ✅ Tools |
| 提交代码 | 执行 git commit 操作 | ✅ Tools |
| 写入数据库 | 新增或修改数据库记录 | ✅ Tools |
Prompts
作用:预定义的交互模板
特征:Server 端维护,Client 端调用
为什么需要 Prompts 原语
问题:如果没有 MCP Prompts,当你想让多个 AI 客户端使用同一个复杂的提示词时会发生什么?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
❌ 没有 MCP Prompts 的情况(Copy-Paste)
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
你维护一段 2000 字的"安全扫描提示词",需要分发给 3 个同事:
同事 A (Dify):复制粘贴了提示词
同事 B (VS Code):复制粘贴了,但觉得自己很懂,偷偷改了两句
同事 C (Claude Desktop):复制粘贴了,但漏了一段关键内容
后来你发现提示词有 Bug,需要修复:
├─ 同事 A:听话,修改了 ✓
├─ 同事 B:觉得你的修改不如他的好,拒绝修改 ✗ 版本冲突
└─ 同事 C:没看邮件,还在用旧版本 ✗ 版本滞后
结果:三份代码,三个版本,无法控制!
✅ 有了 MCP Prompts 的情况(在线公告栏)
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
你把那段 2000 字的提示词写在 MCP Server 的代码里:
同事 A, B, C:他们的客户端里不保存那 2000 字
他们只有一个按钮:"调用安全扫描"
执行过程:
1. 同事点击按钮
2. 客户端向 MCP Server 发送请求
3. MCP Server 实时返回那段 2000 字 + 参数填充
4. 大模型接收完整指令,直接生成
你想修改 Bug?
└─ 只需改 Server 代码一处
└─ 下一秒,所有客户端都自动用新版本
└─ 他们甚至都不知道你改了
效果:单一事实来源,强制同步,无法篡改!
性能对比表
| MCP 原语 | 机制 | LLM 是否需要额外思考? | 耗时增加 |
|---|---|---|---|
| Prompts | 文本预处理/拼接 | ❌ No(发送前已完成) | 🟢 极低(仅网络传输) |
| Tools | 函数调用 (Function Calling) | ✅ Yes(需判断何时调用) | 🟡 中(多一轮交互) |
| Resources | 上下文挂载 (RAG) | ❌ No(作为背景知识预加载) | 🟢 极低(仅数据加载) |
三大原语的关系与组合
1
2
3
4
5
6
7
8
9
10
11
12
13
14
┌──────────────────────────────────────────────────────┐
│ MCP 三原语的协作方式
├──────────────────────────────────────────────────────┤
│
│ Resources (看) ──┐
│ ├─→ AI 思考 ──→ Tools (做)
│ Prompts (想) ────┘
│
│ 工作流程:
│ 1. 先观察(获取 Resources 的背景信息)
│ 2. 再思考(根据 Prompts 的指导和 Query)
│ 3. 后行动(调用 Tools 执行操作)
│
└──────────────────────────────────────────────────────┘