MCP协议完全教程:AI Agent工具集成标准与实战完全指南(2026)

3次阅读
没有评论

一、开场:为什么我的AI Agent总是个”残疾人”?

大家好,我是老金。

你们有没有这种感觉:

AI Agent听起来很强大,但真正用起来,总感觉缺胳膊少腿?

比如:

  • 让它查个天气,它说”我没有联网功能”
  • 让它发个邮件,它说”我做不到”
  • 让它读个PDF,它说”我不支持”

这不就是个残疾人吗?

我之前也一直被这个问题困扰。

直到我接触了MCP协议

今天这篇文章,就是MCP协议的完全指南。

内容包括:

  1. MCP协议是什么?解决什么问题?
  2. MCP协议架构详解
  3. MCP Server开发实战
  4. MCP Client集成实战
  5. 完整项目示例
  6. 常见问题与解决方案
  7. MCP生态现状与未来

看完这篇,你的AI Agent将不再是个”残疾人”,而是全能选手

二、MCP协议是什么?

2.1 问题背景

在MCP出现之前,给AI Agent扩展能力,是这样的:

GPT-4
  ↓ 需要什么能力
开发者A写搜索插件
开发者B写邮件插件
开发者C写数据库插件
...
  ↓ 每个都不同
GPT-4 需要适配所有插件
  ↓ 噩梦
插件A用"search"接口
插件B用"query"接口
插件C用"find"接口
混乱!不可维护!

每个插件有自己的接口定义,AI需要适配所有插件。

这就是所谓的“Plugin Hell”

2.2 MCP的定义

MCP(Model Context Protocol) = AI模型的USB接口

就像USB统一了各种设备的连接方式,MCP统一了AI与外部工具的交互方式。

     AI Agent
        │
        │  统一接口(MCP)
        │
  ┌─────┴─────┐
  │           │
Search    Email    Database
(MCP)     (MCP)      (MCP)

核心思想

  • 接口标准化:所有工具用同一套协议
  • 即插即用:新工具不需要改AI代码
  • 双向通信:不只是”调用工具”,还能”接收数据”
  • 安全可控:工具调用有明确的权限控制

2.3 MCP vs 传统Plugin

维度 传统Plugin MCP
接口规范 每个插件自定义 统一协议
接入成本 高(需要适配每个插件) 低(一次接入,所有工具可用)
扩展性 差(插件多了就乱) 好(像搭积木一样)
双向通信 不支持 支持
工具发现 手动配置 自动发现
标准化程度 高(Anthropic主导)

三、MCP协议架构详解

3.1 核心组件

┌─────────────────────────────────────────────────────────┐
│                    MCP Host                              │
│                   (Claude App)                           │
└─────────────────────────────────────────────────────────┘
                          │
                          │ MCP Protocol
                          │
┌───────────────┬─────────────────────────┬───────────────┐
│  MCP Client   │                         │  MCP Client   │
└───────┬───────┘                         └───────┬───────┘
        │                                       │
        │ MCP Protocol                          │ MCP Protocol
        │                                       │
┌───────┴───────┐                         ┌───────┴───────┐
│  MCP Server   │                         │  MCP Server   │
│  (File System)│                         │  (Web Search) │
└───────────────┘                         └───────────────┘

组件说明

  • MCP Host:用户使用的AI应用(如Claude Desktop)
  • MCP Client:Host内的客户端,负责与Server通信
  • MCP Server:工具提供者,每个Server提供一类工具
  • MCP Protocol:通信协议(JSON-RPC 2.0)

3.2 通信流程

1. 初始化
   Client → Server: initialize (协议版本、客户端能力)
   Server → Client: initialized (确认、Server能力)
  1. 工具发现 Client → Server: tools/list Server → Client: 工具列表 (name, description, inputSchema)
  2. 工具调用 Client → Server: tools/call (tool name, arguments) Server → Client: 工具结果 (content, isError)
  3. 资源访问 (可选) Client → Server: resources/list Client → Server: resources/read (resource URI)
  4. 提示模板 (可选) Client → Server: prompts/list Client → Server: prompts/get (prompt name, arguments)

3.3 工具定义格式

