ARTICLE DETAIL

资讯详情

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

Agno框架中MCP协议接入实战:从本地工具到远程服务器

Agno框架中MCP协议接入实战:从本地工具到远程服务器 1. 为什么我在Agno里专门折腾MCP先说清楚这套组合的价值先说结论最近一个月我把手头几个Agent项目全部从Phidata迁到了Agno并且把工具调用层彻底换成了MCPModel Context Protocol模型上下文协议。这段时间折腾下来最大的感受是——MCP不是一个锦上添花的协议而是把Agent从玩具推向生产工具的关键一环。如果你对这两个词还比较陌生我简单交代一下背景。Agno是一个轻量级的AI Agent构建框架前身叫Phidata2025年正式改名发布。它的核心卖点非常朴素你可以用很短的时间把一个带有工具调用、知识库、记忆、多模态能力的Agent跑起来代码量比LangChain那套动不动几百行的编排少一个数量级。而MCP是Anthropic在2024年底提出的模型上下文协议它做的事情本质上是一句话把模型能调用哪些工具、工具长什么样、工具怎么被调用这件事标准化。为什么这两个东西放一起特别合适我打个比方。在没有MCP的时代Agent接一个外部工具流程是——你要先研究这个工具的SDK文档然后把它的API封装成Agent框架能识别的函数结构在Agno里就是装饰器类型注解那一套再自己处理鉴权、错误、超时、上下文窗口裁剪最后还要祈祷这个工具的参数结构和模型理解之间不发生冲突。每个工具都是这么一遍。接三五个工具你还能扛得住接几十个工具光维护函数签名就够你喝一壶。MCP的思路是所有工具都长一个样子都通过一套标准协议声明自己的名字、描述、参数JSON SchemaAgent不需要知道工具内部是什么语言写的、跑在哪台机器上只要发一个标准化的工具调用请求MCP服务器执行完把结果原样返回就行。所以这篇文章的定位很明确我以Agno v3.1.0为基准带你从零把一个MCP工具接入到Agent里从本地文件系统工具讲到远程MCP服务器把所有原理、代码、踩坑点、排查链路全部摊开。适合三类人看一是已经在用Agno但还没接MCP的二是想从LangChain/LlamaIndex迁移过来的三是对MCP协议感兴趣、想看看它在真实框架里怎么落地的。2. Agno的MCP接入模型三种模式、两个关键组件、一套异步任务系统2.1 MCP协议的核心机制30秒讲完在看Agno的API之前得先把MCP协议本身说清楚。MCP的架构是典型的C/S结构但不是普通的HTTP请求-响应模型它内部有一套状态机。客户端比如Agno里的Agent和MCP服务器建立连接后要经历这么几个阶段初始化握手Initialize客户端告诉服务器自己支持的协议版本、客户端能力服务器返回自己的协议版本、服务器能力、服务器信息。能力协商Capability Negotiation双方确认了工具列表、资源列表、提示模板这三类能力各自是否启用。工具发现Tools/List客户端向服务器拉取全部工具定义每一条包含name、description、inputSchemaJSON Schema格式的参数声明。工具调用Tools/Call客户端发送工具名参数JSON服务器执行并返回结构化结果。这里有一个很关键的设计MCP工具调用默认是异步的。什么意思就是客户端发起工具调用后服务器不一定立即返回最终结果可能先返回一个已收到请求的进度通知然后客户端可以主动去拉结果或者等服务器推送通知。某些长任务比如搜索、生成PDF、跑数据管道可能需要几十秒甚至几分钟异步机制保证客户端不会被卡死。MCP里还有两个容易被忽略的概念McpClient和McpSession。McpClient是管理整个连接生命周期的对象它负责启动子进程针对本地MCP服务器、发起握手、保持连接活跃McpSession是每次工具调用级的会话理论上在同一个连接上可以并发多个Session。Agno接管了这两层的大部分细节你在业务代码里基本只跟配置McpServer和把工具塞给Agent打交道但一旦遇到连接异常、结果丢失这类问题知道这两个概念能让你排查快得多。2.2 Agno里的McpServer抽象stdin类型和sse类型Agno直接给了一个高层封装McpServer。这个类有两种常见初始化方式from agno.mcp.mcp import McpServer # 方式一通过stdio子进程启动本地MCP服务器 local_server McpServer( commanduvx, args[mcp-server-filesystem, /tmp/agno-mcp-demo], env{API_KEY: xxx}, ) # 方式二通过Streamable HTTP / SSE连接远程MCP服务器 remote_server McpServer( urlhttps://your-mcp-server.example.com/mcp, headers{Authorization: Bearer xxx}, )方式一适用于本地跑的MCP服务器比如mcp-server-filesystem、mcp-server-github这类通过npx或uvx一键启动的工具方式二适用于部署在远程的MCP服务器走HTTP长连接。Agno内部会根据你传的是command还是url自动选择用子进程管道还是HTTP客户端去初始化McpClient。这两个方向在资深的Agent开发眼里有一个本质差异stdio模式的服务器跟Agent跑在同一台机器上生命周期由Agent管理进程死了你负责重启sse/http模式则把连接创建和鉴权的复杂度放到了网络层你需要考虑重连、超时、并发会话这些问题。后面我会分别给一个完整可跑的Demo。2.3 Agent怎么识别MCP工具framework参数与自动标注机制这里有个是很多从旧版升级上来的朋友最容易懵的地方。在Agno里如果你直接把McpServer传给Agent的mcp_servers参数然后期待通过tools参数去控制它你会发现问题MCP工具不在tools列表里以普通函数的形式出现而是被Agno在运行时自动捆绑进Agent的工具集。Agno文档里把这个行为叫Framework Annotation。也就是说你在代码里不需要显式声明tools[...]去包含MCP工具框架在收到mcp_servers列表后会自动对每个连接的MCP服务器调用list_tools把拿到的工具定义转换成语义内核Semantic Kernel能识别的函数结构在Agent的模型上下文里自动追加这些工具的描述。如果你用的不是Agno的Agent而是更底层的Model调用方式比如直接Assistant(modelOpenAIChat())那么MCP工具不会自动注入你得手动完成list_tools和call_tool两步。我在实际项目里80%的时间是用高层Agent所以自动标注这个机制对日常开发影响很大——它意味着你不能用tools_enabled去筛选某个MCP工具参与某次对话。这个坑后面细讲。2.4 为什么Agno选MCP而不是继续用装饰器函数一个成本账很多人会问Agno自己的函数工具机制tool装饰器已经很成熟了为什么还要套一层MCP我算过一笔账。假设我要给Agent接五个工具文件系统、GitHub API、搜索、Slack发消息、数据库查询。用Agno原生tool的方式我得为每个工具写一个Python函数处理参数解析、错误返回、鉴权而且这些函数只对这个Agent项目有效换个框架全部重写。五个工具大概要写200-400行胶水代码另外还要维护JSON Schema和类型注解的双重对应。用MCP的方式我只要准备五个McpServer实例每个用命令行把现成的MCP服务器跑起来GitHub官方出mcp-server-github、Slack官方出mcp-server-slack、搜索有brave-search-mcp等等Agent侧代码缩短到每个工具一两行。五个工具总计不超过50行而且这些MCP服务器是跨框架复用的——今天在Agno里用明天在Claude Desktop里用后天在自研的前端Agent里用零改造。这就是MCP带来的真正价值框架的边界被打破了工具生态重新变得可迁移。我从LangChain时代开始就被框架绑死工具这件事坑过现在这个方向是对的。3. 完整实操1在Agno中接入本地MCP文件系统工具3.1 环境准备里最容易踩的坑uv、uvx与Node.js版本先给一份我的实测环境Python 3.11.9推荐3.113.10以下部分依赖装不上Agno v3.1.0pip install -U agnoMCP相关依赖pip install mcp[cli]注意这里会装一个大一坨的官方客户端uvx用于启动本地MCP服务器安装uv即可这个工具链现在基本是Python生态的标配了这个组合里最容易踩的不是Agno本身而是uvx。mcp-server-filesystem这类官方服务器需要用uvx来运行如果你没有装uv直接pip install uv然后确保uvx在PATH里。Windows用户尤其注意装完uv后uvx命令可能需要重启终端才生效另外uvx首次启动会去拉对应包网络环境差的地方会卡很久甚至报timeout。我一般提前手动执行一次uvx mcp-server-filesystem --help把缓存预热一遍。3.2 最小可跑DemoPython代码逐行拆解下面这段是我项目里最常用的模板你直接可以复制。我不多废话直接上代码然后逐段拆。import asyncio from agno.agent import Agent from agno.models.openai import OpenAIChat from agno.mcp.mcp import McpServer async def main(): # 1. 配置一个本地文件系统MCP服务器 filesystem_server McpServer( commanduvx, args[ mcp-server-filesystem, /tmp/agno-mcp-demo, ], ) # 2. 创建Agent自动捆绑MCP工具 agent Agent( nameMCP File Explorer Agent, modelOpenAIChat(idgpt-4o), mcp_servers[filesystem_server], instructions你是文件系统助手使用提供的工具完成用户请求并简要说明你做了什么。, markdownTrue, show_tool_callsTrue, debug_modeTrue, ) # 3. 运行一个真实请求 response await agent.arun(请列出 /tmp/agno-mcp-demo 目录下的所有文件并读取其中第一个文件的内容。) print(response.content) if __name__ __main__: asyncio.run(main())逐段拆McpServer(commanduvx, args[...])指定用子进程方式启动MCP服务器。args里第一个参数给命令行工具名第二个参数给文件系统根目录。注意这个根目录是MCP服务器能访问的根Agent的模型只知道这个根下面的路径不会越界到整个文件系统——这是MCP安全边界设计的核心点之一。mcp_servers[filesystem_server]把服务器列表传给Agent。上一节说过Agno会自动去调list_tools然后把这套工具注入上下文。show_tool_callsTrue让输出打印模型选择了哪个工具、传了什么参数。调试阶段我强烈建议开着否则模型一旦乱调用工具你根本不知道哪里出了问题。debug_modeTrueAgno会把MCP连接初始化、握手、工具列表拉取过程全部打日志。我只能说这个开关救过我太多次。3.3 跑通后的日志解读怎么确认MCP真的被挂上了第一次跑起来后你会看到debug_mode打印一大堆日志。别被吓到核心看三样东西日志信息会包含Initializing MCP connection...这表示Agno的McpClient开始和子进程服务器建立stdio管道。接着是Negotiating protocol version...这对应着我在第一节讲的握手阶段。对照工具工具名是否出现如果一切正常日志里或调试信息里会看到类似Available MCP tools: [read_file, write_file, list_directory, ...]的信息。这时候你就能确认工具真的被加载进Agent了。如果没有出现这个输出第一个怀疑对象就是服务器启动失败加debug_mode查进程启动报错。第三个是工具调用的日志。当模型决定调用list_directory时日志里会出现Tool Call: list_directory({directory_path: /tmp/agno-mcp-demo})之类的行后面跟Tool Result: ...。对照着看能让你明确分辨是模型选错了工具还是工具执行报错还是结果返回但模型没理清楚。3.4 本地模式的核心优势与局限本地stdio模式最大的优点是安全和隔离。MCP服务器是一个独立的子进程有自己的权限边界和沙箱Agent崩溃了不会把MCP服务器一起带崩反之亦然。我试过在本地跑文件系统PostgreSQL查询浏览器自动化三套MCP进程间互不干扰。局限也很明显子进程MCP服务器只能在Agent所在的机器上访问。你做本地脚本没问题但如果你把Agent部署到Docker或K8s里stdio模式就麻烦了——容器里的路径映射、进程生命周期管理、日志收集全都要额外处理。这种场景下面这种远程MCP服务器模式更适合。4. 完整实操2接入远程MCP服务器并深挖许可校验机制4.1 远程MCP服务器的基本接入姿势远程MCP服务器在Agno里的接入方式非常清爽。以我现在正在用的一个内部数据查询MCP为例from agno.agent import Agent from agno.models.anthropic import Claude from agno.mcp.mcp import McpServer # 连接远程MCP服务器 internal_data_server McpServer( urlhttps://internal-data.example.com/mcp, headers{Authorization: Bearer your-api-token}, ) agent Agent( nameData Query Agent, modelClaude(idclaude-sonnet-4-20250514), mcp_servers[internal_data_server], instructions根据用户的自然语言问题选择合适的MCP工具查询内部数据。如果查询结果为空需如实说明。, show_tool_callsTrue, debug_modeTrue, ) agent.print_response(帮我查一下上个月华东区的销售额汇总, streamTrue)远程模式的优点倒不是免安装而是MCP服务器可以是一组共享服务多个Agent可以连同一个服务器。在家里写代码、在公司跑Agent、在服务器上部署定时任务全连同一个内网MCP端点工具逻辑只维护一份。4.2 Streamable HTTP和SSE协议选择我在兼容旧版Agno的项目里见过两种远程MCP传输方式传统的SSEServer-Sent Events和2025年3月之后官方推行的Streamable HTTP。两者最终的请求语义几乎一致主要差别在服务器推送机制和连接管理上。我强烈建议新项目直接用Streamable HTTP理由是SSE模式只有一个长连接服务端通过这个连接向客户端推事件但因为MCP的工具调用是异步的你很容易在哪个响应属于哪次调用上出混淆Streamable HTTP则允许客户端与服务器建立多个可切换的会话每次工具调用独立对应一个响应流错误处理、日志追踪和会话复用都要清爽得多。Agno v3.x的McpServer(url...)默认走的就是Streamable HTTP。如果你用的旧版是sse_url那尽快升版本因为SSE的协议语义在某些边缘场景比如服务端主动推送进度更新行为不一致。4.3 许可校验License Check这个坑很多人不知道这里我要专门讲一个在Agno v3.0以上才出现、文档里一笔带过、但实际使用中极易撞上的机制许可校验License Check。远程MCP服务器在会话建立时会向客户端发送一组tools/permissions/list题目我们内部叫许可校验题目客户端需要调用tools/permissions/check提交校验结果。校验通过的题目才会开放给模型调用不通过的会被标记为不可用。这个机制的设计初衷是给MCP工具加上一层能力开关服务器可以把某些敏感工具设置为需要额外授权。Agno目前的默认行为是本地连接stdio不发送许可校验请求也不用处理但远程连接会自动返回许可校验题目。如果你的MCP服务器要求校验、而Agno没自动处理你会遇到一个灵魂场景模型明明看到了工具的description日志里工具也在工具列表里但模型每次尝试调用结果都是工具不可用或者直接跳过这个工具去编答案。这个问题的排查链路我放在第五部分。这里只贴一个关键的解决办法在McpServer初始化时显式跳过远程许可校验remote_server McpServer( urlhttps://your-mcp-server.example.com/mcp, headers{Authorization: Bearer xxx}, ignore_remote_license_errorsTrue, )适合自己内部服务器的场景因为你们可以自己保证权限边界。如果是公共MCP服务器还是老老实实让Agno参与校验别把敏感工具裸奔出来。4.4 远程模式下的鉴权方式汇总远程MCP服务器的鉴权方式目前没有一个一家独大的标准我实践过的三种方式你可以按需取用Header Token方式最常见直接在McpServer(headers...)里加Authorization: Bearer token适合内部服务和API网关场景。OAuth方式MCP spec推荐但生态还不成熟Agno没有内置OAuth授权流程你需要先自己完成OAuth换取token再把这个token塞进Header。IP白名单方式自建服务如果你部署在内网直接在网关层限制来源IPMCP服务器本身不鉴权。我的建议是内部自用一律走IP白名单Header Token双保险面向外部用户的公共MCP服务器再考虑OAuth。别在MCP层做太复杂的鉴权逻辑否则排查问题的时候会很痛苦——你分不清是模型调用错误还是授权链路断了。5. 深度排查实录MCP工具不可见或不可用的完整链路5.1 第一个坑模型看到了工具但调用时报tool not found上周我在接一个内部慢查询MCP时遇到过一个诡异现象Agent日志里能看到工具加载成功模型也在思考但每次真正调用都返回一个错误大意是tool not found。我一开始怀疑是Agno的版本问题后来一步步排查才发现根因就在许可校验。排查链路如下第一步确认工具目录。我把debug_mode打开看到工具确实出现在上下文里。第二步查看模型实际调用了什么。日志显示模型调用时用的工具名是query_dashboard但MCP服务器工具定义里这个工具的真实名字叫dashboard.query——工具名里带点。模型在生成参数时可能因为系统提示或上下文里的展示格式问题把点号给吞了。于是query_dashboard这个工具永远不存在。这个坑提醒我MCP服务器里工具命名尽量避免特殊字符。如果工具名是你无法控制的比如第三方服务器已经写死建议在接入层做一层命令映射把工具名统一改写成正则友好的命名。第三步排查许可校验。如果工具名完全对得上但还是不可用就把ignore_remote_license_errorsTrue打开试一下确认是不是校验环节被卡住了。我这次就是在这儿定位到问题的——工具名对上了但许可校验有一道题没通过服务器把工具标记为不可用Agno内部就直接跳过了。5.2 第二个坑流式输出时MCP工具的结果在流中断裂还有一个高频问题使用streamTrue或print_response(streamTrue)时MCP工具返回较长的结果会触发截断甚至整个流中断。原因是Agno的流式输出针对的是模型生成的token流但MCP工具调用是异步的工具返回前模型是暂停的。这个暂停期间如果你使用的是嵌套的MCP工具工具A调用工具B输出流可能会先遇到一个空事件导致前端或CLI以为流结束了。我验证过的最稳方案是给McpServer传入stream_inputTrue参数强制让MCP工具调用结果也以流式事件的方式传给模型。但这个参数不是我自创的它在Agno的源码里叫stream_input默认False。实测打开后长文本的流式输出会稳定很多。5.3 第三个坑Agent记住上一次会话导致MCP工具行为异常这是我迁移到Agno之后最需要习惯的一点。Agno默认有一个storage功能可以在多次对话间保留会话历史。问题是如果会话历史里保存了之前MCP工具返回的大量上下文而这一次运行你只启动了部分MCP服务器那么会话历史里的工具调用字段可能引用一个本次不存在的工具ID模型会尝试用历史里的数据去回答而不是发起新的工具调用。我的处理方式很粗暴但有效评测和调试时一律不启用storage线上才打开并且每次任务配一个独立的session_id。如果你需要把MCP工具的多轮上下文在会话内传递我把方案放在下一节。6. 进阶MCP工具流式输出、会话隔离、变量替换与工具标注6.1 把MCP工具的结果真正流式给模型前面提到stream_input。我再补一段流式使用的实际模板这个模式在让Agent读大文件并总结这种长任务场景下体验极好from agno.agent import Agent from agno.mcp.mcp import McpServer server McpServer( commanduvx, args[mcp-server-filesystem, /tmp/data], stream_inputTrue, # 关键参数 ) agent Agent( modelOpenAIChat(idgpt-4o), mcp_servers[server], show_tool_callsTrue, ) response agent.print_response( 阅读/tmp/data/report.pdf并总结每段核心观点最后输出Markdown列表。, streamTrue, )注意stream_input只影响输入到模型的工具结果这一层模型最终的回复流式输出不受影响。日志里你会看到工具结果是通过增量事件逐步送到模型上下文的而不是一次性硬灌。6.2 MCP上下文变量的替换机制更新方向Agno 3.x在MCP集成里做了一个挺聪明的机制MCP上下文MCP Context支持变量替换。什么意思一个MCP工具返回结果里可能带一段长文本你需要让模型知道这段文本对应哪次调用的什么含义。Agno允许你定义MCP上下文变量比如mcp_context { current_folder: 必须从list_directory结果中提取, report_summary: 从read_file结果的第一段生成, user_query: 用户这次查询的原始输入, }然后把mcp_contextmcp_context传给Agent。运行模型时Agno会自动把工具返回结果里匹配这些模式的内容替换成变量定义的值模型在后续推理时可以直接引用{{current_folder}}不用自己翻前面的对话历史。这个机制比LangGraph的状态传递要轻量得多。我举个例子Agent先让MCP工具列出目录再让MCP工具读取某个文件如果不用变量替换模型在第二轮有时会忘记第一轮返回的绝对路径或者把不同目录混淆。用上变量替换后路径信息被固化成一个结构化变量模型绝不搞混。6.3 会话隔离与端到端保留MCP上下文在Agno里有个关键页面是storage和会话。如果你要让Agent长时间驻留比如每周六自动连同一个MCP服务器跑数据报告我建议每次任务启动时都创建一个新会话而不是复用旧会话。复用旧会话会带来三个问题历史上下文里残留的旧工具结果可能超出模型的上下文窗口会话里引用的session_id如果对应着丢失的工具定义模型会混乱MCP服务器本身的工具列表可能已经更新但会话历史里还是老的工具名。如果你非要在多轮里记住MCP调用的中间产物要这么做用storage保存会话并且同一个MCP服务器配置要保持完全一致包括参数、环境变量、版本。Agno官方demo里其实写过一个storage_with_mcp的示例就是把session_id和工具调用结果一起持久化但那个demo场景比较简单别照搬到生产环境。6.4 工具标注Tool Annotation与工具的叠加裁剪最后讲一个很多人问但文档里很隐晦的点MCP工具不能通过tools_enabled裁剪。Agno的tools_enabled参数只作用于通过tools参数显式传入的普通函数工具。对MCP工具Agno的自动注入机制会把这些工具全部塞进模型的上下文包括那些你希望它这次不要用的工具。从协议角度讲MCP服务器下发什么工具客户端就有什么工具客户端本身不裁剪。如果你确实需要同一套MCP服务器不同场景用不同子集目前的推荐做法是启动多个不同的McpServer实例分别对应不同功能组然后按场景把对应的McpServer传给不同的Agent。比如文件读写一个Agent搜索一个Agent数据库一个Agent模型通过路由机制决定把请求交给哪个Agent。这比试图裁一个服务器更可靠。6.5 失败重试与超时真实生产环境必须做的配置生产环境里MCP工具调用不会永远那么顺。我踩过的坑有本地文件系统MCP服务器因为目录不存在直接崩溃、远程MCP服务器因为网络抖动返回了空结果但Agent以为成功了。Agno在高层的arun请求里其实封装了重试逻辑但它默认的重试次数不多。我建议所有远程MCP调用在业务代码里再包一层自己的超时和重试逻辑import asyncio from agno.agent import Agent from agno.mcp.mcp import McpServer async def run_mcp_with_retry(agent, prompt, max_retries2): for attempt in range(max_retries 1): try: response await asyncio.wait_for( agent.arun(prompt), timeout120, # 自定义超时 ) return response except (asyncio.TimeoutError, Exception) as e: if attempt max_retries: raise print(f[retry {attempt1}] error: {e}) await asyncio.sleep(2 ** attempt) # 指数退避核心思路MCP工具调用的超时永远不应该依赖模型请求的超时因为工具本身可能耗时很长。120秒是我试下来比较折中的值如果你的工具经常超过两分钟再往上调。7. 综合选型建议与我的使用体会把上面这些踩坑整理完我对Agno里上MCP的选型建议可以浓缩成一张表。你直接拿这张表对照自己的场景选就行使用场景推荐连接方式推荐的McpServer配置本地脚本/个人项目快速原型stdio子进程McpServer(commanduvx, args[...])跨进程、跨机器的Agent服务Streamable HTTPMcpServer(url..., headers{...})长耗时工具文件解析、SQL、搜索任意但必须保证stream_inputTrue额外包一层业务超时工具结果需要在多轮中复用stdio/local优先用mcp_context变量替换生产环境多人共享工具远程MCP服务器网关鉴权ignore_remote_license_errors按需另外补充一点容易被忽视的MCP服务器的日志和健康检查。本地stdio模式下MCP服务器进程的stdout/stderr会跟Agent的日志混在一起如果你没做日志重定向排查时会很痛苦。我给生产环境的建议是不要在McpServer里裸跑uvx而是用systemd或supervisor把MCP服务器常驻化暴露一个内部HTTP端口再用McpServer(url...)连它。这样MCP服务本身的健康状态、CPU、内存都能监控到Agent侧不用管进程死活。再说回到开头那个问题到底值不值得在Agno里接MCP我的答案是如果你的Agent只需要两三个自研的简单工具原生tool就够了没必要引入MCP那套握手和异步事件系统但只要你的工具数量多、来源杂、有第三方工具或者你希望未来能在不同Agent框架之间复用工具资产MCP几乎就是唯一正确的选择。Agno在这一点上的抽象做得比较到位McpServer把你从连接管理、协议版本、许可校验这些底层细节里解放出来了接起来比我在LangChain里遇到的那堆缺胳膊少腿的实现顺手得多。最后分享一个我的使用习惯每接一个新的MCP工具我都会先在debug_modeTrue下用一个最小请求验证三件事——工具是否成功加载进上下文、模型是否正确选中工具、返回结果是否能被模型正确解读。这三步全过再上生产。不管用Agno还是别的框架这套验证逻辑都通用。MCP协议本身还在快速演进但“先验证工具可见、可用、可用好”这三点硬标准什么时候都不过时。
返回列表