MCP(Model Context Protocol)让 Agent 可以连接外部工具和数据源,但单个 MCP Server 能力有限。本文展示如何组合多个 MCP Server(GitHub + Figma + PostgreSQL + Confluence),构建一个完整的 Agent 工作流:从设计稿获取需求、从数据库获取 Schema、从代码仓库获取上下文、从知识库获取业务规则,让 Age...

MCP 组合实战:把 GitHub、Figma、数据库和知识库接进 Agent 工作流

MCP(Model Context Protocol)让 Agent 可以连接外部工具和数据源,但单个 MCP Server 能力有限。本文展示如何组合多个 MCP Server(GitHub + Figma + PostgreSQL + Confluence),构建一个完整的 Agent 工作流:从设计稿获取需求、从数据库获取 Schema、从代码仓库获取上下文、从知识库获取业务规则,让 Agent 拥有全链路的信息访问能力。同时总结 MCP 组合使用中最容易踩的 5 个坑和解决方案。

一、为什么需要组合 MCP

1.1 单个 MCP 的局限

MCP Server 能力 局限
GitHub MCP 读写代码、PR、Issue 不知道设计意图
Figma MCP 获取设计稿、组件规范 不知道实现细节
Database MCP 查询 Schema、数据 不知道业务规则
Confluence MCP 获取文档、需求 不知道代码实现

问题:单个 MCP 只能提供局部信息,Agent 无法理解全局上下文。

1.2 组合后的全链路能力

text
设计稿(Figma)
  ↓ 获取组件规范、交互说明
需求文档(Confluence)
  ↓ 获取业务规则、验收标准
数据库(PostgreSQL)
  ↓ 获取 Schema、数据样例
代码仓库(GitHub)
  ↓ 获取实现细节、历史变更
Agent 工作流
  ↓ 综合分析,生成代码
代码提交(GitHub)
  ↓ 创建 PR、触发 CI/CD

价值:Agent 拥有全链路信息,生成的代码更符合设计、业务和技术要求。

二、MCP 组合架构

2.1 架构图

text
┌─────────────────────────────────────────────────────────┐
│                    Agent 工作流                          │
│                                                         │
│  ┌──────────┐  ┌──────────┐  ┌──────────┐  ┌────────┐ │
│  │  Figma   │  │Confluence│  │PostgreSQL│  │ GitHub │ │
│  │   MCP    │  │   MCP    │  │   MCP    │  │  MCP   │ │
│  └────┬─────┘  └────┬─────┘  └────┬─────┘  └───┬────┘ │
│       │              │              │             │      │
│       └──────────────┴──────────────┴─────────────┘      │
│                      │                                   │
│              ┌───────▼────────┐                          │
│              │  MCP Router    │                          │
│              │  (权限控制)     │                          │
│              └───────┬────────┘                          │
│                      │                                   │
│              ┌───────▼────────┐                          │
│              │  Audit Logger  │                          │
│              │  (调用审计)     │                          │
│              └───────┬────────┘                          │
│                      │                                   │
│              ┌───────▼────────┐                          │
│              │  Claude Code   │                          │
│              │  (Agent 核心)  │                          │
│              └────────────────┘                          │
└─────────────────────────────────────────────────────────┘

2.2 配置文件

