文思AI产品笔记
首页
最新文章
AI编程
AI架构
关于我
  • AI生态圈
  • AI大模型
  • 多维表格
  • AI创业笔记
  • AI落地案例
  • 个人产品推介
  • 问题集
  • 简体中文
  • English
首页
最新文章
AI编程
AI架构
关于我
  • AI生态圈
  • AI大模型
  • 多维表格
  • AI创业笔记
  • AI落地案例
  • 个人产品推介
  • 问题集
  • 简体中文
  • English
  • Claude Code 教程

    • Claude Code 从入门到精通
    • 01 - 快速入门
    • 02 - 核心特点
    • 03 - 版本演进史
    • 04 - 架构深入解析
    • 05 - Claude Skills 详解
    • 06 - MCP 协议完全指南
    • 07 - 高级功能全解
    • 08 - 最佳实践
    • 09 - 使用诀窍与技巧
    • 10 - 配置优化指南

06 - MCP 协议完全指南

🔌 Model Context Protocol:打通 AI 与任何系统的桥梁


📋 本章目标

  • ✅ 理解 MCP 的设计理念和架构
  • ✅ 掌握 MCP Server 的开发
  • ✅ 学会常用 MCP 集成
  • ✅ 了解 MCP 最佳实践和安全性

预计阅读时间: 40分钟


🤔 什么是 MCP?

Model Context Protocol (MCP)

MCP 是 Anthropic 开发的开放协议,用于连接 AI 模型与外部系统。

简单理解:
MCP = AI 的"USB 接口"

就像 USB 让你的电脑连接任何设备(鼠标、键盘、打印机...),
MCP 让 Claude 连接任何系统(数据库、API、工具...)

为什么需要 MCP?

问题:AI 的局限性

传统 AI:
┌─────────────┐
│   Claude    │  只能:
│             │  - 读取你提供的文本
│   (孤岛)    │  - 生成回复
└─────────────┘  
     ❌ 无法访问外部数据
     ❌ 无法执行操作
     ❌ 无法持久化状态

解决:MCP 连接一切

Claude + MCP:
┌─────────────┐
│   Claude    │
└──────┬──────┘
       │ MCP
       ├──────→ 数据库 (读写数据)
       ├──────→ API (调用服务)
       ├──────→ 文件系统 (管理文件)
       ├──────→ 浏览器 (自动化测试)
       └──────→ 任何你想连接的系统!

MCP vs 传统方案

特性MCP传统 API传统插件
标准化✅ 统一协议❌ 各自标准❌ 平台特定
双向通信✅ 是🟡 有限✅ 是
动态能力✅ 运行时发现❌ 需预定义🟡 部分
安全性✅ 权限系统🟡 API Key🟡 沙盒
易扩展✅ 插拔式❌ 需集成🟡 中等

🏗️ MCP 架构

核心组件

┌──────────────────────────────────────────────┐
│                 Claude (Client)               │
│  - 理解用户意图                               │
│  - 规划任务                                   │
│  - 调用 MCP Server                            │
└───────────────────┬──────────────────────────┘
                    │ MCP Protocol
                    ↓
┌──────────────────────────────────────────────┐
│              MCP Transport Layer              │
│  - stdio (标准输入输出)                        │
│  - HTTP/WebSocket                             │
│  - 序列化/反序列化                             │
└───────────────────┬──────────────────────────┘
                    │
        ┌───────────┴───────────┬───────────┐
        ↓                       ↓           ↓
┌──────────────┐     ┌──────────────┐  ┌───────────┐
│ MCP Server 1 │     │ MCP Server 2 │  │  Server N │
│  (Database)  │     │    (API)     │  │   (...)   │
└──────────────┘     └──────────────┘  └───────────┘
        │                       │           │
        ↓                       ↓           ↓
┌──────────────┐     ┌──────────────┐  ┌───────────┐
│  PostgreSQL  │     │  GitHub API  │  │  Notion   │
└──────────────┘     └──────────────┘  └───────────┘

MCP 消息流程

1. 用户: "查询数据库中最近的用户"
   ↓
2. Claude 分析: 需要数据库查询能力
   ↓
3. Claude 发现: PostgreSQL MCP Server
   ↓
