20 KiB
Fleet Manual: Grok Bot, Hermes, and Regis
Operator manual. Version 2.0 — 27 September 2026.
Changelog: v2.0 merges v1.0 MANUAL.md and the v0.1 companion (webhooks + Regis).
Based on PixelRainbow (@PixelRainbowNFT) public write-up and hermes-grok-bridge.
Table of contents
- What this is
- Architecture
- Roles
- Decision tree
- Prerequisites
- Tailscale
- Method A — SSH Relay
- Method B — Native API (:8642)
- Marketplace templates
- Identity bots and Chief of Staff
- The mailbox
- Polling
- Webhook wake-up
- Regis integration
- Job Card loop
- Memory policy
- Secrets
- First-host build
- Cadence
- Lessons learned
- Worked example
- Troubleshooting
- Security checklist
- Sources
1. What this is
Grok Bot is the chat surface. Hermes Agent is the worker that already has memory, skills, models, local files, and coding harnesses.
Do not install another Hermes inside every Grok Bot VM. Leave Hermes on the Mac (or fleet of Macs). Let Grok Bot talk to it over Tailscale.
This manual covers both directions:
- Out: Grok Bot calls Hermes (SSH relay or native API).
- In: outside agents wake the Chief of Staff (CoS) Grok Bot with a webhook, and an outside planner/drafter agent (Regis) works through a shared mailbox.
Unlocks:
- Chat existing Hermes from the Grok Bot UI
- Identity bot per host
- Fleet orchestration without hopping SSH by hand
- Hermes brains stay on the Mac; Grok is the front door
- Optional Chief of Staff that delegates across hosts and other Grok Bots
- Outside agents that draft and report back without holding credentials
Nothing here is tied to one business. Swap the names; keep the rules.
2. Architecture
| Layer | Where | Job |
|---|---|---|
| Front door | Grok Bot app + Grok Bot computer | Chat, identity bots, COS, MCP connectors, webhook routines |
| Private net | Tailscale (no Funnel) | SSH :22 and API :8642 stay private |
| Brain | Hermes host(s) | Memory, skills, tools, models, files |
| Record | Git repo (mailbox file) | Append-only line between CoS and outside agents |
| Outside agent | Regis, on its own runtime | Research, drafts, drive-and-takeover page editing |
| Link | Direction | How | Cost / note |
|---|---|---|---|
| SSH relay | Grok → Hermes | stdio MCP SSHs and runs hermes -z "<prompt>" |
Extra hop. Fine for one host. Desktop-primary, no gateway. |
| Native API | Grok → Hermes | HTTP http://<magicdns>:8642/v1 + Bearer key |
Gateway + API on :8642. Must bind to Tailscale IP and lock ACLs. |
| Webhook | Regis or Hermes watcher → Grok (CoS) | One HTTPS POST to a routine's private URL | Doorbell only. Outbound from the pinger. Untested (§13). |
| Mailbox | Everyone ↔ everyone | Append to one markdown file in git | Each poll costs model usage. |
Relay MCP tools: ask, health. That is the whole surface.
3. Roles
| Role | Who | Does | Never |
|---|---|---|---|
| Gatekeeper | Human | Go/no-go, logins, final Save / Send / publish / spend | Pastes secrets into chat |
| CoS | Grok Bot | Job Cards, routing, fact checks, owns the mailbox line | Approves "done" without evidence |
| Regis | Muse agent on its own runtime | Research, drafts, drive-and-takeover page editing, artifacts | Sends, posts, or logs in |
| Hermes identity bots | One per Hermes host | Audits, research, desktop hands | Page editing (weak at it) |
| Fleet Ops | Grok Bot | Updates, prune, doctor, disk, quiet health | Business work |
One rule covers all of them: anything irreversible goes to the Gatekeeper.
4. Decision tree
- One Desktop-primary Mac, no gateway → SSH Relay template.
- Gateway +
API_SERVER_ENABLED=true→ Native API Fleet. Connector per host:hermes-<hostname>. - More than one host and you are tired of snowflake updates → add Fleet Ops.
- One human conversation that fans out → Chief of Staff bot allowed to call the per-host connectors.
- An outside agent needs to hand work to CoS → mailbox (§11). Add polling (§12).
- Poll latency hurts → add a webhook wake-up (§13). Keep the poll as backup.
5. Prerequisites
- Grok Bot account and app
- Hermes already useful on at least one machine (
~/.local/bin/hermes) - Tailscale tailnet you control
- SSH key auth from the Grok Bot computer if using SSH Relay
- Python 3 on the Grok Bot computer for the stdio MCP
- A vault (Bitwarden is what Fleet Ops expects). Chat is not a vault.
- For the inbound side: a git repo for the mailbox, and a way to mint a narrow repo-scoped token
On the Hermes host first:
hermes doctor
hermes --version
hermes -z "Reply with PONG only."
If -z does not print a clean answer, fix Hermes before you build a bridge.
6. Tailscale
Join every Hermes host and the Grok Bot computer. One hostname for the shared Grok Bot computer.
curl -fsSL https://tailscale.com/install.sh | sh
sudo tailscale up --hostname=grokbot-box --accept-dns=false
Approve the device. If tailscale ping works but SSH hangs, the bot computer is likely in userspace networking:
Host scooby-mac
HostName scooby-mac
User yourmacuser
IdentityFile ~/.ssh/id_ed25519
IdentitiesOnly yes
ProxyCommand ts nc %h %p
ACL starting posture from the bridge SECURITY.md: only tag:herdr-controller → Hermes ports 22 / 8642 / 9119. No Funnel.
Regis is not a normal tailnet node. See §14.
7. Method A — SSH Relay
Clone onto the Grok Bot computer:
git clone https://github.com/shagghiesuperstar/hermes-grok-bridge.git
MCP command mode:
- command:
python3 - args:
…/ssh-relay/src/hermes_grok_relay/server.py - env:
HERMES_RELAY_SSH_TARGET=user@host,HERMES_RELAY_IDENTITY_NAME=Scooby
Optional env: HERMES_RELAY_SSH_IDENTITY, HERMES_RELAY_SSH_OPTS, HERMES_RELAY_HERMES_BIN (default $HOME/.local/bin/hermes), HERMES_RELAY_TIMEOUT_SEC (default 300), HERMES_RELAY_MODE=ssh|http.
Create a Grok Bot named after the identity. Confine it. Never instruct Hermes to write memory plugins. Never print keys.
Prove:
ssh -o BatchMode=yes scooby-mac '$HOME/.local/bin/hermes -z "Reply with PONG only."'
Then in the bot: Run health. then Reply with PONG only.
Template: https://x.ai/bot/NVF3Rx9T7jkQPsqYjeDn-
8. Method B — Native API (:8642)
On each Hermes host, ~/.hermes/.env:
API_SERVER_ENABLED=true
API_SERVER_HOST=<that node's Tailscale IP>
API_SERVER_PORT=8642
API_SERVER_KEY=<generate on this host>
chmod 600. Restart gateway. Confirm bind is the Tailscale IP, not 127.0.0.1 or 0.0.0.0.
From the Grok Bot computer:
curl http://<host>:8642/health
curl -H "Authorization: Bearer $API_SERVER_KEY" http://<host>:8642/v1/models
One connector per host named hermes-<hostname>, URL http://<magicdns>:8642/v1, key from the vault.
Same MCP in HTTP mode:
HERMES_RELAY_MODE=http
HERMES_RELAY_HTTP_URL=http://<host>:8642
HERMES_RELAY_HTTP_KEY=<from vault>
HERMES_RELAY_IDENTITY_NAME=Scooby
Template: https://x.ai/bot/5KLpaL-JIM2q629kbTh5L
Official API docs: https://hermes-agent.nousresearch.com/docs/user-guide/features/api-server
9. Marketplace templates
| Template | Role | URL |
|---|---|---|
| Hermes SSH Relay | Identity / talk path, Desktop-primary | https://x.ai/bot/NVF3Rx9T7jkQPsqYjeDn- |
| Hermes API Fleet | Wire :8642 connectors. Not the ops desk. | https://x.ai/bot/5KLpaL-JIM2q629kbTh5L |
| Hermes Fleet Ops | Updates, Bitwarden SSOT, homogenization, quiet health | https://x.ai/bot/rzq0UV2MmBsvVR1EspZE- |
Public listing pages do not show the system prompt. Click Add to Grok Bot in the app, then point env / connectors at your machines. Templates ship no hosts and no keys.
Optional CRT avatars: assets/pfp/ in the bridge repo.
10. Identity bots and Chief of Staff
One identity bot per Hermes host. COS is a different bot allowed to call many host connectors. You talk to COS. COS picks the host.
COS also owns the mailbox line (§11) and the webhook routine (§13). Outside agents talk to COS only through those.
Maintenance (update, prune, doctor, disk) goes to Fleet Ops, not COS freelancing package upgrades.
Long goals go to Hermes kanban, not a Grok thread you will lose.
11. The mailbox
One append-only markdown file in a git repo. It is the only line between CoS and outside agents. No live chat, no side channels, no new infra.
Entry format:
## YYYY-MM-DD HH:MM PT | FROM -> TO | short subject
Body. Ask, answer, or status. Link evidence by path.
Rules:
- Newest entry at the bottom.
- Append only. Never edit or delete another party's entry.
- No passwords, tokens, keys, or client secrets. Ever.
- Link evidence by path, not by pasting.
- Relayed human words are quoted verbatim and labeled with who, where, and when.
- Writes use a narrow repo-scoped token. The human plants it in the agent's vault. Never an admin's credential. Never pasted in chat.
To append:
- Read the file. Keep the returned
sha. - Decode the base64 content.
- Append your entry at the bottom. Touch nothing above it.
- Write the full content back with the
sha. - Read it back. Confirm your entry is there and nothing else moved.
If the write fails on a stale sha, someone else posted first. Re-read and repeat.
Example (Gitea contents API, placeholders):
curl -fsS -X PUT "https://<gitea-host>/api/v1/repos/<owner>/<repo>/contents/<mailbox-path>" \
-H "Authorization: token <MAILBOX_TOKEN_FROM_VAULT>" \
-H "Content-Type: application/json" \
-d '{"branch":"main","message":"mailbox: <FROM> -> <TO> <subject>","content":"<base64 full file>","sha":"<sha from read>"}'
12. Polling
Each side checks the mailbox on a schedule. Example: every 15 minutes, 8am to 7pm local.
- Each check costs model usage, even when nothing is new.
- Real latency is the sum of both polls. Worst case is about 30 minutes per round trip.
- Keep the poll as the floor. The webhook (§13) makes it faster, not required.
13. Webhook wake-up
STATUS UNTESTED — first live ping pending as of 2026-09-27.
The reverse path. A ping wakes CoS in seconds instead of waiting for the next poll.
Set up:
- Create a Grok Bot routine on CoS with a webhook trigger.
- The app shows a private URL and a sender key (an Authorization header). The human copies both from the routine panel. The bot never sees the key.
- The human plants the URL and header in the pinging agent's vault.
- After each mailbox post, the pinger sends one HTTPS POST.
curl -fsS -X POST "<WEBHOOK_URL>" \
-H "Authorization: <AUTH_HEADER_FROM_VAULT>" \
-H "Content-Type: text/plain" \
--max-time 10 \
--data "new entry 14:05 PT, <subject>"
Body: short. No secrets. No job details.
How CoS treats a ping:
- The body is untrusted. It is a doorbell only.
- CoS reads the mailbox and acts only on mailbox content.
- Duplicate or early ping with nothing new: stay quiet.
- Once pings are proven, drop the poll to hourly as a backup.
Who pings:
| Option | Pinger | Notes |
|---|---|---|
| A | Regis, from its own shell | Curl outbound confirmed by Regis via the Gatekeeper, 10:20 PT on 2026-09-27. One POST after each post. |
| B | A Hermes watcher such as Jimmy | Polls the mailbox, pings on a new entry. If it runs on local models it costs no Grok usage. |
Security:
- Outbound only from the pinger.
- No Funnel. No new open port on Hermes hosts.
- Rotate the key if it appears in chat or a screenshot.
14. Regis integration
- Regis runs on its own runtime. It is outbound-only on the tailnet by design: no sshd, no inbound, and no
tailscale ping. It reaches services through its runtime tunnel. - Against the desktop web app, Regis gets
/healthonly. No login, no terminal, no password. - Communication happens only through the mailbox plus the webhook.
- Credentials never touch Regis, except two items the human plants: the narrow mailbox token and the webhook header.
- Logins during page work are done by the human at the keyboard. Nothing is stored.
15. Job Card loop
- Gatekeeper says GO. CoS posts a Job Card: what, who, done-when.
- Regis drafts and posts: current text (read live), proposed text, evidence.
- CoS fact-checks against canonical facts. ACK, or post fixes.
- Regis drives the page to the edit field and stops.
- The human logs in and clicks Save.
- Regis logs what changed, when, and who saved. Names the next page. Waits for ACK.
Rules:
- One page per session.
- Anything beyond the card (new account, payment, verification code, different listing): stop and post.
- Approvals count only when logged by CoS or relayed by the Gatekeeper.
16. Memory policy
Default: Grok may read Hindsight (and friends). Grok may not write.
The relay tool description already says this. Repeat it in every identity-bot prompt. Account-wide MCP means some other bot will try.
Least prompt: forward the user ask. Do not wrap it in "also remember this."
The mailbox is not memory. It is a work log. Do not copy it into Hermes memory by default.
17. Secrets
- Generate
API_SERVER_KEYon the host. Store under that hostname in the vault. - SSH private keys stay on the Grok Bot computer, mode 600.
- Messaging tokens are per-profile. Do not reuse across homogenized hosts.
- Mailbox token: narrow, repo-scoped, planted by the human in the agent's vault. Never an admin's credential.
- Webhook URL and sender key: copied by the human from the routine panel into the pinger's vault. The bot never sees the key.
- Nothing secret goes in chat, git, or the mailbox.
- If a key has been in a screenshot or a group chat, rotate it.
18. First-host build
- Mac:
hermes -z "PONG"works locally. - Mac on tailnet. sshd running.
- Grok Bot computer on tailnet. Sees the Mac.
- Key auth + BatchMode SSH prints PONG.
- Clone bridge. Add stdio MCP.
- Create identity bot. Confine rules.
- Bot: health, then PONG.
- Only then enable
:8642, bind to Tailscale IP, vault the key, curl/health. - Add
hermes-<hostname>connector. Repeat PONG over HTTP. - Second Mac: repeat. Then Fleet Ops + COS.
- Create the mailbox file in a git repo. CoS posts
mailbox open. - Human plants a narrow mailbox token in Regis's vault. Regis posts
write test. Read back. - Set CoS and Regis polls (§12).
- Create the CoS webhook routine. Human plants URL and header in the pinger's vault.
- Pinger sends one test POST after a mailbox post. Confirm CoS wakes and replies in the mailbox.
- Only after pings are proven, drop the poll to hourly.
19. Cadence
- Morning: Fleet Ops health. Quiet unless broken.
- Day: COS for work. Identity bot only when you need that host's hands. Asks over
:8642. SSH for surgery. - Day: mailbox polled every 15 minutes, 8am to 7pm local (hourly once webhooks are proven). Webhook pings wake CoS in between.
- Weekly: one update pass, secrets discovery, memory health (fail loud).
20. Lessons learned
| Lesson | What broke | Rule now |
|---|---|---|
| Evidence for "done" | A close-out letter claimed work never done; it was approved as written | Any "done" claim points to a link, screenshot, or log line before CoS approves |
| Stale "current text" | A draft quoted old text from a non-live source | Read the live page on the same surface before drafting a replacement |
| Vault 401 | The agent's vault credential failed; every write needed a hand-off token | Human plants one narrow repo token in the agent's vault |
| Approval claimed early | Regis said "Gatekeeper approved" before CoS had a record | Approvals count only when logged by CoS or relayed by the Gatekeeper |
| Someone already fixed it | The target text was already live when the edit was about to run | Re-check the live page right before the edit; stand down if done |
What worked: a self-correction in the mailbox plus one go/no-go question kept it to one touch for the Gatekeeper.
21. Worked example
VeriPath running a client punchlist for Phoenix (a salon). Illustration only.
- Gatekeeper GO. CoS posted a Job Card: work the punchlist one page per session, Google Business Profile (GBP) description first.
- Regis posted current vs proposed text. CoS ACKed and corrected the "current" (it was stale).
- Before pasting, the human read the live GBP. The description was already live at 691 of 750 characters, written by someone else.
- Regis put the paste on hold and posted the live text. CoS fact-checked it: KEEP AS-IS. No paste, no Save.
- Next: Regis logs the page done and names the next page.
22. Troubleshooting
| Symptom | Likely cause | Fix |
|---|---|---|
| SSH timeout | Off tailnet / ACL | tailscale status both sides |
| Ping works, SSH hangs | Userspace Tailscale | ProxyCommand ts nc |
hermes: command not found |
Non-interactive PATH | HERMES_RELAY_HERMES_BIN=$HOME/.local/bin/hermes |
:8642 refused |
Still bound to 127.0.0.1 | Set API_SERVER_HOST to Tailscale IP, restart gateway |
| HTTP 401 | Wrong key | Use that host's API_SERVER_KEY |
| Other bots calling Scooby | Account-scoped MCP | Tighten prompt; remove connector from other bots |
| Memory filling with Grok summaries | Write path left open | Strip write instructions |
| Mailbox write 401 | Wrong or unplanted token | Human replants the token in the vault. Never paste it. |
| Mailbox write conflict | Stale sha |
Re-read, re-append, write again |
| No wake after a ping | Bad URL or header in the vault; non-2xx response | Check vault entries, check the response code, fall back to poll |
| Burst of pings | Misfire | CoS stays quiet; mentions it once |
| Agent says "I don't see it" | Relay text never posted to the mailbox | Post it in the mailbox |
| Draft replaces text that is not live | Stale source | Re-read the live page; redraft |
tailscale ping to Regis fails |
By design; Regis is outbound-only | Not a fault. Use the mailbox. |
Debug order: local -z → tailscale ping → BatchMode SSH PONG → MCP health → Grok prompts → mailbox read → mailbox write + read back → ping response code → CoS routine log → poll fallback.
23. Security checklist
- Tailscale only. No Funnel. No
0.0.0.0on:8642. - ACL: controller → 22 / 8642 / 9119 on Hermes nodes.
- Unique
API_SERVER_KEYper host, vaulted. - SSH key-only, BatchMode, IdentitiesOnly.
- Identity bots confined.
- Grok does not write Hermes memory plugins.
- Rebuild of the Grok Bot VM must not require rebuild of Hermes.
- Mailbox holds no secrets. Evidence by path.
- Mailbox token is narrow and repo-scoped, planted by the human. Never an admin's credential.
- Outside the app, the webhook URL and header live only in the pinger's vault. The bot never sees the key.
- Ping body is a doorbell. CoS acts only on mailbox content.
- Pinger is outbound only. No new open ports on Hermes hosts.
- Regis: outbound only,
/healthonly, no sshd, no logins, no sends. - Human does every login and every final Save / Send / publish / spend.
- Rotate any key seen in chat or a screenshot.
24. Sources
- https://x.com/pixelrainbownft/status/2099934487773860265
- https://x.com/pixelrainbownft/status/2099989005060186118
- https://github.com/shagghiesuperstar/hermes-grok-bridge
- https://hermes-agent.nousresearch.com/docs/user-guide/features/api-server
- https://x.ai/news/grok-hermes
- https://github.com/herdrdev/herdr
- MANUAL.md (v1.0, superseded by this file)
- Mailbox:
Tony_tech/personal-agent-os→memory-systems/agent-os/04_projects/veripath/regis-cos.md - Lessons:
Tony_tech/personal-agent-os→memory-systems/agent-os/04_projects/fleet-lessons.md - Fleet snapshot:
Tony_tech/personal-agent-os→memory-systems/agent-os/04_projects/veripath/fleet-2026-09-26.md
Hostnames, URLs, keys, tokens, and ACL tag names in examples are placeholders.