2026-05-21 23:54:13 +02:00
2026-05-21 23:54:13 +02:00
2026-05-21 23:54:13 +02:00
2026-05-21 23:54:13 +02:00
2026-06-02 15:42:43 +02:00
2026-05-21 23:54:13 +02:00
2026-05-21 23:54:13 +02:00
2026-05-21 23:54:13 +02:00

beaver-agent

My real beaver-gateway setup (paired with the protocol from beaver.kotikot.com).

Uses Claude Code and Raycast subscriptions for agents, has some MCPs set up. You can use this as-is or modify to match your needs (config.py).

Requirements

  • Docker + Docker Compose
  • Obsidian Sync (for obsidian-headless)
  • claude.ai sub
  • raycast sub
  • Firefly III and its PAT

First launch

1. Create .env and raycast.json

cp .env.example .env
# fill CHANGE-ME
nvim .env

# build raycast config on your mac (beta by default, consider checking raycast-api for instructions)
raycast-api init

# copy config.json to your deployment server

docker compose up -d

2. Set up Obsidian Sync

docker exec -it beaver-obsidian ob login
docker exec -it beaver-obsidian ob sync-setup --vault "yourvault"
docker restart beaver-obsidian

Check:

docker exec beaver-obsidian ls /vault

Only markdown is synced by default. To sync everything:

docker exec beaver-obsidian ob sync-config \
  --file-types image,audio,video,pdf,unsupported
docker restart beaver-obsidian

3. Set up claude

docker exec -it beaver-gateway claude /login
docker exec -it beaver-gateway bash -c 'cd /vault && claude --dangerously-skip-permissions --model claude-opus-4-7'

Click through every dialog, then /exit or Ctrl+C.

4. Mint a token

Open admin at http://localhost:62992 (or https://<DOMAIN>/admin/ if Caddy), sign in with ADMIN_USER / ADMIN_PASS, go to Tokens → Create, scope * for first run.

5. Smoke test

docker exec beaver-gateway ls /vault | head
docker logs beaver-gateway | grep -i "agent registered"

curl http://localhost:62990/v1/models \
  -H "Authorization: Bearer <YOUR_TOKEN>"

Where to plug things in

The admin dashboard renders ready-to-copy URLs and snippets for each of these

  • any Anthropic client: http://localhost:62990 or https://<DOMAIN>/anthropic, model = agent name (beaver-opus-high etc)
  • MCP clients (Claude Desktop, Raycast extension): just find in admin
  • Obsidian companion plugin: paste the dashboard's plugin base (http://localhost:62993 raw, or https://<DOMAIN>/md behind Caddy) into the plugin's "Base URL" setting
  • Admin UI: http://localhost:62992 or https://<DOMAIN>/admin, login from ADMIN_USER / ADMIN_PASS

Exposing to the internet

Reference config in caddy. Designed for: gateway on rpi, Caddy on a server with a public IP, wired through tailscale.

cd caddy
cp Caddyfile.example Caddyfile
cp .env.example .env   # only for cloudflare
# replace <DOMAIN>; point upstreams at wherever the gateway is reachable
docker compose up -d

Set PUBLIC_BASE_URL=https://<DOMAIN> in beaver-agent's .env. For per-subdomain layout, rewrite the Caddyfile and pass full public_base_url=... per frontend in config.py.

Useful commands

# shell into the gateway container (claude CLI, bun, python with venv all live here)
docker exec -it beaver-gateway bash

# what obsidian-sync has pulled
docker exec beaver-obsidian ob status

# force a one-off sync (don't wait for the continuous tick)
docker exec beaver-obsidian ob sync

# per-service logs
docker compose logs -f gateway
docker compose logs -f obsidian-headless

# pull the latest beaver-gateway (when GATEWAY_REF=main)
docker compose build gateway && docker compose up -d gateway

# reload config.py without a full rebuild
docker compose restart gateway

Gotchas

  • claude in the container doesn't see the vault - cwd=VAULT in config.py resolves to /vault inside the container, not on the host. Don't change it.
  • gateway hangs on JSONL file did not appear within 30s - claude's onboarding wasn't clicked through (see step 3). Re-enter interactively with docker exec -it beaver-gateway ..., click trust folder + bypass permissions, exit.
S
Description
My setup for Beaver Agent
Readme 631 KiB
Languages
Python 84.8%
Dockerfile 15.2%