{
  "markdown": "<p align=\"center\">\n  <img src=\"images/cairn-readme-banner.png\" alt=\"Cairn — persistent memory for agents and humans\" width=\"800\">\n</p>\n\n<p align=\"center\">\n  <a href=\"https://github.com/jasondostal/cairn-mcp/releases\"><img src=\"https://img.shields.io/github/v/release/jasondostal/cairn-mcp?style=flat-square&color=blue\" alt=\"Release\"></a>\n  <a href=\"LICENSE\"><img src=\"https://img.shields.io/github/license/jasondostal/cairn-mcp?style=flat-square\" alt=\"License\"></a>\n  <img src=\"https://img.shields.io/badge/MCP-compatible-brightgreen?style=flat-square\" alt=\"MCP\">\n  <img src=\"https://img.shields.io/badge/PostgreSQL-16%20%2B%20pgvector-336791?style=flat-square\" alt=\"PostgreSQL\">\n</p>\n\n> [!IMPORTANT]\n> **Cairn is retired, and this repository is archived (read-only).**\n> Its successor is **[rill](https://github.com/jasondostal/rill)** — a faster, leaner,\n> MCP-native memory server written in Go that learned from everything Cairn got right\n> (and the things it got wrong). Cairn was the first; rill is where the work continues.\n> This repo stays up as a read-only archive — explore it, fork it, but new development\n> lives in rill.\n\n---\n\nA self-hosted persistent memory platform for AI agents and humans. Store something once, find it later, across sessions, across projects. Four containers. `docker compose up`. Done.\n\nCairn is the memory brain. Your agent runtime handles execution — Cairn handles knowing. What decisions were made, what facts are known, what patterns emerge across projects.\n\nIt's built for the systems person. The curious. The t-shaped. The ones who need a memory that works the way they do, across everything, all at once.\n\n## Quick Start\n\n### 1. Pull and run\n\n```bash\ncurl -O https://raw.githubusercontent.com/jasondostal/cairn-mcp/main/docker-compose.yml\ndocker compose up -d\n```\n\nFour containers start:\n- **cairn** on port 8000 (MCP server + REST API)\n- **cairn-ui** on port 3000 (web dashboard)\n- **cairn-db** (PostgreSQL 16 + pgvector)\n- **cairn-graph** (Neo4j 5, knowledge graph)\n\nMigrations run on first boot. Ready in about a minute.\n\n### 2. Connect your IDE\n\nAdd this to your MCP config:\n\n```json\n{\n  \"mcpServers\": {\n    \"cairn\": {\n      \"type\": \"http\",\n      \"url\": \"http://localhost:8000/mcp\"\n    }\n  }\n}\n```\n\nWhere that goes:\n\n| IDE | Config file |\n|-----|------------|\n| **Claude Code** | `.mcp.json` in your project root |\n| **Cursor** | `.cursor/mcp.json` |\n| **Windsurf** | `.windsurf/mcp.json` |\n| **Cline** | MCP settings panel in VS Code |\n| **Continue** | `.continue/config.yaml` |\n| **PiClaw** | `.pi/mcp.json` |\n\nOr run the setup wizard — it walks you through everything: LLM backend, database, embeddings, auth, and IDE configuration:\n\n```bash\ngit clone https://github.com/jasondostal/cairn-mcp.git && ./cairn-mcp/scripts/setup.sh\n```\n\nPick a tier (local dev, recommended, enterprise, or custom) and the wizard collects only what that tier needs. Supports `--dry-run` and `--non-interactive` for CI.\n\n### 3. Use it\n\nTell your agent to remember something:\n\n> \"Remember that we chose PostgreSQL for storage because it handles hybrid search without a separate vector DB.\"\n\nSearch for it later:\n\n> \"What did we decide about the storage layer?\"\n\nThat's it. 11 tools available. The ones you'll use most:\n\n| Tool | What it does |\n|------|-------------|\n| `store` | Save a memory with auto-enrichment. Supports `event_at` and `valid_until` for bi-temporal tracking |\n| `search` | Find memories (vector + keyword + recency + tags). Temporal filters: `as_of`, `event_after`, `event_before` |\n| `recall` | Get full content for specific memory IDs |\n| `orient` | Boot a session with rules, recent activity, beliefs, and open work |\n| `rules` | Load behavioral guardrails (global or per-project) |\n| `beliefs` | Durable epistemic state — crystallize, challenge, retract knowledge with confidence tracking |\n| `work_items` | Create, claim, and complete tasks with dependencies and gates |\n| `working_memory` | Capture ephemeral thoughts — hypotheses, questions, tensions — with salience decay |\n| `projects` | Manage project docs (briefs, PRDs, plans) |\n| `code_query` | Structural queries: dependents, impact, callers, callees, dead code, complexity, hotspots |\n| `arch_check` | Validate architecture boundary rules against imports |\n\nThe rest: `modify`, `insights`, `think`, `status`, `consolidate`, `ingest`.\n\n## What's in the box\n\n**Memory that persists across sessions.** Your agent makes a decision at 2am. Next morning, different session, it finds that decision. That's the core. Bi-temporal tracking separates when something happened (`event_at`) from when you learned it (`created_at`). Memories that go unaccessed decay naturally; important ones are protected. Related memories get consolidated into higher-order insights automatically.\n\n**Beliefs.** Durable epistemic state — knowledge held with confidence. Crystallize hypotheses into beliefs, challenge them with counter-evidence, retract them when wrong. Beliefs surface in session boot alongside rules and memories, giving agents a clear picture of what the organization knows and how confident it is.\n\n**Search that fuses signals.** Vector similarity, recency, access frequency, keyword matching, and tag overlap blended via Reciprocal Rank Fusion. Filter by project, type, or time range. Temporal queries: \"what did we know as of Tuesday?\" via `as_of`, \"what happened last week?\" via `event_after`/`event_before`.\n\n**Knowledge graph.** Entities and facts get extracted into a Neo4j graph that connects memories through shared people, places, projects, and concepts. Optional, but powerful when you're working across domains.\n\n**Thinking sequences.** Structured deliberation — start with a goal, add thoughts (observations, hypotheses, analysis, alternatives), conclude. Both humans and agents contribute. The exploration itself becomes searchable memory.\n\n**Work management.** Hierarchical work items with dependency tracking, gates that pause for human decisions, and activity logging. Experimental — evolving as we learn what works.\n\n**Web dashboard.** Browse memories with OKLCH-colored toggle filters, score gradient bars, and shareable URL state. Explore the knowledge graph and entity relationships. View analytics, manage work items. Port 3000.\n\n<p align=\"center\">\n  <img src=\"images/cairn-dashboard.jpg\" alt=\"Cairn dashboard with memory growth and token usage\" width=\"700\">\n  <br>\n  <sub>Memory growth by type, token usage tracking, and the full nav.</sub>\n</p>\n\n**Code intelligence.** A standalone worker indexes codebases with tree-sitter (30 languages) and builds a code graph in Neo4j. The server queries the graph without ever touching source files. Ask structural questions — \"what depends on this file?\", \"who calls this function?\", \"what's the blast radius?\" — and get answers from the code graph. Call graph extraction, cyclomatic complexity, dead code detection. Enforce architecture boundaries with YAML rules. Works across projects.\n\n<details>\n<summary>Supported languages (30)</summary>\n\n| Category | Languages |\n|---|---|\n| Systems | C, C++, Rust, Go, Zig |\n| JVM | Java, Scala, Kotlin, Groovy |\n| .NET | C# |\n| Scripting | Python, Ruby, PHP, Lua, Bash |\n| Web | TypeScript/TSX, HTML, CSS |\n| Apple | Swift, Objective-C |\n| ML/Scientific | OCaml, MATLAB |\n| Config & Data | JSON, YAML, TOML, HCL (Terraform), Dockerfile, Makefile, SQL, Markdown |\n\n</details>\n\n**Multi-user authentication and RBAC.** Off by default, zero to enterprise in one command. `./scripts/setup.sh` includes auth configuration, or run `./scripts/setup-auth.sh` standalone. Auth mode selection (none / local JWT / OIDC SSO), JWT secret generation, OIDC provider validation. Personal Access Tokens for machine clients, stdio identity for MCP. Three roles, project-level scoping, first-user-becomes-admin. Groups with OIDC sync. See the **[Authentication Guide](docs/authentication.md)**.\n\n**Disaster recovery.** Cron-friendly scripts for PostgreSQL dump and Neo4j graph export with configurable retention. Tested restore procedures with migration safety checks. See the **[Backup Guide](docs/backup.md)**.\n\n## Do I need an LLM?\n\nNo. Store, search, recall, and rules work without one. You lose auto-enrichment (summaries, tags, importance scoring), knowledge extraction, and thinking.\n\nIf you want enrichment:\n\n| Backend | Setup |\n|---------|-------|\n| **Ollama** (default) | Install [Ollama](https://ollama.com), pull a model. Cairn connects to `host.docker.internal:11434`. |\n| **AWS Bedrock** | Set `CAIRN_LLM_BACKEND=bedrock`, export AWS creds. |\n| **Google Gemini** | Set `CAIRN_LLM_BACKEND=gemini`, add `CAIRN_GEMINI_API_KEY`. Free tier available. |\n| **OpenAI-compatible** | Set `CAIRN_LLM_BACKEND=openai`, add key. Works with OpenAI, Groq, Together, LM Studio, vLLM. |\n\n## Configuration\n\nAll via environment variables. The ones that matter:\n\n| Variable | Default | What it does |\n|----------|---------|-------------|\n| `CAIRN_PROFILE` | *(empty)* | Preset: `vector`, `enriched`, `knowledge`, `enterprise`. Sets capability defaults. |\n| `CAIRN_LLM_BACKEND` | `ollama` | LLM provider: `ollama`, `bedrock`, `gemini`, `openai` |\n| `CAIRN_DB_PASS` | `cairn-dev-password` | Database password. Change this for anything beyond local. |\n| `CAIRN_AUTH_ENABLED` | `false` | Multi-user authentication (JWT, PATs, OIDC/SSO) |\n| `CAIRN_AUTH_JWT_SECRET` | *(empty)* | JWT signing secret (required when auth enabled) |\n| `CAIRN_OIDC_ENABLED` | `false` | OIDC/SSO integration (any OIDC-compliant provider) |\n| `CAIRN_MCP_OAUTH_ENABLED` | `false` | OAuth2 Authorization Server for remote MCP clients (Claude.ai, mobile) |\n| `CAIRN_GRAPH_BACKEND` | *(disabled)* | Set to `neo4j` to enable knowledge graph |\n| `CAIRN_KNOWLEDGE_EXTRACTION` | `false` | Entity/statement extraction on store |\n| `CAIRN_EMBEDDING_BACKEND` | `local` | `local` (MiniLM, 384-dim) or `bedrock` (Titan V2, 1024-dim) |\n| `CAIRN_INGEST_DIR` | `/data/ingest` | Staging directory for file-path ingestion of large documents |\n| `CAIRN_CODE_DIR` | `/data/code` | Root directory for code intelligence indexing (mount codebases here) |\n\nFull reference is in [docker-compose.yml](docker-compose.yml). Every variable has a sensible default.\n\n## Authentication\n\nOff by default. The fastest way to enable it is through the setup wizard:\n\n```bash\n./scripts/setup.sh          # includes auth as step 2\n./scripts/setup-auth.sh     # or run auth setup standalone\n```\n\nThree modes — no auth, local JWT, or OIDC/SSO. Generates secrets, validates\nyour identity provider's discovery endpoint, writes `.env`. Provider-specific\nURL hints for Authentik, Keycloak, Auth0, Okta, and Azure AD. Both scripts\nsupport `--dry-run` and `--non-interactive` for CI.\n\nFirst user to register becomes admin. Role-based access control enforces\npermissions across REST API, MCP HTTP, and the web UI. Personal Access Tokens\nfor machine clients, groups with OIDC sync.\n\nSee the **[Authentication Guide](docs/authentication.md)** for the full reference\ncovering all auth modes, OIDC provider configuration, and MCP client examples.\n\n> **Security note:** Cairn's auth system is functional and production-tested but\n> has not been independently audited. For network-exposed deployments, add TLS\n> termination and network-level access controls.\n\n## Remote MCP Access (Claude.ai, Mobile)\n\nConnect Cairn to Claude.ai, the Claude mobile app, or any OAuth2-capable MCP client. Cairn acts as an OAuth2 Authorization Server, delegating user authentication to your existing OIDC identity provider.\n\n**Prerequisites:** Auth enabled (`CAIRN_AUTH_ENABLED=true`), OIDC configured (`CAIRN_OIDC_ENABLED=true`), and a public URL set (`CAIRN_PUBLIC_URL`).\n\n**Enable it:**\n\n```bash\nCAIRN_MCP_OAUTH_ENABLED=true\n```\n\n**Connect from Claude.ai:**\n\n1. Go to Claude.ai Settings > Integrations > Add custom MCP\n2. Enter your Cairn URL: `https://your-cairn-domain.com/mcp`\n3. Claude.ai discovers the OAuth2 endpoints automatically\n4. You'll be redirected to your identity provider to log in\n5. After login, Claude.ai has full access to your Cairn MCP tools\n\nThe OAuth2 flow uses Authorization Code + PKCE with Dynamic Client Registration (RFC 7591). If your identity provider supports SSO sessions, the auth redirect is invisible after the first login.\n\nSee the **[Remote MCP Guide](docs/remote-mcp.md)** for reverse proxy configuration, security hardening, and troubleshooting.\n\n## Code Intelligence\n\nCode intelligence runs as a **standalone worker** that indexes source code and writes to Neo4j. The cairn server queries the graph but never touches source files directly. This separation means indexing doesn't block the event loop and the worker can run on the machine where code lives.\n\n**Requirements:** Neo4j (the `cairn-graph` service in docker-compose) must be running.\n\n### Quick start\n\n```bash\n# Index a single project (one-shot, no watching)\npython -m cairn.code \\\n  --watch /path/to/your/repo:your-project \\\n  --neo4j-uri bolt://localhost:7687 \\\n  --cairn-url http://localhost:8000 \\\n  --no-watch\n\n# Index and watch for changes (long-running)\npython -m cairn.code \\\n  --watch /home/user/working/myproject:myproject \\\n  --watch /home/user/working/other:other \\\n  --neo4j-uri bolt://my-server:7687\n```\n\n### Environment variables\n\n| Variable | Default | What it does |\n|----------|---------|-------------|\n| `CAIRN_NEO4J_URI` | `bolt://localhost:7687` | Neo4j bolt URI |\n| `CAIRN_NEO4J_USER` | `neo4j` | Neo4j username |\n| `CAIRN_NEO4J_PASSWORD` | `cairn-dev-password` | Neo4j password |\n| `CAIRN_API_URL` | `http://localhost:8000` | Cairn server URL (for project ID resolution) |\n| `CAIRN_API_KEY` | *(empty)* | API key if cairn auth is enabled |\n| `CAIRN_CODE_PROJECTS` | *(empty)* | Comma-separated `project=path` pairs (alternative to `--watch`) |\n| `CAIRN_CODE_WATCH` | `true` | Enable filesystem watching after initial index |\n| `CAIRN_CODE_FORCE` | `false` | Force re-index even if content hash unchanged |\n\n### Docker / remote codebases\n\nMount source code into the cairn container and set `CAIRN_CODE_DIR`:\n\n```yaml\n# docker-compose.yml\nvolumes:\n  - /path/to/code:/data/code:ro   # read-only mount\nenvironment:\n  CAIRN_CODE_DIR: /data/code\n```\n\nOr run the worker on the code host and point it at your cairn + Neo4j instances:\n\n```bash\nCAIRN_NEO4J_URI=bolt://cairn-host:7687 \\\nCAIRN_API_URL=http://cairn-host:8000 \\\nCAIRN_CODE_PROJECTS=\"myproject=/home/user/code/myproject\" \\\npython -m cairn.code\n```\n\n### What gets indexed\n\n- **Symbols:** functions, classes, methods, interfaces, enums, React components/hooks\n- **Relationships:** `IMPORTS` (file-level), `CALLS` (function-level), `CONTAINS` (parent-child)\n- **Metadata:** signatures, docstrings, cyclomatic complexity, line numbers, content hashes\n- **Languages:** Python, TypeScript/TSX, and 28 more (C, Rust, Go, Java, Ruby, etc.)\n\n### Query examples (via `code_query` MCP tool)\n\n| Action | What it does |\n|--------|-------------|\n| `dependents` | Files that import the target |\n| `dependencies` | Files the target imports |\n| `callers` | Functions that call the target |\n| `callees` | Functions the target calls |\n| `call_chain` | Trace call paths between two functions |\n| `dead_code` | Functions with zero callers |\n| `complexity` | Rank functions by cyclomatic complexity |\n| `impact` | Blast radius — transitive dependents |\n| `hotspots` | PageRank — structurally important files |\n| `search` | Fulltext search over symbol names and docstrings |\n\n## Architecture\n\n```\nMCP clients (Claude Code, Cursor, PiClaw)    REST clients (web UI, scripts)\n        |                                            |\n        | MCP (stdio or HTTP)                        | REST API\n        |                                            |\n+-------v--------------------------------------------v--------+\n|  cairn.server (MCP tools)     cairn.api (FastAPI endpoints) |\n|                                                             |\n|  core: memory, search, enrichment, extraction, clustering   |\n|        working memory, beliefs, thinking, work items        |\n|                                                             |\n|  embedding: local (MiniLM) or Bedrock (Titan V2)            |\n|  llm: Ollama, Bedrock, Gemini, OpenAI-compatible            |\n+------+----------------------------------------------+------++\n       |                                              |       |\n       v                                              v       |\n  PostgreSQL 16 + pgvector                    Neo4j 5 <-------+\n                                             (optional)       |\n                                                ^             |\n  code worker (python -m cairn.code)            |             |\n  tree-sitter parsing, call graph      --------+             |\n  watches filesystem for changes                             |\n```\n\n## Benchmark\n\nTested against [LoCoMo](https://github.com/snap-stanford/locomo), a long-conversation memory benchmark with 1,986 questions across five categories.\n\n| System | Score | LLM |\n|--------|-------|-----|\n| **Cairn** | **81.6%** | Llama-3.3-70B |\n| Human baseline | 87.9% | — |\n| Letta/MemGPT | 74.0% | GPT-4o-mini |\n| Mem0 | 66.9% | GPT-4o |\n\nTest configuration: Titan V2 embeddings (Bedrock, 1024-dim), episodic ingestion (raw turns + two-pass fact extraction), Search V2 with graph-primary retrieval, type routing, cross-encoder reranking, LLM-as-judge evaluation. Full results and methodology in [`eval/`](eval/).\n\n## Development\n\n```bash\ngit clone https://github.com/jasondostal/cairn-mcp.git\ncd cairn-mcp\ncp .env.example .env\ndocker compose up -d --build\n```\n\n## Status\n\nCairn is under active development. It's a real system used daily in production, and it's evolving as I learn what actually works for agent memory. Migrations handle schema changes. If something breaks, [open an issue](https://github.com/jasondostal/cairn-mcp/issues).\n\n## License\n\n[GNU General Public License v3.0](LICENSE)\n",
  "bytes": 17882,
  "sha": "2a1ea627de0d0653009c104e113835faa76e47644eeb1c7542a98bce90766db9",
  "repo_slug": "jasondostal/cairn-mcp",
  "fonte": "repo",
  "truncated": false,
  "api": "https://agentalog.com/api/listings/mcp_io_github_jasondostal_cairn_mcp_ac043eaf/readme"
}