MCP 架构原理
概述
MCP(Model Context Protocol)是 Anthropic 于 2024 年 11 月开源的标准化协议,用于 AI 模型与外部服务的连接。它定义了一套统一的接口规范,让 AI 能够安全、高效地访问外部工具和数据源。
设计目标
1. 标准化连接
- 统一接口:为所有外部服务提供一致的连接方式
- 协议透明:AI 无需了解具体实现细节
- 易于扩展:新服务可以快速接入
2. 安全可控
- 权限管理:细粒度的访问控制
- 沙盒隔离:限制潜在危险操作
- 审计追踪:记录所有交互行为
3. 性能优化
- 按需加载:只在需要时激活工具
- 资源管理:优化内存和计算资源使用
- 缓存机制:减少重复请求
核心概念
1. MCP Server(服务器)
MCP 服务器是提供具体功能的独立进程,例如:
- 文件系统服务器:提供文件读写功能
- 数据库服务器:提供数据查询操作
- Web 服务服务器:提供 HTTP 请求能力
- Git 服务器:提供版本控制操作
2. MCP Client(客户端)
MCP 客户端负责:
- 发现和管理 MCP 服务器
- 路由 AI 请求到合适的服务器
- 聚合多个服务器的响应
- 管理服务器生命周期
3. Tools(工具)
工具是 MCP 服务器暴露的具体功能:
{
"name": "read_file",
"description": "读取文件内容",
"inputSchema": {
"type": "object",
"properties": {
"path": {
"type": "string",
"description": "文件路径"
}
}
}
}
4. Resources(资源)
资源是服务器可以访问的数据源:
{
"uri": "file:///home/user/config.json",
"name": "配置文件",
"description": "应用配置信息",
"mimeType": "application/json"
}
协议架构
消息流程
┌─────────────┐ ┌─────────────┐ ┌─────────────┐
│ AI Model │────▶│ MCP Client │────▶│ MCP Server │
└─────────────┘ └─────────────┘ └─────────────┘
│ │ │
│ Tool Call Request │ │
│◀──────────────────│ │
│ Tool Call Result │ │
│◀──────────────────┼──────────────────│
│ Resource Request │ │
│◀──────────────────│ │
│ Resource Data │ │
│◀──────────────────┴──────────────────│
通信协议
MCP 使用 JSON-RPC 2.0 作为通信协议:
工具调用示例
请求:
{
"jsonrpc": "2.0",
"id": "1",
"method": "tools/call",
"params": {
"name": "read_file",
"arguments": {
"path": "/path/to/file.txt"
}
}
}
响应:
{
"jsonrpc": "2.0",
"id": "1",
"result": {
"content": [
{
"type": "text",
"text": "文件内容..."
}
]
}
}
技术特性
1. 异步支持
- 非阻塞操作
- 支持长时间运行的任务
- 流式响应处理
2. 错误处理
{
"jsonrpc": "2.0",
"id": "1",
"error": {
"code": -32601,
"message": "Method not found",
"data": {
"details": "工具 'unknown_tool' 不存在"
}
}
}
3. 通知机制
服务器可以主动发送通知:
{
"jsonrpc": "2.0",
"method": "notifications/message",
"params": {
"level": "info",
"message": "操作完成"
}
}
服务器实现
基本结构
import { Server } from '@modelcontextprotocol/sdk/server/index.js';
const server = new Server(
{
name: "my-server",
version: "1.0.0"
},
{
capabilities: {
tools: {},
resources: {}
}
}
);
// 注册工具
server.setRequestHandler(ListToolsRequestSchema, async () => ({
tools: [
{
name: "my_tool",
description: "我的工具",
inputSchema: {
type: "object",
properties: {
// schema定义
}
}
}
]
}));
// 处理工具调用
server.setRequestHandler(CallToolRequestSchema, async (request) => {
const { name, arguments: args } = request.params;
if (name === "my_tool") {
// 实现工具逻辑
return {
content: [
{
type: "text",
"text": "工具执行结果"
}
]
};
}
});
服务器类型
1. 进程内服务器
与 Claude Code 在同一进程运行:
- 快速响应
- 共享内存
- 适合轻量级工具
2. 独立进程服务器
作为独立进程运行:
- 隔离性好
- 可独立升级
- 适合重量级服务
3. HTTP 服务器
通过 HTTP 暴露服务:
- 跨语言支持
- 远程访问
- 易于集成
配置管理
全局配置
// ~/.claude/mcp.json
{
"mcpServers": {
"filesystem": {
"command": "npx",
"args": ["@modelcontextprotocol/server-filesystem", "/path/to/allowed/directory"]
},
"git": {
"command": "git-mcp-server",
"args": ["--repo", "/path/to/repo"]
}
}
}
项目配置
// .mcp.json
{
"mcpServers": {
"database": {
"url": "http://localhost:3001/mcp",
"env": {
"DB_HOST": "localhost",
"DB_PORT": "5432"
}
}
}
}
动态配置
// 程序化配置
const mcpManager = new MCPManager();
mcpManager.addServer('my-server', {
command: 'node',
args: ['my-server.js'],
cwd: process.cwd()
});
安全机制
1. 权限控制
{
"permissions": {
"allow": [
"filesystem:read",
"filesystem:write:/tmp/*",
"network:http:api.example.com"
],
"deny": [
"filesystem:write:/etc/*",
"network:ssh:*"
]
}
}
2. 沙盒模式
const server = new Server({
sandbox: {
allowedPaths: ['/safe/directory'],
denyNetwork: true,
maxMemory: '512MB'
}
});
3. 审计日志
server.addMiddleware((req, next) => {
console.log(`[${new Date().toISOString()}] ${req.method}: ${req.params}`);
return next(req);
});
性能优化
1. 连接池
class ConnectionPool {
private connections: Map<string, Connection> = new Map();
async getConnection(serverId: string): Promise<Connection> {
if (!this.connections.has(serverId)) {
const conn = await this.createConnection(serverId);
this.connections.set(serverId, conn);
}
return this.connections.get(serverId)!;
}
}
2. 缓存策略
const cache = new LRUCache({
max: 100,
ttl: 1000 * 60 * 5 // 5分钟
});
server.addTool({
name: "get_data",
cacheable: true,
handler: async (args) => {
const key = JSON.stringify(args);
if (cache.has(key)) {
return cache.get(key);
}
const result = await fetchData(args);
cache.set(key, result);
return result;
}
});
最佳实践
1. 设计原则
- 单一职责:每个服务器专注一个领域
- 无状态:服务器不应依赖会话状态
- 错误友好:提供清晰的错误信息
2. 开发建议
- 渐进式开发:从简单工具开始
- 充分测试:包含边界情况
- 文档完整:提供清晰的 API 文档
3. 部署建议
- 版本管理:使用语义化版本
- 监控告警:跟踪服务器状态
- 备份恢复:确保数据安全