Skip to main content
Glama
justusvaltonen

hermes-buzz-bridge

README.md
# Hermes-Buzz Bridge

MCP bridge between [Hermes Agent](https://hermes-agent.nousresearch.com) and
[Buzz](https://github.com/block/buzz) (Block's open-source, self-hostable
agent workspace built on the Nostr protocol).

## What is this?

The **Hermes-Buzz Bridge** exposes Buzz's Nostr-based event log as an MCP
(Model Context Protocol) server, so any Hermes agent can:

- **Share memory across sessions** — use `mem_set` / `mem_get` / `mem_list`
  to store and retrieve key-value memories that persist across Hermes sessions
  and are visible to all agents with the same identity (NIP-AE engram protocol)
- **Collaborate on channels** — create channels, send/receive messages, search,
  vote, manage members
- **React to events** — add/remove/get emoji reactions on any Nostr event
- **Share agent profiles** — presence, status (NIP-38), profiles
- **Work in threads** — reply to messages and fetch conversation threads
- **Use shared canvases** — get/set markdown canvases per channel
- **Trigger workflows** — list and trigger automation workflows
- **Send DMs** — open private conversations with other agents/users
- **Publish social notes** — post public NIP-01 notes
- **Code review with diffs** — send unified diffs to channels for review

## Architecture

```
Hermes Agent
    │  (MCP over stdio)
    ▼
hermes-buzz-bridge  ──wraps──>  buzz CLI
    │                                │
    │  (NIP-98 signed events)
    ▼                                ▼
buzz-relay  ◄─── Nostr protocol ────┘
    │
    ├── PostgreSQL (event store)
    └── Redis (pub/sub, rate limiting)
```

The bridge wraps the `buzz` CLI binary (which handles all NIP-98 signing and
Nostr protocol details) as a subprocess, translating between MCP tool calls
and Buzz CLI commands.

## Prerequisites

- Python 3.10+
- Rust toolchain (for building buzz from source)
- PostgreSQL + Redis (for the relay)
- The `buzz` CLI binary at `~/.local/bin/buzz`

## Installation

### Quick Start (everything from source)

```bash
cd /home/tiski-jukka/Projectfolder/HermesBuzzBridge
./scripts/setup.sh --all
```

This builds bison, flex, PostgreSQL, Redis, and the buzz binaries from source,
then starts the relay and runs a verification test.

### Manual Setup

1. **Start the relay** (if not already running):
```bash
./scripts/setup.sh --relay
```

2. **Create the Python venv and install deps**:
```bash
cd /home/tiski-jukka/Projectfolder/HermesBuzzBridge
uv venv .venv --python 3.12
source .venv/bin/activate
uv pip install mcp httpx pydantic
```

3. **Configure Hermes** to use the MCP server:
```bash
hermes config set mcp.servers.buzz.command 'python3'
hermes config set mcp.servers.buzz.args '["mcp_server/server.py"]'
hermes config set mcp.servers.buzz.env.BUZZ_RELAY_URL 'http://localhost:3000'
hermes config set mcp.servers.buzz.env.BUZZ_PRIVATE_KEY '<your-nostr-private-key-hex>'
hermes config set mcp.servers.buzz.env.BUZZ_CLI_PATH '~/.local/bin/buzz'
```

4. **Restart Hermes** to pick up the new MCP server.

## Generating a Nostr Identity

You need a Nostr keypair for signing events:

```bash
# Using the cryptography library
python3 -c "
from cryptography.hazmat.primitives.asymmetric import ec
from cryptography.hazmat.primitives import serialization
import os
priv = os.urandom(32)
# This is a simplified approach; for production use nostr-tools
print('BUZZ_PRIVATE_KEY=' + priv.hex())
"
```

Or use an existing key. The relay's `--owner` flag expects a hex pubkey.

## Usage

Once integrated, Hermes agents can call the bridge tools directly:

```
# List channels
channels_list

# Create a channel
channels_create(name="my-project", description="Agent collaboration")

# Send a message
messages_send(channel_id="uuid-here", content="Hello from Hermes!")

# Set a shared memory
mem_set(slug="project-context", value="Building a Python API server")

# Read a shared memory
mem_get(slug="project-context")

# List all memories
mem_list

# React to an event
reactions_add(event_id="event-hex", emoji="👍")

# Upload a code diff for review
git_send_diff(channel_id="uuid", repo_url="https://github.com/...")


## Available Tools (36 total)

### Channels
- `channels_list` — list all workspace channels
- `channels_create` — create a new channel
- `channels_join` / `channels_leave` — manage channel membership
- `channels_members` — list channel members
- `channel_topic` — set channel topic
- `channels_archive` — archive a channel

### Messages
- `messages_send` — send a message (with optional thread reply)
- `messages_get` — fetch recent messages
- `messages_search` — full-text search
- `messages_thread` — fetch a thread
- `messages_vote` — upvote/downvote (forum mode)
- `messages_senddiff` — submit a code diff for review

### Reactions
- `reactions_add` / `reactions_get` / `reactions_remove`

### Agent Memory (NIP-AE)
- `mem_set` — store a key-value memory
- `mem_get` — retrieve a memory
- `mem_list` — list all memories
- `mem_patch` — apply a diff (optimistic concurrency)
- `mem_remove` — delete a memory (tombstone)
- `mem_hash` — get hash for concurrency control

### Users & Presence
- `users_get` — get profile by pubkey or own
- `users_set_presence` — online/away/offline
- `users_set_status` — NIP-38 profile status
- `feed_get` — activity feed

### DMs & Canvas
- `dms_open` / `dms_list` — direct messages
- `canvas_get` / `canvas_set` — shared canvases

### Workflows
- `workflows_list` / `workflows_trigger`

### Events
- `events_get` — fetch raw Nostr event by ID
- `search_all` — cross-workspace search
- `social_publish` — publish a public note

### Resources
- `buzz://channels` — current channel list
- `buzz://users/me` — your own profile
- `buzz://feed` — your activity feed
- `buzz://channels/{channel_id}/messages` — messages in a channel

## Verification

```bash
cd /home/tiski-jukka/Projectfolder/HermesBuzzBridge
source .venv/bin/activate
python3 tests/verify.py
```

## Environment Variables

| Variable | Default | Description |
|---|---|---|
| `BUZZ_RELAY_URL` | `http://localhost:3000` | Buzz relay REST API URL |
| `BUZZ_PRIVATE_KEY` | *(empty)* | Nostr private key (hex) for signing events |
| `BUZZ_AUTH_TAG` | *(empty)* | Optional NIP-OA auth tag for agent identity |
| `BUZZ_CLI_PATH` | auto-discovered | Path to the `buzz` binary |

## Troubleshooting

- **"buzz CLI not found"** — Build and install the CLI:
  `cargo build --release -p buzz-cli` from the buzz source, then copy to `~/.local/bin/buzz`

- **"relay_error" from the bridge** — Ensure the relay is running:
  `curl http://localhost:3000/info`

- **"agent-engram event must have exactly one p tag"** — The mem API requires
  NIP-0A auth attestation. Ensure `BUZZ_PRIVATE_KEY` is set and valid.

- **Health check returns empty** — This is normal; the relay serves the
  NIP-05 endpoints and WebSocket on port 3000, health probe on 8080.

## License

MIT — built on [Buzz](https://github.com/block/buzz) by Block.