json
// .claude/mcp-config.json
{
  "mcpServers": {
    "github": {
      "command": "npx",
      "args": ["-y", "@modelcontextprotocol/server-github"],
      "env": {
        "GITHUB_TOKEN": "${GITHUB_TOKEN}",
        "GITHUB_REPOS": "myorg/frontend,myorg/backend"
      },
      "allowedTools": [
        "read_file",
        "list_files",
        "search_code",
        "create_issue",
        "create_pr"
      ],
      "timeout": 30000,
      "rateLimit": {
        "maxRequests": 100,
        "windowMs": 60000
      }
    },
    
    "figma": {
      "command": "npx",
      "args": ["-y", "@modelcontextprotocol/server-figma"],
      "env": {
        "FIGMA_TOKEN": "${FIGMA_TOKEN}",
        "FIGMA_FILES": "abc123,def456"
      },
      "allowedTools": [
        "get_file",
        "get_nodes",
        "get_styles",
        "get_components"
      ],
      "timeout": 30000,
      "rateLimit": {
        "maxRequests": 50,
        "windowMs": 60000
      }
    },
    
    "postgres": {
      "command": "npx",
      "args": ["-y", "@modelcontextprotocol/server-postgres"],
      "env": {
        "DATABASE_URL": "${DATABASE_URL}"
      },
      "allowedTools": [
        "query",
        "list_tables",
        "describe_table"
      ],
      "timeout": 10000,
      "rateLimit": {
        "maxRequests": 200,
        "windowMs": 60000
      },
      "security": {
        "readOnly": true,
        "maxRows": 1000,
        "blockedTables": ["users", "payments"]
      }
    },
    
    "confluence": {
      "command": "npx",
      "args": ["-y", "@modelcontextprotocol/server-confluence"],
      "env": {
        "CONFLUENCE_URL": "https://myorg.atlassian.net/wiki",
        "CONFLUENCE_TOKEN": "${CONFLUENCE_TOKEN}",
        "CONFLUENCE_SPACES": "ENG,PROD"
      },
      "allowedTools": [
        "search",
        "get_page",
        "list_spaces"
      ],
      "timeout": 30000,
      "rateLimit": {
        "maxRequests": 100,
        "windowMs": 60000
      }
    }
  },
  
  "router": {
    "priority": ["github", "figma", "postgres", "confluence"],
    "fallback": "github",
    "timeout": 60000
  },
  
  "audit": {
    "enabled": true,
    "logFile": ".claude/mcp-audit.log",
    "fields": [
      "timestamp",
      "server",
      "tool",
      "parameters",
      "result_size",
      "duration_ms",
      "user"
    ],
    "sensitiveFields": [
      "password",
      "token",
      "secret",
      "api_key"
    ]
  }
}

三、实战场景:从设计到代码

3.1 场景描述

text
任务:根据 Figma 设计稿实现"用户列表"页面

输入:
- Figma 设计稿链接
- Confluence 需求文档
- 数据库 users 表
- 代码仓库 src/pages/

输出:
- React 组件代码
- API 接口代码
- 单元测试
- PR 提交

3.2 Agent 工作流

yaml
# workflow.yaml
steps:
  - step: 1
    name: "获取设计稿"
    mcp: "figma"
    tool: "get_file"
    parameters:
      fileKey: "abc123"
    output:
      - "组件结构"
      - "样式规范"
      - "交互说明"
  
  - step: 2
    name: "获取需求文档"
    mcp: "confluence"
    tool: "search"
    parameters:
      query: "用户列表页面需求"
      space: "PROD"
    output:
      - "业务规则"
      - "验收标准"
      - "边界情况"
  
  - step: 3
    name: "获取数据库 Schema"
    mcp: "postgres"
    tool: "describe_table"
    parameters:
      table: "users"
    output:
      - "字段定义"
      - "索引信息"
      - "关联关系"
  
  - step: 4
    name: "获取代码上下文"
    mcp: "github"
    tool: "list_files"
    parameters:
      path: "src/pages/"
      repo: "myorg/frontend"
    output:
      - "现有页面结构"
      - "组件规范"
      - "代码风格"
  
  - step: 5
    name: "生成代码"
    agent: "claude-code"
    input:
      - "设计稿规范"
      - "需求文档"
      - "数据库 Schema"
      - "代码上下文"
    output:
      - "UserList.tsx"
      - "UserList.test.tsx"
      - "api/users.ts"
  
  - step: 6
    name: "提交代码"
    mcp: "github"
    tool: "create_pr"
    parameters:
      repo: "myorg/frontend"
      branch: "feature/user-list"
      title: "feat: 实现用户列表页面"
      description: "根据设计稿实现用户列表页面"
    output:
      - "PR 链接"
      - "CI/CD 状态"

3.3 实际执行示例

typescript
// Agent 执行的完整流程

// 1. 获取设计稿
const figmaData = await mcp.figma.get_file({
  fileKey: "abc123",
  depth: 2
});

console.log("设计稿信息:", {
  components: figmaData.components.length,
  styles: figmaData.styles.length,
  pages: figmaData.pages.map(p => p.name)
});

// 2. 获取需求文档
const requirements = await mcp.confluence.search({
  query: "用户列表页面需求",
  space: "PROD",
  limit: 5
});

console.log("需求文档:", {
  pages: requirements.length,
  titles: requirements.map(r => r.title)
});

// 3. 获取数据库 Schema
const schema = await mcp.postgres.describe_table({
  table: "users",
  includeIndexes: true,
  includeRelations: true
});

console.log("数据库 Schema:", {
  columns: schema.columns.length,
  indexes: schema.indexes.length,
  relations: schema.relations.length
});

