Open Brain Documentation

Persistent, searchable memory for every AI tool you use.

What is Open Brain?

Open Brain is a personal, database-backed AI knowledge system that gives every AI tool persistent memory. Based on Nate B Jones' architecture, it turns your scattered conversations across Copilot, Claude, ChatGPT, Cursor, and other tools into a single, searchable knowledge base.

Credit: Open Brain was originally created by Nate B Jones. This version by Scott Nichols extends the original with self-hosted Kubernetes deployment, Ollama local embeddings, Tailscale Funnel networking, Docker Compose quickstart, and multi-replica SSE support. See Nate's setup guide, prompt kit, and Substack post for the original vision.

The Problem

Every AI conversation starts from zero. Decisions, preferences, and context are lost across sessions and tools.

The Solution

A unified memory backend — capture once, recall everywhere. Semantic search finds thoughts by meaning, not keywords.

Philosophy

  • One row = one retrievable idea — Zettelkasten-style atomic notes
  • Vector search = associative retrieval — search by meaning, not keywords
  • Metadata extraction is automatic — LLM classifies and tags on ingest
  • Backend, not frontend — use with any UI or AI tool you prefer
  • Your memory is portable — self-hosted, open protocol, compounding

Cost

DeploymentMonthly Cost
Docker Compose (self-hosted)$0
Kubernetes homelab$0 (adds to existing cluster)
Supabase Cloud + OpenRouter$0.10 – $0.30
Azure ManagedVaries by tier

Architecture

Open Brain has a simple, layered architecture — AI clients talk to the MCP server via SSE, which handles tool dispatch, embedding generation, metadata extraction, and database operations.

AI Client (Copilot, Claude, ChatGPT, Cursor, etc.)
    ↓ MCP Protocol (SSE transport)
    ↓ Auth: x-brain-key header or ?key= param
    ↓
MCP Server (Node.js + Hono / Deno Edge Function)
    ├─ Tool dispatch (7 MCP tools)
    ├─ Embedding generation (OpenRouter or Ollama)
    ├─ Metadata extraction (LLM)
    └─ Database client
    ↓
PostgreSQL + pgvector
    ├─ thoughts table (content + embedding + metadata)
    ├─ HNSW index (vector search)
    ├─ GIN index (metadata filtering)
    └─ match_thoughts() RPC function

Data Flows

Capture Flow

Client → capture_thought → Embed (parallel) + Extract metadata (parallel) → Insert row → Return confirmation with metadata

Search Flow

Client → search_thoughts → Embed query → match_thoughts() RPC → Return ranked results with similarity scores

Scaling

ScaleThoughtsNotes
Personal1 – 10KSingle instance, no tuning needed
Power User10K – 100KHNSW index handles smoothly
Team100K+Consider dedicated Postgres, read replicas

Database Schema

Single table design on PostgreSQL with pgvector extension. Rich JSONB metadata enables flexible filtering without schema migrations.

The thoughts Table

ColumnTypePurpose
idUUIDPrimary key (auto-generated)
contentTEXTThe thought itself
embeddingVECTOR(768/1536)Semantic embedding vector
metadataJSONBType, topics, people, action items, source
created_atTIMESTAMPTZWhen captured
updated_atTIMESTAMPTZLast modified (auto-trigger)
created_byTEXTUser provenance for multi-dev teams

Metadata Fields

Extracted automatically by the LLM on capture:

type topics[] people[] action_items[] dates[] source project created_by supersedes

Indexes

IndexTypePurpose
thoughts_embedding_idxHNSWFast vector similarity search
thoughts_metadata_idxGINJSONB metadata containment queries
thoughts_created_at_idxB-treeDate range filtering

match_thoughts() Function

The core search RPC — combines vector similarity with a configurable threshold:

SELECT * FROM match_thoughts(
    query_embedding := '[0.1, 0.2, ...]'::vector,
    match_count := 10,
    match_threshold := 0.5
);

MCP Server

Open Brain's MCP server exposes 7 tools via the Model Context Protocol, Anthropic's open standard for AI-to-tool integration. Uses SSE transport over HTTP.

Tools

search_thoughts query, limit?, threshold?

Semantic vector search — finds thoughts by meaning, ranked by similarity score.

capture_thought content

Store a thought. Auto-generates embedding and extracts metadata (type, topics, people, action items) in parallel.

capture_thoughts thoughts[]

