理解 MCP 协议
MCP 协议是一种模型上下文协议,旨在解耦工具提供方与应用研发者,为 AI Agent 应用开发提供标准化的协议支持。它允许将工具服务器(MCP Server)与 Agent 应用分离,Agent 无需关注工具的具体实现细节,通过 MCP 协议即可调用各种工具。
开发环境搭建
- 安装 Node.js 和 npm :确保本地有 Node.js 环境和 npm 包管理工具,以便后续安装和管理相关依赖。
- 创建项目目录 :创建一个用于开发基于 MCP 的 AI Agent 应用的项目目录,并初始化 npm 项目。
- 安装必要的依赖 :根据项目需求,安装如
@modelcontextprotocol/inspector
、zod
、openai
等依赖包,这些工具分别用于调试 MCP Server、定义工具的输入输出格式以及与 OpenAI 等大语言模型进行交互。
MCP Server 开发
- 定义工具 :使用 JSON Schema 约束工具的输入、输出格式,推荐使用 zod 来定义 Zod Schema,然后将其转换为 JSON Schema 导出。例如,定义一个浏览器导航工具
browser_navigate
和一个页面滚动工具browser_scroll
,分别指定它们的输入参数和返回值格式。 - 实现工具逻辑 :为每个工具编写具体的实现逻辑,如在
browser_navigate
工具中,根据输入的 URL 进行页面导航,并返回导航后的页面信息和可点击元素;在browser_scroll
工具中,根据输入的滚动像素值进行页面滚动,并返回滚动后的页面状态。 - 配置 package.json :编写
package.json
文件,指定通过 stdio 调用的入口文件、通过 Function Call 同进程调用的入口文件等信息,以便 MCP Server 能够正确启动和运行。 - 编写启动入口文件 :在入口文件中,导出
listTools
、callTool
、close
等共用方法,用于列举所有函数、调用具体函数以及 Server 不使用后的清理工作。同时,支持 Stdio 调用方式,以便在不同场景下使用 MCP Server。
开发调试
- 使用 Inspector :通过运行
npm run dev
启动 MCP Inspector,它会提供一个 Playground,包含 MCP Server 可调试的功能,如 Prompts、Resources、Tools 等。在 Inspector 中,可以方便地测试和调试 MCP Server 的各项功能,但需注意在 Inspector 调试时console.log
无法显示。 - 单步调试 :在开发工具的实现逻辑时,可以使用断点调试等单步调试方法,深入分析工具的执行流程和数据传递情况,确保工具的正确性和稳定性。
MCP Client 集成
- 创建 MCP Client 实例 :在 Agent 应用中,创建 MCP Client 实例,并将开发好的 MCP Server 配置信息添加到 Client 中。例如,对于内置的 MCP Server,可以通过指定其名称、描述以及 localClient 等属性来进行配置。
- 调用 MCP Server 的工具 :通过 MCP Client 提供的
listTools
方法获取 MCP Server 中可用的工具列表,然后根据需要调用具体的工具。例如,在与 OpenAI 的 Chat Completions API 交互时,可以将 MCP Server 的工具信息转换为模型能够理解的格式,并设置tool_choice
参数为 ‘auto’,让模型自动选择合适的工具进行调用。
远程调用与云化
- FaaS 转换 :如果是 Web 应用无法使用 Stdio MCP Server,可以利用 FaaS 将 Stdio 转成 SSE MCP Server,实现 MCP Servers 的云化。这样,就可以在 Function Call 的基础上无缝支持 MCP 类型的 Tools,使得 Web 应用也能够方便地使用 MCP Server 提供的功能。
- 调用远程 MCP Server :在代码中,通过相应的客户端库或自定义实现,与远程的 MCP Server 进行通信。例如,使用 Python 的
aiohttp
库或 JavaScript 的fetch
API 等,向远程 MCP Server 发送请求并接收响应,从而实现对远程工具的调用。
代码示例
以下是一个基于 MCP 的 AI Agent 应用开发的简单示例:
- MCP Server 定义工具 :
import { z } from 'zod';
const toolsMap = {
browser_navigate: {
description: 'Navigate to a URL',
inputSchema: z.object({
url: z.string(),
}),
handle: async (args) => {
// Implements
const clickableElements = ['...'];
return {
content: [
{
type: 'text',
text: `Navigated to ${args.url}\nclickable elements: ${clickableElements}`,
},
],
isError: false,
};
},
},
browser_scroll: {
name: 'browser_scroll',
description: 'Scroll the page',
inputSchema: z.object({
amount: z.number().describe('Pixels to scroll (positive for down, negative for up)'),
}),
handle: async (args) => {
return {
content: [
{
type: 'text',
text: `Scrolled ${actualScroll} pixels. ${
isAtBottom ? 'Reached the bottom of the page.' : 'Did not reach the bottom of the page.'
}`,
},
],
isError: false,
};
},
},
// more
};
const callTool = async ({ name, arguments: toolArgs }) => {
return handlers[name].handle(toolArgs);
};
- MCP Client 集成与调用 :
import { MCPClient } from '@agent-infra/mcp-client';
import { client as mcpBrowserClient } from '@agent-infra/mcp-server-browser';
const client = new MCPClient([
{
name: 'browser',
description: 'web browser tools',
localClient: mcpBrowserClient,
},
]);
const mcpTools = await client.listTools();
const response = await openai.chat.completions.create({
model,
messages,
tools: convertToTools(tools),
tool_choice: 'auto',
});
优势与应用场景
- 优势 :MCP 协议使得工具提供方和应用研发者能够解耦开发,降低了开发门槛,提高了开发效率。它支持多种调用方式,包括 Stdio、SSE、Streamable HTTP、Function Call 等,具有良好的灵活性和可扩展性。同时,通过语义化的返回值设计,能够更好地连接模型与工具,提升模型对工具调用结果的理解能力,从而提高工具调用的成功率。
- 应用场景 :基于 MCP 的 AI Agent 应用可以在多个领域发挥作用,如金融领域的股票分析和交易、数据收集与整理、自动化办公流程、智能客服等。例如,通过集成券商 MCP Server、文件系统 MCP Server、命令行 MCP Server、代码执行 MCP Server 和浏览器操作 MCP Server 等,可以实现股票的技术面分析和交易、系统信息查询、数据收集与整理、自动化办公任务以及网页信息获取等功能。