安全地开放 Hermes Agent Dashboard

AI

应用发展太快,本节适用当前 v0.16.0 (2026.6.5) 版本

我想在远程服务器上部署 Hermes,中心化管理。远程中心化的好处是:

  • 只在一处管理 API Key,当然服务器泄露就一起完蛋
  • 人格文件也只在一处,不用各处同步和分发。当然我也会定时 git backup
  • 给 AI Agent 一台能自己操作的设备,我不在边上也能持续运行
  • 我一直想不通为什么云平台要推广云上部署 OpenClaw,除了可以 IM 聊天外有什么使用场景,如果能由它通过 SSH 等方式操控其他设备,那才更有中心大脑的感觉

这个 Dashboard 和 Remote 方案刚出来,还没 OpenClaw 那么健全,连文档都是前后矛盾的。

  • 需要设置 hermes dashboard --host 为非 localhost 才能 启用认证
  • 网络流量均未加密
  • 反向代理/Tailscale 会提示 Invalid Host header. Dashboard requests must use the hostname the server was bound to.
  • 我的账号没法用 hermes dashboard register,会提示 Registration failed: Self-hosted dashboard registration is not available for this account

本着离开本机的流量都得加密,怎么也得套一层 HTTPS,过程不提了,总之方案是这样:

  1. 修改 Hermes Agent | Proxmox VE Helper Scripts 创建的 Dashboard Service,把绑定改为非 localhost。这里我特意没选 0.0.0.0,是在保留 9119 传统 port 的基础上,绕过 限制
/etc/systemd/system/hermes-dashboard.service.d/override.conf
[Service]
ExecStart=
ExecStart=/home/hermes/.local/bin/hermes dashboard --host 127.0.1.1 --port 9119 --no-open --skip-build
  1. 添加 Caddyfile,绑定主网卡,或者 Tailscale 网卡。设置重写 Host Header 来绕过 限制
https://hermes.pve.kokomi.site:9119 {
    bind 192.168.2.83
    reverse_proxy 127.0.1.1:9119 {
        header_up Host 127.0.1.1
    }
}
  1. 去 Nous Portal 添加 Local Dashboard。URL 是为了过 OAuth 重定向校验
HERMES_DASHBOARD_OAUTH_CLIENT_ID=agent:xxx
HERMES_DASHBOARD_PUBLIC_URL=https://hermes.pve.kokomi.site:9119
  1. 修改 DNS 指向
  2. 重启服务
  3. 在 Desktop App 上开个新 Profile,只有它选择 Remote Gateway,这样既能远程也能本地。

当然这么做还留下个问题,估计得未来正式支持 Reverse Proxy 才有解

  • 网页 Dashboard 的 Chat 页面 WebSocket 被域名校验拦了

时不时闪现控制台窗口

最近两天使用 Windows 时,过个半小时左右,会闪现一两个控制台窗口,打断心流。
之前有过 Windows 开机闪现个控制台创建 ,但这次不一样,闪地太快眼睛抓不住。

开了个 Process Explorer,调低点 Update Speed,在闪现后眼疾手快去按 Space 暂停,可算抓到了现场。

其实就是个 tokentracker-cli 的 sync 定时任务?工作目录在当前 VSCode 开启的项目上。环境变量看上去是 AI_AGENT claude-code_2-1-170_harness

'use strict';
const fs = require('node:fs');
const cp = require('node:child_process');
const retryPath = \"C:\\Users\\enihsyou\\.tokentracker\\tracker\\auto.retry.json\";
const trackerBinPath = \"C:\\Users\\enihsyou\\.tokentracker\\tracker\\app\\bin\\tracker.js\";
const fallbackPkg = \"tokentracker-cli\";
const delayMs = 1830651;
setTimeout(() => {
  let retryAtMs = 0;
  try {
    const raw = fs.readFileSync(retryPath, 'utf8');
    retryAtMs = Number(JSON.parse(raw).retryAtMs || 0);
  } catch (_) {}
  if (!retryAtMs || Date.now() + 1000 < retryAtMs) process.exit(0);
  const argv = ['sync', '--auto', '--from-retry'];
  const cmd = fs.existsSync(trackerBinPath)
    ? [process.execPath, trackerBinPath, ...argv]
    : ['npx', '--yes', fallbackPkg, ...argv];
  try {
    const child = cp.spawn(cmd[0], cmd.slice(1), { detached: true, stdio: 'ignore', env: process.env });
    child.unref();
  } catch (_) {}
}, delayMs);
 

想起来 tokentracker 确实设置了 claude / codex 等的 hook

命令行运行 node "C:\\Users\\enihsyou\\.tokentracker\\bin\\notify.cjs" --source=claude 确实复现了。窗口是 spawn tokentracker sync 产生的,感觉没啥用,把 hook 删了。

使用 GitHub App 以 Bot 身份创建属于 AI Agent 的提交

未来肯定是 AI Agent 替人来提交,目前见过几种署名方式

核心是 commit 的 author 填写 GitHub App 的 email。参考 GitHub Apps: Configuring the Git Email for Commits | josh-ops

调用 https://api.github.com/users/ API 取得 bot 的 user-id 就行。