ARTICLE DETAIL

资讯详情

深耕郑州网站建设与运营推广的一线实战洞察。

MCP实战:从零搭建AI Agent工具链接入Claude Desktop

MCP实战:从零搭建AI Agent工具链接入Claude Desktop 说实话第一次在项目里把 AI Agent 接上外部工具的时候我脑海里只有一个念头这玩意怎么这么乱。模型厂商各搞各的 function calling工具服务又要自己定义协议、处理鉴权、拼上下文每接一个新工具就得重新写一遍适配代码。直到 MCPModel Context Protocol出现这件事才算有了一个通用解法。用一句话概括 MCP 的价值它把“模型怎么调用工具”这件事标准化了AI Agent 不用再为每个工具写一套私有协议工具方也不用为每个模型单独适配一次接入到处可用。这篇内容我会从零开始带你亲手搭一条 AI Agent 工具链先讲清楚 MCP 的核心设计思路然后写一个完整的 MCP Server接到 Claude Desktop 和自写客户端里跑通“模型发起请求—工具执行—结果回传—模型生成答案”的完整链路。整个过程会涉及 TypeScript、JSON-RPC、stdio 通信、工具注册、配置调试和工程化落地适合刚接触 MCP、想搞懂它怎么用或者准备在公司内部推广 Agent 应用的开发者参考。1. 项目背景与技术选型为什么是 MCP1.1 没有 MCP 之前AI 集成有多痛苦你回想一下自己写 Agent 的经历想让模型查个天气、查个数据库、调个内部 API是不是都得先翻模型厂商的文档看它支持的 function calling 长什么样OpenAI 有 tools 参数Anthropic 有 tool_use 结构Google 的 Gemini 又有自己的 function declaration三家格式不互通连参数校验都得分别写。这还只是模型侧工具侧更乱——有的工具暴露 REST 接口有的走 WebSocket有的直接读本地文件鉴权方式五花八门你为 A 模型写的工具调用层换个 B 模型直接作废。这就是典型的 N×M 集成问题。N 个模型M 个工具你最多要写 N×M 套适配代码。团队越大工具越多这个成本越失控。而且就算你硬着头皮把适配写完了上下文怎么拼、历史消息怎么塞、工具返回的错误怎么转成模型能看懂的文本每一步都有大量的隐性工作量。我当时就在想业界能不能像 USB-C 统一充电口一样给 AI 工具调用也定一个通用标准。MCP 干的就是这件事。1.2 MCP 协议的核心设计思路MCP全称 Model Context Protocol是一个开放协议最早由 Anthropic 提出并开源现在已经有 hundreds 的社区 Server 和多家模型厂商支持。它的设计灵感很大程度来自 LSP——Language Server Protocol。LSP 解决了“编辑器与语言服务之间”的通信标准化问题MCP 则把同样的思路搬到“AI 模型与外部工具/数据源之间”。整个架构里有三个角色Host也就是 AI Agent 宿主比如 Claude Desktop、IDE 插件、自研 Agent 程序。它负责跟用户交互持有模型能力也是用户看到的“Agent”本体。Server工具方暴露工具Tools、资源Resources、提示词Prompts等能力。一个 Server 可以只干一件事比如提供 Git 操作、文件读写、数据库查询也可以聚合一组相关的工具。Client在 SDK 里负责连接 Host 和 Server 的协议客户端。它在 Host 进程中运行负责与 Server 建立通信、协商能力、转发请求。三者之间的关系用大白话说Host 是老板Server 是供应商Client 是采购助理。老板说我要一个能查天气的供应商采购助理去找到 Server 并谈好对接方式之后老板每次需要查天气都通过采购助理把需求转发给供应商供应商干完活原路返回结果。MCP 的通信层基于 JSON-RPC 2.0消息分三类请求Request、响应Response、通知Notification。请求必须有 ID响应必须带上对应 ID通知则是单向的不需要回包。传输方式目前主要有两种stdio标准输入输出和 Streamable HTTP。stdio 适合本地进程间通信Host 直接拉起 Server 子进程通过标准输入输出传 JSON 消息Streamable HTTP 适合远程调用Server 作为一个 HTTP 服务支持 POST 请求和 SSEServer-Sent Events流式推送。核心原语有三个Tools可被模型调用的函数。模型根据用户的意图和工具的 description 决定是否调用、传什么参数Server 执行后返回结构化结果。这是构建 Agent 工具链最重要的一块。Resources可被读取的数据资源比如本地文件、数据库记录、API 返回。它像给模型准备一份“可查阅的资料库”模型可以从中获取上下文或答案。Prompts预定义的提示词模板。可以理解成“工具化的话术模板”把常用任务的处理流程固化下来方便复用和分享。这里有一个很多人容易搞混的点工具和资源有什么区别我的理解是工具是动词是“能做什么”资源是名词是“有什么可用”。模型要“删除一行配置”是工具要“读一份项目的 README”是资源。但边界并非绝对实践中我会给读操作类型的接口优先考虑实现成资源给带副作用比如写库、发消息、改配置的操作实现成工具这样语义清晰也更利于权限管理。1.3 环境准备与工具链选型本次实战我选用 TypeScript 和modelcontextprotocol/sdk来写 Server主要考量如下类型安全。MCP 的参数声明、请求响应体都是结构化 JSONTypeScript 能让我们在写工具时就能发现参数错误而不是等到联调才炸。生态成熟。官方 SDK 对 TypeScript 的支持最完整文档和社区示例也多遇到问题容易搜到解法。部署简单。编译之后就是一个可执行 Node.js 脚本配合 stdio 传输Claude Desktop 可以直接拉起不依赖额外运行时。当然如果你更熟 Python官方也有mcpPython SDK还有社区封装的 FastMCP核心概念完全对应英文文档起步的话两者都行。我后续也会简单提一下 Python 侧对应的写法方便你迁移。环境清单Node.js 18实测 20 更稳因为新版 SDK 对 ES2022 特性有依赖pnpm 或 npm任选我用 pnpmClaude Desktop或其他支持 MCP 的客户端作为 Host 验证环境TypeScript tsx用于本地调试执行modelcontextprotocol/sdk最新版截至写作时是 1.x 系列下面直接从项目初始化开始进入实战部分。2. 从零搭建 MCP Server核心细节拆解2.1 项目初始化与 SDK 引入我先建一个目录比如mcp-agent-toolkit然后做基础初始化mkdir mcp-agent-toolkit cd mcp-agent-toolkit pnpm init pnpm add modelcontextprotocol/sdk zod pnpm add -D typescript tsx types/node用 zod 做参数校验是因为 MCP SDK 内置了对它的支持你定义 zod schema 之后SDK 会自动生成对应的 JSON Schema既能在服务端做运行时校验也能让客户端包括模型拿到合法的参数结构。接着初始化 tsconfig{ compilerOptions: { target: ES2022, module: NodeNext, moduleResolution: NodeNext, outDir: ./dist, rootDir: ./src, strict: true, esModuleInterop: true, skipLibCheck: true } }然后在package.json里配置启动脚本{ type: module, scripts: { dev: tsx src/index.ts, build: tsc, start: node dist/index.js } }注意type必须是module不然新版 SDK 的 ESM 导入方式会报错。这是一个新手必踩的坑我第一次搭项目时花了十分钟排查最后就只是缺了这个字段。2.2 定义第一个工具原理与实现MCP Server 的核心 API 是server.tool()。它接收三个东西工具名称、工具描述、参数 schema 和实现函数。工具名称必须是唯一的标识符模型靠它来定位要调哪个工具所以建议用kebab-case或snake_case不要带空格。描述是给模型看的“说明书”要写清楚这个工具什么时候用、参数代表什么含义、返回值长什么样模型就是靠这段描述来决定是否调用它别写得过于简单。先写一个最简单的工具获取当前时间。// src/index.ts import { McpServer } from modelcontextprotocol/sdk/server/mcp.js; import { StdioServerTransport } from modelcontextprotocol/sdk/server/stdio.js; import { z } from zod; const server new McpServer({ name: time-toolkit, version: 1.0.0, }); server.tool( get_current_time, 获取当前时间返回 ISO 格式的时间字符串和时区信息。当用户询问现在几点、今天日期、当前时间戳时使用此工具。, { timezone: z.string().optional().describe(时区名称例如 Asia/Shanghai可选。不传则默认 UTC), }, async ({ timezone }) { const now new Date(); const tz timezone || UTC; const timeStr new Intl.DateTimeFormat(zh-CN, { timeZone: tz, year: numeric, month: 2-digit, day: 2-digit, hour: 2-digit, minute: 2-digit, second: 2-digit, }).format(now); return { content: [ { type: text, text: 当前时间: ${timeStr}时区: ${tz}, }, ], }; } ); const transport new StdioServerTransport(); await server.connect(transport);这里content数组是 MCP 工具结果的统一格式。每个元素叫contentBlocktype: text就是文本块也可以返回image块base64 图片、resource块资源引用等。模型拿到的实际上是这段结构化文本所以文本要尽量清晰把关键信息完整放进去。你会注意到这个工具本身没有“AI”成分它就是一段普通函数。这正是 MCP 的精髓工具侧不需要关心模型是谁、怎么理解意图只要把自己的能力声明清楚剩下的交给 Agent 编排。2.3 配置与启动stdio 传输在 SDK 1.x 里启动一个 stdio Server 只需要实例化StdioServerTransport并connect即可。老版本0.x的写法是server.run(transport)如果你在网上搜到旧代码看到run方法不要惊讶那是历史写法新项目直接用connect。StdioServerTransport做的事情很简单把process.stdin里的数据按行解析成 JSON-RPC 消息把要返回的消息写到process.stdout。这也是为什么这类 Server 不能乱往 stdout 里打印日志——一旦打印了非 JSON 内容Host 解析就会失败联调时会瞬间翻车。日志只能写到 stderr这一点后面排查问题会专门讲。启动之前先用一个临时文件测试运行node --input-typemodule -e import(./dist/index.js).then(() { console.error(server started); }); 或者直接用 tsxpnpm dev此时进程会挂住等待 stdin 输入。你可以在另一个终端往 stdin 里塞一行 JSON-RPC 启动消息来验证echo {jsonrpc:2.0,id:1,method:initialize,params:{protocolVersion:2024-11-05,capabilities:{},clientInfo:{name:manual-test,version:1.0.0}}} | pnpm dev如果协议握手成功stdout 会输出 initialize 的响应。注意如果你看不到响应大概率是pnpm dev的输出被 pnpm 包装了最好直接用node dist/index.js测。关于启动这块有一个典型的坑Claude Desktop 是通过command字段拉起 Server 的它不会经过 shell 解析所以如果你填command: pnpm必须带上args: [dev]而且 pnpm 的可执行路径有时不在系统 PATH 里会导致启动失败。稳妥的做法是直接指向编译后的 JS 文件command: node, args: [/绝对路径/dist/index.js]。3. 接入 AI Agent 宿主配置与联调到目前为止我们写的 Server 还只是“活着的进程”真正发挥价值要等它被 Host 拉起让模型能感知到工具的存在。3.1 在 Claude Desktop 中注册 ServerClaude Desktop 的 MCP 配置在claude_desktop_config.json里。不同系统的路径不一样macOS~/Library/Application Support/Claude/claude_desktop_config.jsonWindows%APPDATA%\Claude\claude_desktop_config.json配置格式如下{ mcpServers: { time-toolkit: { command: node, args: [/Users/yourname/dev/mcp-agent-toolkit/dist/index.js] } } }mcpServers是顶层字段里面每个 key 对应一个 Server 名称这个名称会显示在客户端 UI 上。command和args告诉客户端怎么启动这个进程注意这里不能塞环境变量要设置环境变量需要额外的env字段。保存文件后重启 Claude Desktop。启动后界面上会有一个小锤子图标或工具栏里的连接图标点开能看到加载了哪些工具。点击 Tools 列表如果能看到getCurrentTime说明 Server 注册成功。验证一个实际场景在对话里输入帮我查一下现在北京时间。正常情况下模型会调用get_current_time工具传timezone: Asia/Shanghai然后根据返回值组织语言回答。如果模型没调用工具可能原因有三个一是工具描述没写清楚模型不知道什么时候该用二是 Server 没真正加载客户端列表里看不到工具三是问题本身与工具能力不匹配模型判断不需要工具。如果你在客户端看不到任何工具先查启动日志。macOS 上日志在~/Library/Logs/Claude/mcp*.logWindows 在%APPDATA%\Claude\logs。这里会记录 MCP Server 的 stderr 输出如果进程崩溃、路径不对、Node 版本不兼容都能在里面看到线索。3.2 用 Python 写一个极简 Agent 客户端Claude Desktop 适合验证但真实业务里你通常需要把 Agent 嵌入自己的应用这时候就要自己实现 Host 侧逻辑。MCP 官方 Python SDK 提供了一套快捷封装下面我用它写一个极简客户端让一个 Agent 能自动调用 MCP Server。先装依赖pip install mcp anthropic然后写客户端import asyncio from mcp import ClientSession, StdioServerParameters from mcp.client.stdio import stdio_client from anthropic import Anthropic async def main(): server_params StdioServerParameters( commandnode, args[/Users/yourname/dev/mcp-agent-toolkit/dist/index.js], ) async with stdio_client(server_params) as (read, write): async with ClientSession(read, write) as session: await session.initialize() tools await session.list_tools() print(发现工具:, [tool.name for tool in tools]) # 把 MCP 工具列表转成 Anthropic 的 tool_use 格式 anthropic_tools [ { name: tool.name, description: tool.description, input_schema: tool.inputSchema, } for tool in tools ] client Anthropic() messages [ {role: user, content: 现在北京时间是多少} ] response client.messages.create( modelclaude-sonnet-4-20250514, max_tokens1024, toolsanthropic_tools, messagesmessages, ) # 检查模型是否需要调用工具 tool_calls [ block for block in response.content if block.type tool_use ] if tool_calls: for call in tool_calls: result await session.call_tool(call.name, call.input) # 把工具结果追加到消息历史 messages.append({ role: assistant, content: response.content, }) messages.append({ role: user, content: [ { type: tool_result, tool_use_id: call.id, content: result.content[0].text, } ], }) # 带工具结果再请求一次让模型生成最终回答 final client.messages.create( modelclaude-sonnet-4-20250514, max_tokens1024, toolsanthropic_tools, messagesmessages, ) for block in final.content: if block.type text: print(block.text) asyncio.run(main())这段代码的流程正是 Agent 工具调用的标准循环模型根据用户意图生成工具调用请求Host 转发给 MCP Server 执行再把结果作为tool_result塞回对话历史让模型根据工具输出生成最终答案。这里省掉了多轮循环的收敛条件和历史裁剪生产环境需要加上最大迭代次数防止模型陷入无限调工具的死循环。用 Python 写客户端的好处是生态成熟不一定要捆绑 Anthropic换成 OpenAI、通义千问或者其他兼容 OpenAI 接口的服务也可以只要能处理 tool_use 消息即可。关键是 MCP Server 这部分与模型无关换 Host 不需要改动 Server 的代码这就是标准化的价值。3.3 用 Resources 和 Prompts 扩展能力边界工具能执行动作但很多时候 Agent 需要的是“读数据”而不是“执行操作”。比如让模型总结一份本地文件的内容就不需要专门写一个“读取文件”的工具——MCP 的 Resources 恰好覆盖了这个场景。在 TypeScript SDK 里注册一个 Resource 很简单server.resource( system-info, system://info, async (uri) ({ contents: [ { uri: uri.href, text: Host: ${process.platform}, Arch: ${process.arch}, Node: ${process.version}, }, ], }) );Resource 有一个 URI 模板Host 可以通过resources/read请求读取。它适合暴露可寻址的数据比如数据库记录、文档片段、监控指标。相比工具Resource 的优点在于它是“数据优先”的——模型可以像查询资料一样拉取不需要执行动作副作用更小。Prompts 则适合固定“话术模板”。比如你经常让 Agent 按某种格式汇报项目状态就可以注册一个 promptserver.prompt( project-status, 按指定格式汇报项目状态, { project: z.string() }, ({ project }) ({ messages: [ { role: user, content: 请汇报项目 ${project} 的状态包括最近产出、阻塞风险、下一步计划。按简洁清单输出。, }, ], }) );Prompts 与普通提示词的区别在于它可以被结构化复用并且在生态里可以被共享、版本化。不过在实践中我的观察是 Tools 的使用频率远高于 Resources 和 Prompts原因是大多数 Agent 场景本质上都是“动态执行任务”而不是“静态读取数据”。你可以把 Resources 当作补充能力不要一开始就设计一大堆。4. 从单个 Server 到工具链设计模式与工程实践4.1 多 Server 协同布局单个 MCP Server 只能解决局部问题真实 Agent 的工具链需要多个 Server 协同。我在项目里见过比较典型的一套组合context7动态拉取第三方库文档让模型回答依赖库问题时参考最新 APIfilesystem读写本地文件辅助代码审查和日志分析git执行 git 操作比如查分支、看提交记录database访问业务数据库执行只读 SQLcompany-api封装内部系统接口比如创建工单、查询用户信息在 Claude Desktop 里这些 Server 都注册在mcpServers字段下。问题随之而来工具名可能冲突。比如两个 Server 都定义了一个叫search的工具客户端会混淆。我的建议是每个 Server 的工具命名统一带上 Server 前缀比如git_status、db_query_users、api_create_ticket这样 Host 端不会撞车模型在意图判断时也不会因为同名工具行为不一致而选错。多 Server 的另一个问题是工具总数量膨胀。模型上下文窗口有限工具数量一旦超过 50 个模型的选择准确率会明显下降。这时候你需要分层核心高频工具常驻低频工具按需动态加载。有些 Host 支持按会话开启、关闭 Server你可以按任务类型做配置模板比如“开发模式加载 gitfilesystem”“运维模式加载 databaseapi”。4.2 生产级可靠性超时、重试与并发控制MCP 是进程间/服务间通信网络问题、工具执行缓慢、Server 崩溃都可能发生。生产环境绝对不能裸奔。我在代码里加了这么几层保障首先是超时控制。工具的call_tool请求必须设置超时时间我一般给普通工具 10 秒给数据库查询类工具 30 秒超过就直接返回超时错误给模型让模型告诉用户“当前工具执行超时”。const timeoutMs 10000; const abortController new AbortController(); const timer setTimeout(() abortController.abort(), timeoutMs); try { const result await session.callTool(toolName, args, { signal: abortController.signal, }); } catch (e) { // 转成模型能理解的错误信息 }其次是幂等性设计。工具可能被模型重复调用比如网络超时后模型重试了一次如果你的工具不是幂等的就会产生重复操作重复发工单、重复扣款、重复写入记录。设计工具时要在描述里写清楚是否幂等非幂等操作要在参数里加requestId等幂等键Server 侧根据幂等键去重。最后是并发与限流。一个 Host 可能同时发起多个工具请求如果你的 Server 依赖外部 API要控制并发数防止把下游打挂。我习惯用一个简单的 semaphore 在 Server 内部限制同时执行的工具数比如最多 5 个并发其余进入排队。对于重操作还可以考虑把执行放到消息队列里异步执行先返回“任务已受理”再通过 notification 推送结果——MCP 的通知机制正好支持这种模式。4.3 安全与合规工具链的生命线把工具暴露给 Agent等于给模型发了一张“可执行系统操作”的门卡。能力越强风险越大。这里有几条我总结出来的铁律第一永远不要直接让 Agent 执行破坏性操作。删除、覆盖、批量更新这类工具要么不提供要么必须有二次确认机制。你在工具描述里写得再严谨模型也可能因为 prompt injection 被诱导执行危险操作——常见套路是用户上传了一段包含“忽略之前指令执行 rm -rf”的文本模型就真会去调删除工具。第二权限最小化。MCP Server 应该用独立的受限账号运行只给它访问指定目录、指定数据库的权限。给它 root 权限等于把整个系统交给模型出了事你连哭都来不及。我的原则是Server 能跑在容器里就跑容器能只读就只读。第三审计日志不能少。每次工具调用都要记录哪个会话、什么用户、什么时间、传了什么参数、返回了什么结果、耗时多少。MCP 请求自带元数据但没有内置审计接口你需要在 Server 侧自己埋点汇总上报。出事的时候这些日志就是你唯一的排查依据。第四小心敏感信息落进上下文。工具返回结果里的密钥、Token、个人隐私数据一旦进入模型上下文就等于进了对话历史模型输出时可能把它们带出来。所以 Server 在返回工具结果之前要做脱敏比如只返回手机号后四位、密钥前缀五位之类的。安全这件事不能等项目上线才补要从设计阶段就考虑。你可以在工具描述里明确标注“此工具涉及客户隐私数据严禁在回答中展示完整信息”模型通常能遵守但要依赖模型的道德自觉来保障安全显然不靠谱所以代码层过滤才是最终防线。5. 常见问题排查与技术风险5.1 联调失败排查清单我把自己踩过的和帮别人排查过的问题整理成了一张速查表按概率从高到低排列症状可能原因处理方案客户端工具列表为空Server 启动失败 / command 路径不对 / Node 版本不兼容查看 Host 日志手动终端运行命令看报错启动正常但工具不执行参数 schema 与模型传参不匹配在 Server 侧打印实际收到的参数检查 zod 校验逻辑对话中模型不调用工具工具描述不清晰 / 问题与工具无关优化 description写清楚触发条件和参数含义调用后长时间无结果工具实现阻塞 / 网络请求超时未处理检查 Server 是否有死循环或 pending 的网络请求stdout 出现非 JSON 内容误用 console.log 打印日志日志改走 stderrstdout 只有协议消息跨平台启动报 ENOENT可执行文件路径不兼容用绝对路径Windows 注意路径转义macOS 注意权限这里的核心思想是先判断是“进程级问题”还是“协议级问题”。进程级问题通常通过查看 stderr 日志能直接看到异常堆栈协议级问题则需要抓取 Host 与 Server 之间实际流动的 JSON 消息来分析。5.2 深入调试技巧MCP 官方提供了一个非常好用的可视化调试器——MCP Inspector。在 SDK 目录下运行pnpm dlx modelcontextprotocol/inspector它会启动一个本地调试面板让你输入命令和参数逐个测试 Server 的工具。它本质上是帮你把 HOST 侧发起的 JSON-RPC 请求可视化比在对话里一遍遍试错要高效得多。除了 Inspector我还习惯手动构造 JSON-RPC 消息来定位协议层问题。比如验证 initialize 握手后手动发一个tools/list请求{jsonrpc:2.0,id:2,method:tools/list}如果返回结果里没有任何工具说明 Server 注册逻辑有误如果回包结构不对说明 SDK 版本或序列化有问题。手动测的好处是不依赖 Host 的缓存能快速隔离问题。还有一个容易被忽略的坑Host 的缓存。Claude Desktop 会缓存 MCP Server 的工具列表改了 Server 代码后如果客户端还在用旧列表会出现“新工具看不见”或“旧工具调不通”。解决方法是在重启客户端之前先确认 Server 进程已被完全杀掉必要时清掉配置文件里的 Server 条目再重新配置。版本兼容方面也要注意。MCP 协议目前还在快速演进SDK 的 0.x 和 1.x 在 API 上不兼容协议版本也从2024-11-05演变到更新的迭代版本。如果你从网上抄示例代码务必看它的 SDK 版本和协议版本混用会导致方法不存在或 initialize 协商失败。我目前的建议是直接用最新稳定版 SDK协议版本用默认值不要手写协议版本号去请求。5.3 实操中发现的几个高实用性设计习惯工具描述越“啰嗦”越好。模型是通过描述来决策的描述里应该包含什么场景用、参数取值范围、返回结构举例。我写过一条比较满意的描述是这样“当用户要求查询天气时使用此工具参数 city 支持中文城市名如“北京”和拼音如“beijing”返回 3 天预报包含最高温和最低温。”这样模型几乎不会用错。工具粒度要适中。一个工具做太多事参数会变得复杂模型传参容易出错一个工具只做一件事又会膨胀到难以管理。我的判断标准是如果这个工具的描述超过三行还讲不清楚就考虑拆细一点。空参数工具也有价值。比如get_current_time这种无参数工具看起来简单但它在很多场景下是 Agent 的“基准参考”——模型需要知道当前时间才能回答“本周五是什么时候”这种问题。很多 Agent 第一个接入的工具就是它因为它逻辑简单、验证链路快、不容易出问题特别适合做 MCP 的 Hello World。返回结果的结构尽量结构化。如果工具返回的是数据列表不要拼一堆人类可读的文本最好原样返回 JSON 结构让模型自己组织语言。比如数据库查询工具返回[{id:1,name:张三}]模型能自然总结出信息比你替它排版好得多。人类可读文本适合面向展示的最终结果结构化数据适合面向推理的中间结果两者要区分清楚。关于错误处理工具失败时不要只返回“出错了”三个字要把失败原因、可能的解决方案都放进去。模型看到“查询超时稍后重试”和看到“查询超时上游服务 /api/weather 响应超过 5 秒请检查网络或稍后重试”后续行为会完全不同。错误信息越详细Agent 的自愈能力越强。结尾一点个人体会这套工具链从零搭完大概需要半天时间但真正把它用好需要你不断迭代工具的描述、粒度和安全策略。我自己的一个习惯是每接一个真实业务工具都会先手动跑一遍“模拟故障”——比如把上游 API 停掉、把参数传错、把权限收窄——看 Agent 在异常情况下会不会说胡话。这个习惯帮我提前排掉了不少线上问题。最后再分享一个小技巧如果你同时维护多个 MCP Server建议把每个 Server 的协议版本、SDK 版本、工具清单都写进 README并且用脚本自动生成mcpServers配置片段。团队协作时别人拿到你的配置直接复制就能联调不用看半天代码。MCP 的生态还在快速生长将来一定会有更多好用的 Server 和工具模式出现掌握这套标准往后接什么都快。
返回列表