Batch capture — store multiple thoughts in one call.

list_thoughts type?, topic?, person?, days?

Filtered listing — browse by type, topic, person mentioned, or date range.

update_thought id, content

Edit a thought's content and regenerate its embedding.

delete_thought id

Remove a thought by ID.

thought_stats

Aggregate stats — total count, type distribution, top topics, top people mentioned.

Authentication

API key sent via x-brain-key header (preferred) or ?key= URL parameter.

# Auth is enforced on /sse connection only.
# /messages endpoint uses sessionId for implicit auth.
GET /sse?key=YOUR_64_CHAR_HEX_KEY     → SSE stream
POST /messages?sessionId=xxx           → JSON-RPC calls (no key needed)

Capture Pipeline

Multiple ways to feed thoughts into Open Brain — from AI tool conversations to Slack messages to bulk imports.

Capture Methods

MethodHowBest For
MCP Toolcapture_thought from any AI clientDaily workflow captures
REST APIPOST /memoriesScripts, automations, webhooks
Slack WebhookDM the Slack botQuick captures, mobile
Bulk ImportMigration scriptsNotion, Obsidian, Apple Notes, ChatGPT exports

Quick Capture Templates

Decision: "Decision: Using PostgreSQL with pgvector instead of Pinecone. Reason: self-hosted, lower cost."
Person Note: "Mike prefers async communication, Slack over email. Timezone: PST."
Insight: "Vector search with 768-dim nomic-embed-text is nearly as good as 1536-dim for short content."

Prompt Kit

Five core prompts covering the full lifecycle — from migration to daily capture to weekly review.

Prompt 1: Memory Migration

Import memories from Copilot, Claude, ChatGPT, or other AI platforms into Open Brain.

Prompt 2: Second Brain Migration

Migrate from Notion, Obsidian, Apple Notes, Google Keep, or Evernote.

Prompt 3: Open Brain Spark

System prompt that teaches your AI to proactively capture and search thoughts.

Prompt 4: Quick Capture Templates

Structured templates for decisions, meetings, person notes, and insights.

Prompt 5: The Weekly Review

Review your week's captures — surface patterns, stale tasks, and connections.

Daily Rhythm

☀️ Morning — Quick review of recent captures

💻 During work — Capture decisions and insights as they happen

🤝 After meetings — Debrief with capture templates

🌙 End of day — Save key takeaways

📊 Friday — Run the weekly review prompt

Supabase Deployment

Deploy to Supabase's free tier with Edge Functions. ~45 minutes, ~$0.10-$0.30/month.

Full step-by-step guide in 07-DEPLOYMENT.md.

  1. 1. Create Supabase project
  2. 2. Set up database (pgvector extension, thoughts table, indexes, match_thoughts function)
  3. 3. Get OpenRouter API key
  4. 4. Generate MCP access key (openssl rand -hex 32)
  5. 5. Set Supabase secrets
  6. 6. Deploy Edge Functions
  7. 7. Configure AI clients
  8. 8. Slack integration (optional)
  9. 9. Verify everything works

Docker Compose

The fastest path — PostgreSQL + pgvector + Ollama + API server in one command.

# Clone the repo
git clone https://github.com/srnichols/OpenBrain.git
cd OpenBrain

# Configure
cp .env.example .env
# Edit .env with your settings

# Start everything
docker compose up -d

# Verify
curl http://localhost:8000/health
curl http://localhost:8080/health

The Docker Compose stack includes PostgreSQL with pgvector pre-configured, Ollama for local embeddings (nomic-embed-text), and the Open Brain API + MCP server.

Kubernetes Deployment

Full homelab deployment with Tailscale networking, MetalLB, Ollama GPU, and monitoring integration.

Stack

ComponentTechnology
Container RuntimeK8s + containerd
DatabasePostgreSQL + pgvector (StatefulSet)
EmbeddingsOllama (nomic-embed-text, local GPU)
NetworkingMetalLB (LAN) + Tailscale (VPN + Funnel)
MonitoringPrometheus + Grafana + Loki
Cost$0/month (uses existing cluster resources)

Networking Options

OptionAccessURL Pattern
Tailscale MagicDNSTailnet onlyhttp://openbrain.your-tailnet.ts.net:8080
MetalLBLAN onlyhttp://192.168.x.x:8080
Tailscale FunnelPublic internethttps://openbrain.your-tailnet.ts.net
Cloudflare TunnelPublic (custom domain)https://brain.yourdomain.com

