跳到主要内容

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. 部署建议

  • 版本管理:使用语义化版本
  • 监控告警:跟踪服务器状态
  • 备份恢复:确保数据安全

相关资源