post cover

技术热点落地:MCP 协议与企业 AI Agent 工具集成(2026-05-07)


适用场景与目标

适用场景

MCP(Model Context Protocol)适用于以下场景:

  • 企业知识库对接:让 AI Agent 实时查询内部 CRM、ERP、Wiki 等系统
  • 开发流程自动化:AI 编程工具(如 Cursor、Claude Code)调用内部代码库、CI/CD 系统
  • 多工具编排:一个 Agent 同时调用飞书、GitHub、Jira 等多个外部服务
  • 数据平台集成:将数据仓库、BI 工具的能力暴露给大模型

目标

本篇聚焦:在一周内,从零搭建一个连接企业内部工具的 MCP Server,并将它接入 Claude Desktop / Cursor,实现可演示的原型


最小可行方案(MVP)步骤

步骤一:搞清 MCP 核心架构

MCP 采用 客户端-服务器架构,分为三层:

┌──────────────┐      MCP Protocol (JSON-RPC 2.0)      ┌─────────────────┐
│  MCP Host    │  ←───  Claude Desktop / Cursor / ...  │   MCP Server    │
│  (AI 应用)   │                                      │ (你的工具封装)   │
└──────────────┘                                      └────────┬────────┘

                                                         你的业务系统
                                                         (DB / API / 文件)
  • MCP Host:内置 MCP Client 的 AI 应用(Claude Desktop、Cursor 等)
  • MCP Server:用 SDK(TypeScript/Python)封装你的工具,以 JSON-RPC 2.0 对外提供服务
  • Transport:支持两种传输层:stdio(本地 CLI)和 streamable-http(生产环境推荐)

步骤二:安装 MCP SDK

# Node.js 环境(TypeScript SDK)
npm install @modelcontextprotocol/sdk

# Python 环境(Python SDK)
pip install mcp

验证安装:

node -e "const { Server } = require('@modelcontextprotocol/sdk'); console.log('OK');"

步骤三:编写一个最小 MCP Server(TypeScript)

创建文件 src/server.ts

import { Server } from "@modelcontextprotocol/sdk/server.js";
import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
import {
  CallToolRequestSchema,
  ListToolsRequestSchema,
} from "@modelcontextprotocol/sdk/types.js";

// 定义工具列表
const TOOLS = [
  {
    name: "search_internal_kb",
    description: "搜索内部知识库,返回相关文档摘要",
    inputSchema: {
      type: "object",
      properties: {
        query: { type: "string", description: "搜索关键词" },
        limit: { type: "number", description: "返回结果数量上限", default: 5 },
      },
      required: ["query"],
    },
  },
  {
    name: "create_task",
    description: "在任务系统中创建待办事项",
    inputSchema: {
      type: "object",
      properties: {
        title: { type: "string" },
        assignee: { type: "string" },
        due_date: { type: "string" },
      },
      required: ["title"],
    },
  },
];

const server = new Server(
  { name: "enterprise-mcp-server", version: "1.0.0" },
  { capabilities: { tools: {} } }
);

// 暴露工具列表
server.setRequestHandler(ListToolsRequestSchema, async () => ({
  tools: TOOLS,
}));

// 处理工具调用
server.setRequestHandler(CallToolRequestSchema, async (request) => {
  const { name, arguments: args } = request.params;

  try {
    if (name === "search_internal_kb") {
      // TODO: 替换为真实知识库查询
      const results = await searchKnowledgeBase(args.query, args.limit ?? 5);
      return { content: [{ type: "text", text: JSON.stringify(results) }] };
    }

    if (name === "create_task") {
      const task = await createTask(args.title, args.assignee, args.due_date);
      return { content: [{ type: "text", text: `任务创建成功: ${task.id}` }] };
    }

    throw new Error(`Unknown tool: ${name}`);
  } catch (err: any) {
    return { content: [{ type: "text", text: `Error: ${err.message}` }], isError: true };
  }
});

// 启动服务器
const transport = new StdioServerTransport();
server.connect(transport).catch(console.error);

步骤四:打包并注册到 Claude Desktop

  1. 编译 TypeScript
npx tsc src/server.ts --outDir dist --esModuleInterop
  1. 配置 Claude Desktop

    macOS 路径:~/Library/Application Support/Claude/claude_desktop_config.json

    Windows 路径:%APPDATA%\Claude\claude_desktop_config.json

{
  "mcpServers": {
    "enterprise-kb": {
      "command": "node",
      "args": ["/absolute/path/to/dist/server.js"],
      "env": {
        "KB_API_KEY": "your-api-key-here"
      }
    }
  }
}
  1. 重启 Claude Desktop,在设置 → MCP 中确认服务器状态为绿色。

步骤五:验证工具可用

在 Claude Desktop 对话框中测试:

请帮我搜索"Q3 财务报告",然后在任务系统中创建一个待办事项,提醒小明在周五前review这份报告。

关键实现细节

生产级 HTTP Transport(替代 Stdio)

本地开发用 Stdio 没问题,但生产环境推荐 streamable-http

import { StreamableHTTPServerTransport } from "@modelcontextprotocol/sdk/server/streamable-http.js";

const transport = new StreamableHTTPServerTransport({
  port: 3001,
  // 开启健康检查端点
  healthCheckEndpoint: "/health",
  // 请求超时(毫秒)
  timeoutMs: 60000,
});

server.connect(transport);

配合 Nginx 反向代理,配置 HTTPS 和基础认证:

