diff --git a/MANUAL.md b/MANUAL.md new file mode 100644 index 0000000..59f39a9 --- /dev/null +++ b/MANUAL.md @@ -0,0 +1,253 @@ +# Wire Nous Hermes Agent into Grok Bot + +Operator manual. Version 1.0 — 15 September 2026. + +Based on PixelRainbow (@PixelRainbowNFT) public write-up and [hermes-grok-bridge](https://github.com/shagghiesuperstar/hermes-grok-bridge). + +## Table of contents + +1. [What this is](#1-what-this-is) +2. [Architecture](#2-architecture) +3. [Decision tree](#3-decision-tree) +4. [Prerequisites](#4-prerequisites) +5. [Tailscale](#5-tailscale) +6. [Method A — SSH Relay](#6-method-a--ssh-relay) +7. [Method B — Native API (:8642)](#7-method-b--native-api-8642) +8. [Marketplace templates](#8-marketplace-templates) +9. [Identity bots and Chief of Staff](#9-identity-bots-and-chief-of-staff) +10. [Memory policy](#10-memory-policy) +11. [Secrets](#11-secrets) +12. [First-host build](#12-first-host-build) +13. [Cadence](#13-cadence) +14. [Troubleshooting](#14-troubleshooting) +15. [Security checklist](#15-security-checklist) +16. [Sources](#16-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. + +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 + +## 2. Architecture + +| Layer | Where | Job | +|---|---|---| +| Front door | Grok Bot app + Grok Bot computer | Chat, identity bots, COS, MCP connectors | +| Private net | Tailscale (no Funnel) | SSH :22 and API :8642 stay private | +| Brain | Hermes host(s) | Memory, skills, tools, models, files | + +| Method | Use when | How | Cost | +|---|---|---|---| +| SSH relay | Desktop-primary, no gateway | stdio MCP SSHs and runs `hermes -z ""` | Extra hop. Fine for one host. | +| Native API | Gateway + API on :8642 | HTTP `http://:8642/v1` + Bearer key | Must bind to Tailscale IP and lock ACLs. | + +Relay MCP tools: `ask`, `health`. That is the whole surface. + +## 3. Decision tree + +1. One Desktop-primary Mac, no gateway → SSH Relay template. +2. Gateway + `API_SERVER_ENABLED=true` → Native API Fleet. Connector per host: `hermes-`. +3. More than one host and you are tired of snowflake updates → add Fleet Ops. +4. One human conversation that fans out → Chief of Staff bot allowed to call the per-host connectors. + +## 4. 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. + +On the Hermes host first: + +```bash +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. + +## 5. Tailscale + +Join every Hermes host and the Grok Bot computer. One hostname for the shared Grok Bot computer. + +```bash +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. + +## 6. Method A — SSH Relay + +Clone onto the **Grok Bot computer**: + +```bash +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: + +```bash +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- + +## 7. Method B — Native API (:8642) + +On each Hermes host, `~/.hermes/.env`: + +``` +API_SERVER_ENABLED=true +API_SERVER_HOST= +API_SERVER_PORT=8642 +API_SERVER_KEY= +``` + +`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: + +```bash +curl http://:8642/health +curl -H "Authorization: Bearer $API_SERVER_KEY" http://:8642/v1/models +``` + +One connector per host named `hermes-`, URL `http://:8642/v1`, key from the vault. + +Same MCP in HTTP mode: + +``` +HERMES_RELAY_MODE=http +HERMES_RELAY_HTTP_URL=http://:8642 +HERMES_RELAY_HTTP_KEY= +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 + +## 8. 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. + +## 9. 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. + +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. + +## 10. 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." + +## 11. Secrets + +- Generate `API_SERVER_KEY` on 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. +- If a key has been in a screenshot or a group chat, rotate it. + +## 12. First-host build + +1. Mac: `hermes -z "PONG"` works locally. +2. Mac on tailnet. sshd running. +3. Grok Bot computer on tailnet. Sees the Mac. +4. Key auth + BatchMode SSH prints PONG. +5. Clone bridge. Add stdio MCP. +6. Create identity bot. Confine rules. +7. Bot: health, then PONG. +8. Only then enable `:8642`, bind to Tailscale IP, vault the key, curl `/health`. +9. Add `hermes-` connector. Repeat PONG over HTTP. +10. Second Mac: repeat. Then Fleet Ops + COS. + +## 13. 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. +- Weekly: one update pass, secrets discovery, memory health (fail loud). + +## 14. 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 | + +Debug order: local `-z` → tailscale ping → BatchMode SSH PONG → MCP health → then Grok prompts. + +## 15. Security checklist + +- Tailscale only. No Funnel. No `0.0.0.0` on `:8642`. +- ACL: controller → 22 / 8642 / 9119 on Hermes nodes. +- Unique `API_SERVER_KEY` per 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. + +## 16. 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 + +Hostnames, keys, and ACL tag names in examples are placeholders.