从零实现 GeekAgent —— Day15 MCP 工具接入
内容提要
本文介绍GeekAgent项目第15天实现MCP工具接入。通过配置文件声明服务器,Agent启动时自动连接并获取工具清单,以`mcp_`前缀注册到现有工具表。MCP与Skills区别在于前者动态发现外部能力,后者组织任务指令。实现采用stdio传输和JSON-RPC协议,支持权限控制,代码净增311行。
延伸解读
MCP 与 Skills 的分工
MCP 和 Skills 看似都在增加工具,但解决的问题不同。Skills 按任务组织指令和工具,工具在 Skill 目录中预先声明;MCP 则通过统一协议动态发现外部能力,Agent 启动时连接 server 并调用 tools/list 获取工具清单。MCP 让工具可以独立演进,server 更新后 Agent 下次启动即可发现新工具,无需修改 Agent 代码。两者互补,MCP 负责接入外部能力,Skills 负责任务编排。
MCP 的适用边界与限制
当前实现仅支持 stdio 传输,只能连接本机命令,无法连接远程 HTTP 服务,也没有 OAuth 鉴权。MCP 工具与 Agent 共享用户权限,安全性依赖权限层默认的 ask 策略。此外,实现不处理 server 运行期间的工具动态变化(如增删通知)和断线重连,server 崩溃后需重启 Agent。resources、prompts 等 MCP 能力也未接入,仅支持 tools。
工具命名与权限控制
MCP 工具以 `mcp_<服务名>_<工具名>` 格式注册,避免不同 server 提供同名工具时冲突。外部工具默认使用 ask 权限策略,每次调用前需用户确认;可在配置文件中按完整工具名改为 allow 或 deny。权限控制沿用 Day 8 的策略,确保外部代码执行前经过用户授权,降低安全风险。
Q&A
MCP和Skills在GeekAgent中有什么区别?
Skills按任务组织指令和工具,工具在Skill目录中静态声明;MCP通过统一协议动态发现外部能力,工具由server提供,Agent启动时通过tools/list获取。
GeekAgent如何接入MCP工具?
在.geekagent/mcp.json中配置server的启动命令,Agent启动时自动连接,通过JSON-RPC握手并调用tools/list获取工具清单,然后以mcp_前缀注册到工具表。
MCP工具注册时如何命名?
以mcp_<服务名>_<工具名>的格式命名,例如mcp_demo_dice,以避免不同server提供同名工具时的冲突。
MCP工具调用时如何控制权限?
外部工具默认使用ask策略,每次调用前询问用户;也可以在.geekagent/GeekAgent.json中按工具名配置为allow或deny。
MCP支持哪些传输方式?本次实现支持哪种?
MCP支持stdio和Streamable HTTP两种传输方式。本次实现只支持stdio,适用于本地子进程,无需鉴权。
MCP协议中如何发现工具?
Agent连接server后,发送tools/list请求,server返回工具清单,包括名称、描述和参数Schema。
MCP工具与内置工具在实现上有什么不同?
内置工具是Agent仓库内的TypeScript函数,与Agent同进程;MCP工具是外部进程,通过JSON-RPC调用,独立于Agent,崩溃互不影响。
MCP server崩溃后如何处理?
如果server启动失败或中途退出,客户端会拒绝挂起的请求,并记录错误状态;需要重启Agent才能重新连接。