给 Hermes Agent 设计一套最小可用的外部集成架构
把 Hermes Agent 接进团队时,最先爆雷的往往是三件事:谁都能进来、工具开太大、命令在宿主上裸奔。下面按「入口 → 能力 → 护栏」三层搭一套够用、又好收手的架子;用到的能力就是 Messaging Gateway、内建 Toolsets、MCP,再加安全相关配置。
为什么从「最小可用」起步
内建工具已经覆盖网页检索、浏览器、终端、文件、cron、发消息等一大坨场景,没必要为集成而集成。MCP 适合这种情况:外面已经有一个 MCP server,你懒得改 Hermes 本体,只想让模型多几个「外挂函数」。
实操上记住两件事就够:先接一个边界清晰的服务器(比如只允许某个项目目录的文件系统),跑通再加第二个;内置工具能搞定的就别硬上 MCP——多一个进程或 HTTP 端点,就多一份运维和暴露面。
入口层:从哪里来、谁能动
Messaging Gateway 把 Telegram、Discord、Slack、邮件等渠道收到同一个后台进程里,按聊天维度会话,再把本轮交给 AIAgent;需要定时的事还可以交给网关侧的 cron。你要决定的其实是:开哪几个渠道、每个渠道默认带多大工具权限。
网关默认对陌生人说不——对有终端能力的 bot 来说这是合理默认。你可以用平台 ID 白名单、全局 GATEWAY_ALLOWED_USERS,或者用 DM 配对:对方拿到一次性码,你在本机执行 hermes pairing approve 平台名 配对码 放行(把两项换成真实值,例如 telegram 与机器人给出的码)。生产环境尽量别图省事开「全员放行」类开关。
第一次搭网关,交互向导最直接:
hermes gateway setup
Slack 只让指定成员进,可以在 ~/.hermes/.env 里写(把 ID 换成你们真人的):
SLACK_ALLOWED_USERS=U01ABC123,U01XYZ999
忙的时候消息是打断当前任务、排队还是 steer,以及 /background 后台会话,按团队习惯调就行;核心仍是:先把「谁能触发 Hermes Agent」收紧,再谈自动化。
能力层:内建工具 vs MCP
内建工具管「通用探索」:搜网页、抓页面、开浏览器、跑终端、改文件、拆解任务等,并且按 toolset 在不同渠道裁剪可见工具。Slack 常用预设类似 hermes-slack,往往仍带终端——所以入口白名单不是摆设,得和工具面一起想。
想手工收窄一轮 CLI 试跑,可以类似:
hermes chat --toolsets "web,terminal"
MCP 适合 GitHub、数据库、单仓库文件树、公司内 HTTP MCP 这类形状固定的系统。Hermes Agent 会把工具注册成 mcp_<server>_<tool>,每个 server 也会对应一个 mcp-<server> 的 toolset,方便你在脑子里分区:「这段能力从哪个外挂来的」。
最小一套 MCP可以先「单目录文件系统 + 窄权限」,例如只允许 /home/user/my-project(路径换成你的仓库根):
mcp_servers:
project_fs:
command: "npx"
args: ["-y", "@modelcontextprotocol/server-filesystem", "/home/user/my-project"]
再接 Git(本地仓库)可以并排写第二个 server,仍是官方示例那种写法:
mcp_servers:
fs:
command: "npx"
args: ["-y", "@modelcontextprotocol/server-filesystem", "/home/user/project"]
git:
command: "uvx"
args: ["mcp-server-git", "--repository", "/home/user/project"]
涉及 GitHub 这类敏感面,一上来就 whitelist,比事后 exclude 省心:
mcp_servers:
github:
command: "npx"
args: ["-y", "@modelcontextprotocol/server-github"]
env:
GITHUB_PERSONAL_ACCESS_TOKEN: "***"
tools:
include: [list_issues, create_issue, search_code]
prompts: false
resources: false
改完 ~/.hermes/config.yaml 里的 mcp_servers,聊天里敲 /reload-mcp 重新加载。stdio 型 MCP 不会继承你 shell 里一堆密钥,只在条目下的 env 里显式写的才会跟进进程——令牌尽量只出现在这里,别指望「反正本机环境里有」。
安全层:几条并行护栏
危险命令:命中敏感模式时要人点个头。网关在聊天里可以用 /approve、/deny,或者直接回复 yes/no 一类关键字;超时默认判拒绝。另有一层硬线黑名单,属于「怎么开关都拦」的底线。
默认手工把关可以这样写在 ~/.hermes/config.yaml:
approvals:
mode: manual
timeout: 60
执行环境:终端 backend 设成 docker、modal、daytona、vercel_sandbox 等隔离形态时,宿主上的危险命令审批会被跳过——边界换成容器/远端沙箱了。这和长期 local 直连宿主是两种心态;网关对外暴露时,更常见做法是隔离后端 + 收紧入口,而不是只靠模型自觉。
terminal:
backend: docker
MCP 暴露面:除了 tools.include / tools.exclude,还可以关掉 Hermes 帮你挂的 list_resources / read_resource、list_prompts / get_prompt 包装(tools.resources: false、tools.prompts: false),让模型少摸一层界面。
一条串起来的例子:Slack → 仓库
拼起来就是这样一块乐高,而不是一次性全开:
- Slack 走 Messaging Gateway;
SLACK_ALLOWED_USERS只写团队账号。 - 日常搜网页、看页面、跑命令仍走内建工具;终端尽量别长期钉在
local生产网关主机上。 - 用 MCP 接 Git + 单目录 filesystem,路径锁死在仓库根,避免「顺手摸到整个家目录」。
- 真要跑删库级终端命令,仍走审批;删客户、退款这类 API,如果没有 MCP 白名单,就别整颗接进来。
最后一截常常被人忽略但很实用:故意不接某些能力——比如 GitHub 只放开少数 issue 相关工具,而不是整颗 REST 接口面全交给模型,这是在缩小误触半径,不是功能残缺。
小结:入口是谁、工具边界画在哪、命令落到哪颗内核旁边,三块对齐了,再加 MCP 就是平滑扩容;一开始就追求「全家桶」,反而最难排查是哪一层漏风。