Technical Guide

15. MCP:外部工具如何变成 Hermes 工具

理解 Hermes 的 MCP 客户端:stdio、HTTP、SSE 服务器如何接入工具注册表。

这篇解决什么问题

Hermes 内置了很多工具,但总会遇到外部系统:GitHub、数据库、内部平台、设计工具、浏览器服务、公司自己的 API。

MCP 解决的是:外部服务怎么以统一协议接进 Agent。

先看哪个文件

关键文件是:

tools/mcp_tool.py

文件开头说明得很清楚:它支持连接外部 MCP servers,通过 stdio、HTTP/StreamableHTTP 或 SSE transport,发现工具,并注册到 Hermes 的 tool registry 里。

也就是说,MCP 工具最后和内置工具一样,会进入同一套工具系统。

配置在哪里

MCP 配置来自:

~/.hermes/config.yaml

通常在 mcp_servers 下。

示例形态类似:

mcp_servers:
  filesystem:
    command: "npx"
    args: ["-y", "@modelcontextprotocol/server-filesystem", "/tmp"]
    env: {}
    timeout: 120
    connect_timeout: 60

  remote_api:
    url: "https://example.com/mcp"
    headers:
      Authorization: "Bearer ..."
    timeout: 180

stdio 适合本地命令型 server。

HTTP/SSE 适合远程服务。

MCP 接入后的链路

简化看:

读取 mcp_servers 配置
→ 启动或连接 MCP server
→ 发现 server 暴露的 tools
→ 把 MCP tool 注册进 Hermes registry
→ 模型看到这些工具 schema
→ 模型发起 tool_call
→ Hermes 转发给 MCP server
→ 结果回到模型上下文

所以 MCP 不是独立的一套工具调用系统。它最后仍然回到 Hermes 的 registry / tool call 链路。

为什么 MCP 要后台 event loop

mcp_tool.py 里提到:MCP 使用专门的后台 event loop 和 daemon thread。

原因是 MCP server 可能是长连接,不能每次工具调用都重新启动一次。

后台 loop 负责保持 server transport 活着,并把工具调用 coroutine 安排到对应 loop 上执行。

安全和日志

MCP 有几个需要注意的点:

  • stdio server 是外部进程,环境变量要过滤;
  • server stderr 不能直接打到 TUI,否则会污染终端;
  • 错误信息要去掉 credential;
  • 远程 MCP headers 可能包含 token,不能进聊天上下文;
  • server 超时和断线要能恢复。

源码里也专门把 MCP subprocess stderr 重定向到:

~/.hermes/logs/mcp-stderr.log

什么时候用 MCP,什么时候写内置 Tool

适合 MCP:

外部系统已有 MCP server
团队内部服务想同时给多个 Agent 用
工具能力比较独立
需要跨语言/跨进程接入

适合内置 Tool:

和 Hermes 内部状态强相关
需要特殊权限控制
需要复用 Hermes 内部工具/会话上下文
只是一个很小的本地能力

下一篇看什么

下一篇看 Delegation。

MCP 扩展工具边界,Delegation 扩展任务执行边界。