0%

Model Context Protocol (MCP)与 AI 工具集成实践

【本文由 Claude 3.7 辅助编写】

Git 仓库

1. MCP 协议简介

Model Context Protocol (MCP) 是一个开放协议,旨在标准化应用程序如何为大型语言模型 (LLMs) 提供上下文。MCP 类似于 AI 应用中的 USB-C 接口,提供了一种标准化的方式,将 AI 模型连接到不同的数据源和工具。

为什么需要 MCP?

MCP 帮助用户在 LLMs 之上构建代理和复杂的工作流。LLMs 经常需要与数据和工具集成,MCP 提供了以下支持:

  • 预建集成:LLM 可以直接插入的预建集成列表。
  • 灵活性:在不同 LLM 提供商和供应商之间切换的灵活性。
  • 最佳实践:在基础设施内保护数据的最佳实践。

核心架构

MCP 采用客户端-服务器架构,主机应用程序可以连接到多个服务器:

  • MCP 主机:如 Claude Desktop、IDE 或 AI 工具,希望通过 MCP 访问数据。
  • MCP 客户端:与服务器保持 1:1 连接的协议客户端。
  • MCP 服务器:通过标准化 Model Context Protocol 暴露特定功能的轻量级程序。
  • 本地数据源:MCP 服务器可以安全访问的计算机文件、数据库和服务。
  • 远程服务:MCP 服务器可以通过互联网连接的外部系统(如 API)。

2. 使用 fastmcp 框架实现 MCP Server

fastmcp 是一个用于快速构建 MCP 工具服务器的框架。让我们看看如何使用它实现一个简单的工具服务器:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
import { FastMCP } from "fastmcp";
import { z } from "zod";

// 创建MCP服务器实例
const server = new FastMCP({
name: "My Server",
version: "1.0.0",
});

// 添加一个数学计算工具
server.addTool({
name: "add",
description: "Add two numbers",
parameters: z.object({
a: z.number(),
b: z.number(),
}),
execute: async (args) => {
return String(args.a + args.b);
},
});

// 添加一个系统状态查询工具
server.addTool({
name: "system-battery",
description: "Get the current system battery status",
parameters: z.object({}),
execute: async () => {
const command = new Deno.Command(
"C:\\Program Files\\PowerShell\\7\\pwsh.exe",
{
args: [
"-c",
"Get-WmiObject -Class Win32_Battery | Select-Object -Property EstimatedChargeRemaining | ConvertTo-Json",
],
}
);
const output = await command.output();
return new TextDecoder().decode(output.stdout);
},
});

// 启动服务器
server.start({
transportType: "stdio",
});

工具定义的关键要素

  1. 名称 (name): 工具的唯一标识符
  2. 描述 (description): 工具功能的简要说明
  3. 参数模式 (parameters): 使用 zod 定义的参数类型验证规则
  4. 执行逻辑 (execute): 实际执行工具功能的异步函数

FastMCP 使工具服务器的开发变得简单直观。通过定义工具名称、描述、参数模式和执行逻辑,开发者可以快速创建功能丰富的工具集合。服务器通过 stdio 传输方式启动,方便与客户端进行交互。

3. MCP Client 与 OpenAI 接口集成

接下来,我们来看看如何创建 MCP 客户端并将其与 OpenAI 接口集成:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
import { createOpenAI } from "@ai-sdk/openai";
import { Client } from "@modelcontextprotocol/sdk/client/index.js";
import { StdioClientTransport } from "@modelcontextprotocol/sdk/client/stdio.js";
import { CoreMessage, Tool, generateText } from "ai";
import { z } from "zod";

// 创建与MCP服务器的通信通道
const transport = new StdioClientTransport({
command: "deno",
args: ["run", "-A", "server.ts"],
});

// 初始化MCP客户端
const client = new Client(
{
name: "example-client",
version: "1.0.0",
},
{
capabilities: {
prompts: {},
resources: {},
tools: {},
},
}
);

// 连接到MCP服务器
await client.connect(transport);