4. Claude → MCP Server:
   {
     "method": "tools/call",
     "params": {
       "name": "query",
       "arguments": {
         "sql": "SELECT * FROM users ORDER BY created_at DESC LIMIT 10"
       }
     }
   }
   ↓
5. MCP Server 执行查询
   ↓
6. MCP Server → Claude:
   {
     "result": [
       { "id": 1, "name": "Alice", ... },
       { "id": 2, "name": "Bob", ... }
     ]
   }
   ↓
7. Claude → 用户: "找到了10个最近的用户:..."

🛠️ 创建 MCP Server

基础 MCP Server 结构

// server.ts

import { Server } from '@modelcontextprotocol/sdk/server/index.js'
import { StdioServerTransport } from '@modelcontextprotocol/sdk/server/stdio.js'

// 1. 创建 Server 实例
const server = new Server(
  {
    name: 'my-awesome-server',
    version: '1.0.0',
  },
  {
    capabilities: {
      tools: {},  // 提供 tools
      resources: {},  // 提供 resources
    },
  }
)

// 2. 注册 Tools
server.setRequestHandler('tools/list', async () => {
  return {
    tools: [
      {
        name: 'get_weather',
        description: 'Get current weather for a location',
        inputSchema: {
          type: 'object',
          properties: {
            location: {
              type: 'string',
              description: 'City name'
            }
          },
          required: ['location']
        }
      }
    ]
  }
})

// 3. 处理 Tool 调用
server.setRequestHandler('tools/call', async (request) => {
  if (request.params.name === 'get_weather') {
    const location = request.params.arguments.location
    const weather = await fetchWeather(location)
    
    return {
      content: [
        {
          type: 'text',
          text: JSON.stringify(weather, null, 2)
        }
      ]
    }
  }
  
  throw new Error('Tool not found')
})

// 4. 启动 Server
const transport = new StdioServerTransport()
await server.connect(transport)

完整示例:数据库 MCP Server

// database-server.ts

import { Server } from '@modelcontextprotocol/sdk/server/index.js'
import { Pool } from 'pg'

const pool = new Pool({
  connectionString: process.env.DATABASE_URL
})

const server = new Server(
  { name: 'postgres-server', version: '1.0.0' },
  { capabilities: { tools: {} } }
)

// 列出可用 Tools
server.setRequestHandler('tools/list', async () => {
  return {
    tools: [
      {
        name: 'query',
        description: 'Execute a SQL query',
        inputSchema: {
          type: 'object',
          properties: {
            sql: {
              type: 'string',
              description: 'SQL query to execute'
            },
            params: {
              type: 'array',
              description: 'Query parameters',
              items: { type: 'string' }
            }
          },
          required: ['sql']
        }
      },
      {
        name: 'list_tables',
        description: 'List all tables in the database',
        inputSchema: { type: 'object', properties: {} }
      },
      {
        name: 'describe_table',
        description: 'Get table schema',
        inputSchema: {
          type: 'object',
          properties: {
            table: { type: 'string', description: 'Table name' }
          },
          required: ['table']
        }
      }
    ]
  }
})

// 处理 Tool 调用
server.setRequestHandler('tools/call', async (request) => {
  const { name, arguments: args } = request.params
  
  switch (name) {
    case 'query': {
      const { sql, params = [] } = args
      const result = await pool.query(sql, params)
      
      return {
        content: [
          {
            type: 'text',
            text: JSON.stringify({
              rows: result.rows,
              rowCount: result.rowCount
            }, null, 2)
          }
        ]
      }
    }
    
    case 'list_tables': {
      const result = await pool.query(`
        SELECT tablename 
        FROM pg_tables 
        WHERE schemaname = 'public'
      `)
      
      return {
        content: [
          {
            type: 'text',
            text: JSON.stringify(result.rows, null, 2)
          }
        ]
      }
    }
    
    case 'describe_table': {
      const { table } = args
      const result = await pool.query(`
        SELECT column_name, data_type, is_nullable
        FROM information_schema.columns
        WHERE table_name = $1
      `, [table])
      
      return {
        content: [
          {
            type: 'text',
            text: JSON.stringify(result.rows, null, 2)
          }
        ]
      }
    }
    
    default:
      throw new Error(`Unknown tool: ${name}`)
  }
})