Important Notes

  • Session Affinity — Required for multi-replica SSE. Set sessionAffinity: ClientIP on the ClusterIP service.
  • Tailscale Funnel — The K8s Operator (v1.92.4) doesn't auto-configure Funnel serve. Manual tailscale funnel command needed inside the proxy pod.
  • Auth — API key is checked on /sse only. /messages uses sessionId for implicit auth.

Full guide in 09-SELF-HOSTED-K8S.md.

Implementation Roadmap

Four phases, each independently functional. Total time: 2-4 hours.

Phase 1

Foundation (45 min)

Database → Edge functions → MCP server → CLI test

Phase 2

Capture Pipeline (30 min)

Slack app → Ingest webhook → Confirmation replies

Phase 3

Knowledge Migration (30-60 min)

Memory migration from AI platforms + Second brain migration (Notion, Obsidian)

Phase 4

Optimization & Habits (30 min)

Multi-client setup + Daily habits + Weekly review

Success Criteria

📅 Week 1 — Deployed, 20+ thoughts captured

📅 Month 1 — 100+ thoughts, 2+ weekly reviews, established daily habit

📅 Month 3 — Full compounding, knowledge graph effect, AI tools feel contextual

Client Configuration

Copy-paste configs for every supported AI client.

Claude Desktop

Requires mcp-remote bridge (Claude Desktop doesn't support SSE natively).

File: %APPDATA%\Claude\claude_desktop_config.json (Windows) or ~/Library/Application Support/Claude/claude_desktop_config.json (macOS)

{
  "mcpServers": {
    "openbrain": {
      "command": "npx",
      "args": ["-y", "mcp-remote", "https://YOUR_HOST/sse?key=YOUR_KEY"]
    }
  }
}

Claude Code / VS Code Copilot

File: ~/.claude/settings.json

{
  "mcpServers": {
    "openbrain": {
      "type": "sse",
      "url": "http://YOUR_HOST:8080/sse?key=YOUR_KEY"
    }
  }
}

Cursor

File: .cursor/mcp.json

{
  "mcpServers": {
    "openbrain": {
      "url": "http://YOUR_HOST:8080/sse?key=YOUR_KEY",
      "transport": "sse"
    }
  }
}

ChatGPT

Enable Developer Mode → Add MCP connector with your Funnel/public URL. Set auth to "none" (key in URL).

REST API

Every MCP tool has a REST equivalent on port 8000. Useful for scripts, testing, and non-MCP integrations.

MethodEndpointPurpose
GET/healthHealth check
POST/memoriesCapture a thought
POST/memories/searchSemantic search
POST/memories/listFiltered listing
GET/statsAggregate statistics

Example: Capture

curl -X POST http://localhost:8000/memories \
  -H "Content-Type: application/json" \
  -d '{"content": "Decision: Using pgvector for embeddings"}'

Example: Search

curl -X POST http://localhost:8000/memories/search \
  -H "Content-Type: application/json" \
  -d '{"query": "database decisions", "limit": 5}'

Troubleshooting

"No active session. Connect to /sse first."

Cause: SSE connection and /messages POST hitting different pods (multi-replica without session affinity).

Fix: kubectl patch svc openbrain-api -n openbrain -p '{"spec":{"sessionAffinity":"ClientIP"}}'

mcp-remote ServerError / OAuth errors

Cause: /messages endpoint returning 401, triggering mcp-remote's OAuth flow.

Fix: Auth must only be enforced on /sse, not on /messages. The sessionId proves authentication.

Claude Desktop doesn't show OpenBrain tools

Check: Verify %APPDATA%\Claude\claude_desktop_config.json has the mcpServers entry. Claude Desktop may overwrite on launch.

Fix: Fully quit (system tray → Quit) and relaunch. Check logs at %APPDATA%\Claude\logs\mcp-server-openbrain.log.

Search returns no results

Check: Run thought_stats. Under 20-30 entries = sparse data, not broken.

Fix: Lower similarity threshold (try 0.3 instead of 0.5). Test with exact captured terminology.

Tailscale Funnel not serving

Cause: K8s Operator v1.92.4 doesn't auto-configure Funnel serve from the annotation.

Fix: Run tailscale funnel --bg --https=443 http://openbrain-api.openbrain.svc.cluster.local:8080 inside the proxy pod. Re-run after pod restarts.