一、MCP 是什么?
Model Context Protocol (MCP) 是 Anthropic 推出的开源标准协议 ,用于连接 AI 应用与外部系统。如果用一个形象的比喻,MCP 就像是 AI 应用的 USB-C 接口------提供了一个标准化的连接方式,让 AI 应用能够与各种数据源、工具和工作流无缝集成。
1.1 为什么需要 MCP?
当前 AI 应用面临的核心挑战:
- 信息孤岛问题:每个数据源都需要单独的集成方案
- 开发复杂度高:为每个 AI 应用构建定制化的数据连接器
- 缺乏标准化:不同厂商的集成方案互不兼容
- 上下文丢失:AI 在不同工具间切换时难以保持上下文连续性
MCP 通过提供统一的协议标准,将这些碎片化的集成方案替换为单一的标准协议,从根本上解决了这些问题。
二、核心架构设计
2.1 架构组件
MCP 采用经典的客户端-服务器架构,包含以下核心组件:
arduino
┌─────────────────┐
│ MCP Host │ ← AI 应用(如 Claude Desktop)
│ (协调者) │
└────────┬────────┘
│
├─── MCP Client 1 ──→ MCP Server A (数据库)
│
├─── MCP Client 2 ──→ MCP Server B (文件系统)
│
└─── MCP Client 3 ──→ MCP Server C (API 服务)
各组件职责:
- MCP Host:AI 应用本身,负责协调多个 MCP 客户端
- MCP Client:维护与 MCP 服务器的连接,处理协议通信
- MCP Server:提供具体的上下文数据和能力(工具、资源、提示)
2.2 协议设计
MCP 基于 JSON-RPC 2.0 构建,包含两个核心层:
数据层 (Protocol Layer)
- 定义通信协议格式
- 管理连接生命周期
- 处理能力协商机制
传输层 (Transport Layer)
- 管理通信信道
- 处理身份认证
- 支持多种传输方式:
- stdio:用于本地进程通信
- HTTP with SSE:用于远程服务器通信
- 可扩展支持 WebSocket 等其他传输方式
2.3 通信机制
MCP 是一个有状态协议,通信流程如下:
关键特性:
- 初始化握手建立连接
- 能力动态发现机制
- 支持实时通知更新
- 版本协商保证兼容性
三、三大核心原语
MCP 服务器可以向客户端提供三种类型的能力:
3.1 Resources(资源)
类似文件系统的只读数据源,供客户端读取。
典型应用场景:
- 数据库查询结果
- 本地文件内容
- API 响应数据
- 知识库文档
示例:
json
{
"uri": "file:///path/to/document.txt",
"name": "项目文档",
"mimeType": "text/plain",
"description": "项目需求文档"
}
3.2 Tools(工具)
LLM 可调用的可执行函数,实现具体操作。
典型应用场景:
- 数据库写操作
- API 调用
- 文件系统操作
- 计算任务
Python 实现示例:
python
from mcp.server.fastmcp import FastMCP
mcp = FastMCP("weather")
@mcp.tool()
async def get_weather(city: str, state: str) -> str:
"""获取指定城市的天气信息"""
# 实现天气查询逻辑
return f"{city}, {state} 的天气是晴天,温度 25°C"
3.3 Prompts(提示模板)
预编写的任务模板,用于标准化常见操作。
典型应用场景:
- 代码审查模板
- 文档生成模板
- 数据分析流程模板
- 问题诊断清单
示例:
json
{
"name": "code_review",
"description": "代码审查提示模板",
"arguments": [
{
"name": "language",
"description": "编程语言",
"required": true
}
]
}
四、实战:构建一个 MCP 服务器
让我们通过一个实际示例来理解如何构建 MCP 服务器。
4.1 Python 实现(使用 FastMCP)
python
from mcp.server.fastmcp import FastMCP
import sqlite3
# 初始化服务器
mcp = FastMCP("database-server")
@mcp.tool()
async def query_users(limit: int = 10) -> str:
"""查询用户列表"""
conn = sqlite3.connect('app.db')
cursor = conn.cursor()
cursor.execute('SELECT * FROM users LIMIT ?', (limit,))
results = cursor.fetchall()
conn.close()
return str(results)
@mcp.tool()
async def create_user(name: str, email: str) -> str:
"""创建新用户"""
conn = sqlite3.connect('app.db')
cursor = conn.cursor()
cursor.execute(
'INSERT INTO users (name, email) VALUES (?, ?)',
(name, email)
)
conn.commit()
user_id = cursor.lastrowid
conn.close()
return f"用户创建成功,ID: {user_id}"
# 启动服务器(使用 stdio 传输)
if __name__ == "__main__":
mcp.run()
4.2 TypeScript/Node.js 实现
typescript
import { Server } from "@modelcontextprotocol/sdk/server/index.js";
import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
const server = new Server(
{
name: "file-server",
version: "1.0.0",
},
{
capabilities: {
tools: {},
},
}
);
// 注册工具
server.setRequestHandler("tools/list", async () => {
return {
tools: [
{
name: "read_file",
description: "读取文件内容",
inputSchema: {
type: "object",
properties: {
path: {
type: "string",
description: "文件路径",
},
},
required: ["path"],
},
},
],
};
});
// 处理工具调用
server.setRequestHandler("tools/call", async (request) => {
if (request.params.name === "read_file") {
const fs = await import("fs/promises");
const content = await fs.readFile(request.params.arguments.path, "utf-8");
return {
content: [
{
type: "text",
text: content,
},
],
};
}
throw new Error("未知工具");
});
// 启动服务器
const transport = new StdioServerTransport();
await server.connect(transport);
4.3 最佳实践
- 日志处理:对于基于 stdio 的服务器,永远不要写入 stdout,使用 stderr 或文件日志
- 错误处理:实现完善的异常处理和错误信息返回
- 类型安全:使用类型提示和输入验证
- 文档完善:为每个工具提供清晰的描述和参数说明
- 安全控制:实现适当的访问控制和参数验证
五、构建 MCP 客户端
5.1 客户端职责
python
from anthropic import Anthropic
from mcp import ClientSession, StdioServerParameters
from mcp.client.stdio import stdio_client
class MCPClient:
def __init__(self):
self.anthropic = Anthropic()
self.session = None
async def connect_to_server(self, server_script_path: str):
"""连接到 MCP 服务器"""
server_params = StdioServerParameters(
command="python",
args=[server_script_path],
)
stdio_transport = await stdio_client(server_params)
self.stdio, self.write = stdio_transport
self.session = ClientSession(self.stdio, self.write)
await self.session.initialize()
async def process_query(self, query: str) -> str:
"""处理用户查询"""
# 获取可用工具
tools = await self.session.list_tools()
# 发送查询到 AI 模型
response = self.anthropic.messages.create(
model="claude-3-5-sonnet-20241022",
max_tokens=4096,
messages=[{"role": "user", "content": query}],
tools=[{
"name": tool.name,
"description": tool.description,
"input_schema": tool.inputSchema
} for tool in tools.tools]
)
# 处理工具调用
if response.stop_reason == "tool_use":
tool_results = []
for content in response.content:
if content.type == "tool_use":
result = await self.session.call_tool(
content.name,
content.input
)
tool_results.append({
"type": "tool_result",
"tool_use_id": content.id,
"content": result.content
})
# 将工具结果发送回 AI
final_response = self.anthropic.messages.create(
model="claude-3-5-sonnet-20241022",
max_tokens=4096,
messages=[
{"role": "user", "content": query},
{"role": "assistant", "content": response.content},
{"role": "user", "content": tool_results}
]
)
return final_response.content[0].text
return response.content[0].text
5.2 使用示例
python
async def main():
client = MCPClient()
# 连接到数据库服务器
await client.connect_to_server("database_server.py")
# 处理查询
result = await client.process_query(
"帮我创建一个名为张三,邮箱是zhangsan@example.com的用户"
)
print(result)
# 运行
import asyncio
asyncio.run(main())
六、生态系统与实际应用
6.1 官方参考服务器
Anthropic 提供了多个参考实现:
服务器 | 功能描述 |
---|---|
filesystem | 安全的文件系统操作,支持访问控制 |
git | Git 仓库读取、搜索和操作 |
github | GitHub API 集成,仓库和问题管理 |
fetch | Web 内容抓取和转换 |
memory | 基于知识图谱的持久化记忆系统 |
sequential-thinking | 动态问题解决的思维链 |
6.2 企业级应用
已集成 MCP 的公司和产品:
- Block:将 MCP 集成到支付和金融系统
- Apollo:GraphQL 开发平台集成
- Zed 、Replit 、Codeium 、Sourcegraph:代码编辑器和开发工具
- Microsoft:提供 Azure、Microsoft 365 等服务的 MCP 实现
6.3 社区生态
- 官方 SDK:Python, TypeScript, Kotlin, Java, C#, Ruby
- 社区驱动的注册中心 :modelcontextprotocol/registry
- 微软教程项目 :mcp-for-beginners 提供跨语言实战示例
七、MCP vs 传统方案
7.1 对比传统集成方式
维度 | 传统方式 | MCP 方式 |
---|---|---|
开发成本 | 每个数据源需单独实现 | 一次实现,到处复用 |
维护难度 | 多套代码分别维护 | 统一协议标准 |
扩展性 | 添加新数据源需重写集成 | 实现 MCP 服务器即可 |
互操作性 | 厂商方案互不兼容 | 开放标准,跨平台 |
上下文保持 | 工具切换丢失上下文 | 协议层保持状态 |
7.2 与 Function Calling 的关系
MCP 不是替代 Function Calling,而是更高层次的抽象:
- Function Calling:LLM 层面的工具调用机制
- MCP:应用层面的标准化连接协议
MCP 实际上是通过 Function Calling 来调用工具,但提供了:
- 标准化的工具描述格式
- 统一的连接和通信机制
- 可发现和可组合的能力系统
八、技术深入:协议细节
8.1 初始化流程
json
// 客户端请求
{
"jsonrpc": "2.0",
"id": 1,
"method": "initialize",
"params": {
"protocolVersion": "2024-11-05",
"capabilities": {
"roots": {
"listChanged": true
},
"sampling": {}
},
"clientInfo": {
"name": "ExampleClient",
"version": "1.0.0"
}
}
}
// 服务器响应
{
"jsonrpc": "2.0",
"id": 1,
"result": {
"protocolVersion": "2024-11-05",
"capabilities": {
"logging": {},
"prompts": {
"listChanged": true
},
"resources": {
"subscribe": true,
"listChanged": true
},
"tools": {
"listChanged": true
}
},
"serverInfo": {
"name": "ExampleServer",
"version": "1.0.0"
}
}
}
8.2 能力协商机制
MCP 使用能力声明来确定客户端和服务器支持的功能:
客户端可声明的能力:
roots
:支持项目根目录管理sampling
:支持 LLM 采样请求
服务器可声明的能力:
tools
:提供可调用工具resources
:提供数据资源prompts
:提供提示模板logging
:支持日志记录
8.3 通知机制
服务器可以主动向客户端推送变更通知:
json
{
"jsonrpc": "2.0",
"method": "notifications/resources/list_changed",
"params": {}
}
客户端收到通知后,可以重新获取资源列表以获得最新状态。
九、实战场景示例
9.1 场景一:个性化 AI 助手
需求:构建一个能访问用户日历、邮件和任务管理系统的 AI 助手
实现方案:
python
# calendar_server.py
@mcp.tool()
async def get_today_events() -> str:
"""获取今天的日程安排"""
# 连接 Google Calendar API
events = calendar_api.get_events(date=today)
return format_events(events)
@mcp.tool()
async def create_event(title: str, start_time: str, duration: int) -> str:
"""创建新的日程事件"""
event = calendar_api.create_event(title, start_time, duration)
return f"事件创建成功: {event.id}"
用户可以自然语言交互:
"今天下午有什么安排?帮我安排一个明天上午 10 点的会议"
9.2 场景二:代码生成工具
需求:AI 根据设计规范自动生成代码
实现方案:
python
# design_spec_server.py
@mcp.resource()
async def get_design_spec(component_name: str) -> str:
"""获取组件设计规范"""
spec = load_spec(component_name)
return spec.to_json()
@mcp.tool()
async def generate_component(spec: dict) -> str:
"""根据规范生成组件代码"""
code = code_generator.generate(spec)
return code
9.3 场景三:企业数据分析
需求:跨部门数据的统一分析
实现方案:
python
# Multi-server setup
servers = [
"sales_db_server", # 销售数据库
"hr_api_server", # 人力资源 API
"finance_server", # 财务系统
]
# AI 可以跨系统查询
query = """
分析一下上季度销售业绩与人员投入的关系,
并给出下季度的人力资源建议
"""
十、安全与最佳实践
10.1 安全考虑
-
访问控制
python@mcp.tool() async def read_file(path: str) -> str: # 验证路径在允许的目录内 if not is_path_allowed(path): raise PermissionError("路径访问被拒绝") return read_file_content(path)
-
参数验证
pythonfrom pydantic import BaseModel, validator class QueryParams(BaseModel): limit: int @validator('limit') def validate_limit(cls, v): if v > 1000: raise ValueError('limit 不能超过 1000') return v
-
敏感信息处理
- 不在日志中记录敏感数据
- 使用环境变量管理密钥
- 实现适当的身份认证机制
10.2 性能优化
-
连接池管理
pythonfrom contextlib import asynccontextmanager class DatabaseServer: def __init__(self): self.pool = create_connection_pool() @asynccontextmanager async def get_connection(self): conn = await self.pool.acquire() try: yield conn finally: await self.pool.release(conn)
-
缓存策略
pythonfrom functools import lru_cache @mcp.tool() @lru_cache(maxsize=100) async def get_static_data(key: str) -> str: return expensive_computation(key)
-
并发控制
pythonimport asyncio semaphore = asyncio.Semaphore(10) # 限制并发数 @mcp.tool() async def api_call(endpoint: str) -> str: async with semaphore: return await fetch(endpoint)
十一、未来展望
11.1 技术演进方向
-
更丰富的传输层支持
- WebSocket 双向通信
- gRPC 高性能传输
- 云原生部署方案
-
智能能力发现
- 基于语义的工具推荐
- 自动化的能力组合
- 跨服务器的协同工作
-
企业级特性
- 更完善的安全机制
- 审计和合规支持
- 多租户隔离
11.2 生态系统建设
MCP 正在构建一个协作式的开源生态:
- 社区驱动:开发者可以贡献自己的服务器实现
- 注册中心:便于发现和共享 MCP 服务器
- 跨平台支持:多语言 SDK 降低接入门槛
- 标准化演进:通过社区反馈持续改进协议
十二、MCP 实战
从源码角度对比
- Codex CLI:(OpenAI)用 Rust 写成一体化 Host,~/.codex/config.toml 的
\[mcp_servers\]\] 片段定义要挂载的 Server(含 command、args、env、工作目录、 速率限制)。它默认把 Server 包在 Codex 的沙箱与审批体系里:每个工具调用都经 过权限检查,长命令会触发"approval"交互,同时把 Server 输出写入结构化日志,供 codex.log 与审计面板消费。底层整合了本地文件树索引、诊断(lint/test)和 plan/ review 工作流,并以 MCP 资源流的形式把这些上下文塞给模型。优点是安全治理彻底、 与 CLI 体验绑定紧密;缺点是可视化和多窗口体验有限,Server 生命周期基本受 Codex 控制,外部想复用需额外做桥接。 * **Claude Code**:(Claude Desktop/VS Code 插件)同样作为 Host,但更偏 IDE 场景。 配置文件 claude_desktop_config.json 或 VS Code 插件设置里的 mcpServers 字段声 明 MCP Server。它把文件树、终端、Run\&Debug 面板对齐到同个会话里,Claude 输出时 会流式显示 modelOutput、toolProgress,并允许用户在工具调用前直接修改参数或拿到 diff。Anthropic 的参考实现大量使用 TS SDK,支持热加载 Server、per-project 覆 盖、以及 UI 级别的冲突提示。Claude Code 的强项是 IDE 深度集成与 Prompt 工程资 产管理;不足在于 CLI 自动化较弱,而且对权限/审批的内置治理比 Codex 稍轻,更多 依赖 IDE 环境或企业版的外围策略。 * **Genim CLI**:(genimxyz/genim 开源仓库)定位成"工作流型" Host:它用 TypeScript 实现,在 genim.config.ts 里用类 Graph 方式声明 MCP Server、资源映射与触发 器。Genim 会把每次模型交互拆成显式的 Node:ResourceFetch、PromptTemplate、 ToolCall,并在 CLI 中输出 DAG 式追踪,方便把上下文拼装过程纳入 CI/CD。它默认支 持把 Server 运行在 Docker/Nix profile 里,强调 reproducible run,以及 CLI 中的 genim run、genim diff。长处是自动化友好、易嵌入现有流水线;短板是交互式体验偏 弱,安全策略需要用户自己在 Docker profile 或 Server 里兜底。 ### 差异与优劣 - **治理与安全**:Codex CLI \> Genim CLI \> Claude Code。Codex 的审批流和沙箱最完 整,Genim 提供容器化但策略自管,Claude Code 更依赖 IDE 权限。 - **交互体验**:Claude Code 在 IDE 内的 UI、上下文回放最强;Codex 在高级 CLI 操作 与调试方面领先;Genim 着重自动化,没有图形界面。 - **生态与可扩展性**:Genim 把工作流开放给脚本最方便;Codex/Claude 都能挂任意 MCP Server,但前者耦合 Codex 沙箱,后者耦合 IDE 环境。 - **默认能力**:Codex 自带大量内置 Server(shell、fs、git、issue);Claude 依赖 IDE 插件生态;Genim 倚重用户自定义。 **谁更适合哪类团队**\*\*\*\* - 想要"安全高可信、命令行驱动"的团队:Codex CLI。 - 需要"IDE 即时回馈、开发体验优先"的团队:Claude Code。 - 希望"把上下文拼装纳入自动化流水线"的团队:Genim CLI。 ### AI 下一步方向 - **上下文编排层标准化**:三者都在尝试把 RAG、工具、Prompt 合成流程显式化,下一步 会朝"可视化 DAG + 版本化上下文包"演进。 - **细粒度权限治理**:未来 MCP Host 预计会原生支持资源/工具级 RBAC、Secret 委托、 审计事件流。Codex 走得最前,但还需跨 Host 对齐。 - **多代理协作**:把多个 MCP Host/Server 串联,让不同能力代理共享上下文,这对 Genim 的流水线和 Codex 的 plan/review 模式是自然进化。 - **端到端可观测性**:谁能把 modelOutput、toolProgress、resourceUpdated 串成统一追 踪,谁就更易进企业。Genim 已有 DAG 可视化雏形,值得关注。 如需继续深挖,建议:1) 实测在 Codex/Claude/Genim 下挂同一个 Server(如 mcp- git),比较上下文注入效果;2) 根据自身安全需求选主力 Host,再看是否要做二次封 装或把三个结合使用。 ## 十三、总结 MCP (Model Context Protocol) 代表了 AI 应用集成的**范式转变**: ### 核心价值 * ✅ **标准化**:统一的协议规范,替代碎片化集成 * ✅ **开放性**:开源协议,任何人都可以实现和扩展 * ✅ **可组合性**:模块化设计,灵活组合不同能力 * ✅ **跨平台**:多语言支持,适应不同技术栈 * ✅ **易用性**:简洁的 API,快速上手开发 ### 适用场景 * 需要访问多种数据源的 AI 应用 * 企业级 AI 助手开发 * 开发工具的 AI 增强 * 跨系统的智能工作流 ### 开始使用 1. 访问官方文档:[modelcontextprotocol.io](https://link.juejin.cn?target=https%3A%2F%2Fmodelcontextprotocol.io "https://modelcontextprotocol.io") 2. 查看参考实现:[github.com/modelcontex...](https://link.juejin.cn?target=https%3A%2F%2Fgithub.com%2Fmodelcontextprotocol "https://github.com/modelcontextprotocol") 3. 选择适合的 SDK:Python、TypeScript、Java、Kotlin、C#、Ruby 4. 从简单的服务器开始实践 MCP 不仅仅是一个技术协议,更是**AI 应用走向标准化、工程化的重要一步**。随着生态的发展,它有潜力成为 AI 应用集成的事实标准。 *** ** * ** *** **参考资源** * [MCP 官方文档](https://link.juejin.cn?target=https%3A%2F%2Fmodelcontextprotocol.io "https://modelcontextprotocol.io") * [MCP GitHub 组织](https://link.juejin.cn?target=https%3A%2F%2Fgithub.com%2Fmodelcontextprotocol "https://github.com/modelcontextprotocol") * [Anthropic 官方博客](https://link.juejin.cn?target=https%3A%2F%2Fwww.anthropic.com%2Fnews%2Fmodel-context-protocol "https://www.anthropic.com/news/model-context-protocol") * [Microsoft MCP 初学者教程](https://link.juejin.cn?target=https%3A%2F%2Fgithub.com%2Fmicrosoft%2Fmcp-for-beginners "https://github.com/microsoft/mcp-for-beginners") **关于作者** 如果你对 AI 应用开发和工程化实践感兴趣,欢迎关注我的掘金账号,一起探讨技术! *** ** * ** ***