# Hermes In Buzz

> Use when connecting a remote Hermes gateway to Buzz end-to-end. Do not use for a Buzz-managed ACP runtime; use the official buzz-acp relay-bridge guide instead.

- Skill: `tonbistudio/hermes-in-buzz` (Agent Skill, multi-file: 4 files)
- Install (CLI): `npx skillmds@latest add tonbistudio/hermes-in-buzz`
- Raw SKILL.md: https://api.skillmd.com/api/skills/tonbistudio/hermes-in-buzz/raw
- Safety review: pending
- Works with: Claude Code, Claude.ai, OpenAI Codex
- Category: Coding & Dev Tools
- License: MIT
- Author: tonbistudio (https://skillmd.com/u/tonbistudio)
- Updated: 2026-09-17
- Page: https://skillmd.com/skills/tonbistudio/hermes-in-buzz

---


# Hermes in Buzz

## Overview

Set up a dedicated Hermes Agent running on one machine as a native messaging agent in a Buzz community used from another machine. The default topology is:

```text
Buzz Desktop / web client
          |
          v
      Buzz relay
          ^
          | Nostr WebSocket + buzz CLI
          |
Remote Hermes gateway
```

The client PC does not SSH into the Hermes host. Both independently connect to the same Buzz relay, and Buzz Desktop may be offline while Hermes continues running.

This skill executes the setup, not merely describes it. Continue until the CLI works, relay authorization succeeds, the gateway logs `buzz connected`, and one inbound plus outbound message has been verified.

Authoritative docs change quickly. At the start of every run, load the `hermes-agent` skill and inspect:

- https://hermes-agent.nousresearch.com/docs/integrations/buzz
- https://hermes-agent.nousresearch.com/docs/user-guide/messaging/buzz
- https://hermes-agent.nousresearch.com/docs/user-guide/features/acp
- the latest stable `block/buzz` release and its actual assets

If docs and this skill differ, follow the docs and patch this skill after the successful run.

## When to Use

Use when:

- Buzz Desktop is on one computer and Hermes should run continuously on another;
- a user says they created a Buzz agent but the Hermes gateway is silent;
- errors progress through `buzz CLI binary not found`, `relay_membership_required`, zero channels, or ignored mentions;
- moving an existing native Buzz/Hermes gateway to Linux, macOS, Windows, or WSL.

Do not use this native-gateway workflow when the user explicitly wants Buzz to own the runtime and show ACP activity. In that case use the official `buzz-acp` relay-bridge guide. Do not improvise an SSH-stdio bridge unless the user explicitly requests an experimental design.

## Hard Security Rules

1. Use a dedicated agent identity. Never reuse the human Buzz `nsec` as `BUZZ_PRIVATE_KEY`.
2. Never ask for an `nsec`, API token, or owner key in chat or via `clarify`.
3. Secret input must be local and hidden (`getpass`, `Read-Host -AsSecureString`, or equivalent), never argv.
4. Never print, log, persist temporarily, or return owner private-key material.
5. Store the agent key and `BUZZ_AUTH_TAG` only in the active profile's Hermes secret environment file. Resolve `HERMES_HOME`; do not assume `~/.hermes` when a profile is active.
6. Use `hermes config set` for non-secret settings. Never hand-edit `config.yaml`.
7. Default to `allow_all_users: false`, an explicit owner allowlist, and `require_mention: true`. Do not broaden access merely to diagnose delivery.
8. Ask approval before installing Rust, Git, build tools, downloading Buzz, or changing persistence/service configuration.
9. An ACP-hosted Hermes can execute terminal tools without a visible approval because Buzz may auto-answer ACP permissions. Keep ACP agents owner-only. Native gateway approvals retain Hermes gateway semantics.

## Phase 1: Discover the Host and Choose the Architecture

1. Detect OS, architecture, shell, active Hermes home/profile, service manager, and tool availability. Check at least `hermes`, `git`, `cargo`, `rustc`, and `buzz`/`buzz.exe`. On Windows distinguish native Windows from WSL.
2. Run `hermes status`, `hermes gateway status`, and inspect redacted `BUZZ_*` presence. Never print secret values.
3. Confirm the intended architecture:
   - **Native gateway (default):** full Hermes memory, skills, normal sessions, DMs, cron delivery, images, reactions, threaded replies, and multiple messaging platforms in one gateway.
   - **Relay bridge (`buzz-acp`):** Buzz owns transport; Hermes runs in ACP mode on the server; reduced ACP-oriented surface and stronger owner-only warning.
   - **Buzz Desktop runtime:** Hermes runs on the same computer as Buzz Desktop, not the remote-host goal.
4. Collect only non-secret facts in chat: relay URL, desired agent display name, owner public `npub`, intended channels/home channel, and whether other community members may invoke it.

Completion criterion: topology and access policy are explicit, no secret has appeared in conversation, and native gateway is selected unless the user chose otherwise.

## Phase 2: Obtain a Dedicated Buzz Identity

Preferred native-gateway identity:

- dedicated agent `nsec` and matching `npub`;
- direct relay membership when a relay administrator can add it; or
- NIP-OA owner attestation when a hosted/closed community uses managed agents.

For Buzz Desktop-managed identities:

1. Have the user create the agent in Buzz Desktop and save the one-time displayed agent `nsec` locally.
2. Use `scripts/update_buzz_credentials.py set-agent-key` on the Hermes host. The script prompts locally with hidden input and atomically writes `BUZZ_PRIVATE_KEY`.
3. Do not assume creating or adding an agent to a channel makes it a direct relay member. Channel membership and relay/community admission differ.
4. If direct authentication returns `relay_membership_required` and the configured public key exactly matches the Buzz agent, keep the key and proceed to NIP-OA attestation. Do not regenerate identities repeatedly.

Resolve a Python interpreter the user can invoke locally:

- Linux/macOS/WSL: prefer the active Hermes venv Python, then `python3`.
- Native Windows: prefer `%HERMES_HOME%\hermes-agent\venv\Scripts\python.exe`, then `py -3` or `python`.

Run the bundled updater from a real local terminal so the user—not the agent chat—enters the secret:

```text
<python> <skill-dir>/scripts/update_buzz_credentials.py set-agent-key --hermes-home <resolved-HERMES_HOME>
```

Completion criterion: `BUZZ_PRIVATE_KEY` exists with restricted permissions where supported, but no secret value was printed.

## Phase 3: Install the Buzz CLI Portably

Outbound messages always require the external `buzz` CLI even when inbound WebSocket transport is healthy.

### 3.1 Prefer a verified prebuilt CLI

1. Query the current stable `block/buzz` release API.
2. Inspect asset names and content—not just the release title.
3. Use a prebuilt asset only if it is a standalone Buzz CLI matching the exact OS and architecture.
4. Verify its published digest when available, install it to a user-writable path, mark executable on Unix, and run `buzz --help`.

Desktop `.dmg`, `.deb`, `.rpm`, `.AppImage`, or Windows desktop installers are not automatically standalone CLI assets.

### 3.2 Build from a pinned stable release when necessary

Ask approval before downloads or installs. Install prerequisites using the native package mechanism:

| Host | Typical prerequisites |
|---|---|
| Linux | Git, Rustup/Cargo, C/C++ compiler, make, cmake, pkg-config; use the detected distro package manager |
| macOS | Xcode Command Line Tools, Git, Rustup/Cargo; Homebrew is optional, not assumed |
| Windows native | Git, Rustup MSVC toolchain, Visual Studio C++ Build Tools; prefer `winget` when present |
| WSL | Follow Linux branch; enable systemd for managed-service persistence or use foreground mode |

Do not hardcode `main`. Resolve the latest stable release tag from GitHub, show the pinned tag, then clone into a cache/temp build directory:

```bash
git clone --depth 1 --branch <stable-tag> https://github.com/block/buzz.git <build-dir>
cargo build --release -p buzz-cli
```

Install to a user path:

- Linux/macOS/WSL: `~/.local/bin/buzz`
- Windows: `%USERPROFILE%\.local\bin\buzz.exe`

Use the absolute path in Hermes config so service PATH differences cannot break it. On macOS, rerun `hermes gateway install --force` after adding executables so launchd snapshots the current PATH.

### 3.3 Build the safe NIP-OA helper

When a hosted managed agent may need owner attestation, copy linked file `scripts/hermes_buzz_credential_helper.rs` into the pinned Buzz checkout as:

```text
crates/buzz-sdk/examples/hermes_buzz_credential_helper.rs
```

Build it with the same pinned source:

```bash
cargo build --release -p buzz-sdk --example hermes_buzz_credential_helper
```

Install beside the Buzz CLI as `hermes-buzz-credential-helper` (append `.exe` on Windows). This helper reads private input from stdin; never alter it to accept private keys via argv.

Completion criterion: the installed absolute CLI path executes `--help`; if attestation may be needed, the credential helper also runs and its smoke test with a generated disposable key returns a structurally valid result.

## Phase 4: Configure Non-Secret Hermes Settings

Use `hermes config set`, with the active profile selected when applicable. Set:

```text
gateway.platforms.buzz.enabled = true
gateway.platforms.buzz.extra.relay_url = <relay URL>
gateway.platforms.buzz.extra.cli_path = <absolute CLI path>
gateway.platforms.buzz.extra.channels = [] or explicit UUID list
gateway.platforms.buzz.extra.home_channel = <UUID when outbound cron/notifications are wanted>
gateway.platforms.buzz.extra.poll_interval = 4
gateway.platforms.buzz.extra.require_mention = true
gateway.platforms.buzz.extra.allow_all_users = false
gateway.platforms.buzz.extra.allowed_users = [<owner npub or hex>]
display.platforms.buzz.interim_assistant_messages = false
display.platforms.buzz.tool_progress = off
```

Use JSON array syntax accepted by the live `hermes config set` implementation. Verify each value with `hermes config get`; do not infer success from exit code alone.

Migrate legacy or wizard-created environment-only setups. Environment variables override canonical config, so an old `BUZZ_ALLOW_ALL_USERS=true` silently defeats `allow_all_users: false`. After copying every non-secret value into canonical config and verifying it, atomically remove these overrides from the active profile's `.env`:

```text
BUZZ_RELAY_URL
BUZZ_CHANNELS
BUZZ_HOME_CHANNEL
BUZZ_ALLOWED_USERS
BUZZ_ALLOW_ALL_USERS
BUZZ_POLL_INTERVAL
BUZZ_CLI_PATH
BUZZ_TRANSPORT
```

Retain credential material such as `BUZZ_PRIVATE_KEY`, `BUZZ_AUTH_TAG`, and any documented API token. Before removal, show only variable names and redacted set/unset state; never print values. Restart and re-read effective config after migration.

If the user explicitly wants community-wide invocation, explain that every community member who can address the agent may trigger tools, obtain approval, then set `allow_all_users: true`. Keep owner/admin command authorization separate.

Completion criterion: canonical non-secret configuration is present, no legacy environment variable overrides it, owner-only access is effective by default, and `cli_path` is absolute.

## Phase 5: Verify Identity and Relay Admission

Load credentials with Hermes' dotenv parser or the bundled updater—not by shell-sourcing `.env`. Raw `BUZZ_AUTH_TAG` JSON loses quotation marks when shell-sourced and produces a false `invalid JSON` diagnosis.

1. Run the helper's `public` command through the Python updater to derive safe public values from the stored agent key:

```text
<python> update_buzz_credentials.py public --hermes-home <home> --helper <helper-path>
```

2. Compare the emitted public `npub`/hex with the agent shown in Buzz.
3. Invoke `buzz channels list` with the exact dotenv values passed through a subprocess environment.
4. Interpret results:
   - binary missing: fix install path/service PATH;
   - malformed auth tag only after shell sourcing: retest without shell parsing;
   - `relay_membership_required` plus matching public key: direct membership or NIP-OA is missing;
   - successful auth but zero channels: attach the agent to intended channels;
   - identity mismatch: replace the wrong agent key before doing anything else.

Completion criterion: public identity matches and direct CLI channel discovery succeeds, or the failure is specifically proven to require NIP-OA.

## Phase 6: Generate NIP-OA Attestation Safely When Needed

Buzz Desktop-managed agents have both an agent key and an owner-signed auth tag. Desktop injects the tag into locally launched managed agents but may reveal only the agent `nsec` during creation.

If no relay-admin membership path exists:

1. Confirm the agent public key matches.
2. Ask the user to open Buzz Desktop on the owner PC and locate the **human/owner** private key under Identity settings.
3. On the Hermes host, run:

```text
<python> update_buzz_credentials.py set-auth-tag \
  --hermes-home <home> \
  --helper <absolute-helper-path> \
  --agent-pubkey <64-char-agent-hex>
```

The updater uses hidden local input, sends the owner key to the Rust helper over stdin, validates a JSON four-string tag whose first value is `auth`, atomically writes only `BUZZ_AUTH_TAG`, and discards the owner key from memory. Never request that key in chat.

Then rerun direct channel discovery using exact dotenv parsing.

Completion criterion: CLI authentication succeeds and visible channel UUIDs are listed.

## Phase 7: Install and Start the Gateway by OS

### Linux with systemd

```bash
hermes gateway install --force
hermes gateway start
hermes gateway status
```

For a remote user service that must survive logout, explain and request approval before:

```bash
sudo loginctl enable-linger "$USER"
```

A Linux system service is an explicit alternative: `sudo hermes gateway install --system`.

### macOS

```bash
hermes gateway install --force
hermes gateway start
hermes gateway status
```

This installs/reloads a launchd agent. Reinstall after PATH changes.

### WSL2

Preferred persistent route: enable systemd in `/etc/wsl.conf`, restart WSL, then use Linux commands. Otherwise run `hermes gateway run` in a durable terminal/tmux, or create a Windows Task Scheduler job launching:

```text
wsl -d <Distro> -- bash -lc 'hermes gateway run'
```

### Native Windows

Do not claim systemd/launchd service support. Start with:

```powershell
hermes gateway run
```

For persistence, use Windows Task Scheduler to launch the full Hermes executable path at user logon with arguments `gateway run --external-supervisor`, a working directory under the active Hermes home, restart-on-failure enabled, and the intended user account. Verify in foreground before creating the task. Never create persistence without explicit approval.

Completion criterion: exactly one gateway instance is running for the profile and survives according to the persistence method the user approved.

## Phase 8: End-to-End Verification

Do not declare success from process state alone.

1. `hermes gateway status` shows a running gateway.
2. Inspect `gateway.log` and OS service logs for:
   - `Connecting to buzz...`
   - `connected to <relay> as <name>, watching N channel(s)`
   - `buzz connected`
3. Confirm channel count and intended UUIDs.
4. Ask the user to send:
   - one DM (`Hello`) to the agent;
   - one channel mention (`@Agent hello`).
5. Verify logs show `inbound message: platform=buzz`, `response ready`, and `[Buzz] Sending response` for each path.
6. Confirm the replies actually appear in Buzz; logs alone do not prove UI delivery.
7. If the displayed agent name is wrong, change the Buzz profile name separately; do not confuse host name, Hermes identity, and Buzz display name.

Completion criterion: one inbound message reached Hermes, Hermes generated a response, Buzz accepted the outbound send, and the user saw the response.

## Failure Ladder

Treat each new error as progress to the next layer:

1. **`buzz CLI binary not found`** — missing executable or service PATH/`cli_path` problem.
2. **`relay_membership_required` / 403** — valid signing key but no direct membership or NIP-OA attestation.
3. **Zero channels** — relay admission works; channel attachment/filtering is wrong.
4. **Messages ignored** — mention gating, allowlist, access policy, or self-echo suppression.
5. **Inbound works, outbound fails** — CLI path, media path, or exact subprocess environment.
6. **Gateway appears stuck on another platform** — read `gateway.log`, not only journal/stderr; successful INFO-level connection messages may not appear in system journal. Do not disable an unrelated platform before checking the file log.

After every repair: restart once, read the newest failure, and continue until the end-to-end criterion passes.

## Common Pitfalls

1. Assuming a Buzz Desktop package contains the CLI.
2. Building unpinned `main` instead of a stable tag.
3. Copying the agent `nsec` but omitting its NIP-OA auth tag on a closed hosted relay.
4. Treating channel membership as relay membership.
5. Asking the user to paste an owner key into chat.
6. Passing private keys in process argv.
7. Shell-sourcing dotenv JSON and misdiagnosing a valid auth tag as malformed.
8. Setting `BUZZ_ALLOW_ALL_USERS=true` as a quick test and forgetting it.
9. Running a second foreground gateway beside a managed service.
10. Declaring success from `gateway status` without a real inbound/outbound Buzz exchange.
11. Assuming Windows native has Linux/macOS service management; use foreground verification and Task Scheduler only with approval.
12. Forgetting to copy this entire skill directory, including `scripts/`, to the new device.

## Verification Checklist

- [ ] Official docs and current Buzz release inspected
- [ ] OS/architecture/profile/Hermes home detected
- [ ] Native gateway versus ACP choice explicit
- [ ] Dedicated agent identity used
- [ ] No private key entered into chat or argv
- [ ] Buzz CLI installed and smoke-tested
- [ ] Absolute CLI path configured
- [ ] Non-secret settings written with `hermes config set`
- [ ] Owner-only access default preserved
- [ ] Public agent identity matches Buzz
- [ ] Direct CLI channel discovery succeeds
- [ ] NIP-OA tag added only when required
- [ ] Exactly one gateway instance runs
- [ ] `buzz connected` confirmed in logs
- [ ] DM and channel mention tested
- [ ] User saw outbound replies in Buzz

## Invocation and Transfer

Invoke in a fresh Hermes session with:

```text
/hermes-in-buzz
```

or ask: “Use the hermes-in-buzz skill to connect this Hermes host to my Buzz community.”

To install on another device, copy the whole `hermes-in-buzz` directory into that profile's skills directory, preserving `SKILL.md` and `scripts/`, then start a new Hermes session so skill discovery refreshes.