// 4. 获取代码上下文
const codeContext = await mcp.github.list_files({
  repo: "myorg/frontend",
  path: "src/pages/",
  recursive: true
});

console.log("代码上下文:", {
  files: codeContext.length,
  patterns: [...new Set(codeContext.map(f => f.extension))]
});

// 5. 生成代码(Agent 自动完成)
// Claude Code 会综合以上信息生成代码

// 6. 提交 PR
const pr = await mcp.github.create_pr({
  repo: "myorg/frontend",
  branch: "feature/user-list",
  title: "feat: 实现用户列表页面",
  body: `## 变更内容

根据设计稿实现用户列表页面。

### 设计稿
- Figma: https://figma.com/file/abc123

### 需求文档
- ${requirements[0].url}

### 实现细节
- 支持分页(每页 20 条)
- 支持搜索(用户名、邮箱)
- 支持排序(创建时间、最后登录时间)
- 响应式布局(移动端适配)

### 测试覆盖
- 单元测试:85%
- E2E 测试:关键流程覆盖`,
  draft: false
});

console.log("PR 已创建:", pr.url);

四、MCP 最容易踩的 5 个坑

4.1 坑 1:凭证过宽

问题:MCP Server 的 Token 权限过大,Agent 可以访问不该访问的资源。

典型案例

json
// ❌ 错误配置
{
  "github": {
    "env": {
      "GITHUB_TOKEN": "ghp_xxx"  // 有所有仓库的写权限
    }
  }
}

// 问题:Agent 可以访问所有仓库,包括私有仓库

解决方案

json
// ✅ 正确配置
{
  "github": {
    "env": {
      "GITHUB_TOKEN": "ghp_xxx",  // 只有特定仓库的读权限
      "GITHUB_REPOS": "myorg/frontend,myorg/backend"  // 限制仓库范围
    },
    "allowedTools": [
      "read_file",
      "list_files",
      "search_code"
      // 不给 create_pr、merge_pr 等写权限
    ]
  }
}

最佳实践

yaml
# credential-best-practices.yaml
principles:
  - name: "最小权限"
    description: "Token 只授予必要的权限"
    example: "只读任务不给写权限"
  
  - name: "范围限制"
    description: "限制可访问的资源范围"
    example: "GITHUB_REPOS 只列出需要的仓库"
  
  - name: "凭证隔离"
    description: "不同环境使用不同的 Token"
    example: "开发、测试、生产使用不同的 Token"
  
  - name: "定期轮换"
    description: "Token 定期更换"
    example: "每 90 天更换一次 Token"

4.2 坑 2:工具返回太多

问题:MCP 工具返回的数据量过大,超出 Agent 的上下文窗口。

典型案例

typescript
// ❌ 错误做法
const files = await mcp.github.list_files({
  repo: "myorg/large-repo",
  recursive: true  // 返回 10000+ 个文件
});

// 问题:10000 个文件的信息超出上下文窗口

解决方案

typescript
// ✅ 正确做法
const files = await mcp.github.list_files({
  repo: "myorg/large-repo",
  path: "src/pages/",  // 限制目录
  recursive: false,     // 不递归
  limit: 100            // 限制数量
});

// 或者使用分页
const files = [];
let page = 1;
while (true) {
  const result = await mcp.github.list_files({
    repo: "myorg/large-repo",
    path: "src/pages/",
    page: page,
    perPage: 50
  });
  
  files.push(...result.files);
  
  if (result.files.length < 50) break;
  page++;
}

最佳实践

yaml
# data-volume-best-practices.yaml
principles:
  - name: "限制范围"
    description: "使用 path、filter 等参数限制数据范围"
    example: "只获取 src/pages/ 目录"
  
  - name: "限制数量"
    description: "使用 limit、perPage 等参数限制数量"
    example: "每次最多获取 100 个文件"
  
  - name: "分页获取"
    description: "大数据集使用分页"
    example: "每页 50 个,逐页获取"
  
  - name: "摘要优先"
    description: "先获取摘要,需要时再获取详情"
    example: "先获取文件列表,需要时再读取内容"

4.3 坑 3:超时无回退

问题:MCP Server 响应慢或超时,Agent 卡住。

典型案例

typescript
// ❌ 错误做法
const data = await mcp.figma.get_file({
  fileKey: "abc123"
});

// 问题:Figma API 慢,等待 60 秒后超时,Agent 卡住

解决方案