// 启动
const transport = new StdioServerTransport()
await server.connect(transport)

配置 MCP Server

// .cursor/mcp.json 或 ~/Library/Application Support/Cursor/mcp.json

{
  "mcpServers": {
    "postgres": {
      "command": "node",
      "args": ["/path/to/database-server.js"],
      "env": {
        "DATABASE_URL": "postgresql://user:pass@localhost:5432/mydb"
      }
    },
    "weather": {
      "command": "node",
      "args": ["/path/to/weather-server.js"],
      "env": {
        "WEATHER_API_KEY": "your-api-key"
      }
    }
  }
}

🔌 常用 MCP 集成

1. 数据库集成

PostgreSQL MCP Server

// 安装
npm install @modelcontextprotocol/server-postgres

// 配置
{
  "postgres": {
    "command": "npx",
    "args": ["-y", "@modelcontextprotocol/server-postgres", "postgresql://..."]
  }
}

// 使用
Prompt: "查询 users 表中年龄>25的用户"
Claude 会: 自动生成SQL并执行

MongoDB MCP Server

{
  "mongodb": {
    "command": "node",
    "args": ["mongodb-server.js"],
    "env": {
      "MONGO_URI": "mongodb://localhost:27017/mydb"
    }
  }
}

// 使用
Prompt: "统计每个类别的文章数量"
Claude 会: 使用聚合管道查询

2. API 集成

GitHub MCP Server

// 安装官方 GitHub MCP
npm install @modelcontextprotocol/server-github

// 配置
{
  "github": {
    "command": "npx",
    "args": ["-y", "@modelcontextprotocol/server-github"],
    "env": {
      "GITHUB_TOKEN": "ghp_..."
    }
  }
}

// 使用示例
Prompt: "查看我的仓库最近的issues"
Claude: [调用 GitHub API 获取 issues]

Prompt: "为issue #123 添加标签 'bug'"
Claude: [调用 API 添加标签]

自定义 API MCP

// notion-server.ts

server.setRequestHandler('tools/list', async () => {
  return {
    tools: [
      {
        name: 'create_page',
        description: 'Create a new Notion page',
        inputSchema: {
          type: 'object',
          properties: {
            database_id: { type: 'string' },
            title: { type: 'string' },
            content: { type: 'string' }
          }
        }
      },
      {
        name: 'query_database',
        description: 'Query a Notion database',
        inputSchema: {
          type: 'object',
          properties: {
            database_id: { type: 'string' },
            filter: { type: 'object' }
          }
        }
      }
    ]
  }
})

3. 文件系统集成

// filesystem-server.ts

const tools = [
  {
    name: 'read_directory',
    description: 'List files in a directory',
    inputSchema: {
      type: 'object',
      properties: {
        path: { type: 'string' }
      }
    }
  },
  {
    name: 'search_files',
    description: 'Search files by pattern',
    inputSchema: {
      type: 'object',
      properties: {
        pattern: { type: 'string' },
        path: { type: 'string' }
      }
    }
  },
  {
    name: 'watch_directory',
    description: 'Watch directory for changes',
    inputSchema: {
      type: 'object',
      properties: {
        path: { type: 'string' }
      }
    }
  }
]

4. 浏览器自动化

// browser-server.ts (基于 Playwright)

import { chromium } from 'playwright'

server.setRequestHandler('tools/call', async (request) => {
  const browser = await chromium.launch()
  const page = await browser.newPage()
  
  const { name, arguments: args } = request.params
  
  switch (name) {
    case 'navigate':
      await page.goto(args.url)
      break
      
    case 'screenshot':
      const screenshot = await page.screenshot()
      return {
        content: [
          {
            type: 'image',
            data: screenshot.toString('base64')
          }
        ]
      }
      
    case 'fill_form':
      await page.fill(args.selector, args.value)
      break
      
    case 'click':
      await page.click(args.selector)
      break
      
    case 'extract_data':
      const data = await page.evaluate(() => {
        // 提取页面数据
        return document.body.innerText
      })
      return {
        content: [{ type: 'text', text: data }]
      }
  }
  
  await browser.close()
})