location /mcp/ {
    proxy_pass http://127.0.0.1:3001/;
    proxy_set_header Host $host;
    proxy_set_header X-Real-IP $remote_addr;
    # MCP 需要支持 WebSocket
    proxy_http_version 1.1;
    proxy_set_header Upgrade $http_upgrade;
    proxy_set_header Connection "upgrade";
}

工具调用结果缓存

减少重复调用,降低延迟和 API 成本:

const cache = new Map<string, { result: any; expiry: number }>();

async function cachedCall(tool: string, args: any) {
  const key = `${tool}:${JSON.stringify(args)}`;
  const entry = cache.get(key);
  if (entry && entry.expiry > Date.now()) {
    return entry.result;
  }
  const result = await actualCall(tool, args);
  cache.set(key, { result, expiry: Date.now() + 5 * 60 * 1000 }); // 5min TTL
  return result;
}

多租户隔离

企业场景下,不同用户访问不同数据:

server.setRequestHandler(CallToolRequestSchema, async (request) => {
  // 从 HTTP Header 获取租户标识
  const tenantId = request.headers?.["x-tenant-id"] ?? "default";
  const userPermissions = await getUserPermissions(tenantId, request.params);

  if (!userPermissions.includes(request.params.name)) {
    return {
      content: [{ type: "text", text: "权限不足" }],
      isError: true,
    };
  }
  // ...执行业务逻辑
});

常见坑与规避清单

坑一:MCP Server 返回格式错误

MCP 严格要求工具返回 content 数组,不是直接返回字符串

❌ 错误:

return { content: "结果" };

✅ 正确:

return { content: [{ type: "text", text: "结果" }] };

坑二:Stdio 模式下进程卡住不退出

MCP Stdio 模式使用 stdin/stdout 进行通信,不要在代码中任何地方使用 console.log 打印非 JSON 内容。所有调试输出请写日志文件或使用 stderr

import { log } from "./logger.js"; // 写文件日志
log.error("连接失败:", err); // 不走 stdout

坑三:长时运行任务超时

MCP 默认 tool call 超时较短(60s)。对于 AI 分析、批量查询等长任务:

// 在工具定义中使用 verbose 描述耗时
{
  name: "bulk_export",
  description: "批量导出数据(可能需要 2-5 分钟)⏱ 此操作耗时较长",
  ...
}

同时在调用侧使用 timeoutMs 配置:

const result = await client.callTool({
  name: "bulk_export",
  arguments: { format: "csv" },
}, { timeoutMs: 300000 }); // 5 分钟超时

坑四:生产环境安全漏洞

MCP Server 通常有公司内部系统的高权限,绝对不要

// ❌ 绝对不要这样做:直接用 admin token 查询全量数据
const result = await db.query(`SELECT * FROM ${userInput}`);

✅ 生产环境必须:

  1. 参数化查询防注入
  2. MCP Server 部署在独立网络域,最小权限访问后端
  3. 添加请求签名验证(HMAC)

坑五:上下文膨胀(Context Bloat)

MCP 工具描述太多会导致每次请求 context 膨胀,影响模型推理速度和成本。

建议:按需加载工具,不在 Server 启动时暴露所有工具。实现动态工具注册:

// 只在需要时暴露特定工具集
function getToolsForUser(userRole: string) {
  const base = [...BASE_TOOLS];
  if (userRole === "admin") base.push(...ADMIN_TOOLS);
  if (userRole === "analyst") base.push(...ANALYTICS_TOOLS);
  return base;
}

成本/性能/维护权衡

部署方案对比

方案适用规模月成本(估算)延迟维护难度
本地 Stdio(Claude Desktop)个人/小团队原型$0<50ms
单机 HTTP Server(2核4G)50人以内的团队¥200-50050-200ms
K8s 容器化(多副本)中型企业¥2000-800030-150ms中高
云函数(按调用计费)低频调用按量计费200-800ms

性能关键点

  • P50 延迟:主要瓶颈在工具调用后端 API,MCP 协议本身 overhead < 5ms
  • 吞吐量:单 Node.js 进程约 500 QPS,多 worker 模式可线性扩展
  • 上下文成本:每次工具调用结果会写回 context window,需控制返回数据量(建议 < 8KB/条)

维护建议

  1. 版本化你的 MCP Server:每次更新工具 schema 时升版本号,避免破坏性变更
  2. 健康检查:实现 /health 端点,接入 Prometheus + Grafana
  3. Schema 变更日志:维护 CHANGELOG.md,记录每个工具的入参出参变化

一周内可执行行动清单

Day 1-2:本地原型

  • 安装 @modelcontextprotocol/sdk(TypeScript 或 Python)
  • 阅读官方 MCP 规范文档(modelcontextprotocol.io
  • 跑通官方 examples 中的 file-system 示例
  • 用 Stdio Transport 跑通第一个自定义工具

Day 3-4:连接真实系统

  • 选择一个企业内部系统(Wiki / Task / CRM)作为第一个 MCP Server 目标
  • 实现该系统的 MCP Server 封装(真实 API 调用)
  • 配置 Claude Desktop MCP 客户端,验证端到端调用

Day 5:生产准备

  • 从 Stdio 迁移到 streamable-http Transport
  • 添加健康检查 /health 端点
  • 编写 Dockerfile,支持一键部署

Day 6-7:安全与文档

  • 实现 HMAC 请求签名验证
  • 补充工具的完整 JSON Schema 描述(AI 靠它理解工具用法)
  • 撰写内部文档:如何注册新工具、如何排错

延伸阅读


MCP 已成为 2026 年 AI Agent 工具集成的实施标准。越早掌握落地方法,越能在企业 AI 竞争中占据先机。