typescript
// ✅ 正确做法
const data = await Promise.race([
  mcp.figma.get_file({ fileKey: "abc123" }),
  new Promise((_, reject) => 
    setTimeout(() => reject(new Error("Figma 超时")), 10000)
  )
]).catch(err => {
  console.warn("Figma 超时,使用缓存数据");
  return getCachedFigmaData("abc123");
});

配置方式

json
{
  "figma": {
    "timeout": 10000,
    "retry": {
      "maxRetries": 3,
      "delayMs": 1000
    },
    "fallback": {
      "enabled": true,
      "cacheTTL": 3600000,
      "mockData": "./mocks/figma-data.json"
    }
  }
}

最佳实践

yaml
# timeout-best-practices.yaml
principles:
  - name: "设置超时"
    description: "所有 MCP 调用必须设置超时"
    example: "timeout: 10000(10 秒)"
  
  - name: "重试机制"
    description: "超时后自动重试"
    example: "最多重试 3 次,每次间隔 1 秒"
  
  - name: "回退方案"
    description: "超时后使用缓存或 Mock 数据"
    example: "使用本地缓存的设计稿数据"
  
  - name: "降级策略"
    description: "关键 MCP 不可用时降级处理"
    example: "Figma 不可用时使用文字描述"

4.4 坑 4:上下文污染

问题:多个 MCP 返回的信息互相冲突,Agent 困惑。

典型案例

text
Figma 设计稿:按钮颜色 #3B82F6(蓝色)
Confluence 需求:按钮颜色 #EF4444(红色)

问题:Agent 不知道用哪个颜色

解决方案

yaml
# context-priority.yaml
strategy: "定义 MCP 优先级"

priority:
  - name: "设计稿(Figma)"
    priority: 1
    scope: "UI 样式、布局、交互"
  
  - name: "需求文档(Confluence)"
    priority: 2
    scope: "业务规则、功能需求"
  
  - name: "数据库(PostgreSQL)"
    priority: 3
    scope: "数据结构、字段定义"
  
  - name: "代码仓库(GitHub)"
    priority: 4
    scope: "实现细节、代码规范"

conflict_resolution:
  - rule: "UI 样式以设计稿为准"
    example: "颜色、字体、间距以 Figma 为准"
  
  - rule: "业务规则以需求文档为准"
    example: "功能逻辑、边界条件以 Confluence 为准"
  
  - rule: "数据结构以数据库为准"
    example: "字段名、类型以 PostgreSQL 为准"

最佳实践

yaml
# context-management.yaml
principles:
  - name: "明确优先级"
    description: "定义不同 MCP 的优先级"
    example: "设计稿 > 需求文档 > 数据库 > 代码"
  
  - name: "明确职责"
    description: "每个 MCP 负责特定的信息领域"
    example: "Figma 负责 UI,Confluence 负责业务"
  
  - name: "冲突检测"
    description: "检测不同 MCP 的信息冲突"
    example: "颜色和需求的颜色不一致时告警"
  
  - name: "人工确认"
    description: "冲突时请求人工确认"
    example: "颜色冲突时询问设计师"

4.5 坑 5:缺少调用审计

问题:不知道 Agent 调用了哪些 MCP、访问了哪些数据。

典型案例

text
问题:Agent 访问了 users 表,但不知道为什么
结果:无法追踪数据访问,存在安全隐患

解决方案

json
// .claude/mcp-audit.json
{
  "enabled": true,
  "logFile": ".claude/mcp-audit.log",
  "format": "json",
  "fields": [
    "timestamp",
    "session_id",
    "user",
    "server",
    "tool",
    "parameters",
    "result_size",
    "duration_ms",
    "status"
  ],
  "sensitiveFields": [
    "password",
    "token",
    "secret",
    "api_key",
    "ssn",
    "credit_card"
  ],
  "redaction": {
    "enabled": true,
    "replacement": "***REDACTED***"
  },
  "rotation": {
    "enabled": true,
    "maxSize": "100MB",
    "maxFiles": 10
  }
}

审计日志示例

