Hermes Agent 本来就能在一台远程机器上跑 shell 命令。它的 SSH 终端后端指向一台主机,每条命令都通过 ssh 执行。对单台服务器来说,这没问题。可一旦你有不止一台,或者你不想让一把私钥待在跑代理的那台机器上,这个后端就用错了工具。更干净的做法,是把 Hermes 接到一个替它够到你服务器的远程 MCP 服务器上——代理机器上没有密钥、多台主机、按连接设规则,还有一条审计日志。本文两件都讲:今天这个 SSH 后端是怎么工作的,以及怎样改成把 Termalin 接成一个 MCP 服务器。
利益披露:我们开发 Termalin。下面关于 Hermes Agent 的细节来自它的公开文档和问题追踪器,核对于 2026 年 10 月 15 日。
Hermes Agent 今天是怎么用 SSH 的
Hermes Agent 通过一个终端后端来跑它的工具。其中一个后端是 SSH。你在 ~/.hermes/config.yaml 里设置它:
terminal:
backend: ssh
凭据放在 ~/.hermes/.env 里:
TERMINAL_SSH_HOST=my-server.example.com
TERMINAL_SSH_USER=ubuntu
TERMINAL_SSH_PORT 默认是 22,TERMINAL_SSH_KEY 是一把私钥的路径(留空时就用系统默认的那把)。文档把这套机制讲得很直白:它“通过 SSH 在一台远程服务器上执行命令”,用 ControlMaster 和一个 5 分钟空闲保活来复用连接,每条命令都是一个全新的 ssh … bash -c。
这个设计引出三个事实,它们正是人们去另寻他路的原因:
- 一个后端意味着一台主机。
TERMINAL_SSH_HOST和TERMINAL_SSH_USER都是必填的,而且这个后端没有多主机清单。要操作第二台服务器,你得重新配置。 - 一把私钥待在 Hermes 机器上,要么是一个文件,要么通过系统的
ssh-agent。任何能读到那台机器的东西都能用这把密钥,而这把密钥能打开每一台信任它的主机。 - **Hermes 会把它自己的凭据复制到远程机器上。**文档指出,对于 SSH、Modal 和 Daytona 这几个后端,Hermes 会在会话期间把你的
~/.hermes/状态——凭据文件、技能、缓存——推进远程沙箱,并在拆除时把有改动的状态文件同步回来。
文档确实为 SSH 后端给出了一个站得住脚的理由:因为代理跑在另一台机器上,它“无法修改自己的代码”。这种隔离是真实的,我们在下文会回到它。
人们会撞上的问题
hermes-agent 的问题追踪器里,围绕这些 SSH 路径有一簇一眼就能认出来的开放 issue。按编号列出,不去夸大每一个对你意味着什么:
- 用命名的 profile 时,SSH 后端会以“path too long for Unix domain socket”失败(#133436)。
- 改了配置之后,
/reload不会清掉缓存的 SSH 环境(#71085)。 - 桌面端的 SSH 模式有它自己的一摞:一个大约一秒就失败的 macOS 探测(#80836),以及 Windows OpenSSH 的卡死和超时(#118983、#138378、#127320)。
- 一场启动时的重试风暴,大约每分钟 25 次 SSH 登录(#134197)。
- 在封了 22 端口的网络上,
hermes update会失败(#133439)。
这里面有些是关于桌面应用、而非后端的,还有些等你读到时可能已经修好了。重要的是这个规律:SSH 后端只是裹在一条 ssh 连接外面的一层薄壳,所以它继承了那条连接的每一处棱角——包括需要 22 端口可达。
一个无密钥的替代方案:把 Termalin 当作远程 MCP 服务器
Hermes Agent 支持 MCP。它能和 stdio 服务器对话,也能和远程 HTTP 服务器对话,用一个 Bearer header 或 OAuth 都行。这就是突破口。与其给代理一把密钥和一台主机,不如把它指向一个已经知道怎么够到你整片机群的远程 MCP 服务器。
Termalin 是一款带托管 MCP 服务器的 SSH 客户端。每一台你想让它够到的服务器都跑一个 Connector——一行命令就能装好,它向外拨号、从不监听端口,所以在 NAT 和 CGNAT 之后也能用,22 端口也不需要开放。注册时,服务器的 sshd 会信任 Termalin 的 SSH 证书颁发机构(CA)。之后每次登录都用一张范围限定到你账户的短期证书。机器上没有常驻的长期密钥,也没有任何密钥交到代理手里。
MCP 服务器配置在 ~/.hermes/config.yaml 顶层的 mcp_servers 键下。有两种认证方式。在 VPS 上——Hermes 通常就跑在那里——API 密钥更简单,所以从它开始。
方案 A——API 密钥(在 VPS 上最佳)
在 Termalin 网页控制台里创建一把 API 密钥,把它的范围限定到这个代理该碰的服务器,设成只读或一份允许列表,并给它一个过期时间。把它放进 ~/.hermes/.env:
TERMALIN_API_KEY=tk_live_your_key_here
然后添加这个服务器。Hermes 在连接服务器时解析 ${VAR} 引用,headers 里面也一样:
# ~/.hermes/config.yaml
mcp_servers:
termalin:
url: "https://termal.in/api/v1/mcp"
headers:
Authorization: "Bearer ${TERMALIN_API_KEY}"
检查连接,然后在一个会话里重新加载 MCP:
hermes mcp test termalin
/reload-mcp
对 url 型服务器来说,Streamable HTTP 是默认的传输方式,而 termal.in 说的正是它,所以你不需要一行 transport:。
方案 B——OAuth 登录(用于笔记本)
如果 Hermes 跑在你自己的、带浏览器的机器上,OAuth 能省掉存储密钥:
# ~/.hermes/config.yaml
mcp_servers:
termalin:
url: "https://termal.in/mcp"
auth: oauth
hermes mcp login termalin
首次连接时,Hermes 会打印一个授权 URL,在它能做到时打开你的浏览器,并在一个本地回环端口上等待 OAuth 回调。Termalin 的登录接受那个回环重定向(http://127.0.0.1:<port>/callback),所以 auth: oauth 在我们这一侧是可行的。
在一台无头 VPS 上,回环回调够不到你的笔记本。有两种绕法在 Termalin 上管用:把重定向 URL 粘回到 Hermes 的提示符处,或者用 ssh -N -L <port>:127.0.0.1:<port> user@host 转发端口,再在你笔记本的浏览器里完成登录。Hermes 还有一种设备码流程,但 Termalin 的登录不提供它——在服务器上,方案 A 里的 API 密钥是更简单的路线。
连上之后你得到什么
在 hermes mcp test termalin(或 hermes mcp login termalin)和 /reload-mcp 之后,Termalin 的工具就出现在代理面前:hosts_list 看它能够到哪些服务器,ssh_exec 和 ssh_exec_many 在一台或多台上执行命令,sftp_list / sftp_read / sftp_write 处理文件,server_metrics 和 alerts_list 看健康状况,还有 job_start / job_status / job_stop / job_list 处理那些比单次调用活得更久的工作。
和 SSH 后端相比,实际的差别在于:
- 一次管很多台服务器。
ssh_exec_many在一组主机上跑同一条命令。没有单主机的限制,换机器也不用重新配置。 - **按连接设规则。**在 AI 应用卡片里,你为这个连接设一个命令策略:完全访问、一份允许列表,或只读。从只读开始,之后再放宽。
- **一条审计日志。**代理跑的每一条命令都被标记为代理的,被记录,并显示在实时监控网格里。“这是代理干的”是一个筛选条件,而不是一场事后重建。见审计代理做了什么(英文)。
- **后台任务。**一次漫长的迁移或构建作为一个任务来跑,这样一个慢活不会堵住会话、也不会撞上一个固定的超时。
- **无需开放端口。**Connector 向外拨号,这也顺带绕开了“22 端口被封”那一类问题。
撤销访问是一个开关,而不是在每一台主机上轮换密钥。这笔取舍背后的道理,见为什么不该把你的 SSH 密钥交给代理(英文)和影响半径。
什么时候反而该保留 SSH 后端
这不是那种一个选项赢下每一行的情况。
- 如果你正好只有一台机器、已经在 Hermes 机器上放了一把密钥,而且不想让别的东西掺和进来,那 SSH 后端要搭的东西最少。
- 文档关于隔离的那个观点是成立的:跑在一台单独的主机上,意味着代理无法编辑自己的代码。MCP 这条路也保留了这个性质,因为命令是在你的服务器上、而不是在代理机器上执行的——但如果 SSH 后端已经给了你这一点、而且也不需要别的,那就没有理由切换。
- Termalin 的 MCP 和监控工具需要一个 Pro 套餐($10/月,或按年付费 $8/月——每年 $96),或者那个 14 天试用,外加每台服务器上一个 Connector。而一把孤零零的密钥加 SSH 后端,什么都不花。
当你有好几台服务器、当你不想在代理机器上放密钥、当服务器在 NAT 之后,或者当你需要按连接的规则和一条审计轨迹时,就用 Termalin。当一台主机上的一把密钥确实就是你全部所需时,就留着 SSH 后端。
排障
- **工具没出现。**跑
hermes mcp test termalin,确认url是对的,并且TERMALIN_API_KEY已在~/.hermes/.env里设置。然后在会话里/reload-mcp。 - **端点返回
401。**API 密钥缺失、错误,或已过期。在控制台里新建一把,并更新~/.hermes/.env。 - **
${TERMALIN_API_KEY}引用被原样发了出去。**Hermes 在连接时展开${VAR};确认这个变量在~/.hermes/.env里(或在启动 Hermes 的那个 shell 里),然后重新连接。 - **无头 VPS 上的 OAuth 一直完不成。**回环回调够不到你的笔记本。用
ssh -N -L <port>:127.0.0.1:<port> user@host转发端口,或者把重定向 URL 粘回到提示符处。在服务器上,API 密钥路线更简单。 - 传输方式不对。
url型服务器默认用 Streamable HTTP,termal.in用的就是它。只有对那些只说 SSE 的服务器才设transport: sse——这个不是。
常见问题
**Hermes Agent 支持 MCP 吗?**支持。它连接 stdio 服务器和远程 HTTP 服务器,用一个 Bearer header 或 OAuth,在 ~/.hermes/config.yaml 的 mcp_servers 下配置。
**我能在 VPS 上的 Hermes Agent 用这个吗?**能,而且在那里 API 密钥路线最省事。OAuth 流程需要一个浏览器,或者上面那些无头环境的变通办法之一。
**我需要在服务器上开一个端口吗?**不需要。Connector 向外拨号,所以它在 NAT 和 CGNAT 之后也能用,不需要任何入站端口。见 SSH 穿越 NAT(英文)。
**我的 SSH 密钥会交给代理吗?**不会。服务器是用每次登录签发的短期证书够到的。没有长期密钥离开 Termalin,也没有任何密钥被放进代理的环境里。
Termalin 是一款跨平台 SSH 客户端,带一个托管 MCP 服务器、一个密钥托管方(替你保管密钥、代为签名的中间层),以及按主机的代理策略。在跑别的代理?同一套无密钥设置也适用于 OpenClaw、Codex(英文)等等——或者下载应用开始上手。