One shared brain for your team’s AI coding agents.
Git-native memory that Claude Code, Cursor, and any MCP-capable agent read from — and that your team writes to the same way it writes code: as a pull request someone approves.
Your team’s AI agents start every session knowing nothing. The migration gotcha someone hit on Tuesday is re-discovered on Thursday by a different developer in a different tool. Every session re-reads the same files, re-asks the same questions, and re-derives the same conclusions.
Teams patch this with CLAUDE.md and .cursorrules — hand-maintained files that drift, live in one tool, and only contain what someone remembered to write down. Nobody updates them after the session where they learned the thing.
TeamBrain keeps that knowledge in your repo, serves it to every agent, and proposes new entries from what your sessions actually did — with a human approving each one.
memories are markdown files in your repo ← you can read, diff, and revert them
│
├─► a local daemon indexes them ← retrieval is on your machine, offline
│ └─► serves them over MCP ← any agent, no vendor lock-in
│
└─► a CI job watches how sessions go ← metadata only, redacted on-device
└─► opens a pull request ← nothing is written without a human
Four things follow from that, and they’re the whole product:
git clone is a complete export. There is no TeamBrain server, database, or account.memories/ on your default branch. Every addition is a PR.npm i -g @teambrain/cli
cd your-repo
tb init # imports CLAUDE.md / .cursorrules / AGENTS.md / ADRs → PR-ready branch
# review the branch, open a PR, merge it
tb install claude-code # registers the MCP server + hooks (shows a diff, asks first)
tb serve # start the local daemon
tb doctor # confirm it's all wired
npm 11 prints an
npm warn install-scriptswarning, and the install still succeeded. It namesbetter-sqlite3andonnxruntime-node, whose install scripts npm 11 no longer runs by default. Both ship prebuilt binaries, so those scripts do not need to run — verified onnode:26/ npm 11.19.0: the install exits 0,better-sqlite3opens a database and executes SQL,onnxruntime-nodeloads, andtb initworks end to end. The warning is informational; do not pass--allow-scriptsto silence it. Confirm withtb --version, thentb doctoroncetb serveis running.
What you’ll see next: nothing. Your next Claude Code session starts with the team’s memories already in context — injected silently, with no banner and no output. This is deliberate (a hook that prints breaks some clients), but it means the only way to know it’s working is to check:
tb doctor # daemon running, socket reachable, index docs: N
tb audit --last-session # exactly what the last session recorded, as stored
If tb doctor is green and index docs is greater than zero, your agents are being served.
A memory is one markdown file with YAML front-matter. That’s the entire format.
---
id: 01J8XQ2F7K3N5P9R1T4V6W8Y0Z
class: convention
scope: team
status: active
priority: required
title: Payment retries belong in the gateway wrapper, not the caller
created: 2026-06-14
evidence:
sessions: [01J8X9M2K4P6R8T0V2X4Z6B8D0]
commits: [a3f9c21, 7b2e884]
tags: [payments, resilience]
ttl_days: null
---
Retry logic for payment provider calls lives in `src/payments/gateway-wrapper.ts`.
Do not add retries at call sites.
The wrapper owns idempotency-key generation. A retry issued from a call site
reuses the outer key and the provider treats it as a duplicate charge attempt —
this caused the double-authorization incident on 2026-05-31.
When adding a new provider, implement `PaymentProvider` and register it with the
wrapper. The wrapper handles backoff, jitter, and the circuit breaker.
class is one of decision, convention, map, learning. priority: required means it’s force-included in every session’s context; advisory means it competes on relevance. Bodies are capped at 400 words by the linter — a memory that needs more than that is two memories.
Serving. tb serve runs a per-machine daemon that watches .teambrain/, keeps a derived SQLite index, and exposes an MCP server with four tools: memory_context (session-start bundle, ≤2000 tokens, required memories first), memory_search, memory_propose, memory_feedback. Retrieval is hybrid — BM25 via FTS5 unioned with vector search over local embeddings, fused by reciprocal rank, then filtered and trimmed to budget.
Capturing. Thin hooks emit metadata about what the session did: which files were touched, which commands exited non-zero, whether the session ended in a commit. Events are redacted on-device before they’re written anywhere, then spooled locally and pushed to a dedicated teambrain/sessions branch that is never merged to main.
Distilling. A scheduled CI job in your repo, using your LLM key, reads new session records and merged diffs, clusters the signals (same file fought with across multiple sessions, repeated failing commands, searches that returned nothing), drafts candidate memories, checks them for duplicates and contradictions against the existing brain, and opens a pull request.
Approving. You review the PR like any other. Merge it and every developer’s daemon picks it up on the next fetch. Retirement is the same loop in reverse: tb retire <id> <reason> opens a PR that moves the file to retired/.
Full component map, trust boundaries, and design decisions: docs/ARCHITECTURE.md.
Most of the value depends on habits, not configuration. The short version:
required is a budget, not a label. Every required memory is force-included in every session and permanently costs context. Most teams should have fewer than ten.The full playbook — memory quality rules with examples, the 60-second PR review, why your memory isn’t being retrieved, weekly rhythm, anti-patterns, and troubleshooting: docs/USAGE.md.
Default is capture.level: metadata:
| Captured | Not captured |
|---|---|
| File paths touched | File contents, diffs, patches |
| Command kinds and exit codes | Command arguments |
| A ≤200-char local summary of intent | Your prompts, raw or otherwise |
| Session outcome, duration, commit SHAs | Anything the redactor flags as a secret or PII |
Redaction (secrets, PII, entropy scan) runs on your machine before anything is written to disk or pushed. The redaction corpus is public and lives in packages/redact/; it gates CI on every push.
The weekly digest is aggregate-only by construction — the aggregator can only see a projection of events that structurally drops session, tool, model, repo, and branch identifiers, and a test asserts no identity-bearing field survives even when it’s fed authored fixtures. No individual metrics, no leaderboards.
There is no phone-home. Network calls happen in exactly four places, all of them yours: your git remote, your LLM provider (distiller only, in your CI), your Slack webhook if you configure one, and a one-time checksum-pinned download of the local embedding model. This is enforced by a test that scans all shipped source and fails the build on a new network call anywhere else.
Threat model and the full trust architecture: SECURITY.md.
Don’t take the section above on trust — the point of this architecture is that you don’t have to:
tb audit --last-session # the exact events stored for your last session, verbatim
tb doctor --json # daemon, index freshness, retrieval latency, capture state
git log teambrain/sessions # every session record that has ever left your machine
The redaction corpus, the egress scanner, and the privacy negative tests are all in the repo and run with pnpm test.
723 tests across 91 test files, all green on @teambrain/cli@0.5.0. This line is generated by scripts/claims.mjs from a real vitest run, and CI fails if it drifts from the suite.
Serving works with any MCP-capable agent. Capture depth depends on what lifecycle hooks the tool exposes. This matrix is generated from the adapter capabilities declared in code (packages/hooks), and a CI test fails the build if the table drifts from them — so it cannot overclaim:
| Capability | Claude Code | Codex | Cursor | Gemini CLI |
| — | — | — | — | — |
| Install command | tb install claude-code | tb install codex | tb install cursor | tb install gemini-cli |
| Capture tier | Native hooks | MCP-side inference | MCP-side inference | Native hooks |
| Session start | Yes (native hook) | Yes (MCP-side inference) | Yes (MCP-side inference) | Yes (native hook) |
| Session end | Yes (native hook) | Yes (MCP-side inference) | Yes (MCP-side inference) | Yes (native hook) |
| Tool use (edits / commands / tests / exploration) | Yes (native hook) | No | No | Yes (native hook) |
| Commit SHAs & outcome | Yes (native hook) | No | No | Yes (native hook) |
| Plan revisions | No | No | No | No |
| Memory search / retrieve (MCP tool) | Yes | Yes | Yes | Yes |
| Propose memory (MCP tool) | Yes | Yes | Yes | Yes |
Cursor and Codex lack usable native lifecycle/post-tool hooks, so their sessions carry no tool_use events. Session boundaries are inferred from MCP tool calls: a session ends when it proposes a memory or after 30 minutes of inactivity; commit SHAs and outcome are not captured. Any other MCP-capable agent can still read and propose memories (serving) — it just isn’t captured.
tb install automates setup for claude-code, codex, cursor, and gemini-cli. Other MCP clients work by pointing them at the server manually.
-c core.longpaths=true and expect less coverage.Measured on a clean clone, 5,000-memory synthetic brain, ordinary CI hardware:
| Result | Budget | |
|---|---|---|
| Search latency | p50 39ms · p95 53ms | p50 <80ms · p95 <300ms |
| Index rebuild (5k memories) | 22.6s | <60s |
| Recall@8 on the golden query set | 1.00 | ≥0.85 |
Reproduce with pnpm bench.
| Document | What’s in it |
|---|---|
| docs/ARCHITECTURE.md | How the pieces fit, data flow, trust boundaries, design decisions, extension points |
| docs/USAGE.md | Writing good memories, reviewing proposals, retrieval hygiene, weekly rhythm, troubleshooting |
| FORMAT.md | The memory file spec and session event schema |
| SECURITY.md | Threat model, redaction, egress, memory-poisoning stance |
| CONTRIBUTING.md | How to work on TeamBrain itself |
| docs/DEVELOPMENT.md | Local development setup |
| ci-templates/ | Ready-to-copy workflows: distill, digest, lint, session rotation, codemap |
V1 is complete and dogfooded. The governed loop — capture, distill, propose, approve, serve, retire — works end to end and is covered by an integration test that runs it on every build.
Not yet built: org and multi-repo scoping, GitLab distiller driver, a hosted tier, and verified Cline, Kiro, and Antigravity install adapters.
Apache-2.0. Issues and PRs welcome — please read CONTRIBUTING.md first.