json
// .claude/mcp-audit.log
[
  {
    "timestamp": "2024-01-15T10:30:00Z",
    "session_id": "sess_abc123",
    "user": "developer@example.com",
    "server": "github",
    "tool": "read_file",
    "parameters": {
      "repo": "myorg/frontend",
      "path": "src/pages/UserList.tsx"
    },
    "result_size": 15234,
    "duration_ms": 234,
    "status": "success"
  },
  {
    "timestamp": "2024-01-15T10:30:05Z",
    "session_id": "sess_abc123",
    "user": "developer@example.com",
    "server": "postgres",
    "tool": "query",
    "parameters": {
      "sql": "SELECT * FROM users LIMIT 10"
    },
    "result_size": 8923,
    "duration_ms": 456,
    "status": "success"
  },
  {
    "timestamp": "2024-01-15T10:30:10Z",
    "session_id": "sess_abc123",
    "user": "developer@example.com",
    "server": "figma",
    "tool": "get_file",
    "parameters": {
      "fileKey": "abc123"
    },
    "result_size": 45678,
    "duration_ms": 1234,
    "status": "success"
  }
]

最佳实践

yaml
# audit-best-practices.yaml
principles:
  - name: "全量记录"
    description: "记录所有 MCP 调用"
    example: "包括成功的和失败的"
  
  - name: "敏感信息脱敏"
    description: "自动脱敏敏感字段"
    example: "密码、Token、身份证号"
  
  - name: "定期审计"
    description: "定期审查审计日志"
    example: "每周审查一次异常访问"
  
  - name: "告警机制"
    description: "异常访问自动告警"
    example: "访问敏感表时告警"
  
  - name: "日志保留"
    description: "日志保留足够长时间"
    example: "保留 90 天用于审计"

五、凭证隔离方案

5.1 环境变量隔离

bash
# .env.development
GITHUB_TOKEN=ghp_dev_xxx
FIGMA_TOKEN=figd_dev_xxx
DATABASE_URL=postgresql://dev:password@localhost:5432/dev_db
CONFLUENCE_TOKEN=conf_dev_xxx

# .env.production
GITHUB_TOKEN=ghp_prod_xxx
FIGMA_TOKEN=figd_prod_xxx
DATABASE_URL=postgresql://prod:password@prod-db:5432/prod_db
CONFLUENCE_TOKEN=conf_prod_xxx

5.2 配置文件隔离

json
// .claude/mcp-config.dev.json
{
  "mcpServers": {
    "github": {
      "env": {
        "GITHUB_TOKEN": "${GITHUB_TOKEN}",
        "GITHUB_REPOS": "myorg/frontend-dev"
      }
    },
    "postgres": {
      "env": {
        "DATABASE_URL": "${DATABASE_URL}"
      },
      "security": {
        "readOnly": false,
        "blockedTables": []
      }
    }
  }
}

// .claude/mcp-config.prod.json
{
  "mcpServers": {
    "github": {
      "env": {
        "GITHUB_TOKEN": "${GITHUB_TOKEN}",
        "GITHUB_REPOS": "myorg/frontend"
      }
    },
    "postgres": {
      "env": {
        "DATABASE_URL": "${DATABASE_URL}"
      },
      "security": {
        "readOnly": true,
        "blockedTables": ["users", "payments"]
      }
    }
  }
}

5.3 权限控制矩阵

环境 GitHub Figma PostgreSQL Confluence
开发 读写(dev 仓库) 只读 读写(dev 库) 只读
测试 只读 只读 只读(test 库) 只读
生产 只读(prod 仓库) 只读 只读(屏蔽敏感表) 只读

六、工具调用审计 JSON

6.1 审计日志结构

json
{
  "audit_log": {
    "version": "1.0",
    "entries": [
      {
        "id": "audit_001",
        "timestamp": "2024-01-15T10:30:00Z",
        "session": {
          "id": "sess_abc123",
          "user": "developer@example.com",
          "ip": "192.168.1.100"
        },
        "mcp": {
          "server": "github",
          "tool": "read_file",
          "version": "1.2.0"
        },
        "request": {
          "parameters": {
            "repo": "myorg/frontend",
            "path": "src/pages/UserList.tsx",
            "ref": "main"
          },
          "size_bytes": 234
        },
        "response": {
          "status": "success",
          "size_bytes": 15234,
          "duration_ms": 234
        },
        "context": {
          "task_id": "task_xyz789",
          "workflow_step": 4,
          "purpose": "获取代码上下文"
        }
      }
    ]
  }
}

6.2 审计分析脚本

python
# scripts/analyze-mcp-audit.py
import json
from datetime import datetime, timedelta
from collections import defaultdict

