AI Agent的“万能工具箱”:MCP协议实战,让工具调用不再受语言和进程束缚 你是否遇到过这种情况辛辛苦苦给Agent写了一个本地工具换个项目、换种语言就得重写MCPModel Context Protocol就是为了解决这个问题而生的。本文将带你从零实现一个MCP Server并用LangChain调用它让你彻底理解MCP如何让工具跨语言、跨进程“即插即用”。一、从“自嗨工具”到“通用能力”我们为什么需要MCP先灵魂拷问一下你平时给AI Agent写的工具Tool有什么痛点绑定特定项目工具只能在一个代码库中用换个项目就得复制粘贴。语言限制你用Node.js写了工具但团队可能用Python、Java想复用得重写。进程隔离工具作为函数直接集成在Agent进程里一崩溃全完蛋而且无法分布式部署。说白了工具和LLM耦合太紧变成了一次性的“自嗨玩具”。如果有一种方式让工具独立于LLM无论本地还是远程无论什么语言Agent都能像插USB一样即插即用那该多好MCPModel Context Protocol就是来填补这个空白的。二、MCP是什么一句话说清核心价值MCP 标准化 LLM 与工具/资源通信的协议让跨进程、跨语言的工具调用成为家常便饭。MCP定义了Agent作为客户端与工具提供者作为服务端之间的通信规范通信方式支持stdio本地跨进程基于标准输入输出和HTTP远程调用。暴露内容Tool可执行工具、Resource只读上下文数据、Prompt复用模板。核心作用给Model扩展Context让LLM不仅能“说”还能“做”Tool还能“知道更多”Resource。你可能会想“这不就是API调用吗” 不API是接口数据交互而MCP是上下文扩展它把Tool和Resource当作LLM的“外挂大脑”让Agent在推理时能动态调用或参考。架构概览图MermaidAgent可以同时连接多个MCP Server每个Server可以暴露任意数量的Tool和Resource。三、实战手写一个MCP ServerNode.js版我们从最基础的开始实现一个简单的MCP Server提供用户查询工具和静态资源。3.1 项目初始化mkdir mcp-demo cd mcp-demo npm init -y npm install modelcontextprotocol/sdk zod3.2 编写 Servermy-mcp-server.mjs先看完整代码再逐段解析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: zh, email: zhqq.com, role: admin }, 002: { id: 002, name: gg, email: ggqq.com, role: user }, 003: { id: 003, name: xh, email: xhqq.com, role: user }, } }; const server new McpServer({ name: my-mcp-server, version: 1.0.0 }); // ---------- 注册 Tool ---------- server.registerTool(query_user, { description: 查询数据库中的用户信息输入用户ID返回该用户的详细信息(姓名、邮箱、角色), inputSchema: { userId: z.string().describe(用户ID,例如001002003), } }, async ({ userId }) { const user database.users[userId]; if (!user) { return { content: [ { type: text, text: 用户 ID ${userId} 不存在. 可用的ID: 001,002,003 } ] }; } return { content: [ { type: text, text: 用户 ID ${userId} 信息是 姓名${user.name} 邮箱${user.email} 角色${user.role} } ] }; }); // ---------- 注册 Resource ---------- server.registerResource( 使用指南, docs://guide, // URI 标识 { description: MCP Server 使用指南, mimeType: text/plain, }, async () { return { contents: [ { uri: docs://guide, mimeType: text/plain, text: MCP Server 使用指南 功能提供用户查询等工具。 使用在 Cursor 等 MCP Client 中通过自然语言对话Cursor 会自动调用相应工具。 } ] }; } ); // ---------- 启动 stdio 传输 ---------- const transport new StdioServerTransport(); await server.connect(transport);关键点解读StdioServerTransport通过标准输入输出与父进程通信。当你的Agent以子进程方式启动这个Server时双方通过stdin/stdout交换JSON-RPC消息。Tool注册用registerTool定义名称、描述、参数Schemazod校验执行逻辑返回content数组支持多种类型如text、image。Resource注册registerResource定义URI类似URL但用于本地标识提供只读数据。Resource可以当作静态文档、配置、知识库片段等Client可以读取并注入到System Prompt中。3.3 Server 核心执行流程四、Agent集成用LangChain MCP适配器调用Server有了Server我们还需要一个AgentClient来消费它。这里我们用LangChain MCP适配器。4.1 安装依赖npm install langchain/mcp-adapters langchain/openai dotenv chalk4.2 编写 Clientlangchain-mcp-test.mjsimport dotenv/config; import { MultiServerMCPClient } from langchain/mcp-adapters; import { ChatOpenAI } from langchain/openai; import chalk from chalk; import { HumanMessage, SystemMessage, ToolMessage } from langchain/core/messages; // 1. 创建 MCP Client配置要连接的 Server const mcpClient new MultiServerMCPClient({ mcpServers: { my-mcp-server: { command: node, args: [E:\workspace\lgl_ai\ai\agent_in_action\mcp-demo\src\my-mcp-server.mjs] } } }); // 2. 初始化 LLMDeepSeek为例 const model new ChatOpenAI({ modelName: deepseek-v4-flash, apiKey: process.env.DEEPSEEK_API_KEY, configuration: { baseURL: https://api.deepseek.com/v1, } }); // 3. 从 MCP Server 获取工具和资源 const tools await mcpClient.getTools(); const resourcesMap await mcpClient.listResources(); // 4. 读取所有资源内容拼成 System Prompt let resourceContent ; for (const [serverName, resources] of Object.entries(resourcesMap)) { for (const resource of resources) { const content await mcpClient.readResource(serverName, resource.uri); resourceContent content[0].text; } } console.log(资源内容\n, resourceContent); // 5. 绑定工具到模型 const modelWithTools model.bindTools(tools); // 6. Agent 循环 async function runAgentWithTools(query, maxIterations 30) { const messages [ new SystemMessage(resourceContent), // 资源作为系统消息 new HumanMessage(query) ]; for (let i 0; i maxIterations; i) { console.log(chalk.bgGreen(正在等待AI思考, 第 ${i 1} 轮....)); const response await modelWithTools.invoke(messages); messages.push(response); if (!response.tool_calls || response.tool_calls.length 0) { console.log(\n AI 最终回复: ${response.content}); return response.content; } console.log(chalk.bgBlue(检测到 ${response.tool_calls.length} 个工具调用: ${response.tool_calls.map(t t.name).join(, )})); 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 })); } } } return messages[messages.length - 1].content; } // 执行测试 // await runAgentWithTools(查一下用户002的信息); await runAgentWithTools(MCP Server使用指南是什么); // 7. 关闭所有连接释放子进程 await mcpClient.close();4.3 代码要点剖析MultiServerMCPClient可以管理多个MCP Server的连接每个Server通过commandargs启动子进程基于stdio通信。getTools()自动将Server注册的Tool转换为LangChain兼容的StructuredTool可直接调用。listResources()readResource()读取所有Resource的内容我们将其拼成SystemMessage作为LLM的固定上下文。这是除RAG之外另一种丰富上下文的手段。Agent循环标准ReAct风格模型自主决策是否调用工具直到不再调用工具为止。释放资源mcpClient.close()会终止子进程并清理通信通道避免脚本一直挂起。4.4 Client 核心执行流程4.5 stdio通信时序图五、Resource的妙用不只是静态文档细心的读者会发现我们把Resource内容直接塞进了SystemMessage。这有什么好处轻量上下文增强对于不常变化的知识如使用指南、API文档、业务规则没必要每次都走RAG检索直接作为System Prompt的一部分既省时又省钱。扩展性Resource可以是本地文件、数据库查询结果、甚至远程API返回的只读数据只要Server注册了对应URIClient就能读取。金句Tool让Agent能“动手”Resource让Agent能“懂行”。两者结合才能真正扩展LLM的认知边界。六、踩坑与进阶思考6.1 stdio通信注意事项子进程必须通过stdio传输确保stdout只输出MCP协议消息避免夹杂console.log等调试信息否则解析会失败。若Server启动失败Client可能卡住建议加超时机制。6.2 多语言支持MCP协议不限制语言。你可以用Python、Rust、Java等实现Server只要遵循JSON-RPC消息规范Agent都能通过stdio或HTTP调用。这正是MCP最大的魅力——工具生态不再受技术栈约束。6.3 远程Server将transport替换为SSEServerTransport或WebSocketServerTransport即可支持HTTP远程调用配合身份认证企业级分布式Agent架构就搭建起来了。七、总结MCP让Agent开发进入“乐高时代”我们从一个痛点出发理解了MCP如何通过标准化协议解耦LLM和工具/资源。通过实战代码你学会了用Node.js实现一个MCP Server注册Tool和Resource。用LangChain的MCP适配器作为Client集成到Agent中。利用Resource注入System Prompt丰富上下文。通过流程图和时序图深入理解跨进程通信和Agent循环机制。MCP的本质是给AI Agent打造了一个“万能工具箱”的接口标准。从此不同语言、不同团队开发的工具可以像积木一样自由组合极大提升了Agent的可扩展性和复用性。未来随着MCP生态的成熟我们或许会看到大量公共MCP Server出现就像今天的NPM或PyPI一样让Agent开发真正进入“乐高时代”。