{
  "name": "web_search",
  "description": "搜索互联网获取最新信息",
  "inputSchema": {
    "type": "object",
    "properties": {
      "query": {
        "type": "string",
        "description": "搜索关键词"
      },
      "num_results": {
        "type": "integer",
        "description": "返回结果数量",
        "default": 5
      }
    },
    "required": ["query"]
  }
}

四、MCP Server开发实战

4.1 项目结构

my-mcp-server/
├── src/
│   ├── index.ts          # 入口文件
│   ├── tools/
│   │   ├── search.ts     # 搜索工具
│   │   ├── email.ts      # 邮件工具
│   │   └── database.ts   # 数据库工具
│   └── types/
│       └── index.ts      # 类型定义
├── package.json
├── tsconfig.json
└── README.md

4.2 基础Server实现

import { McpServer } from "@modelcontextprotocol/sdk/server";
import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio";
import { z } from "zod";

// 创建Server实例 const server = new McpServer({ name: “my-mcp-server”, version: “1.0.0”, });

// 注册搜索工具 server.tool( “web_search”, “搜索互联网获取最新信息”, { query: z.string().describe(“搜索关键词”), num_results: z.number().optional().default(5).describe(“返回结果数量”), }, async ({ query, num_results }) => { // 实现搜索逻辑 const results = await searchEngine.search(query, num_results);

return {
  content: [
    {
      type: "text",
      text: JSON.stringify(results, null, 2),
    },
  ],
};

}
);

// 注册邮件工具
server.tool(
“send_email”,
“发送电子邮件”,
{
to: z.string().email().describe(“收件人邮箱”),
subject: z.string().describe(“邮件主题”),
body: z.string().describe(“邮件内容”),
},
async ({ to, subject, body }) => {
try {
await emailClient.send({ to, subject, body });
return {
content: [{ type: “text”, text: “邮件发送成功” }],
isError: false,
};
} catch (error) {
return {
content: [{ type: “text”, text: 发送失败: ${error.message} }],
isError: true,
};
}
}
);

// 启动Server
async function main() {
const transport = new StdioServerTransport();
await server.connect(transport);
console.error(“MCP Server started”);
}

main().catch(console.error);

4.3 资源访问实现

// 注册资源
server.resource(
  "customer-data",
  "Customers数据库表结构",
  async (uri) => {
    const tableName = uri.pathname.replace("/", "");
    const schema = await db.getTableSchema(tableName);
return {
  contents: [
    {
      uri: uri.toString(),
      mimeType: "application/json",
      text: JSON.stringify(schema, null, 2),
    },
  ],
};

}
);

// 带参数的动态资源
server.resourceTemplate(
“customer/{id}”,
“单个客户信息”,
async (uri) => {
const customerId = uri.variables.id;
const customer = await db.getCustomer(customerId);

return {
  contents: [
    {
      uri: uri.toString(),
      mimeType: "application/json",
      text: JSON.stringify(customer, null, 2),
    },
  ],
};

}
);

4.4 提示模板实现

// 注册提示模板
server.prompt(
  "analyze_customer",
  "分析客户数据",
  {
    customer_id: z.string().describe("客户ID"),
    analysis_type: z
      .enum(["summary", "risk", "opportunity"])
      .describe("分析类型"),
  },
  ({ customer_id, analysis_type }) => {
    return {
      description: `分析客户 ${customer_id} 的${analysis_type}情况`,
      messages: [
        {
          role: "user",
          content: {
            type: "text",
            text: `请分析客户ID为 ${customer_id} 的数据,
                  进行${analysis_type}分析,
                  包括关键指标、风险点、改进建议。`,
          },
        },
      ],
    };
  }
);

五、MCP Client集成实战

5.1 OpenClaw集成MCP

# config.yaml
mcp:
  enabled: true

MCP Server配置

servers:

  • name: “filesystem” command: “npx” args: [“-y”, “@modelcontextprotocol/server-filesystem”, “/home/user”]
  • name: “web-search” command: “python” args: [“/path/to/search_server.py”] env: SEARCH_API_KEY: “${SEARCH_API_KEY}”
  • name: “custom-tools” command: “node” args: [“/path/to/my-mcp-server/dist/index.js”]

安全配置

security: allowed_servers:

  • “filesystem”
  • “web-search” blocked_tools:
  • “delete_file”
  • “format_disk”

5.2 Claude Desktop集成MCP