def analyze_audit_log(log_file):
    """分析 MCP 审计日志"""
    
    with open(log_file) as f:
        entries = json.load(f)["audit_log"]["entries"]
    
    # 统计各 MCP Server 的调用次数
    server_stats = defaultdict(lambda: {"count": 0, "total_duration": 0})
    
    for entry in entries:
        server = entry["mcp"]["server"]
        server_stats[server]["count"] += 1
        server_stats[server]["total_duration"] += entry["response"]["duration_ms"]
    
    # 统计各工具的调用次数
    tool_stats = defaultdict(int)
    
    for entry in entries:
        tool = f"{entry['mcp']['server']}.{entry['mcp']['tool']}"
        tool_stats[tool] += 1
    
    # 检测异常访问
    anomalies = []
    
    for entry in entries:
        # 检测访问敏感表
        if entry["mcp"]["server"] == "postgres":
            sql = entry["request"]["parameters"].get("sql", "")
            if "users" in sql or "payments" in sql:
                anomalies.append({
                    "type": "sensitive_table_access",
                    "entry": entry,
                    "severity": "HIGH"
                })
        
        # 检测大量数据访问
        if entry["response"]["size_bytes"] > 1000000:  # 1MB
            anomalies.append({
                "type": "large_data_access",
                "entry": entry,
                "severity": "MEDIUM"
            })
        
        # 检测慢查询
        if entry["response"]["duration_ms"] > 5000:  # 5 秒
            anomalies.append({
                "type": "slow_query",
                "entry": entry,
                "severity": "MEDIUM"
            })
    
    # 生成报告
    report = {
        "summary": {
            "total_calls": len(entries),
            "servers": dict(server_stats),
            "tools": dict(tool_stats),
            "anomalies": len(anomalies)
        },
        "anomalies": anomalies,
        "recommendations": []
    }
    
    # 生成建议
    if anomalies:
        report["recommendations"].append(
            f"发现 {len(anomalies)} 个异常访问,建议审查"
        )
    
    for server, stats in server_stats.items():
        avg_duration = stats["total_duration"] / stats["count"]
        if avg_duration > 1000:
            report["recommendations"].append(
                f"{server} 平均响应时间 {avg_duration:.0f}ms,建议优化"
            )
    
    return report

if __name__ == "__main__":
    report = analyze_audit_log(".claude/mcp-audit.log")
    print(json.dumps(report, indent=2))

七、真实经验与踩坑

7.1 第一次翻车:Figma Token 权限过大

场景:给 Agent 配置了 Figma Token,有所有设计稿的编辑权限。

结果:Agent 误操作,删除了一个设计稿的组件。

教训

  • MCP Token 必须遵循最小权限原则
  • 只读任务不给写权限
  • 定期审查 Token 权限

7.2 第二次翻车:数据库查询返回 10 万行

场景:Agent 查询 users 表,没有加 LIMIT,返回 10 万行数据。

结果:超出上下文窗口,Agent 崩溃。

教训

  • 所有数据库查询必须加 LIMIT
  • 使用 MCP 的 security.maxRows 配置限制返回行数
  • 大数据集使用分页

7.3 第三次翻车:设计和需求冲突

场景:Figma 设计稿按钮颜色是蓝色,Confluence 需求文档是红色。

结果:Agent 困惑,生成的代码颜色不对。

教训

  • 必须定义 MCP 优先级(设计稿 > 需求文档)
  • 冲突时请求人工确认
  • 在 Prompt 中明确说明优先级

八、总结

MCP 组合使用可以让 Agent 拥有全链路的信息访问能力,但需要注意 5 个关键问题:

  1. 凭证过宽:遵循最小权限原则,限制 Token 权限和资源范围
  2. 工具返回太多:使用 limit、filter 等参数限制数据量,使用分页
  3. 超时无回退:设置超时、重试机制和回退方案
  4. 上下文污染:定义 MCP 优先级,冲突时请求人工确认
  5. 缺少调用审计:全量记录 MCP 调用,敏感信息脱敏,定期审计

最佳实践

  • 凭证隔离:不同环境使用不同的 Token
  • 权限控制:生产环境只读,屏蔽敏感表
  • 审计日志:全量记录,敏感字段脱敏
  • 降级策略:关键 MCP 不可用时有回退方案

最终建议

MCP 组合是 Agent 工作流的核心基础设施,但必须谨慎配置和管理。把 MCP 当作"外部系统接口",遵循"最小权限、只读优先、全量审计"的原则。

九、系列导航

上一篇:Lab 011:Agent 做大型重构的上限在哪里? 下一篇:生产级 Agent 平台路线图:从 CLI 试点到研发基础设施