Claude Brain
Persistent, cross-device memory for an AI collaborator — git-backed, concurrency-safe, reachable from voice and phone.
Context
Claude starts every session blank. I use it from Claude Code on a Mac and a Linux desktop, from claude.ai in the browser and the phone app, and in voice mode. Claude Code’s auto memory is scoped to one project on one machine. claude.ai’s memory is opaque and I can’t take it with me.
I wanted one collaborator on every surface, one that knows who I am and what we’ve built together. I started the brain on 2026-06-14 and use it daily. The brain is private; its design is public as Brain Kit, a template repo and a Claude Code plugin marketplace.
Problem
- Durable. It has to outlive any service I run for it.
- Every surface. Recall and writes from Claude Code, web, phone and voice, through official channels.
- Concurrent. Several sessions run at once, often on one machine, and nearly every write touches the catalog file.
- Safe. A brain leak must never be a credential leak.
- Cheap on context. It can’t be loaded whole. Recall has to be selective.
What I built
Version one was too much. The first build added a layer over the repo: transcript capture to a VPS, Gemini embeddings, a Qdrant vector store, an n8n distiller and a recall MCP server. On 2026-07-08 I tore it down and rebuilt as Brain 2.0. The vector store mostly re-found facts the notes already held. I judged that keyword recall plus query expansion by the model covered about 90% of real queries on a 9 MB text corpus. The 14 VPS-only transcripts were repatriated first; nothing was lost. Vectors come back only if the corpus grows about 100× or keyword misses start to hurt.
Brain 2.0: the repo is the brain. Markdown notes, one fact per file.
- Recall. A bootloader
CLAUDE.mdloads into every Claude Code session. It says: skimINDEX.md(a one-line description per note, 120 characters max), then open only the notes that match. - Writes. Since 2026-08-11 every write from a clone gets its own git worktree and is pushed to
mainat once. Without that, sessions on one device share one working copy, and concurrent edits toINDEX.mdsilently drop one side. Now remotemainserializes writes. A push is an atomic ref update, the loser rebases, and a real collision surfaces as a conflict. - Sync. A SessionStart hook (since 2026-08-20) fast-forwards the clone and injects one status line, such as STALE or unpushed writes waiting. It always exits 0 and can’t hang, so it never blocks a session.
- Web and phone. GitHub’s hosted MCP connector on claude.ai.
- Secrets. Pointers only, never values. Gitleaks scans every push.
wt=$(brain-write.sh open) # detached worktree at the newest main
# edit the note and its INDEX.md line inside $wt
brain-write.sh publish "$wt" "message" # commit, push to main, rebase on a lost race
Voice needed its own server. Voice mode got connectors on 2026-07-23. By voice, the GitHub connector call succeeded and the model got nothing back. The GitHub MCP server returns a file as a text confirmation plus an embedded resource carrying the body. Text surfaces unwrap the resource. The voice pipeline passes on only the confirmation. No prompt fixes that.
So I built brain-remote, an MCP server that re-serves the repo as plain text. v1.0 shipped on 2026-08-17 and voice recall worked the same day. v1.1 followed that day with brain_write. A validation gate checks path lists, frontmatter, secret patterns and size. Then one atomic commit carries the note and its INDEX.md line through GitHub’s Git Data API, with a non-force ref update retried up to three times. There is no delete tool: voice and irreversible actions don’t mix. v1.2.1 put etiquette into the server’s initialize instructions, because voice clients talked over in-flight tool calls.
On 2026-08-25 I moved it to Cloudflare Workers without touching the write logic. Auth is a secret path segment, since the claude.ai connector form offered no header auth on my plan. A wrong path gets a bare 404. It ships in Brain Kit beside two plugins: brain (sync hook, write script, skills) and brain-remote (registers the server for sessions without a clone).
How I knew it worked
INDEX.md. Since then a pass needs a verbatim quote or a SHA.Adversarial review. A two-agent review of the write script’s port to Brain Kit found two gaps: offline writes weren’t recallable until the next sync, and a sync comment would have lost the write if followed. On 2026-08-11 I verified every path in a sandbox against a bare origin, including a lost push race, chained offline writes and a busy clone.
Reviewed agent builds. I build with Claude Code: a written plan, a subagent and a review per task, a final review over the branch. On brain-remote v1.1 the final review caught a truncating reader on the write path before merge. It would have silently corrupted INDEX.md. On v1.2 every fix round traced back to a bug in the plan, not the implementer.
Live probes. v1.1, v1.2, the Workers port and v1.5.0 each ended with real writes against the live server, checked, then reverted. The Workers port added 16 contract tests mirroring the original suite.
Context cost. v1.5.0 cut brain_index (bootloader plus catalog) from 71k to 45k characters. A session that already holds the bootloader gets the catalog only.
Dogfooding. Two SessionStart hooks on one clone (the old one and the plugin’s, mid-migration) interleaved writes to .git/FETCH_HEAD, and git pull --ff-only failed. The fix: fetch, then a separate merge --ff-only, one retry per step.
What I’d change
Skip the vector layer. I built it before I had evidence I needed it. Files plus an index would have been the right first build.
Hooks over rules. The bootloader used to say consider a journal entry. A soft rule fires only when the model remembers, and one day the entry got written only because I asked. Since 2026-09-11 a Stop hook blocks the end of a turn when the brain has commits today and no journal entry. I’d move rules into hooks sooner.
Move the path secret. claude.ai connectors now accept request headers, so the credential can leave the URL. That change is parked.
Links
- Brain Kit: the public template and plugin marketplace.
- How it works: the design rationale.
- Voice mode: deploy your own brain-remote.
- brain-remote source: the MCP server.
- github-mcp-server #607: the response format behind the voice gap.