A central, self-hosted team brain for AI coding agents. Teammates point their Claude Code at one bearer-gated URL and it both uses the team's shared knowledge (auto-recall) and adds to it (auto-capture) — plus ingests documents (PRDs, decks, PDFs) and catalogs everything in the background. Runs on a single spin-down Sprite, keyless (local embeddings + the Claude subscription).
Built for Podclave. Self-host the brain anywhere and connect any Claude Code (§2); Podclave makes both turnkey for a team — spin-down Sprite hosting, per-user identity, per-Sprite Schedules, and fleet rollout as a managed config-overlay bundle (§3). Get a team set up at https://podclave.com.
teammates' Claude Code ──┐ agentmemory MCP (interactive) + hooks (auto) + skill, bearer token
▼
https://<brain>.sprites.app (public, one bearer secret)
│
┌──────────────────▼───────────────────┐ service: team-brain :8080
│ gateway (FastAPI) — the front door │
│ /agentmemory/* passthrough │
│ /ingest/upload /docs/{id} │
│ /mcp (MCP over HTTP — BYO clients) │
│ /maintenance/run + /status (cataloger)│
│ /viewer /healthz │
└───┬───────────────┬───────────────────┘
passthrough proxy │
┌───▼─────────────┐ ┌▼──────────────┐ service: agentmemory (internal)
│ agentmemory :3111│ │ viewer :3113 │
│ keyless engine │ └───────────────┘
└──────────────────┘
~/brain-docs/ originals + manifest.db (sha256-idempotent)
- Engine:
@agentmemory/agentmemory— local embeddings (all-MiniLM-L6-v2), BM25+vector+graph hybrid search. Apache-2.0. - Gateway (ours): auth, document ingest/retrieval, viewer proxy, and the activity-triggered cataloger. This is the productized layer.
- Keyless: no API keys. Embeddings run locally; the LLM cataloger uses the Claude subscription on the box (
AGENTMEMORY_PROVIDER=agent-sdk).
git clone https://github.com/podclave/podbrain.git && cd podbrainbash server/install-brain.sh— stand up the brain (once)- Teammates with their own Claude Code:
claude plugin install team-brain@podbrain(see §2) - (Podclave fleet)
bash client/overlay_instructions.sh— render the client overlays - (Podclave fleet) Paste the printed blocks into your Podclave
team-brainbundle - Done — teammates are wired up
Details for each step below.
On a fresh Sprite in public URL mode (the bearer secret is the gatekeeper):
git clone https://github.com/podclave/podbrain.git && cd podbrain
bash server/install-brain.sh # installs the engine, gateway, and both servicesThe installer is idempotent and prints a BRAIN_URL + BRAIN_SECRET block at the
end (the secret is also at ~/.agentmemory/team_secret.txt).
Two things the installer can't do itself:
- Set public auth mode — on the Sprite/Podclave side. Without it, clients can't reach the brain.
- Log
claudein on the brain box — the LLM cataloger (AGENTMEMORY_PROVIDER=agent-sdk) runsclaudehere. Capture/recall/ingest all work without it, but deep consolidation silently degrades to a no-op. Runclaudeonce to log in.
Verify:
curl https://<brain>.sprites.app/healthz
curl -H "Authorization: Bearer <secret>" https://<brain>.sprites.app/agentmemory/healthAny Claude Code ≥ 2.1.154 can join — no Podclave required:
claude plugin marketplace add podclave/podbrain # once per machine
cd <the project you want connected>
claude plugin install team-brain@podbrain -s project \
--config brain_url=https://<brain>.sprites.app \
--config brain_secret=<secret>
claude plugin enable team-brain@podbrain -s project # install alone is inert by designThat's auto-recall every turn, passive capture of durable learnings (needs
python3 + a logged-in claude CLI), interactive memory tools, and /team-brain:setup
for diagnostics. (If the installer mentions "1 userConfig option not yet set", that's the optional email for attribution — it falls back to your git email.) First use of a memory tool will show a one-time permission prompt (approve it; fleet installs pre-allow these via managed settings). Pick your scope deliberately — hooks capture wherever the
plugin is enabled:
-
Per-project (recommended, shown above):
-s project— active only inside that project, inert everywhere else. Repeat per project. Note: the URL/secret you--configare stored once globally — a second project's install inherits them (use the multi-brain recipe below for different brains). -
Whole machine: install without
-s, thenclaude plugin enable team-brain@podbrain. Every project on the machine now captures to this brain — only do this on a machine that's all one team's work. -
Different brains per project (e.g. per-client brains under separate MSAs): install
-s projectwithout--config, enable it (claude plugin enable team-brain@podbrain -s project), then put both values in each project's.claude/settings.local.json(and never set the secret via--config/the prompt — a global secret overrides every project's):{ "pluginConfigs": { "team-brain@podbrain": { "options": { "brain_url": "https://foo-brain.sprites.app", "brain_secret": "<foo secret>" } } } }
Each session announces which brain it's connected to; if the plugin is installed
but unconfigured it says so once and stays quiet (recall/capture inactive).
Recall-only mode: set BRAIN_NO_DISTILL=1.
The brain speaks MCP over HTTP directly — add it as a remote/custom connector
pointing at https://<brain>.sprites.app/mcp (bearer: the team secret). That
gives interactive recall/save/curation anywhere Claude runs; the automatic
hooks remain a Claude Code thing.
The client ships as a Podclave config bundle — 5 overlay files, no installer. On the brain box, render them all:
bash client/overlay_instructions.shIt prints all five overlays — each with its destination path + owner, pulled
straight from the repo — and pre-fills the secrets file (.env.podclave.brain)
with this brain's live BRAIN_URL/BRAIN_SECRET. Paste each block into the
team-brain bundle in Podclave at the path it shows (relative paths land in $HOME;
brain.py runs via python3 …, so no executable bit is needed). That's the rollout.
Key things to know:
- Overlays are byte-identical for the whole org. Per-user attribution comes
from
~/.podclave/user-email(written by Podclave on Setup; falls back to git email /$USER), so there's no per-user config. - The two
/etc/claude-code/files areowner: rootso users can't disable them.managed-settings.d/20-team-brain.jsonadds the auto-recall/auto-capture hooks — Claude Code combines hooks across all settings sources, so it never touches anyone's own~/.claude/settings.json— pluspermissions.allowfor the safe MCP tools (read + reversible curation);memory_governance_deleteand the agent-workflow tools are omitted, so they prompt. managed-mcp.jsonis the agentmemory MCP — a localnpx @agentmemory/mcpstdio shim in proxy mode against the shared brain (AGENTMEMORY_FORCE_PROXY=1,${BRAIN_URL}/${BRAIN_SECRET}from the env file). Caveats, all real:managed-mcp.jsonis EXCLUSIVE — once deployed, Claude Code loads only the servers it defines; teammates' own local/project MCP servers stop loading. Add any other team MCP to this same file.allowAllClaudeAiMcps: truekeeps users' claude.ai connectors.- Managed MCP servers are auto-trusted (no per-user approval prompt).
- Needs node on the client (the shim;
npx -yself-fetches on first use) and Claude Code ≥ 2.1.149 (forallowAllClaudeAiMcps).
The gateway runs consolidation on its own when the box is already awake (after
BRAIN_MAINT_WRITES, default 20, writes and BRAIN_MAINT_MIN_SECS, default 1800,
elapsed: consolidate-pipeline → reflect → auto-forget, holding a Sprite keep-alive
so it can't suspend mid-run). For guaranteed runs, point a Podclave per-Sprite
Schedule at the brain:
| Field | Value |
|---|---|
| Method | POST |
| Path | /maintenance/run |
| Interval | e.g. 3600 (hourly) or 21600 (6h) — min 60s |
| Headers | Authorization: Bearer <secret> |
The Authorization header is required (the path is bearer-gated → 401 without
it). The scheduled POST also wakes a suspended box, so the full spin-down → wake →
catalog → keep-alive → re-suspend loop closes on its own; the cataloger no-ops
cheaply when there's nothing new. Check state: GET /maintenance/status.
The agentmemory engine can occasionally wedge — alive but unresponsive (e.g. its internal WS to the iii backend severed by a spin-down suspend/resume) — after which the gateway just times out on every call. Add a second Schedule so a wedged engine self-heals:
| Field | Value |
|---|---|
| Method | POST |
| Path | /maintenance/healthcheck |
| Interval | e.g. 600 (10 min) |
| Headers | Authorization: Bearer <secret> |
The endpoint deep-probes the engine (:3111/agentmemory/health, 5s); if it's wedged it
fires recover-engine.sh, which restarts the engine and is a no-op when healthy. The
gateway is intentionally not needs-bound to the engine, so the engine cycles on its
own while the gateway keeps serving (briefly erroring until it's back). Recovery is logged
to ~/.agentmemory/recover.log, single-flighted via flock, and preserves all stored
memories (the restart is a process cycle, not a wipe).
After overlay Setup on a teammate's VM. Plugin installs (§2): run /team-brain:setup instead.
python3 ~/.claude/skills/team-brain/brain.py health # gateway reachable → {"status":"healthy"}Then in a real Claude Code session there:
- run
/mcp→ theagentmemoryserver shows connected (proxying to the brain). A local/7-tool fallback means thelivezprobe failed — checkBRAIN_URL/BRAIN_SECRET. - "remember
<fact>" then "what do we know about<topic>" → it usesmemory_save/memory_smart_search. - ask about a known project area → expect a
<team-brain-context>block (auto-recall hook). - state a decision and end the turn → after ~90s the async capture distills durable learnings and pushes them (secrets scrubbed; only distilled facts leave the VM).
- "file this
<path>" →brain.py fileingests it server-side (pdf/docx/pptx/md), and its contents become searchable via the MCP.
openssl rand -hex 24 > ~/.agentmemory/team_secret.txt # on the brain Sprite
# update AGENTMEMORY_SECRET in ~/.agentmemory/.env, then:
sprite-env services restart agentmemory && sprite-env services restart team-brainThen re-run client/overlay_instructions.sh to get the new overlay #3 (the env file), update that overlay
and the Schedule's Authorization header, and re-run Setup.
Plugin installs (§2) need the new secret too: re-run claude plugin install team-brain@podbrain --config brain_secret=<new secret> (or update
.claude/settings.local.json in multi-brain projects) and restart the session.
Same for any claude.ai/Desktop connectors pointed at /mcp.
server/
install-brain.sh one-shot, idempotent server provisioner
gateway/app.py the FastAPI gateway
gateway/requirements.txt pinned deps
client/
overlay_instructions.sh prints the 5 client overlays for the Podclave bundle
plugin/ the team-brain Claude Code plugin (§2): manifest, hooks,
MCP config, /team-brain:setup
plugin/skills/team-brain/SKILL.md skill manifest (routes memory to the MCP; file → brain.py)
plugin/skills/team-brain/brain.py single-file Python (stdlib): hooks + file ingest
env.podclave.brain.template → ~/.env.podclave.brain (URL + secret, auto-sourced)
managed-settings.d/20-team-brain.json → /etc/... (hooks + MCP-tool perms, root)
managed-mcp.json → /etc/claude-code/managed-mcp.json (the agentmemory MCP, root)
docs/
DEVELOPING.md working ON podbrain: design decisions, gotchas, tradeoffs
.claude-plugin/marketplace.json repo doubles as the plugin marketplace (§2)
MIT — see LICENSE. The agentmemory engine and MCP shim it builds on are Apache-2.0 (© their authors).