MCP 协议开发实战:从零搭建 AI Agent 工具链
1. 引言
随着大语言模型能力的快速提升,AI Agent 已成为连接模型与真实世界的关键桥梁。然而,如何让 Agent 高效、安全地调用外部工具,一直是工程实践中的核心难题。MCP(Model Context Protocol)协议的出现,为这一难题提供了标准化的解决方案。
本文将带你从零开始,深入理解 MCP 协议的核心原理,并通过实战项目逐步搭建一套完整的 AI Agent 工具链。无论你是后端开发者、AI 应用工程师,还是对 Agent 架构感兴趣的爱好者,都能从本文中获得可落地的实践经验。
2. MCP 协议基础
2.1 什么是 MCP 协议
MCP(Model Context Protocol)是由 Anthropic 于 2024 年底提出的开放协议,旨在标准化大语言模型与外部数据源、工具之间的交互方式。它定义了客户端与服务器之间的通信规范,让 AI 应用能够以统一的方式发现、调用和管理外部能力。
2.2 MCP 的核心架构
MCP 采用客户端-服务器架构,主要包含三个核心角色:
- MCP Host:运行 AI 应用的宿主环境,如 Claude Desktop、IDE 插件或自定义应用。
- MCP Client:与服务器建立连接、发起请求的客户端组件。
- MCP Server:暴露工具、资源和提示词能力的服务端程序。
2.3 MCP 与 Function Calling 的对比
在 MCP 出现之前,开发者通常使用 Function Calling 机制让模型调用工具。两者各有优劣:
| 维度 | Function Calling | MCP |
|---|---|---|
| 标准化程度 | 各家厂商各自实现 | 统一开放协议 |
| 工具发现 | 需预先定义 | 动态发现 |
| 连接管理 | 无标准 | 标准化生命周期 |
| 生态互通 | 封闭 | 跨平台复用 |
3. 环境准备与项目初始化
3.1 开发环境要求
在开始之前,请确保你的开发环境满足以下要求:
- Node.js 18+ 或 Python 3.9+
- 一个支持 MCP 的客户端(如 Claude Desktop、Cursor 或自研客户端)
- 基本的 TypeScript 或 Python 开发经验
3.2 初始化项目结构
我们将使用 TypeScript 构建一个 MCP Server 示例。首先创建项目目录并初始化:
mkdir mcp-toolchain
cd mcp-toolchain
npm init -y
npm install @modelcontextprotocol/sdk
3.3 安装 MCP SDK
MCP 官方提供了 TypeScript 和 Python 两种 SDK。本文以 TypeScript 为例,安装完成后,我们可以开始编写第一个 MCP Server。
4. 构建第一个 MCP Server
4.1 创建基础服务器
下面是一个最简的 MCP Server 实现,它暴露了一个 greet 工具:
import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
const server = new McpServer({
name: "demo-server",
version: "1.0.0",
});
server.registerTool("greet", {
title: "打招呼",
description: "向用户发送问候",
inputSchema: {
type: "object",
properties: {
name: { type: "string", description: "用户名称" },
},
},
async execute(args) {
return { content: [{ type: "text", text: `你好,${args.name}!` }] };
},
});
const transport = new StdioServerTransport();
await server.connect(transport);
4.2 理解工具注册机制
在上述代码中,registerTool 方法完成了工具的定义与注册。每个工具需要声明:
- 名称:工具的唯一标识。
- 描述:帮助模型理解工具用途的自然语言描述。
- 输入 Schema:定义工具参数的 JSON Schema。
- 执行函数:实际处理业务逻辑的异步函数。
4.3 运行与调试
使用以下命令启动服务器:
npx tsx src/index.ts
启动后,服务器会通过标准输入输出与客户端通信。你可以使用 MCP Inspector 工具进行调试和验证。
5. 实现工具链核心功能
5.1 设计工具链架构
一个完整的工具链通常包含多个工具,它们协同完成复杂任务。我们以一个「代码审查助手」为例,设计如下工具集:
fetch_repo:拉取远程仓库代码。analyze_code:静态分析代码质量。generate_report:生成审查报告。
5.2 实现文件读取工具
server.registerTool("read_file", {
title: "读取文件",
description: "读取指定路径的文件内容",
inputSchema: {
type: "object",
properties: {
path: { type: "string", description: "文件路径" },
},
required: ["path"],
},
async execute(args) {
const content = await fs.readFile(args.path, "utf-8");
return { content: [{ type: "text", text: content }] };
},
});
5.3 实现数据查询工具
除了文件操作,工具链还经常需要对接外部数据源。下面是一个查询数据库的工具示例:
server.registerTool("query_database", {
title: "查询数据库",
description: "执行 SQL 查询并返回结果",
inputSchema: {
type: "object",
properties: {
sql: { type: "string", description: "SQL 语句" },
},
required: ["sql"],
},
async execute(args) {
const result = await db.query(args.sql);
return { content: [{ type: "text", text: JSON.stringify(result) }] };
},
});
6. 连接 AI Agent 与 MCP
6.1 在客户端集成 MCP
要让 AI Agent 使用我们构建的工具,需要在客户端侧建立 MCP 连接。以下是一个简单的客户端示例:
import { Client } from "@modelcontextprotocol/sdk/client/index.js";
import { StdioClientTransport } from "@modelcontextprotocol/sdk/client/stdio.js";
const transport = new StdioClientTransport({
command: "node",
args: ["dist/server.js"],
});
const client = new Client({
name: "agent-client",
version: "1.0.0",
});
await client.connect(transport);
const tools = await client.listTools();
6.2 将工具注入 LLM 调用
连接建立后,我们需要将 MCP 工具列表转换为 LLM 可识别的 Function 格式,并在对话循环中动态调用:
const llmTools = tools.map((tool) => ({
type: "function",
function: {
name: tool.name,
description: tool.description,
parameters: tool.inputSchema,
},
}));
// 在对话循环中处理工具调用
const response = await llm.chat({
messages,
tools: llmTools,
});
6.3 处理工具调用循环
当模型决定调用某个工具时,客户端需要执行工具并返回结果,形成完整的调用闭环:
if (response.tool_calls) {
for (const call of response.tool_calls) {
const result = await client.callTool({
name: call.function.name,
arguments: JSON.parse(call.function.arguments),
});
messages.push({
role: "tool",
tool_call_id: call.id,
content: result.content[0].text,
});
}
}
7. 进阶:资源与提示词能力
7.1 暴露资源(Resources)
除了工具,MCP 还支持暴露资源供模型读取。资源可以是文件、数据库记录或 API 响应:
server.registerResource(
"config",
"application-config",
async (uri) => ({
contents: [{
uri: uri.href,
text: JSON.stringify(config, null, 2),
}],
})
);
7.2 定义提示词模板
提示词模板可以帮助模型理解特定任务的执行方式:
server.registerPrompt("code-review", {
title: "代码审查",
description: "对指定代码进行审查",
arguments: [{ name: "code", description: "待审查代码" }],
async load(args) {
return {
messages: [{
role: "user",
content: {
type: "text",
text: `请审查以下代码:\n${args.code}`,
},
}],
};
},
});
7.3 组合使用三种能力
在实际项目中,工具、资源和提示词往往组合使用。工具负责执行操作,资源提供上下文数据,提示词引导模型行为,三者协同构建强大的 Agent 能力。
8. 安全与最佳实践
8.1 权限控制
MCP Server 应实现细粒度的权限控制,避免模型越权执行危险操作:
- 对敏感操作增加二次确认机制。
- 使用白名单限制可访问的资源范围。
- 记录所有工具调用的审计日志。
8.2 错误处理与重试
工具调用可能失败,需要设计健壮的错误处理策略:
async function safeCallTool(name: string, args: any) {
try {
return await client.callTool({ name, arguments: args });
} catch (error) {
return {
content: [{ type: "text", text: `工具调用失败:${error.message}` }],
};
}
}
8.3 性能优化
- 复用 MCP 连接,避免频繁建立和销毁。
- 对高频工具结果做缓存。
- 使用流式传输处理大文件。
9. 实战案例:构建完整工具链
9.1 需求分析
我们将构建一个「智能运维助手」,它能够:
- 查询服务器状态。
- 分析日志文件。
- 生成运维报告。
9.2 实现步骤
首先定义三个核心工具,然后通过 MCP Server 暴露给 Agent。最后在客户端配置好工具调用循环,即可实现完整的智能运维流程。
9.3 效果演示
通过实际运行演示,我们可以看到 Agent 如何自主决定调用哪个工具、传递什么参数,并最终生成结构化的运维报告。
10. 总结与展望
10.1 本文回顾
本文从 MCP 协议的基础概念出发,逐步讲解了如何构建 MCP Server、实现工具链核心功能、连接 AI Agent,并探讨了安全与最佳实践。通过实战案例,我们完整走通了从零搭建 AI Agent 工具链的全过程。
10.2 MCP 生态的未来
随着 MCP 协议的快速普及,越来越多的工具和服务将原生支持 MCP。未来,开发者可以像组装积木一样组合各种 MCP Server,快速构建强大的 AI 应用。MCP 正在成为 AI Agent 时代的「USB-C 接口」,值得每一位开发者深入掌握。
更多推荐


所有评论(0)