前言:大模型的"残疾"困境
2024 年底,你用 Claude、GPT、DeepSeek 聊天,感觉它们无所不知。
但你让它帮你:
- 查一下今天的天气 → "我无法访问实时数据"
- 读一下这个文件 → "我看不到你的本地文件"
- 帮我发个邮件 → "我没有权限操作你的邮箱"
- 查一下我的日程 → "我无法访问你的日历"
大模型是个"聪明的残疾人"——大脑很强,但没有手脚。
于是,Anthropic(Claude 的公司)在 2024 年 11 月发布了 MCP(Model Context Protocol,模型上下文协议)。
这是一个开放协议,目标是:给大模型一个标准化的方式来连接外部世界。
一、MCP 是什么?
1.1 一句话定义
MCP = 大模型的 USB 接口
就像 USB 让各种设备(键盘、鼠标、U盘)可以用统一的方式连接电脑,MCP 让各种工具和数据源可以用统一的方式连接大模型。
1.2 MCP 的核心架构
三个核心角色:
| 角色 | 说明 | 例子 |
|---|---|---|
| Host(宿主) | 运行大模型的应用 | Claude Desktop、Cursor、Trae、VS Code |
| Client(客户端) | Host 内部的连接管理器 | 每个 Server 对应一个 Client |
| Server(服务端) | 提供具体能力的程序 | 文件系统、GitHub、数据库、API |
1.3 MCP Server 提供的三种能力
1. Tools(工具):让大模型"做事"
{
"name": "send_email",
"description": "发送电子邮件",
"parameters": {
"to": "收件人邮箱",
"subject": "邮件主题",
"body": "邮件内容"
}
}2. Resources(资源):让大模型"看到"数据
{
"uri": "file:///Users/joey/documents/report.pdf",
"name": "季度报告",
"mimeType": "application/pdf"
}3. Prompts(提示词):预设的交互模板
{
"name": "code_review",
"description": "代码审查模板",
"arguments": ["language", "code"]
}1.4 为什么需要 MCP?
在 MCP 之前,每个应用都要自己实现"工具调用":
每个 AI 应用都要为每个工具开发专门的插件,重复造轮子!
有了 MCP:
一次开发,处处可用!
二、MCP 生态现状
2.1 支持 MCP 的客户端
| 客户端 | 类型 | MCP 支持 | 备注 |
|---|---|---|---|
| Claude Desktop | 官方客户端 | ✅ 完整支持 | Anthropic 官方 |
| Cursor | AI IDE | ✅ 完整支持 | 开发者首选 |
| Trae | AI IDE | ✅ 完整支持 | 字节跳动出品,国内友好 |
| Windsurf | AI IDE | ✅ 完整支持 | Codeium 出品 |
| VS Code + Copilot | IDE | ✅ Agent 模式 | 微软官方 |
| Continue | IDE 插件 | ✅ 支持 | 开源 |
| Cline | VS Code 插件 | ✅ 支持 | 开源 |
2.2 官方和社区 MCP Server
官方维护的 Server(Anthropic 出品):
| Server | 功能 |
|---|---|
@modelcontextprotocol/server-filesystem | 文件读写 |
@modelcontextprotocol/server-github | GitHub 操作 |
@modelcontextprotocol/server-postgres | PostgreSQL 数据库 |
@modelcontextprotocol/server-sqlite | SQLite 数据库 |
@modelcontextprotocol/server-puppeteer | 浏览器自动化 |
@modelcontextprotocol/server-brave-search | Brave 搜索 |
社区热门 Server:
| Server | 功能 | 地址 |
|---|---|---|
mcp-server-fetch | HTTP 请求 | 官方 |
mcp-obsidian | Obsidian 笔记 | 社区 |
mcp-notion | Notion 集成 | 社区 |
mcp-docker | Docker 管理 | 社区 |
mcp-mysql | MySQL 数据库 | 社区 |
三、实战:在国产 IDE 中使用 MCP
3.1 Trae 配置 MCP(推荐国内用户)
Trae 是字节跳动推出的 AI IDE,对国内用户非常友好,内置了豆包大模型,也支持 DeepSeek、Claude 等。
Step 1: 安装 Trae
从官网下载安装:https://www.trae.ai/
Step 2: 配置 MCP Server
打开 Trae 设置,找到 MCP 配置文件(类似 Claude Desktop 的配置方式):
{
"mcpServers": {
"filesystem": {
"command": "npx",
"args": [
"-y",
"@modelcontextprotocol/server-filesystem",
"/Users/joey/projects",
"/Users/joey/documents"
]
},
"github": {
"command": "npx",
"args": ["-y", "@modelcontextprotocol/server-github"],
"env": {
"GITHUB_PERSONAL_ACCESS_TOKEN": "ghp_xxxxxxxxxxxx"
}
}
}
}Step 3: 使用 MCP 工具
在对话中,Trae 会自动识别你的意图并调用相应的 MCP 工具:
用户: 帮我看看 /Users/joey/projects/my-app 目录下有哪些文件
Trae: [调用 filesystem.list_directory]
该目录下有以下文件:
- src/
- package.json
- README.md
- tsconfig.json
...3.2 Claude Desktop 配置 MCP
Step 1: 安装 Claude Desktop
从官网下载:https://claude.ai/download
Step 2: 找到配置文件
- macOS:
~/Library/Application Support/Claude/claude_desktop_config.json - Windows:
%APPDATA%\Claude\claude_desktop_config.json
Step 3: 编辑配置
{
"mcpServers": {
"filesystem": {
"command": "npx",
"args": [
"-y",
"@modelcontextprotocol/server-filesystem",
"/Users/joey/allowed-directory"
]
},
"sqlite": {
"command": "npx",
"args": [
"-y",
"@modelcontextprotocol/server-sqlite",
"--db-path",
"/Users/joey/data/mydb.sqlite"
]
},
"fetch": {
"command": "npx",
"args": ["-y", "@modelcontextprotocol/server-fetch"]
}
}
}Step 4: 重启 Claude Desktop
重启后,在对话框右下角会看到 🔌 图标,表示 MCP 已连接。
3.3 Cursor 配置 MCP
Cursor 从 v0.45 开始支持 MCP。
配置文件位置:
- macOS:
~/.cursor/mcp.json - Windows:
%USERPROFILE%\.cursor\mcp.json
{
"mcpServers": {
"filesystem": {
"command": "npx",
"args": [
"-y",
"@modelcontextprotocol/server-filesystem",
"/path/to/allowed/directory"
]
}
}
}3.4 使用 DeepSeek + MCP
DeepSeek 本身不直接支持 MCP,但可以通过以下方式使用:
方案 1:在 Trae 中使用 DeepSeek
Trae 支持配置 DeepSeek 作为后端模型,同时使用 MCP Server:
{
"model": "deepseek-chat",
"apiKey": "sk-xxxxxxxx",
"baseUrl": "https://api.deepseek.com/v1"
}方案 2:在 Cline 中使用 DeepSeek + MCP
Cline 是 VS Code 的 AI 插件,支持自定义模型和 MCP:
- 安装 Cline 插件
- 配置 DeepSeek API
- 配置 MCP Server
// .vscode/mcp.json
{
"servers": {
"filesystem": {
"command": "npx",
"args": ["-y", "@modelcontextprotocol/server-filesystem", "."]
}
}
}方案 3:使用 Cherry Studio
Cherry Studio 是一个支持多模型的桌面客户端,支持 DeepSeek 和 MCP:
- 下载 Cherry Studio
- 添加 DeepSeek API
- 配置 MCP Server
四、开发自己的 MCP Server
4.1 MCP Server 的基本结构
4.2 用 Python 开发 MCP Server
#!/usr/bin/env python3
"""
一个简单的 MCP Server 示例:天气查询
"""
import asyncio
import json
import httpx
from mcp.server import Server
from mcp.server.stdio import stdio_server
from mcp.types import Tool, TextContent
# 创建 Server 实例
server = Server("weather-server")
# 定义工具
@server.list_tools()
async def list_tools():
"""列出所有可用的工具"""
return [
Tool(
name="get_weather",
description="获取指定城市的天气信息",
inputSchema={
"type": "object",
"properties": {
"city": {
"type": "string",
"description": "城市名称,如 '北京'、'上海'"
}
},
"required": ["city"]
}
),
Tool(
name="get_forecast",
description="获取指定城市未来几天的天气预报",
inputSchema={
"type": "object",
"properties": {
"city": {
"type": "string",
"description": "城市名称"
},
"days": {
"type": "integer",
"description": "预报天数,1-7",
"default": 3
}
},
"required": ["city"]
}
)
]
# 处理工具调用
@server.call_tool()
async def call_tool(name: str, arguments: dict):
"""处理工具调用请求"""
if name == "get_weather":
city = arguments["city"]
# 这里应该调用真实的天气 API
# 为了演示,返回模拟数据
weather_data = await fetch_weather(city)
return [TextContent(
type="text",
text=json.dumps(weather_data, ensure_ascii=False, indent=2)
)]
elif name == "get_forecast":
city = arguments["city"]
days = arguments.get("days", 3)
forecast_data = await fetch_forecast(city, days)
return [TextContent(
type="text",
text=json.dumps(forecast_data, ensure_ascii=False, indent=2)
)]
else:
raise ValueError(f"未知工具: {name}")
async def fetch_weather(city: str) -> dict:
"""获取天气数据(示例)"""
# 实际应该调用天气 API,如和风天气、心知天气等
# 这里返回模拟数据
return {
"city": city,
"temperature": "25°C",
"weather": "晴",
"humidity": "45%",
"wind": "东南风 3级",
"aqi": 35,
"update_time": "2025-02-25 10:00"
}
async def fetch_forecast(city: str, days: int) -> dict:
"""获取天气预报(示例)"""
forecasts = []
for i in range(days):
forecasts.append({
"date": f"2025-02-{25+i}",
"weather": ["晴", "多云", "小雨"][i % 3],
"temp_high": f"{25-i}°C",
"temp_low": f"{15-i}°C"
})
return {
"city": city,
"forecasts": forecasts
}
async def main():
"""主函数:启动 MCP Server"""
async with stdio_server() as (read_stream, write_stream):
await server.run(
read_stream,
write_stream,
server.create_initialization_options()
)
if __name__ == "__main__":
asyncio.run(main())4.3 用 TypeScript 开发 MCP Server
#!/usr/bin/env node
/**
* 一个简单的 MCP Server 示例:文件操作
*/
import { Server } from "@modelcontextprotocol/sdk/server/index.js";
import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
import {
CallToolRequestSchema,
ListToolsRequestSchema,
ListResourcesRequestSchema,
ReadResourceRequestSchema,
} from "@modelcontextprotocol/sdk/types.js";
import * as fs from "fs/promises";
import * as path from "path";
// 创建 Server
const server = new Server(
{
name: "file-server",
version: "1.0.0",
},
{
capabilities: {
tools: {},
resources: {},
},
}
);
// 允许访问的目录
const ALLOWED_DIRECTORIES = [
"/Users/joey/projects",
"/Users/joey/documents"
];
// 检查路径是否在允许的目录内
function isPathAllowed(filePath: string): boolean {
const normalizedPath = path.normalize(filePath);
return ALLOWED_DIRECTORIES.some(dir =>
normalizedPath.startsWith(path.normalize(dir))
);
}
// 列出工具
server.setRequestHandler(ListToolsRequestSchema, async () => {
return {
tools: [
{
name: "read_file",
description: "读取文件内容",
inputSchema: {
type: "object",
properties: {
path: {
type: "string",
description: "文件路径"
}
},
required: ["path"]
}
},
{
name: "write_file",
description: "写入文件内容",
inputSchema: {
type: "object",
properties: {
path: {
type: "string",
description: "文件路径"
},
content: {
type: "string",
description: "文件内容"
}
},
required: ["path", "content"]
}
},
{
name: "list_directory",
description: "列出目录内容",
inputSchema: {
type: "object",
properties: {
path: {
type: "string",
description: "目录路径"
}
},
required: ["path"]
}
}
]
};
});
// 处理工具调用
server.setRequestHandler(CallToolRequestSchema, async (request) => {
const { name, arguments: args } = request.params;
switch (name) {
case "read_file": {
const filePath = args?.path as string;
if (!isPathAllowed(filePath)) {
throw new Error(`路径不在允许的目录内: ${filePath}`);
}
const content = await fs.readFile(filePath, "utf-8");
return {
content: [{ type: "text", text: content }]
};
}
case "write_file": {
const filePath = args?.path as string;
const content = args?.content as string;
if (!isPathAllowed(filePath)) {
throw new Error(`路径不在允许的目录内: ${filePath}`);
}
await fs.writeFile(filePath, content, "utf-8");
return {
content: [{ type: "text", text: `文件已写入: ${filePath}` }]
};
}
case "list_directory": {
const dirPath = args?.path as string;
if (!isPathAllowed(dirPath)) {
throw new Error(`路径不在允许的目录内: ${dirPath}`);
}
const entries = await fs.readdir(dirPath, { withFileTypes: true });
const result = entries.map(entry => ({
name: entry.name,
type: entry.isDirectory() ? "directory" : "file"
}));
return {
content: [{
type: "text",
text: JSON.stringify(result, null, 2)
}]
};
}
default:
throw new Error(`未知工具: ${name}`);
}
});
// 启动服务器
async function main() {
const transport = new StdioServerTransport();
await server.connect(transport);
console.error("File MCP Server 已启动");
}
main().catch(console.error);4.4 注册自定义 Server
package.json:
{
"name": "my-mcp-server",
"version": "1.0.0",
"type": "module",
"bin": {
"my-mcp-server": "./dist/index.js"
},
"scripts": {
"build": "tsc",
"start": "node dist/index.js"
},
"dependencies": {
"@modelcontextprotocol/sdk": "^1.0.0"
},
"devDependencies": {
"typescript": "^5.0.0"
}
}在客户端配置:
{
"mcpServers": {
"my-server": {
"command": "node",
"args": ["/path/to/my-mcp-server/dist/index.js"]
}
}
}五、MCP 工作流程详解
5.1 完整的请求流程
5.2 工具发现机制
5.3 多 Server 协作
六、实战案例
6.1 案例:智能文档助手
需求:让 AI 能够读取本地文档,回答相关问题。
配置:
{
"mcpServers": {
"docs": {
"command": "npx",
"args": [
"-y",
"@modelcontextprotocol/server-filesystem",
"/Users/joey/Documents/技术文档",
"/Users/joey/Documents/项目资料"
]
}
}
}使用场景:
用户: 帮我找一下上个月的技术方案文档,总结一下核心要点
AI: [调用 filesystem.list_directory]
[调用 filesystem.read_file]
我找到了《2025年1月技术方案.md》,以下是核心要点:
1. 系统架构采用微服务设计...
2. 数据库选型为 PostgreSQL...
...6.2 案例:GitHub 代码助手
配置:
{
"mcpServers": {
"github": {
"command": "npx",
"args": ["-y", "@modelcontextprotocol/server-github"],
"env": {
"GITHUB_PERSONAL_ACCESS_TOKEN": "ghp_xxxxxxxx"
}
}
}
}使用场景:
用户: 帮我看看 my-project 仓库最近有哪些 PR
AI: [调用 github.list_pull_requests]
最近的 Pull Requests:
1. #123 - feat: 添加用户认证功能 (待审核)
2. #122 - fix: 修复登录bug (已合并)
3. #121 - docs: 更新 README (已合并)6.3 案例:数据库查询助手
配置:
{
"mcpServers": {
"database": {
"command": "npx",
"args": [
"-y",
"@modelcontextprotocol/server-postgres"
],
"env": {
"POSTGRES_CONNECTION_STRING": "postgresql://user:pass@localhost:5432/mydb"
}
}
}
}使用场景:
用户: 查一下过去30天的订单总额
AI: [调用 postgres.query]
SELECT SUM(amount) FROM orders
WHERE created_at > NOW() - INTERVAL '30 days'
过去30天的订单总额为 ¥1,234,567.896.4 案例:n8n 工作流集成
如果你用 n8n 做自动化,可以开发一个 MCP Server 来调用 n8n 工作流:
# mcp_n8n_server.py
import httpx
from mcp.server import Server
from mcp.types import Tool, TextContent
server = Server("n8n-server")
N8N_BASE_URL = "http://localhost:5678"
N8N_API_KEY = "your-api-key"
@server.list_tools()
async def list_tools():
return [
Tool(
name="trigger_workflow",
description="触发 n8n 工作流",
inputSchema={
"type": "object",
"properties": {
"workflow_id": {
"type": "string",
"description": "工作流 ID"
},
"data": {
"type": "object",
"description": "传递给工作流的数据"
}
},
"required": ["workflow_id"]
}
),
Tool(
name="list_workflows",
description="列出所有 n8n 工作流",
inputSchema={"type": "object", "properties": {}}
)
]
@server.call_tool()
async def call_tool(name: str, arguments: dict):
async with httpx.AsyncClient() as client:
headers = {"X-N8N-API-KEY": N8N_API_KEY}
if name == "trigger_workflow":
workflow_id = arguments["workflow_id"]
data = arguments.get("data", {})
response = await client.post(
f"{N8N_BASE_URL}/api/v1/workflows/{workflow_id}/execute",
headers=headers,
json=data
)
return [TextContent(type="text", text=response.text)]
elif name == "list_workflows":
response = await client.get(
f"{N8N_BASE_URL}/api/v1/workflows",
headers=headers
)
return [TextContent(type="text", text=response.text)]七、MCP 安全最佳实践
7.1 安全风险
可能读取敏感文件] R2[命令执行
可能运行恶意命令] R3[网络请求
可能访问内网服务] R4[数据泄露
可能暴露敏感数据] end style R1 fill:#ff6b6b style R2 fill:#ff6b6b style R3 fill:#ff6b6b style R4 fill:#ff6b6b
7.2 安全建议
1. 最小权限原则
{
"mcpServers": {
"filesystem": {
"command": "npx",
"args": [
"-y",
"@modelcontextprotocol/server-filesystem",
"/Users/joey/safe-directory" // 只允许特定目录
]
}
}
}2. 环境变量保护
{
"mcpServers": {
"github": {
"command": "npx",
"args": ["-y", "@modelcontextprotocol/server-github"],
"env": {
"GITHUB_PERSONAL_ACCESS_TOKEN": "${GITHUB_TOKEN}" // 从环境变量读取
}
}
}
}3. 审计日志
在自定义 Server 中添加日志:
import logging
logging.basicConfig(level=logging.INFO)
logger = logging.getLogger("mcp-server")
@server.call_tool()
async def call_tool(name: str, arguments: dict):
logger.info(f"Tool called: {name}, args: {arguments}")
# ... 处理逻辑4. 输入验证
def validate_path(path: str) -> bool:
"""验证路径安全性"""
# 防止路径遍历攻击
normalized = os.path.normpath(path)
if ".." in normalized:
return False
# 检查是否在允许的目录内
return any(
normalized.startswith(allowed)
for allowed in ALLOWED_DIRECTORIES
)八、常见问题排查
8.1 Server 无法连接
症状:客户端显示 MCP Server 未连接
排查步骤:
# 1. 检查 Node.js 版本
node --version # 需要 >= 18
# 2. 手动运行 Server 测试
npx -y @modelcontextprotocol/server-filesystem /tmp
# 3. 检查配置文件语法
cat ~/Library/Application\ Support/Claude/claude_desktop_config.json | jq .
# 4. 查看日志
# macOS
tail -f ~/Library/Logs/Claude/mcp*.log
# Windows
type %APPDATA%\Claude\logs\mcp*.log8.2 工具调用失败
症状:AI 调用工具但返回错误
常见原因:
| 错误 | 原因 | 解决方案 |
|---|---|---|
Permission denied | 文件权限不足 | 检查目录权限 |
ENOENT | 文件不存在 | 检查路径是否正确 |
Connection refused | 外部服务不可用 | 检查服务状态 |
Invalid JSON | 返回格式错误 | 检查 Server 代码 |
8.3 性能问题
症状:工具调用很慢
优化建议:
# 1. 使用连接池
client = httpx.AsyncClient(
limits=httpx.Limits(max_connections=10)
)
# 2. 缓存结果
from functools import lru_cache
@lru_cache(maxsize=100)
def get_cached_data(key):
return fetch_data(key)
# 3. 异步处理
async def call_tool(name: str, arguments: dict):
tasks = [
fetch_data_a(),
fetch_data_b(),
]
results = await asyncio.gather(*tasks)九、MCP 的未来
9.1 发展趋势
9.2 与 Agent 的关系
MCP 是 Agent 能力的基础设施:
决策中心] Plan[规划器] Memory[记忆系统] MCP[MCP 工具层] end Brain --> Plan Plan --> MCP Memory --> Brain MCP --> T1[文件操作] MCP --> T2[代码执行] MCP --> T3[网络请求] MCP --> T4[数据库] style MCP fill:#4ecdc4
十、总结
MCP 核心要点
关键 Takeaway
- MCP 是大模型的"手脚":让 AI 能够真正"做事",而不只是"说话"
- 标准化是关键:一次开发 Server,所有支持 MCP 的客户端都能用
- 生态正在爆发:官方 + 社区 Server 越来越多
- 国产 IDE 支持良好:Trae 等对国内用户友好,可以配合豆包/DeepSeek 使用
- 安全不可忽视:最小权限、审计日志、输入验证
- Agent 的基础设施:MCP 是构建 AI Agent 的重要组成部分
适用场景
| 场景 | 推荐方案 |
|---|---|
| 个人开发者 | Claude Desktop + 官方 Server |
| 国内开发者 | Trae + DeepSeek/豆包 + MCP |
| 企业用户 | 自定义 Server + 安全审计 |
| Agent 开发 | MCP + LangChain/LangGraph |
下一步学习
- [ ] 深入学习 MCP SDK
- [ ] 开发自己的 MCP Server
- [ ] 探索 MCP + Agent 架构
- [ ] 关注 MCP 社区动态
参考资料
- MCP 官方文档 - 协议规范和指南
- MCP GitHub - 官方仓库
- Awesome MCP Servers - 社区 Server 列表
- Claude Desktop MCP - 官方客户端
- Trae - 字节跳动 AI IDE