# claude_desktop_config.json
{
  "mcpServers": {
    "filesystem": {
      "command": "npx",
      "args": ["-y", "@modelcontextprotocol/server-filesystem", "/Users/jin/Projects"]
    },
    "web-search": {
      "command": "uvx",
      "args": ["mcp-server-search"],
      "env": {
        "SEARCH_API_KEY": "your-api-key"
      }
    },
    "slack": {
      "command": "node",
      "args": ["/path/to/slack-mcp-server/dist/index.js"],
      "env": {
        "SLACK_BOT_TOKEN": "${SLACK_BOT_TOKEN}",
        "SLACK_TEAM_ID": "T0123456789"
      }
    }
  }
}

5.3 编程方式集成

import { Client } from "@modelcontextprotocol/sdk/client";

async function main() { // 创建Client const client = new Client( { name: “my-agent”, version: “1.0.0”, }, { capabilities: { tools: {}, resources: {}, prompts: {}, }, } );

// 连接Server await client.connect( new StdioClientTransport({ command: “node”, args: [“/path/to/my-server/dist/index.js”], }) );

// 列出可用工具 const tools = await client.listTools(); console.log(“可用工具:”, tools.map((t) => t.name));

// 调用工具 const result = await client.callTool({ name: “web_search”, arguments: { query: “OpenClaw AI Agent”, num_results: 3, }, });

console.log(“搜索结果:”, result.content);

// 读取资源 const resources = await client.listResources(); const resourceContent = await client.readResource(resources[0].uri);

// 使用提示模板 const prompts = await client.listPrompts(); const promptResult = await client.getPrompt({ name: “analyze_customer”, arguments: { customer_id: “C001”, analysis_type: “risk”, }, });

// 断开连接 await client.close(); }

main();

六、完整项目示例

6.1 企业知识库MCP Server

// knowledge_base_server.ts
import { McpServer } from "@modelcontextprotocol/sdk/server";
import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio";
import { z } from "zod";
import { ChromaClient } from "chromadb";
import { OpenAIEmbeddings } from "langchain/embeddings/openai";

// 初始化向量数据库 const chroma = new ChromaClient({ path: “http://localhost:8000” }); const embeddings = new OpenAIEmbeddings();

// 创建Server const server = new McpServer({ name: “knowledge-base”, version: “1.0.0”, });

// 工具1:语义搜索 server.tool( “search_knowledge”, “在企业知识库中搜索相关内容”, { query: z.string().describe(“搜索query”), top_k: z.number().optional().default(5).describe(“返回结果数量”), collection: z.string().optional().default(“documents”).describe(“知识库集合”), }, async ({ query, top_k, collection }) => { try { // 生成query embedding const queryEmbedding = await embeddings.embedQuery(query);

  // 查询向量数据库
  const collection_obj = chroma.getCollection({
    name: collection,
    embeddingFunction: embeddings,
  });

  const results = await collection_obj.query({
    queryEmbeddings: [queryEmbedding],
    nResults: top_k,
  });

  // 格式化结果
  const formatted = results.documents[0].map((doc, i) => ({
    content: doc,
    score: results.distances[0][i],
    metadata: results.metadatas[0][i],
  }));

  return {
    content: [
      {
        type: "text",
        text: JSON.stringify(formatted, null, 2),
      },
    ],
  };
} catch (error) {
  return {
    content: [{ type: "text", text: `搜索失败: ${error.message}` }],
    isError: true,
  };
}

}
);

// 工具2:添加文档
server.tool(
“add_document”,
“向知识库添加新文档”,
{
content: z.string().describe(“文档内容”),
metadata: z
.object({
title: z.string(),
source: z.string(),
tags: z.array(z.string()).optional(),
})
.describe(“文档元信息”),
},
async ({ content, metadata }) => {
try {
const collection = chroma.getCollection({
name: “documents”,
embeddingFunction: embeddings,
});

  await collection.add({
    ids: [crypto.randomUUID()],
    documents: [content],
    metadatas: [metadata],
  });

  return {
    content: [{ type: "text", text: "文档添加成功" }],
    isError: false,
  };
} catch (error) {
  return {
    content: [{ type: "text", text: `添加失败: ${error.message}` }],
    isError: true,
  };
}

}
);