🔐 MCP 安全性

权限系统

// 定义权限级别
const PERMISSIONS = {
  READ: 'read',
  WRITE: 'write',
  ADMIN: 'admin'
}

// 在 MCP Server 中验证权限
server.setRequestHandler('tools/call', async (request, { auth }) => {
  const tool = request.params.name
  
  // 检查权限
  if (tool === 'delete_all' && auth.level !== PERMISSIONS.ADMIN) {
    throw new Error('Insufficient permissions')
  }
  
  // 执行操作
  return await executeTool(tool, request.params.arguments)
})

输入验证

import { z } from 'zod'

// 定义输入 Schema
const QuerySchema = z.object({
  sql: z.string()
    .regex(/^SELECT/i, 'Only SELECT queries allowed')
    .max(1000, 'Query too long'),
  params: z.array(z.string()).optional()
})

// 验证输入
server.setRequestHandler('tools/call', async (request) => {
  if (request.params.name === 'query') {
    try {
      const validated = QuerySchema.parse(request.params.arguments)
      // 执行验证后的查询
      return await executeQuery(validated)
    } catch (error) {
      throw new Error(`Invalid input: ${error.message}`)
    }
  }
})

速率限制

import { RateLimiter } from 'limiter'

const limiter = new RateLimiter({
  tokensPerInterval: 10,
  interval: 'minute'
})

server.setRequestHandler('tools/call', async (request) => {
  // 检查速率限制
  const allowed = await limiter.removeTokens(1)
  
  if (!allowed) {
    throw new Error('Rate limit exceeded')
  }
  
  // 执行操作
  return await handleRequest(request)
})

敏感数据保护

// 过滤敏感信息
function sanitizeResult(data: any) {
  if (typeof data === 'object') {
    const sanitized = { ...data }
    
    // 移除敏感字段
    delete sanitized.password
    delete sanitized.secret_key
    delete sanitized.api_token
    
    // 递归处理嵌套对象
    for (const key in sanitized) {
      if (typeof sanitized[key] === 'object') {
        sanitized[key] = sanitizeResult(sanitized[key])
      }
    }
    
    return sanitized
  }
  
  return data
}

// 在返回结果前过滤
server.setRequestHandler('tools/call', async (request) => {
  const result = await executeQuery(request)
  return {
    content: [
      {
        type: 'text',
        text: JSON.stringify(sanitizeResult(result))
      }
    ]
  }
})

💡 MCP 最佳实践

1. 设计原则

单一职责

// ❌ 不好的设计
{
  "all-in-one-server": {
    // 一个 Server 做所有事情
  }
}

// ✅ 好的设计
{
  "database": { ... },  // 只处理数据库
  "api": { ... },       // 只处理API调用
  "files": { ... }      // 只处理文件操作
}

清晰的命名

// ❌ 模糊的命名
{
  name: 'do_something',
  description: 'Does stuff'
}

// ✅ 清晰的命名
{
  name: 'query_users_by_email',
  description: 'Query users table filtered by email address. Returns user objects with id, name, email fields.'
}

2. 错误处理

server.setRequestHandler('tools/call', async (request) => {
  try {
    return await executeOperation(request)
  } catch (error) {
    // 详细的错误信息
    return {
      isError: true,
      content: [
        {
          type: 'text',
          text: JSON.stringify({
            error: error.message,
            code: error.code,
            suggestion: 'Please check your input parameters',
            documentation: 'https://docs.example.com/api'
          })
        }
      ]
    }
  }
})

3. 性能优化

连接池

// 使用连接池而不是每次创建新连接
const pool = new Pool({
  max: 20,
  idleTimeoutMillis: 30000,
  connectionTimeoutMillis: 2000,
})

// 复用连接
async function query(sql: string) {
  const client = await pool.connect()
  try {
    return await client.query(sql)
  } finally {
    client.release()
  }
}

缓存

import { LRUCache } from 'lru-cache'

const cache = new LRUCache({
  max: 100,
  ttl: 1000 * 60 * 5  // 5分钟
})

server.setRequestHandler('tools/call', async (request) => {
  const cacheKey = JSON.stringify(request.params)
  
  // 检查缓存
  if (cache.has(cacheKey)) {
    return cache.get(cacheKey)
  }
  
  // 执行操作
  const result = await executeOperation(request)
  
  // 存入缓存
  cache.set(cacheKey, result)
  
  return result
})

