MCP入门与实践:AI Agent跨进程调用工具
MCP协议通过标准化通信解耦大语言模型与工具,支持stdio和HTTP两种跨进程调用方式。其核心概念包括Tool(跨进程工具)和Resource(静态资源注入上下文)。实战展示基于LangChain的MCPClient与Server通过子进程stdio通信,实现工具发现、资源注入及Agent循环调用。
MCP(Model Context Protocol)入门与实践:让AI Agent实现跨进程工具调用
在开发AI Agent的过程中,我们时常需要为大语言模型集成各类工具(Tool),例如用于查询用户信息的工具:

const queryUserTool = {
name: 'query_user',
description: '查询用户信息',
// ...
}
然而,这种写法存在明显缺陷,至少有两个痛点。首先,工具代码与Agent代码紧密耦合,换一个项目就需要重新编写,几乎无法复用。其次,语言绑定问题:如果工具采用Node.js实现,那么Java、Python、Rust等语言的项目如何调用?总不能每个项目都重写一遍吧。
因此,核心需求非常明确:让Tool独立于LLM,实现本地或远程、跨进程、跨语言的调用,这才是真正意义上的工具解耦。
二、MCP协议是什么
MCP(Model Context Protocol)的核心价值在于定义了一套标准化协议,用于规范LLM与Tool、Resource之间的通信,其目标非常纯粹:解耦LLM和Tool。
通信方式
MCP支持两种通信模式,各有各的适用场景:
| 模式 | 传输方式 | 适用场景 |
|---|---|---|
| stdio | 标准输入输出流(stdin/stdout) | 适用于本地跨进程调用 |
| HTTP | 远程HTTP通信(REST) | 适用于远程跨进程调用 |
简单来说,MCP让Agent能够跨进程调用工具——无论是本地进程还是远程服务,只需通过MCP协议即可实现。
需要区分的是:MCP与直接使用fetch调用接口不同。MCP并非单纯获取接口数据,而是扩展Context(工具能力+资源知识),使LLM在推理时拥有更丰富的上下文,这才是其真正的价值。
三、MCP的核心概念
3.1 Tool(工具)
Tool本质上就是工具,与常规的Function Calling / Tool Use没有本质区别。不同之处在于,它是跨进程提供的。Agent(MCP Client / Host)通过协议发现并调用远程进程中的工具——就像“抛饵”出去,让其他进程来执行。
3.2 Resource(资源)
Resource是MCP的另一大亮点,它允许MCP Server提供静态资源(如文档、指南等),这些资源可作为System Prompt的一部分注入到Context中。
以下是一个实际的Resource注册示例(来自my-mcp-server.mjs):
server.registerResource(
'使用指南',
'docs://guide', // URI 格式的访问路径
{
description: '使用指南',
mimeType: 'text/plain'
},
async () => {
return {
contents: [{
uri: 'docs://guide',
mimeType: 'text/plain',
text: `MCP Server 使用指南
功能:提供用户查询等工具。
使用:在 Cursor 等 MCP Client 中通过自然语言对话,Cursor 会自动调用相应工具。`
}]
}
}
)
在Client端读取Resource的方式如下:
const res = await mcpClient.listResources()
;
let resourceContent = ''
;
for (const [serverName, resources] of Object.entries(res)) {
for (const resource of resources) {
const content = await mcpClient.readResource(serverName, resource.uri)
;
resourceContent += content
[0]
.text
;
}
}
// 将 resource 内容作为 SystemMessage 注入
const messages = [
new SystemMessage(resourceContent), // 资源内容成为上下文的一部分
new HumanMessage(query),
]
;
四、实战:搭建完整的MCP调用链路
下面通过实际代码演示一个完整的MCP工作流程,架构如下:
┌──────────────┐ stdio ┌─────────────────┐
│MCP Client │ ◄──────────► │MCP Server │
│(LangChain) │ 跨进程通信 │(Node.js 进程) │
│ │ │ │
│- 获取工具 │ │- query_user │
│- 获取资源 │ │- docs://guide │
│- Agent 循环 │ │ │
└──────────────┘ └─────────────────┘
4.1 MCP Server 端
import { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';
import { StdioServerTransport } from '@modelcontextprotocol/sdk/server/stdio.js';
import { z } from 'zod';
// 模拟数据库
const database = {
users: {
'001': { id: '001', name: '祖豪', email: 'zh@qq.com', role: 'admin' },
'002': { id: '002', name: '光光', email: 'gg@qq.com', role: 'user' },
'003': { id: '003', name: '小红', email: 'xh@qq.com', role: 'user' },
}
}
const server = new McpServer({
name: 'my-mcp-server',
version: '1.0.0'
});
// 注册工具
server.registerTool('query_user', {
description: '查询数据库中的用户信息',
inputSchema: {
userId: z.string().describe('用户ID, 例如:001, 002, 003')
}
}, async ({ userId }) => {
const user = database.users[userId];
if (!user) {
return {
content: [{ type: 'text', text: `用户 ID ${userId} 不存在` }]
}
}
return {
content: [{
type: 'text',
text: `用户 ${user.id} 的信息是:姓名:${user.name}, 邮箱:${user.email}, 角色:${user.role}`
}]
}
});
// 注册资源
server.registerResource('使用指南', 'docs://guide', { /* ... */ }, async () => { /* ... */ });
// 通过 stdio 启动通信
const transport = new StdioServerTransport();
await server.connect(transport);
关键点:使用McpServer创建服务实例,通过registerTool注册工具并用Zod定义参数Schema,通过registerResource注册静态资源,最后使用StdioServerTransport建立stdio通信通道。
4.2 MCP Client 端
import { MultiServerMCPClient } from '@langchain/mcp-adapters';
import { ChatOpenAI } from '@langchain/openai';
const model = new ChatOpenAI({
modelName: 'deepseek-v4-flash',
// ...配置
});
// 配置 MCP Client,可以同时连接多个 MCP Server
const mcpClient = new MultiServerMCPClient({
mcpServers: {
'my-mcp-server': {
command: 'node', // 启动命令
args: ['src/my-mcp-server.mjs'], // 脚本路径
cwd: '/path/to/mcp-demo' // 工作目录
}
}
});
// 获取工具和资源
const tools = await mcpClient.getTools();
// 获取资源并拼成上下文字符串
const res = await mcpClient.listResources();
// ...拼接 resourceContent ...
// 绑定工具到模型
const modelWithTools = model.bindTools(tools);
关键点:MultiServerMCPClient可同时配置多个MCP Server,每个Server配置指定启动命令、参数和工作目录,Client内部通过child_process启动子进程,并通过stdio通信。
4.3 Agent 工具调用循环
async function runAgentWithTools(query, maxIterations = 30) {
const messages = [
new SystemMessage(resourceContent), // 资源内容作为系统提示
new HumanMessage(query),
]
;
for (let i = 0; i < maxIterations; i++) {
const response = await modelWithTools.invoke(messages)
;
messages.push(response)
;
// 没有工具调用 → 直接返回最终回复
if (!response.tool_calls || response.tool_calls.length === 0) {
return response.content
;
}
// 执行每个工具调用
for (const toolCall of response.tool_calls) {
const foundTool = tools.find(t => t.name === toolCall.name)
;
if (foundTool) {
const toolResult = await foundTool.invoke(toolCall.args)
;
messages.push(new ToolMessage({
content: toolResult,
tool_call_id: toolCall.id, // ⚠️ 必须带上 tool_call_id
}))
;
}
}
}
return messages
[messages.length - 1]
.content
;
}
这个循环有几个值得注意的细节:首先,SystemMessage注入Resource,将MCP Server提供的文档资源作为系统提示,让模型获得更多信息;其次,设置30轮上限防止无限循环;第三,必须回传tool_call_id,ToolMessage必须携带对应的tool_call_id,这是模型关联工具调用与结果的唯一标识;第四,使用find方法找到第一个匹配项即停止,适用于工具名唯一的场景。
4.4 资源清理
// 关闭所有 MCP 子进程与通信通道,释放进程资源
await mcpClient.close();
这一步非常重要!close()会关闭与MCP Server的stdio连接,终止child_process启动的子进程,避免脚本挂起不退出。
五、关键技术细节
5.1 跨进程通信(IPC)的本质
主进程 (Agent/LangChain)
│
│ child_process.spawn('node', ['my-mcp-server.mjs'])
│
├── stdin──►MCP Server 子进程
│ (接收工具调用请求)
│
◄── stdout ──MCP Server 子进程
(返回工具执行结果)
父子进程模型:Client通过child_process启动Server作为子进程,请求通过stdin发送,响应通过stdout返回。任何语言的进程只要实现了MCP协议的stdio通信,即可被调用。
5.2 JavaScript 的异步特性
在整个通信链路中,JavaScript的单线程异步无阻塞模型确保主线程不会被进程通信阻塞,多个MCP Server可以并发通信,Agent循环中的每轮推理和工具调用也都是异步的。
5.3 Object.entries 的妙用
在处理MCP返回的资源列表时,Object.entries()非常实用:
// MCP 返回的是按 Server 分组的资源对象
const res = {
'my-mcp-server': [
{ uri: 'docs://guide', name: '使用指南' },
{ uri: 'docs://api', name: 'API文档' },
]
};
// Object.entries 拆解为 [key, value] 遍历
for (const [serverName, resources] of Object.entries(res)) {
for (const resource of resources) {
// 逐个读取资源内容
}
}
六、总结
最后,用一张表格对比传统Tool与MCP Tool的差异,一目了然:
| 维度 | 传统Tool | MCP Tool |
|---|---|---|
| 复用性 | 与项目绑定 | 独立进程,可供任意项目使用 |
| 跨语言 | 仅限同语言使用 | 通过stdio/HTTP,支持任意语言 |
| 通信方式 | 同进程函数调用 | 跨进程(本地stdio/远程HTTP) |
| 扩展性 | 需手动添加工具 | 配置式添加MCP Server |
| 上下文丰富 | 仅支持Tool | 支持Tool+Resource+Prompt |
MCP协议的核心价值可概括为四点:第一,解耦——Tool与LLM彻底分离,各自独立开发、部署、迭代;第二,跨进程——无论是本地子进程还是远程服务,均通过MCP协议统一通信;第三,跨语言——Node.js编写的工具可被Python Agent调用,反之亦然;第四,标准化——统一的Tool定义、Resource提供和通信方式,生态可共享。
游乐网为非赢利性网站,所展示的游戏/软件/文章内容均来自于互联网或第三方用户上传分享,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系youleyoucom@outlook.com。
同类文章
手写Mini Cursor:Agent文件读写、命令执行与项目创建
基于ReAct循环构建的MiniCursorAgent,通过Node jsRuntime提供读文件、写文件、查看目录、执行命令四个工具,在本地工作区自主完成创建ReactTodoList项目、实现功能、添加样式动画等编程任务,模型根据工具结果循环决策。
一条脚本结合多步流水线与HereDoc实现全自动内容生产
多步流水线将多个命令调用串联成自动化生产流程,HereDoc通过cat命令以标准输入方式传递长文本prompt,避免引号嵌套引发的混乱,显著提升脚本可读性与可维护性,是处理长文本提示的有效方法,广泛应用于自动化脚本编写。
iOS设备上PlayWright MCP服务器的安装配置与使用详细指南
基于Appium的iOS设备自动化测试MCPServer,提供屏幕截图、元素点击及UI树获取功能,支持Stdio与SSE两种运行模式,可无缝接入Trae等支持MCP协议的AI客户端,所有工具共享同一Appium会话,避免重复启动开销,显著提升测试效率。
MCP Server开发入门与协议调试生产部署
MCPServer开发需解决五个工程问题:多工具共享数据层;输入验证含枚举值、必填字段和业务规则;错误处理区分硬错误与软反馈;日志必须写入stderr避免破坏协议;Resources使LLM能动态获取上下文数据。以JiraServer为例,实现4个工具、1个资源和1个Prompt,覆盖完整测试用例。
机器学习基本术语详解与核心概念解析
机器学习以数据为基础,样本由属性构成特征向量。训练从数据中学习模型,有标记的样本用于监督学习(分类与回归),无标记的样本用于无监督学习(聚类)。泛化能力是衡量模型对新样本适用性的关键标准。
- 热门数据榜
1
2
3
4
5
6
7
8
9
10
相关攻略
2026-07-13 16:15
2026-07-13 16:14
2026-07-13 16:14
2026-07-13 16:14
2026-07-13 16:14
2026-07-13 16:14
2026-07-13 16:13
2026-07-13 16:13
热门教程
- 游戏攻略
- 安卓教程
- 苹果教程
- 电脑教程
热门话题