// 获取服务器提供的工具描述
const { tools: tool_descs } = await client.listTools();
const tools: Record<string, Tool> = {};

// 将MCP工具转换为OpenAI可用的Tool格式
for (const tool_desc of tool_descs) {
const parameters: Record<string, z.ZodType> = {};
for (const [name, { type }] of Object.entries(
tool_desc.inputSchema.properties
) as [string, { type: string }][]) {
parameters[name] = type === "number" ? z.number() : z.string();
}

tools[tool_desc.name] = {
description: tool_desc.description,
parameters: z.object(parameters),
execute: async (args) => {
const result = await client.callTool({
name: tool_desc.name,
arguments: args,
});
console.log(`Tool ${tool_desc.name} executed with result:`, result);
return result.content[0].text;
},
};
}

// 初始化OpenAI客户端
const openai = createOpenAI({
apiKey: process.env.OPENAI_API_KEY,
baseURL: process.env.OPENAI_BASE_URL,
});

// 处理用户查询
async function main() {
const model = openai(process.env.OPENAI_MODEL!);
const messages: CoreMessage[] = [
{ role: "user", content: "系统还有多少电?" },
];

// 使用模型生成文本,可能触发工具调用
const response = await generateText({
model,
tools,
messages,
});

// 处理工具调用和结果
if (response.toolCalls.length > 0) {
// ... 处理工具调用和结果的代码 ...

// 基于工具结果生成最终响应
const { text } = await generateText({
model,
tools,
messages,
});
console.log(text);
}
}

main();

集成过程的关键步骤

  1. 创建传输通道:通过 StdioClientTransport 连接到 MCP 服务器
  2. 初始化客户端:创建 MCP 客户端并连接
  3. 工具映射:将 MCP 工具转换为 OpenAI 可用的 Tool 格式
  4. 模型调用:使用 OpenAI 模型处理用户查询
  5. 工具调用处理:管理模型生成的工具调用和结果
  6. 响应生成:基于工具执行结果生成最终响应

通过这种集成方式,OpenAI 模型可以无缝调用 MCP 服务器提供的工具,实现强大的功能扩展。

4. MCP 协议的未来展望

随着 AI 技术的快速发展,MCP 协议在未来有着广阔的应用前景:

工具生态系统扩展

未来可能会出现专门的 MCP 工具市场,开发者可以分享和使用各种预构建的工具,加速 AI 应用开发。从代码分析工具、数据处理工具到专业领域工具(如金融分析、医疗诊断等),将形成丰富的工具生态系统。

多模态工具支持

MCP 协议可以扩展到支持多模态工具,使模型能够处理和生成图像、音频和视频内容。例如,通过 MCP 协议连接图像生成工具、视频编辑工具等。

安全性增强

未来 MCP 协议可以引入更强大的安全机制,如权限控制、资源限制和调用审计,确保 AI 系统使用工具时的安全性和可控性。

高效工具调用优化

优化工具调用路径和参数传递方式,减少不必要的往返通信,提高工具调用效率。可能会出现智能工具路由和缓存机制,进一步提升性能。

统一标准化

随着更多组织和项目采用 MCP 协议,可能会形成统一的工具描述标准,使不同平台和模型之间的工具更容易共享和互操作。这将大大减少重复开发工作,推动整个行业向前发展。

AI 代理协作系统

未来 MCP 可能成为 AI 代理之间协作的基础设施,使多个 AI 系统能够共享工具和能力,协同解决复杂问题。

结论

MCP 协议为 AI 模型与工具集成提供了一种灵活、标准化的方式。通过 fastmcp 框架,开发者可以轻松构建功能强大的工具服务器;通过 MCP 客户端与 OpenAI 接口集成,可以实现模型与工具的无缝交互。随着 AI 技术的不断发展,MCP 协议有望在工具生态系统、多模态支持、安全性和效率方面取得更多突破,为 AI 应用开发提供更加强大的支持。

通过实际实践 MCP 协议,开发者可以构建更加智能、灵活的 AI 应用,满足各种复杂场景的需求。

扫码加入技术交流群🖱️
QR code