4. 日志和监控

import winston from 'winston'

const logger = winston.createLogger({
  level: 'info',
  format: winston.format.json(),
  transports: [
    new winston.transports.File({ filename: 'mcp-server.log' })
  ]
})

server.setRequestHandler('tools/call', async (request) => {
  logger.info('Tool called', {
    tool: request.params.name,
    timestamp: new Date().toISOString()
  })
  
  try {
    const result = await executeOperation(request)
    
    logger.info('Tool succeeded', {
      tool: request.params.name,
      duration: Date.now() - startTime
    })
    
    return result
  } catch (error) {
    logger.error('Tool failed', {
      tool: request.params.name,
      error: error.message
    })
    
    throw error
  }
})

🎯 实战案例

案例1: 全栈开发工作流

用户: "创建一个博客系统"

Claude 通过 MCP:
1. Database MCP → 创建数据库表
2. Filesystem MCP → 生成后端代码
3. Filesystem MCP → 生成前端代码
4. Git MCP → 初始化仓库
5. Terminal MCP → 安装依赖
6. Terminal MCP → 启动开发服务器
7. Browser MCP → 打开浏览器测试

一条命令,完整的开发环境就绪!

案例2: 数据分析流水线

用户: "分析用户行为数据并生成报告"

Claude 通过 MCP:
1. Database MCP → 从 PostgreSQL 提取数据
2. Python MCP → 运行数据分析脚本
3. Visualization MCP → 生成图表
4. Notion MCP → 创建报告页面
5. Slack MCP → 通知团队

自动化数据分析流程!

案例3: CI/CD 自动化

用户: "部署应用到生产环境"

Claude 通过 MCP:
1. Git MCP → 检查分支状态
2. Terminal MCP → 运行测试
3. Docker MCP → 构建镜像
4. Kubernetes MCP → 部署到集群
5. Monitoring MCP → 设置监控
6. Slack MCP → 发送部署通知

一键部署!

📚 MCP 生态

官方 MCP Servers

  • @modelcontextprotocol/server-postgres - PostgreSQL
  • @modelcontextprotocol/server-sqlite - SQLite
  • @modelcontextprotocol/server-github - GitHub API
  • @modelcontextprotocol/server-slack - Slack API
  • @modelcontextprotocol/server-google-drive - Google Drive

社区 MCP Servers

  • mcp-server-notion - Notion integration
  • mcp-server-jira - Jira/Confluence
  • mcp-server-aws - AWS Services
  • mcp-server-docker - Docker operations
  • mcp-server-k8s - Kubernetes

✅ 检查清单

完成本章后,你应该能够:

  • [ ] 理解 MCP 的架构和工作原理
  • [ ] 创建基本的 MCP Server
  • [ ] 集成常用的 MCP Servers
  • [ ] 实现安全的权限控制
  • [ ] 优化 MCP Server 性能
  • [ ] 设计复杂的自动化工作流

🎯 实战练习

练习1: 创建天气 MCP Server

// 要求:
- 调用天气 API
- 提供多个查询方式(城市、坐标)
- 缓存结果
- 错误处理

练习2: 数据库查询优化

// 要求:
- 实现查询缓存
- 添加连接池
- 记录慢查询日志
- 实现查询超时

练习3: 多 MCP 协作

// 场景: 自动化内容发布
1. 从 Notion 获取草稿
2. 调用 AI 生成摘要
3. 上传图片到 CDN
4. 发布到博客系统
5. 分享到社交媒体

📚 延伸阅读

  • MCP 官方规范
  • MCP SDK 文档
  • MCP Server 示例
  • 05 - Claude Skills - Skills 与 MCP 的结合
  • 08 - 最佳实践 - 生产环境使用

🔌 MCP 是 Claude 连接世界的桥梁

掌握 MCP,你就能让 Claude 访问任何系统!

"The power of AI lies not in isolation, but in connection."

最近更新: 2025/12/22 14:25
Contributors: wsyx
Prev
05 - Claude Skills 详解
Next
07 - 高级功能全解