localbrain is a small offline memory server for MCP clients. It stores
thoughts in local Postgres with pgvector, creates embeddings with a local
Ollama model, and exposes capture/search/list/update/delete tools through a
stdio MCP bridge.
- Local Supabase/Postgres database with pgvector
- Local embedding and metadata extraction through Ollama
- Supabase Edge Function MCP endpoint
- Stdio bridge for desktop MCP clients
- Starter configs for Claude Desktop, Codex, and OpenClaw-style clients
- Smoke test for capture, search, list, update, delete, and stats
- Node.js 20 or newer
- Supabase CLI
- Docker Desktop or a compatible local Docker runtime
- Ollama with
mxbai-embed-largeand a small instruct chat model, preferablyqwen2.5:4b-instruct
Pull the default local models:
ollama pull mxbai-embed-large
ollama pull qwen2.5:4b-instructlocalbrain uses the chat model only to extract small JSON metadata. Prefer a
small instruct model over a reasoning-oriented model; it should follow the
schema and stop quickly. See docs/model-selection.md.
Copy-Item .env.example .env
supabase start
supabase functions serve local-memory-mcp --env-file .env
node scripts/localbrain-stdio.mjsSet MCP_ACCESS_KEY in .env to a local secret before connecting an MCP
client. If Supabase prints a different local API URL or service role key, copy
those values into .env.
For multi-client setups, keep one admin key with MCP_ACCESS_KEY_SCOPES=*
and add scoped keys with MCP_ACCESS_KEYS, for example:
admin:<admin-key>:*
journal-client:<journal-key>:localbrain|journal
Use one of the files in examples/ as a starting point. Replace <repo> with
the path where you cloned this repository and set the same MCP_ACCESS_KEY in
.env.
capture_thought: save a thought with metadata and embedding- duplicate captures in the same namespace are merged by
upsert_thoughtusing a content fingerprint search_thoughts: semantic search across stored thoughtslist_thoughts: list recent thoughts with optional filtersupdate_thought: replace a thought and regenerate metadatadelete_thought: delete by UUID or nearest natural language matchthought_stats: summarize totals, topics, people, and namespaceslist_brains: show available namespaces
The default path is offline-first. The database runs locally, embeddings are
created locally, and OLLAMA_LOCAL_ONLY=true rejects non-local embedding
hosts. See docs/privacy.md before publishing a fork or sharing a memory
store.
After the local function is running:
pwsh ./scripts/smoke-test.ps1Publish this repo from a clean export, not from a private working repository
with old history. Run the privacy checklist in docs/privacy.md and a secret
scanner before the first public push.