brain
This MCP server provides durable memory for coding agents: hybrid recall over episodes, memories, and summaries, full-text retrieval, and memory writing.
Search past Claude Code sessions, memory notes, and session digests with
recall, using scopes (all,episodes,memories,summaries), result limitk, project path filters, and inclusivesince/untilfilters.Receive compact, score-ranked hits with kind, id, date, project, snippet, session/name, and a recency- and kind-weighted normalized RRF score.
Fetch full stored text and metadata for any recall hit via
get_episode(id), using stableep_/mem_ids or ephemeralsum_ids, with text capped at 8k characters.Persist durable facts with
remember, choosing type (user,feedback,project,reference) and optional name, project, session, and force settings; it writes, commits, indexes, returns a stablemem_…id, and avoids near-duplicates unless forced.
Click on "Deploy Server".
Wait a few minutes for the server to deploy. Once ready, it will show a "Started" state.
In the chat, type
@followed by the MCP server name and your instructions, e.g., "@brainwhat do I know about project onboarding?"
That's it! The server will respond to your query, and you can continue using it as needed.
Here is a step-by-step guide with screenshots.
brain
A personal memory engine and MCP server for coding agents. Durable facts, session digests, and recorded sessions are searchable through hybrid recall (full-text plus vector search) from any MCP client.
Replace
OWNERin the badge with the GitHub account that hosts the fork.
Contents
Related MCP server: Agentic Memory
Overview
An agent's context ends with the session. brain keeps what matters across
sessions and makes it recallable through three MCP tools on every
deployment: recall, get_episode, and remember.
It stores three kinds of documents:
Memories: curated, durable facts (preferences, decisions, runbooks, per-project state notes).
Summaries: per-session digests written by the consolidation pass.
Episodes: recorded Claude Code transcript turns.
Each query runs a lexical leg (BM25 or Postgres full-text) and a vector leg.
The two rankings are fused with reciprocal-rank fusion, then weighted
by kind (a curated memory outranks a raw episode at equal evidence) and by
recency. Every hit carries a score in (0, 1].
Two storage backends share one code base:
Backend | Source of truth | Index | Selected by |
SQLite | Markdown files in a git repo |
| default |
Postgres | Schema | Same database |
|
Choosing an install path
1. Local | 2. Supabase store, local server | 3. Self-hosted server | |
Store | Markdown + git, SQLite index | Postgres (Supabase or any pgvector host) | Postgres |
MCP transport | stdio | stdio | HTTP ( |
Authentication | none (local process) | database credentials on each machine | Google OAuth for MCP, device tokens for hooks |
Embeddings | local model (fastembed) | local model or OpenAI | OpenAI (or off) |
Session recording |
| not automatic (see path notes) |
|
Multi-machine | optional git remote | yes, every machine needs the database URL | yes, machines need only a URL and a token |
Cloud account needed | no | Supabase (or a Postgres host) | Postgres host, a container host, Google OAuth client, OpenAI key |
Pick path 1 to try the project or for a single machine. Pick path 3 to share one brain across several machines or agents without handing out database credentials. Path 2 sits between them: one shared database, no server to run.
Path 1: Local
Everything runs on one machine. Markdown under memories/ and summaries/ is
the source of truth, and cache/brain.db is a derived index that can be
deleted and rebuilt at any time.
Prerequisites
Python 3.12+ and uv.
Git.
About 600 MB of disk for the embedding model, downloaded on first run.
Steps
Clone and install.
git clone https://github.com/OWNER/brain-mcp.git ~/src/brain-mcp cd ~/src/brain-mcp uv syncTry recall against the synthetic store in
examples/. PointingBRAIN_CLAUDE_PROJECTSat an empty directory keeps real transcripts out.BRAIN_DIR=$PWD/examples BRAIN_CLAUDE_PROJECTS=$(mktemp -d) \ uv run brain-ingest --full BRAIN_DIR=$PWD/examples uv run brain-recall "postgres backup"Index real data. With
BRAIN_DIRunset, the store is the checkout itself andbrain-ingestreads Claude Code transcripts from~/.claude/projects(and~/.claude-work/projectswhen it exists).uv run brain-ingestRegister the stdio server with Claude Code.
claude mcp add brain -- uv run --directory ~/src/brain-mcp brain-serverFor a client that must only see read tools, register
brain-server-readonlyinstead (recallandget_episodeonly).Optional: add the local hooks to
~/.claude/settings.json.{ "hooks": { "SessionStart": [{ "hooks": [{ "type": "command", "timeout": 10, "command": "uv run --no-sync --directory ~/src/brain-mcp brain-session-start" }] }], "UserPromptSubmit": [{ "hooks": [{ "type": "command", "timeout": 5, "command": "uv run --no-sync --directory ~/src/brain-mcp brain-hook" }] }] } }brain-session-startinjects the project's state note with a freshness banner.brain-hookruns a fast read-only search on each prompt and injects the strongest matches.Optional: consolidation. Link
skills/reflect-localinto~/.claude/skills/and setBRAIN_REFLECT_SKILL=/reflect-localso the debt-triggeredbrain-autoreflectruns the local pass. The other skills inskills/target the hosted MCP tools (paths 2 and 3).Optional: multi-machine sync. Add any private git remote as
origin. Memory writes auto-commit, andbrain-syncpulls and pushes. The index never leaves the machine.BRAIN_SYNC=0disables sync. An always-on Linux box can index the committedepisodes/tree and run maintenance timers; seedeploy/vm/andspecs/episodes-in-git.md.
Environment
None is required. Common settings: BRAIN_DIR, BRAIN_CLAUDE_PROJECTS,
BRAIN_SYNC, BRAIN_REFLECT_SKILL, FASTEMBED_CACHE_PATH. Set
BRAIN_BACKEND=sqlite if DATABASE_URL is exported in the same shell for
another reason.
Path 2: Supabase store, local server
Postgres holds every document and the search index. Each machine runs the
stdio server against the same database. Supabase is the documented host; any
Postgres 17 with the vector extension works (CI uses pgvector/pgvector:pg17).
Prerequisites
Everything from path 1.
A Supabase project (or another Postgres 17 with pgvector).
An OpenAI API key if OpenAI embeddings are used.
Steps
Create the Supabase project. Leave schema
brainoff the Data API's exposed schemas. Details:docs/supabase.md, section 1.Apply the migrations over the direct connection or the session pooler (port 5432), never the transaction pooler.
export DATABASE_URL='postgresql://postgres:PASSWORD@db.PROJECT_REF.supabase.co:5432/postgres' uv run brain-pg-migrateRe-running is safe. For a least-privilege login, create
brain_appand grant itbrain_server(seedocs/supabase.md, section 2).Optional: import an existing path 1 store. Only git-tracked files are read.
uv run brain-pg-load --repo /path/to/store --sqlite /path/to/store/cache/brain.dbChoose one embedding space and keep it. Either leave
BRAIN_EMBED_PROVIDERunset (local model) or setBRAIN_EMBED_PROVIDER=openaiwithOPENAI_API_KEY, then fill vectors:uv run brain-pg-reembed --estimate uv run brain-pg-reembed uv run brain-pg-reembed --swap --require-completeRecall only uses vectors whose stored space matches the running process.
Register the server with Claude Code.
claude mcp add brain \ -e DATABASE_URL='postgresql://...' -e BRAIN_EMBED_PROVIDER=openai -e OPENAI_API_KEY=sk-... \ -- uv run --directory ~/src/brain-mcp brain-serverIn this mode
rememberwrites to Postgres and does not commit to git, and the server does not runbrain-ingest.
Environment
DATABASE_URL (or SUPABASE_DB_URL), BRAIN_EMBED_PROVIDER,
OPENAI_API_KEY for OpenAI embeddings, and optionally BRAIN_PG_POOL_MAX.
Notes
New sessions are not recorded automatically in this path. brain-push and
the remote hooks post to the HTTP server's device routes, which only path 3
provides, and local brain-ingest writes only the SQLite index. Memories
written with remember and data imported with brain-pg-load are the
contents of the store.
Path 3: Self-hosted server
One HTTP MCP server fronts the Postgres store. MCP clients sign in with Google OAuth. Hooks and the session recorder on each device authenticate with a per-device token, so no device holds database credentials.
Routes: /mcp (all tools), /mcp-ro (recall and get_episode only),
/health (open, does not touch the database), and the device routes
/ingest/episodes, /hook/state, /hook/recall.
Prerequisites
A Postgres store set up as in path 2, steps 1 and 2 (migrations through
0007applied).A container host. Cloud Run is documented; the
Dockerfileruns on any host that serves HTTPS in front of port 8080.A Google OAuth client of type Web application (Google Cloud Console, APIs and Services, Credentials).
An OpenAI API key. The image omits the local embedding model to keep cold starts fast;
BRAIN_EMBED_PROVIDER=offruns full-text only.
Steps
Decide the public origin, for example
https://brain.example.comor the Cloud Run service URL. This isBRAIN_PUBLIC_URL.In the OAuth client, add the redirect URI
${BRAIN_PUBLIC_URL}/auth/callback.Configure the service environment. Every variable is listed in
deploy/cloudrun/env.example. Store secrets in a secret manager, not in plain env flags. At runtimeDATABASE_URLshould be the Supavisor transaction pooler (port 6543).Deploy. On Cloud Run:
gcloud run deploy brain --source . --region REGION \ --max-instances=1 --memory=1Gi --port=8080On another host, build with
docker build -t brain-mcp .and run the image with the same environment. The server refuses to start withoutBRAIN_PUBLIC_URL, the Google client id and secret, and at least one ofBRAIN_AUTH_DOMAINorBRAIN_AUTH_ALLOWED_EMAILS. IAM notes for organizations with domain-restricted sharing are indeploy/cloudrun/README.md.Check health.
curl -fsS "$BRAIN_PUBLIC_URL/health"Use
/healthfor probes. Cloud Run's frontend does not route paths that end inz, so/healthzis not reachable from outside.Optional: nightly job.
brain-nightlydumps schemabrainto a Cloud Storage bucket and drains the git export outbox into one commit on a GitHub repo. Setup:deploy/cloudrun/nightly.md. Helper scripts for Cloud Run deploys and a full git resync are inops/.Connect each device as described in Connecting clients.
Environment
Required: DATABASE_URL, BRAIN_PUBLIC_URL, BRAIN_GOOGLE_CLIENT_ID,
BRAIN_GOOGLE_CLIENT_SECRET, and BRAIN_AUTH_DOMAIN and/or
BRAIN_AUTH_ALLOWED_EMAILS. Usually set: BRAIN_BACKEND=postgres,
BRAIN_EMBED_PROVIDER=openai, OPENAI_API_KEY, BRAIN_JWT_SIGNING_KEY.
The image sets the backend, embedding, host, and port defaults.
Access control
BRAIN_AUTH_DOMAINadmits a Google Workspace domain. Google'shdclaim must match; an address that merely ends in the domain is refused.BRAIN_AUTH_ALLOWED_EMAILSadmits individual accounts.BRAIN_AUTH_EMAIL_PROFILESlimits an account to thepersonalorworkprofile, for exampleyou@example.com=personal|work.OAuth client registrations and token mappings are stored encrypted in
brain.oauth_kv. KeepBRAIN_JWT_SIGNING_KEYstable across deploys; changing it invalidates every stored sign-in.
Connecting clients
Claude Code, stdio (paths 1 and 2)
claude mcp add brain -- uv run --directory ~/src/brain-mcp brain-serverClaude Code, HTTP (path 3)
claude mcp add --transport http brain "$BRAIN_PUBLIC_URL/mcp"
# read-only alternative
claude mcp add --transport http brain-ro "$BRAIN_PUBLIC_URL/mcp-ro"Run /mcp in a session to complete the Google sign-in.
Other clients take the same URL. Cursor mcp.json:
{ "mcpServers": { "brain": { "url": "https://brain.example.com/mcp" } } }Codex: point the brain entry in ~/.codex/config.toml at the URL, then run
codex mcp login brain. More detail: docs/connecting-agents.md.
Device tokens and session recording (path 3)
Hooks cannot complete a browser sign-in, so each device gets its own token.
The CLI signs in through the browser and writes the token to
~/.config/brain/device-token, so the token never appears in a transcript.
export BRAIN_URL="$BRAIN_PUBLIC_URL"
uv run --directory ~/src/brain-mcp brain-device-token create --device laptop
uv run --directory ~/src/brain-mcp brain-device-token list
uv run --directory ~/src/brain-mcp brain-device-token revoke <id>BRAIN_URL must point at the server on every device; the default is
http://localhost:8080. The client needs no database credentials, no
embedder, and no SQLite file. Installing the console scripts with
uv tool install --from ~/src/brain-mcp brain puts them on PATH.
Hooks for ~/.claude/settings.json:
{
"hooks": {
"SessionStart": [{ "hooks": [{ "type": "command", "timeout": 10,
"command": "uv run --no-sync --directory ~/src/brain-mcp brain-remote-session-start" }] }],
"UserPromptSubmit": [{ "hooks": [{ "type": "command", "timeout": 5,
"command": "uv run --no-sync --directory ~/src/brain-mcp brain-remote-recall-hook" }] }],
"Stop": [{ "hooks": [{ "type": "command", "timeout": 10,
"command": "uv run --no-sync --directory ~/src/brain-mcp brain-push --hook" }] }],
"SessionEnd": [{ "hooks": [{ "type": "command", "timeout": 10,
"command": "uv run --no-sync --directory ~/src/brain-mcp brain-push --hook" }] }]
}
}brain-push --hook detaches and returns immediately. A periodic catch-up
covers sessions a hook missed:
*/30 * * * * cd ~/src/brain-mcp && uv run --no-sync brain-push >/dev/null 2>&1On Windows, schedule the same command with Task Scheduler. To record history
from before the hooks were installed, run brain-push --backfill --dry-run,
then brain-push --backfill.
Skills
The skills/ directory holds Claude Code skills that drive the
hosted tools: /checkpoint (save a project's state note before /clear),
/handoff, /catchup (deep resume), /reflect (starts a headless
consolidation pass) and /reflect-run (the pass itself). skills/codex/ has
the Codex variant, and skills/reflect-local/ is the path 1 pass. Link or
copy them into ~/.claude/skills/.
Configuration reference
All configuration is environment variables. Defaults live in
src/brain/config.py, src/brain/embedconf.py,
and src/brain/authz.py.
Store and backend
Variable | Default | Purpose |
| auto |
|
| unset | Postgres connection string. |
|
| Connection pool size per process. |
|
| Seconds to wait for a pooled connection. |
| the checkout | Root of the markdown store and |
|
| Transcript roots, colon-separated. A Windows drive letter is split on its colon, so leave it unset on Windows. |
|
|
|
| unset | Profile ( |
| unset | Extra checkout roots for legacy memory ids during |
| on when a remote exists |
|
Embeddings and ranking
Variable | Default | Purpose |
|
|
|
| per provider | Model name. OpenAI default |
|
| Vector dimensions. |
| unset | Required for |
|
| OpenAI-compatible endpoint. |
|
| OpenAI request limits. |
|
| Local model cache. |
|
| Local embedder tuning for small machines. |
| per space | Cosine floor for the vector leg. |
|
| Reciprocal-rank-fusion constant. |
|
| Per-kind weights. |
|
| Per-kind recency half-lives. |
|
| Lowest value the recency factor reaches. |
HTTP server and access control (path 3)
Variable | Default | Purpose |
| required | Public HTTPS origin, no trailing path. |
| required | Google OAuth client. |
| unset | Allowed Google Workspace domain, for example |
| unset | Comma-separated allowed accounts. |
| unset | `email=personal |
| unset | Profile applied when a token names none. |
|
|
|
| derived from the client secret | Signs tokens and encrypts |
|
| Listen address. |
Devices, hooks, and push
Variable | Default | Purpose |
|
| Server base URL for |
|
| Device token or its file. |
|
| Client state, lock, and log directory. |
|
| Hard deadline for remote hooks. |
| unset |
|
| unset |
|
|
| Default |
Privacy, consolidation, and nightly job
Variable | Default | Purpose |
| unset | Comma-separated cwd substrings never digested. |
|
| Cwd substrings whose episodes never reach git (still recallable). |
|
| Skill |
| see | When a consolidation pass is due. |
|
| Seconds before a headless pass is killed. |
| unset |
|
| auto | Path to the |
| required for backup | Cloud Storage bucket for |
|
| IANA zone that names the dump's date; match the scheduler. |
| required for export |
|
|
| Branch for the export. |
| required for export | Fine-grained token with Contents read and write on that repo. |
Commands
Every entry point is a console script, run with uv run <name>.
Command | Path | Purpose |
| 1, 2 | stdio MCP server: |
| 1, 2 | stdio MCP server with |
| 3 | HTTP MCP server with OAuth and device routes. |
| 1 | Index memories, summaries, and episodes into SQLite ( |
| 1, 2 | Recall and write from the shell. |
| 1 | Local prompt and session-start hooks. |
| 1 |
|
| 1 | Debt-gated headless consolidation and its review window. |
| 1 | State-note audit and recall telemetry. |
| 2, 3 | Apply |
| 2, 3 | Import a git markdown store into Postgres. |
| 2, 3 | Stage and swap embeddings. |
| 2, 3 | Ops CLI for the reflect lease. |
| 3 | Record sessions to the server ( |
| 3 | Hooks that call the server. |
| 3 | Create, list, and revoke device tokens. |
| 3 | Nightly dump, git export, and both in sequence. |
Memory file format
A memory is YAML frontmatter plus a markdown body:
---
name: postgres-nightly-backup
description: How the demo acme-webapp Postgres database is backed up each night.
metadata:
type: reference
date: 2026-01-12
---
The `acme-webapp` database is dumped nightly at 02:00 UTC ...Types are user, feedback, project, and reference. See
examples/ for one of each kind and the session-digest format.
The Postgres backend stores the same fields, and the git export renders rows
back into this format.
Repository layout
Path | Contents |
| Server, ingest, both stores, HTTP app, device client. |
| Postgres schema, applied in order by |
| Cloud Run notes, env template, nightly job setup. |
| systemd user units for an always-on path 1 box. |
| Supabase setup in depth, connecting other agents. |
| Cloud Run deploy-by-digest and git resync helpers. |
| Claude Code and Codex skills. |
| Design notes for individual features. |
| Synthetic store for the quickstart. |
Scope and limitations
Built as a single-user personal system. Profiles (
personal,work) separate one person's contexts; the server is not a hardened multi-tenant service.Google is the only OAuth provider the HTTP server supports.
The container image has no local embedding model. A hosted server uses OpenAI embeddings or runs full-text only.
CI runs the SQLite suite without the embedding model and runs the Postgres suite against
pgvector/pgvector:pg17. Postgres tests skip locally unlessDATABASE_URLis set.
License
MIT. See LICENSE.
Available Tools
3 toolsget_episodeA
Fetch full stored text + metadata for one recall hit.
id is the string from a recall hit; its ep_/mem_/sum_ prefix selects
the kind (episode → the USER/ASSISTANT exchange; memory → body + path;
summary → a per-session digest written by reflect). ep_/mem_ ids are
stable across re-ingests and rebuilds; sum_ ids are ephemeral (pair
recall → get_episode within one session). Text capped at 8k chars with a
truncation marker.
Inputs: id (required). Returns: object
recallA
Search past Claude Code sessions (episodes), memory notes (memories), and per-session digests (summaries, written by the nightly reflect pass).
Hybrid full-text + semantic search. scope:
"all" | "episodes" | "memories" | "summaries" ("all" spans all three).
Filters: project matches path segments of the session dir (e.g. "mobile"
=> ~/src/mobile); since/until are "YYYY-MM-DD" or "Nd" (N days ago), inclusive.
Returns compact hits: kind, id, date, project, snippet, session_id
(episodes and summaries) or name (memories), and a score in (0, 1] (recency-
and kind-weighted, normalized RRF); hits are score-descending. Episode/memory
ids are stable content-derived strings (ep_…/mem_…) — safe to persist;
summary ids (sum_…) are ephemeral. Use get_episode(id) for full text.
Inputs: query (required), k, scope, since, +2 more. Returns: object
rememberA
Persist a new memory: write memories/.md, commit, index — immediately recallable.
fact: the durable fact (short markdown, first sentence becomes the description).
type: user|feedback|project|reference. name: optional kebab-slug filename.
session/project: provenance trailers ($CLAUDE_CODE_SESSION_ID from Bash env /
workspace dir); omitted when empty. If a near-duplicate memory exists it is
returned instead of writing; force=true writes anyway. On success returns a
stable mem_… id — pair recall → get_episode(id) to read it back.
Inputs: fact (required), name, type, force, +2 more. Returns: object
Tool Schema Changelog
Recent tool additions, removals, and schema changes observed during successful MCP inspections.
TDQS
Scored across 3 tools
Each tool has a clearly distinct purpose: get_episode retrieves full content for a recall hit, recall searches across memories and episodes, and remember stores new facts. There is no overlap or ambiguity.
The naming pattern is mostly verb_noun (get_episode, remember) with recall as a single verb. This minor inconsistency does not hinder understanding, but a more uniform pattern would improve predictability.
Three tools is a small but reasonable set for a memory recall and persistence system. Each tool provides a core function (search, fetch detail, store) without unnecessary complexity.
The set covers search, retrieval, and creation of memories, but lacks update or delete operations. This may force agents to work around missing lifecycle management, but the core workflows are supported.
Maintenance
Related MCP Connectors
One memory, every AI. A shared, user-owned markdown memory your AI clients read and write over MCP.
Persistent personal memory for AI assistants — save, search, and recall across every MCP client.
Hosted agent memory: store, search, and recall facts across sessions from any MCP client.
Persistent memory for AI assistants. Save once; recall from Claude, ChatGPT, or any MCP client.
Related MCP Servers
- AlicenseNot gradedqualityCmaintenanceMCP server that provides agentic memory management for markdown vaults, enabling hybrid search, governed writing, and maintenance of episodic, semantic, procedural, and working memories for LLM agents.MIT
- AlicenseAqualityBmaintenanceMCP server for persistent, cross-session, local-first memory for AI agents, storing memories as Markdown files with SQLite indexing for hybrid search.24Apache 2.0
- AlicenseAqualityBmaintenanceAudit-grade, git-versioned memory for AI coding agents that enables saving, searching, editing, and rolling back facts through markdown files served via MCP.3959 PyPI46MIT
- AlicenseNot gradedqualityDmaintenanceProvides a file-first personal memory layer for AI agents, enabling them to store and retrieve memories as markdown files with an SQLite index. The MCP server offers read-only search by default, with optional write tools for manual memory addition and conflict resolution.6 npmMIT