# beaver-gateway A gateway for personal agents built on the Claude Agent SDK: conversations with a lifecycle, windows to talk through, jobs, memory hooks, and a policy boundary - without an opinion about what the agent is for. A setup is one `config.py` (or a package next to it) that assembles a `Gateway`; this repo holds the primitives, [beaver-agent](https://git.kotikot.com/beaver/beaver-agent) is a full setup built on them. ## What it gives a setup - **agents/** - what an agent is: a Claude agent with a prompt per conversation kind, skill sets per kind, gateway tools, a `PreToolUse` policy; a Raycast agent for cheap fast answers. - **backends/** - how a turn runs: the Claude Agent SDK subprocess with a session pool, transcripts and session stores; the Raycast wire. - **conversations/** - the model of a conversation: kinds (master, branch, deep, job, fork), rows and windows, the inject queue with priorities, seeds, turns, questions, closing through a distiller, master rotation, the envelope, the in-process gateway tools. - **jobs/** - cron, webhook and event jobs on pgqueuer, deferred injects, the subscription budget. - **frontends/** - the windows: Telegram (master = General, topic = branch), markdown files in a vault, `/api` + the admin SPA, an Anthropic-compatible `/anthropic/v1/messages`, MCP re-exposure at `/mcp/`. - **mcp/** - MCP servers a setup declares (stdio, http, python tools), aggregated in-process and handed to agents by name. - **vault/** - watching a directory of notes for the envelope. - **security/** - bearer tokens, the audit log, credential redaction. - **events/** - the in-process bus every frontend taps, and the stream event protocol backends emit. - **storage/** - SQLModel tables and the Postgres session store. `config.py` defines `Gateway` and loads a setup; `app.py` builds the runtime from it; `cli.py` is the entrypoint. Every string the gateway puts in front of a model or a user has an English default and is overridable (`ConversationTexts`, `TelegramTexts`). ## Run ```sh cd examples CLAUDE_CODE_OAUTH_TOKEN=$(claude setup-token) docker compose up --build ``` `examples/config.py` is the smallest setup that starts: one agent, one python tool, one cron job, the built-in frontends on port 8000; the compose file next to it adds Postgres. Without Docker: `uv sync`, build the SPA with `cd ui && bun install && bun run build`, then run `uv run beaver-gateway` with `DATABASE_URL` and `CONFIG_PATH` set. A setup's own secrets come from `.env` next to its config (`load_dotenv` runs before the config is executed). ## Develop ```sh make check # ruff format --check, ruff check, ty, pytest make fix ``` No comments in code: modules carry a one-line docstring saying what they are for, public configuration fields carry a one-line docstring saying what they mean; everything else is the code.