MCP(Model Context Protocol)详解
一句话总结
MCP 是 AI 和外部工具之间的"万能插头"------一个统一的连接标准。

1. 为什么需要 MCP?
1.1 没有 MCP 的世界
想象一下,AI 模型就像一个很聪明但"手很短"的人:
- 它只能"说话",不能动手做事
- 它读不了你电脑上的文件
- 它查不了数据库
- 它调不了外部 API
- 它搜不了网页
所以我们需要给 AI 接上各种"工具",让它能真正干活。
1.2 以前的痛点
在没有统一协议之前,每给 AI 接一个工具,就要写一套专门的对接代码:
AI ←→ 专用代码 ←→ 文件系统
AI ←→ 专用代码 ←→ 数据库
AI ←→ 专用代码 ←→ GitHub
AI ←→ 专用代码 ←→ 搜索引擎
这就像 USB 出现之前的情况:
| 设备 | 接口 |
|---|---|
| 鼠标 | PS/2 圆口 |
| 键盘 | PS/2 圆口 |
| 打印机 | 并口 LPT |
| 调制解调器 | 串口 COM |
每个设备一个专用接口,适配成本极高。
1.3 MCP 带来的改变
MCP 定义了一个统一标准,就像 USB 一样:
AI ←→ MCP 协议(统一标准) ←→ 文件系统
←→ 数据库
←→ GitHub
←→ 搜索引擎
只要工具按照 MCP 规范实现,AI 就能直接使用,不需要逐个对接。
2. MCP 的三个核心角色
2.1 角色概览
arduino
┌──────────┐ ┌──────────┐ ┌──────────┐
│ Host │────→│ Client │────→│ Server │
│ 宿主程序 │ │ 客户端 │ │ 工具服务 │
└──────────┘ └──────────┘ └──────────┘
比如: 比如: 比如:
Claude Code 内置的连接器 文件读取服务
Claude Desktop 数据库服务
GitHub 服务
2.2 各角色详解
| 角色 | 比喻 | 说明 | 举例 |
|---|---|---|---|
| Host(宿主) | 电脑主机 | 运行 AI 的应用程序,是整个体系的入口 | Claude Code、Claude Desktop、Cursor |
| Client(客户端) | USB 控制器 | 内嵌在 Host 中,负责按 MCP 协议和 Server 通信 | Host 内部自动管理,用户无需关心 |
| Server(服务器) | USB 设备 | 提供具体能力的工具服务,按 MCP 规范暴露能力 | 文件系统 Server、数据库 Server、GitHub Server |
2.3 它们怎么协作?
arduino
你:帮我读一下 config.json 的内容
│
▼
Host(Claude Code)
收到你的请求,发现需要读文件
│
▼
Client(内置)
按 MCP 协议,向文件系统 Server 发出请求:
"请读取 config.json"
│
▼
Server(文件系统 MCP Server)
实际去读文件,把内容返回给 Client
│
▼
Client 把结果交回 Host
│
▼
AI 拿到文件内容,回答你的问题
关键点:一个 Host 可以同时连接多个 Server,就像一台电脑可以插多个 USB 设备。
3. MCP Server 能提供什么能力?
3.1 三种核心能力
MCP Server 可以向 AI 暴露三种类型的能力:
| 能力类型 | 英文 | 说明 | 举例 |
|---|---|---|---|
| 工具 | Tools | AI 可以调用的函数/操作 | 读文件、查数据库、发 HTTP 请求 |
| 资源 | Resources | AI 可以读取的数据 | 文件内容、数据库记录、API 响应 |
| 提示 | Prompts | 预定义的提示模板 | "代码审查模板"、"翻译模板" |
3.2 实际例子
假设你配置了以下 MCP Server:
vbscript
Claude Code(Host)
├── filesystem-server → 可以读写本地文件
├── github-server → 可以操作 GitHub(创建 PR、查看 Issue)
├── postgres-server → 可以查询 PostgreSQL 数据库
└── web-search-server → 可以搜索互联网
然后你对 Claude 说:
"帮我在 GitHub 上创建一个 PR,把最近的改动合并到 main 分支"
Claude 会:
- 用 filesystem-server 读取本地代码变更
- 用 github-server 创建 Pull Request
- 把结果告诉你
整个过程你不需要手动操作,AI 通过 MCP 自主完成。
4. MCP 协议的技术细节
4.1 通信方式
MCP 使用 JSON-RPC 2.0 作为消息格式,通信方式有两种:
| 方式 | 说明 | 适用场景 |
|---|---|---|
| stdio(标准输入输出) | Server 作为子进程运行,通过 stdin/stdout 通信 | 本地工具,最常用 |
| SSE(Server-Sent Events) | 通过 HTTP 通信 | 远程工具服务 |
4.2 消息类型
arduino
Client → Server Server → Client
─────────────── ────────────────
request(请求) response(响应)
notification(通知,不需要回复) notification(通知)
4.3 一次典型的交互流程
json
// 1. Client 请求:列出你有哪些工具?
→ {"method": "tools/list"}
// 2. Server 响应:我有这些工具
← {"tools": [
{"name": "read_file", "description": "读取文件内容"},
{"name": "write_file", "description": "写入文件"}
]}
// 3. Client 请求:帮我调用 read_file
→ {"method": "tools/call", "params": {
"name": "read_file",
"arguments": {"path": "/tmp/config.json"}
}}
// 4. Server 响应:文件内容是...
← {"content": [{"type": "text", "text": "{\n \"port\": 3000\n}"}]}
4.4 生命周期
arduino
初始化(Initialize)
│
▼
能力协商(Capabilities Exchange)
- Host 告诉 Server:"我支持哪些能力"
- Server 告诉 Host:"我能提供哪些工具/资源"
│
▼
正常运行(Normal Operation)
- 请求/响应
- 通知
│
▼
关闭(Shutdown)
5. 如何配置 MCP Server?
5.1 在 Claude Code 中配置
编辑 .claude/settings.json:
json
{
"mcpServers": {
"filesystem": {
"command": "npx",
"args": ["-y", "@modelcontextprotocol/server-filesystem", "/path/to/allowed/dir"]
},
"github": {
"command": "npx",
"args": ["-y", "@modelcontextprotocol/server-github"],
"env": {
"GITHUB_PERSONAL_ACCESS_TOKEN": "your-token-here"
}
}
}
}
5.2 配置字段说明
| 字段 | 说明 | 举例 |
|---|---|---|
command |
启动 Server 的命令 | npx、python、node |
args |
命令参数 | ["-y", "@modelcontextprotocol/server-filesystem"] |
env |
环境变量(如 API Key) | {"GITHUB_TOKEN": "xxx"} |
5.3 常用 MCP Server 一览
| Server | 功能 | 安装命令 |
|---|---|---|
| filesystem | 读写本地文件 | npx @modelcontextprotocol/server-filesystem |
| github | 操作 GitHub | npx @modelcontextprotocol/server-github |
| postgres | 查询 PostgreSQL | npx @modelcontextprotocol/server-postgres |
| sqlite | 查询 SQLite | npx @modelcontextprotocol/server-sqlite |
| brave-search | 搜索互联网 | npx @modelcontextprotocol/server-brave-search |
| puppeteer | 控制浏览器 | npx @modelcontextprotocol/server-puppeteer |
6. 自己写一个 MCP Server
6.1 最简示例(Python)
python
from mcp.server.fastmcp import FastMCP
# 创建一个 MCP Server
mcp = FastMCP("我的工具箱")
# 定义一个工具
@mcp.tool()
def add(a: int, b: int) -> int:
"""两数相加"""
return a + b
# 定义一个资源
@mcp.resource("config://app")
def get_config() -> str:
"""获取应用配置"""
return '{"theme": "dark", "language": "zh"}'
# 启动 Server
mcp.run()
6.2 最简示例(TypeScript)
typescript
import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
const server = new McpServer({ name: "我的工具箱", version: "1.0.0" });
// 定义一个工具
server.tool("add", "两数相加", { a: z.number(), b: z.number() }, async ({ a, b }) => ({
content: [{ type: "text", text: String(a + b) }],
}));
// 启动
const transport = new StdioServerTransport();
await server.connect(transport);
6.3 开发步骤总结
markdown
1. 安装 SDK
npm install @modelcontextprotocol/sdk
或 pip install mcp
2. 创建 Server 实例
3. 注册工具(@mcp.tool() / server.tool())
4. 注册资源(@mcp.resource() / server.resource())
5. 选择通信方式(stdio 最常用)
6. 启动运行
7. 在 Claude Code 中配置使用
7. MCP vs Function Calling vs Skill
这是最容易混淆的三个概念,下面逐一拆解。
7.1 三者是什么?
| 概念 | 一句话 | 谁定义的 |
|---|---|---|
| Function Calling | AI 调用函数的"格式约定" | OpenAI 首先提出,各家跟进 |
| Skill | AI 内置的"技能包" | 由宿主程序(如 Claude Code)定义 |
| MCP | AI 连接外部工具的"通信协议" | Anthropic 提出,开放标准 |
7.2 用一个生活类比
假设 AI 是一个厨师:
| 概念 | 类比 | 说明 |
|---|---|---|
| Function Calling | 厨师知道"怎么点菜" | 厨师能说出"我要西红柿、鸡蛋",但东西还得你去拿 |
| Skill | 厨师自带的"拿手菜" | 厨师天生就会做红烧肉,不需要额外工具 |
| MCP | 厨房的标准接口 | 冰箱、烤箱、搅拌机都有标准插口,插上就能用 |
7.3 Function Calling 详解
本质:AI 输出一段结构化 JSON,告诉调用方"我想调用哪个函数、传什么参数"。
javascript
你:今天北京天气怎么样?
AI 内部思考:我需要调用 get_weather 函数
AI 输出:
{
"name": "get_weather",
"arguments": { "city": "北京" }
}
你的代码:收到这段 JSON → 真的去调 API → 把结果返回给 AI
AI:北京今天晴,25°C
关键点:
- Function Calling 不是 AI 真的执行了函数
- AI 只是"说"了要调什么,你的代码负责真正去执行
- 它是一种 输入输出格式约定,不是通信协议
- 绑定在特定厂商的 API 上(OpenAI 的格式 ≠ Anthropic 的格式)
7.4 Skill 详解
本质:宿主程序内置的"预定义能力",AI 可以直接调用。
swift
你:帮我初始化一个新项目
Claude Code 内部:
- 识别出这是一个 init 任务
- 调用内置的 "init" Skill
- Skill 执行:扫描代码库 → 生成 CLAUDE.md → 完成
关键点:
- Skill 是 宿主程序写死的,用户不能随意添加
- 它是 AI 应用层面的概念,不是协议
- 类似手机出厂预装的 App,你不能自己装新的
- 不同的 AI 应用有不同的 Skill(Claude Code 的 Skill ≠ Cursor 的)
7.5 MCP 详解(对比视角)
本质:一个开放的通信协议,让 AI 能连接任何按标准实现的外部工具。
vbscript
你:帮我查一下数据库里有多少用户
Claude Code(Host):
→ MCP Client 向 postgres-server 发请求
→ postgres-server 执行 SQL
→ 返回结果:1000 个用户
→ AI 回答你
关键点:
- MCP 是 协议,不是具体实现
- 谁都可以按 MCP 规范写 Server
- 跨厂商、跨框架、跨语言
- 用户可以自由添加/删除 Server
7.6 核心区别对比表
| 对比项 | Function Calling | Skill | MCP |
|---|---|---|---|
| 是什么 | AI 输出的格式约定 | 宿主程序内置的能力 | 通信协议 |
| 谁来执行 | 你的代码 | 宿主程序 | 独立的 Server 进程 |
| 谁定义 | AI 厂商(OpenAI 等) | 宿主程序开发者 | 开放标准(Anthropic 发起) |
| 能否扩展 | 改代码才能加新函数 | 改宿主程序才能加新 Skill | 装个新 Server 就行 |
| 跨厂商 | 不行,格式各不同 | 不行,各应用不同 | 行,标准统一 |
| 运行位置 | 在你的代码里 | 在宿主程序里 | 独立进程 |
| 类比 | 点菜用的菜单格式 | 餐厅的招牌菜 | 厨房的标准接口 |
7.7 它们之间的关系
这三个概念不是互斥的,而是不同层面的东西:
scss
┌─────────────────────────────────────────┐
│ AI 应用(如 Claude Code) │
│ │
│ ┌─────────┐ ┌─────────┐ ┌────────┐ │
│ │ Skill │ │ Skill │ │ Skill │ │ ← 内置技能
│ │ (init) │ │ (review)│ │ (run) │ │
│ └─────────┘ └─────────┘ └────────┘ │
│ │
│ ┌──────────────────────────────────┐ │
│ │ MCP Client │ │ ← 通过 MCP 协议
│ │ ┌──────┐ ┌──────┐ ┌──────┐ │ │ 连接外部工具
│ │ │Server│ │Server│ │Server│ │ │
│ │ │(文件) │ │(数据库)│ │(搜索) │ │ │
│ │ └──────┘ └──────┘ └──────┘ │ │
│ └──────────────────────────────────┘ │
│ │
│ ┌──────────────────────────────────┐ │
│ │ Function Calling │ │ ← AI 决定调用什么
│ │ (AI 输出:我要调 read_file) │ │ 的格式约定
│ └──────────────────────────────────┘ │
└─────────────────────────────────────────┘
简单来说:
- Function Calling 是 AI "怎么表达想调什么"的格式
- Skill 是宿主程序"出厂自带"的能力
- MCP 是 AI "连接外部工具"的通道
7.8 什么时候用什么?
| 场景 | 用什么 | 原因 |
|---|---|---|
| 开发 AI 应用,让 AI 能调你的 API | Function Calling | 最简单直接,控制权在你手里 |
| 给 Claude Code 加新能力 | MCP | 配置一个 Server 就行,不用改 Claude Code |
| 用 Claude Code 做代码审查 | Skill(内置) | review 是内置 Skill,直接用 |
| 让 AI 同时连数据库 + 文件系统 + 搜索引擎 | MCP | 一个协议统一搞定,不用写三套对接 |
| 快速给 ChatGPT 加一个工具 | Function Calling | OpenAI 生态内最方便 |
9. 安全性
9.1 MCP 的安全设计
| 机制 | 说明 |
|---|---|
| 权限控制 | 用户可以决定哪些 Server 能用、哪些工具能调用 |
| 沙箱隔离 | Server 运行在独立进程中,不直接访问 Host 内存 |
| 路径限制 | 文件系统 Server 可以限制只能访问特定目录 |
| 环境变量 | 敏感信息(如 API Key)通过 env 注入,不硬编码 |
| 用户确认 | 危险操作前,Host 会弹出确认提示 |
9.2 安全建议
- 只安装信任的 MCP Server
- 仔细检查 Server 的源代码
- 限制文件系统 Server 的可访问目录
- 不要把 API Key 直接写在配置文件中,用环境变量
- 定期审查已安装的 Server 和其权限
10. 完整类比总结
| 概念 | USB 的世界 | MCP 的世界 |
|---|---|---|
| 协议标准 | USB 规范 | MCP 协议 |
| 主机 | 电脑 | Host(Claude Code 等) |
| 控制器 | USB 控制器 | Client |
| 设备 | U盘、鼠标、键盘 | Server(文件、数据库、API) |
| 插上设备 | 插入 USB | 配置 MCP Server |
| 枚举设备 | 系统识别设备 | tools/list、resources/list |
| 使用设备 | 读写 U盘 | tools/call |
| 驱动程序 | 设备驱动 | Server 实现 |
11. 一句话总结
MCP = AI 的 USB 接口
它定义了一个开放标准,让任何 AI 模型都能用统一的方式连接任何工具,
不再需要为每个工具写专门的对接代码。
对开发者来说:写一次 Server,所有支持 MCP 的 AI 都能用。
对用户来说:装一个 Server,AI 立刻多一种能力。