// 工具3:列出所有文档
server.tool(
“list_documents”,
“列出知识库中的所有文档”,
{
limit: z.number().optional().default(100).describe(“返回数量限制”),
},
async ({ limit }) => {
const collection = chroma.getCollection({
name: “documents”,
embeddingFunction: embeddings,
});

const results = await collection.get({ limit });

return {
  content: [
    {
      type: "text",
      text: JSON.stringify(
        results.ids.map((id, i) => ({
          id,
          metadata: results.metadatas[i],
        })),
        null,
        2
      ),
    },
  ],
};

}
);

// 启动
async function main() {
const transport = new StdioServerTransport();
await server.connect(transport);
}

main().catch(console.error);

6.2 在AI Agent中使用

# config.yaml
mcp:
  servers:
    - name: "knowledge-base"
      command: "node"
      args: ["/path/to/knowledge_base_server/dist/index.js"]
      env:
        OPENAI_API_KEY: "${OPENAI_API_KEY}"

agent配置

agent: system_prompt: | 你是一个智能助手,可以访问企业知识库。 可用工具:

  • search_knowledge: 搜索知识库
  • add_document: 添加文档到知识库
  • list_documents: 列出知识库中的文档
当用户询问公司政策、流程、技术文档时,
请先搜索知识库,找到相关信息后再回答。

七、常见问题与解决方案

Q1: MCP Server启动失败?

检查清单

# 1. 检查Node.js/Python版本
node --version  # 需要 18+
python --version  # 需要 3.8+

2. 检查依赖安装

npm list @modelcontextprotocol/sdk pip list mcp

3. 检查命令路径

which npx which node

4. 查看错误日志

node server.js 2>&1

Q2: 工具调用超时?

原因:工具执行时间太长。

解决

# 客户端配置超时
const client = new Client({...}, {
  timeout: 30000,  // 30秒超时
});

或者在工具实现中返回进度

return { content: [{ type: “text”, text: “处理中,已完成30%…” }], isError: false, progress: 0.3 };

Q3: 安全问题?

建议

  • 限制可用工具(白名单)
  • 敏感操作需要二次确认
  • 日志记录所有工具调用
  • 定期审计权限配置
# config.yaml
mcp:
  security:
    # 只允许特定工具
    allowed_tools:
      - "search_knowledge"
      - "send_email"
# 禁止危险操作
blocked_tools:
  - "delete_all"
  - "format_disk"
  - "exec_system"

# 需要确认的工具
confirm_tools:
  - "send_email"
  - "delete_document"

Q4: 多Server冲突?

原因:多个Server定义了同名工具。

解决:使用命名空间

# config.yaml
mcp:
  servers:
    - name: "knowledge-base"
      prefix: "kb_"  # 工具名加前缀
      command: "node"
      args: [...]
- name: "filesystem"
  prefix: "fs_"  # 避免冲突
  command: "node"
  args: [...]

八、MCP生态现状与未来

8.1 官方Server

官方提供的MCP Server:

  • Filesystem:文件系统操作
  • Git:Git版本控制
  • Memory:持久化记忆
  • SQLite:SQLite数据库
  • AWS KB Retrieval:AWS知识库
  • Google Maps:地图服务
  • Brave Search:网页搜索

8.2 社区Server

社区贡献的Server:

  • Slack:Slack消息
  • GitHub:GitHub API
  • PostgreSQL:PostgreSQL数据库
  • Puppeteer:浏览器自动化
  • Stripe:支付集成
  • Notion:Notion笔记

8.3 未来趋势

趋势1:标准化普及

MCP正在成为AI工具集成的事实标准

趋势2:企业级支持

会有更多企业级Server:ERP、CRM、数据仓库…

趋势3:工具编排

不只是单个工具调用,而是工作流编排

九、写在最后:让AI真正”连接”世界

这篇文章,讲的是MCP协议。

我的核心观点:

MCP不只是协议,它是AI Agent的”四肢”。

没有MCP,AI只是个”大脑”,能思考但不能行动。

有了MCP,AI有了”四肢”,能真正感知世界、操作世界

这就是从”AI助手”到”AI Agent”的跨越。

希望这篇文章,能帮你理解MCP、用好MCP。

让你的AI Agent,真正”活”起来。

完。


 

正文完
 0
技术老金
版权声明:本站原创文章,由 技术老金 于2026-03-25发表,共计10106字。
转载说明:除特殊说明外本站文章皆由CC-4.0协议发布,转载请注明出处。
评论(没有评论)