{
  "markdown": "# Kairn\n\n\n![kairn](https://raw.githubusercontent.com/primeline-ai/kairn/main/assets/hero.png)\n\n> Context-aware knowledge engine for AI assistants.\n\n<!-- mcp-name: io.github.primeline-ai/kairn -->\n\n**Status: pre-1.0.** In daily use since February 2026, with 722 tests (see\n[Development](#development)) and a published\n[LongMemEval-S benchmark](#benchmarks). Interfaces may still change between\nreleases until 1.0. Feedback and issues welcome.\n\nOther tools give your AI a memory. **Kairn** gives it a knowledge graph with intelligent context routing. It knows what to load, when to load it, and how much - so your AI stays focused, not overwhelmed.\n\n```bash\npip install kairn-ai\nkairn init ~/brain\nkairn serve ~/brain\n```\n\nAdd it to Claude Code in one line:\n\n```bash\nclaude mcp add kairn -- kairn serve ~/brain\n```\n\nOr install it as a one-click bundle, no Python setup required: download the\n`.mcpb` file from the [latest release](https://github.com/primeline-ai/kairn/releases/latest)\nand open it with a bundle-aware app such as Claude Desktop.\n\nFor other clients, see [Quick Start](#quick-start) below. New to Kairn? Jump to [First 5 Minutes](#first-5-minutes).\n\n## Install routes\n\n| Route | Who it is for | Command |\n|---|---|---|\n| PyPI | anyone with Python, and every MCP client | `pip install kairn-ai` |\n| MCP Bundle (`.mcpb`) | Claude Desktop and other bundle-aware apps; no Python install needed | download from [Releases](https://github.com/primeline-ai/kairn/releases) and open it |\n| Claude Code | one line, uses the PyPI install | `claude mcp add kairn -- kairn serve ~/brain` |\n\nThe bundle carries no Kairn source of its own. It declares `kairn-ai` as a\ndependency and the host resolves it with `uv`, so a bundle install and a\n`pip install` run identical code. Where the database lives is configurable when\nyou install the bundle; it defaults to `~/.kairn` and never leaves your machine.\n\n## Why Kairn?\n\nEvery AI conversation starts from scratch. Previous insights, decisions, and patterns - gone. Existing memory tools store flat key-value pairs that can't represent relationships or surface the *right* context at the *right* time.\n\nKairn is different:\n\n- **Context Router + Progressive Disclosure** - Automatically loads relevant subgraphs based on keywords, starting with summaries and drilling into details only when needed. No other tool does this.\n- **Knowledge Graph with FTS5** - Not flat storage. Typed relationships (`depends-on`, `resolves`, `causes`) between nodes with provenance tracking and full-text search across everything.\n- **Experience Decay + Auto-Promotion** - Experiences lose relevance over time (biological decay model). Frequently-accessed experiences auto-promote to permanent knowledge. Your AI naturally forgets what doesn't matter.\n- **22 MCP Tools** - Works with Claude Desktop, Cursor, VS Code, Windsurf, and any MCP client. Includes `kn_judge` for 5-verb relationship judgments and `kn_doctor` for read-only health diagnostics.\n- **Per-Workspace Isolation** - Each workspace is its own isolated SQLite store. JWT auth and role-based access control (owner / maintainer / contributor / reader) ship for team deployments.\n\n## Quick Start\n\n### Claude Desktop\n\nAdd to `~/Library/Application Support/Claude/claude_desktop_config.json`:\n\n```json\n{\n  \"mcpServers\": {\n    \"kairn\": {\n      \"command\": \"kairn\",\n      \"args\": [\"serve\", \"~/brain\"]\n    }\n  }\n}\n```\n\n### Cursor\n\nAdd to `.cursor/mcp.json`:\n\n```json\n{\n  \"mcpServers\": {\n    \"kairn\": {\n      \"command\": \"kairn\",\n      \"args\": [\"serve\", \"~/brain\"],\n      \"env\": {\n        \"KAIRN_LOG_LEVEL\": \"WARNING\"\n      }\n    }\n  }\n}\n```\n\n### VS Code\n\nAdd to `.vscode/mcp.json`:\n\n```json\n{\n  \"servers\": {\n    \"kairn\": {\n      \"type\": \"stdio\",\n      \"command\": \"kairn\",\n      \"args\": [\"serve\", \"~/brain\"]\n    }\n  }\n}\n```\n\n### Windsurf\n\nAdd to `~/.codeium/windsurf/mcp_config.json`:\n\n```json\n{\n  \"mcpServers\": {\n    \"kairn\": {\n      \"command\": \"kairn\",\n      \"args\": [\"serve\", \"~/brain\"]\n    }\n  }\n}\n```\n\nRestart your editor. Kairn's 22 tools appear in the MCP section.\n\n## First 5 Minutes\n\nA guided first run, end to end:\n\n```bash\npip install kairn-ai\nkairn init ~/brain              # creates the workspace + database\n```\n\nAdd the one-liner from above (or your client's Quick Start snippet), then restart the client. Once connected, ask your assistant to remember something:\n\n> \"Remember that we chose Postgres over SQLite for the analytics service because we needed concurrent writers.\"\n\nThat calls `kn_learn` under the hood and returns a JSON envelope like this (captured from a real run, via `kairn learn`, the CLI mirror of the tool):\n\n```json\n{\"_v\": \"1.0\", \"stored_as\": \"node\", \"node_id\": \"002d9c22\", \"experience_id\": \"d0710c2f\", \"type\": \"decision\", \"confidence\": \"high\", \"namespace\": \"knowledge\", \"candidates\": []}\n```\n\nStart a **new** session and ask it to recall the same thing - that calls `kn_recall` and surfaces what you just stored, no re-explaining required:\n\n```json\n{\"_v\": \"1.0\", \"count\": 2, \"results\": [\n  {\"source\": \"node\", \"id\": \"002d9c22\", \"name\": \"Decision: we chose Postgres over SQLite for the analytics service beca\", \"type\": \"learned_decision\", \"description\": \"we chose Postgres over SQLite for the analytics service because we needed concurrent writers\", \"relevance\": 1.0, \"relevance_kind\": \"match\"},\n  {\"source\": \"experience\", \"id\": \"d0710c2f\", \"type\": \"decision\", \"content\": \"we chose Postgres over SQLite for the analytics service because we needed concurrent writers\", \"confidence\": \"high\", \"relevance\": 1.0, \"relevance_kind\": \"recency\"}\n]}\n```\n\n`kn_learn` stored both a permanent graph node and a decaying experience (high confidence does both, see [Confidence routing](#decay-model)); `kn_recall` found both from a three-word topic.\n\n**Read `relevance_kind` before you read `relevance`.** Both rows above show `1.0` and they do not mean the same thing. `match` is lexical match strength (bm25); the experience's `recency` is time-decay - it is 1.0 because the row was created seconds ago, not because it matched well. A third value, `similarity`, is embedding cosine on the semantic-recall path, and `unscored` marks a row the surface had no ranking for and filled in with a constant. The numbers are not comparable across kinds, so do not sort a mixed result set on `relevance` alone. Same caution for `min_relevance` on `kn_recall`: it gates nodes on match strength and experiences on recency, one number against two scales. On `kn_memories` and `kn_prune`, which see experiences only, it is recency - and on `kn_prune` it **deletes**.\n\nRun `kairn status ~/brain` any time as a smoke test - if it prints a JSON stats block (nodes/edges/experiences counts), the workspace is healthy. Want a scripted tour of every core feature instead of doing it by hand? Run `kairn demo ~/brain` - it walks through node creation, querying, experience saving, learning, recall, and context in about 30 seconds.\n\n### Which tool when\n\n22 tools is a lot to hold in your head on day one. Most sessions only need these:\n\n| You want to... | Use | Why |\n|---|---|---|\n| Remember something new (a decision, gotcha, pattern, solution) | `kn_learn` | Default entry point - auto-routes to a permanent node (high confidence) or a decaying experience (medium/low), no need to decide yourself |\n| Capture a stated user preference the moment it is expressed | `kn_preference` | Dedicated preference write path - you (the calling model) state the preference as one explicit sentence; stored with the longest half-life of any type |\n| Add a permanent named concept you already know is durable | `kn_add` | Skips decay entirely - for structural knowledge, not day-to-day experience |\n| Log a one-off experience with explicit confidence/decay control | `kn_save` | Lower-level primitive `kn_learn` wraps - reach for it when you want to set confidence/decay yourself |\n| Search the permanent knowledge graph by text, type, tags, or namespace | `kn_query` | You're looking for nodes, not decaying experiences |\n| Search saved experiences, ranked by relevance and decay | `kn_memories` | You're looking for experience content (solutions, gotchas, workarounds), not graph nodes |\n| Surface everything relevant to a topic in one call | `kn_recall` (flat list) or `kn_context` (subgraph, progressive disclosure: summary first, full detail on demand) | You don't know yet whether the answer is a node or an experience - let Kairn search both |\n\nEverything else (`kn_crossref`, `kn_related`, `kn_connect`, `kn_judge`, `kn_project`/`kn_projects`/`kn_log`, `kn_idea`/`kn_ideas`, `kn_promote_pending`, `kn_prune`, `kn_remove`, `kn_status`, `kn_doctor`) is advanced usage - see the full [22 Tools](#22-tools-kn_-prefix) reference below once you're past the basics.\n\n## 22 Tools (kn_ prefix)\n\nAll tools follow MCP protocol with JSON responses.\n\n### Graph (6)\n\n| Tool | Description |\n|------|-------------|\n| `kn_add` | Add node to knowledge graph |\n| `kn_connect` | Create typed edge between nodes (lax-mode vocabulary) |\n| `kn_judge` | Record 5-verb judgment edge (strict mode: `conflicts_with` / `supersedes` / `compatible` / `scoped` / `related`) |\n| `kn_query` | Search by text, type, tags, namespace |\n| `kn_remove` | Soft-delete node or edge (undo-safe) |\n| `kn_status` | Graph stats, health, system overview |\n\n### Project Memory (3)\n\n| Tool | Description |\n|------|-------------|\n| `kn_project` | Create or update project |\n| `kn_projects` | List projects, switch active |\n| `kn_log` | Log progress or failure entry |\n\n### Experience Memory (5)\n\n| Tool | Description |\n|------|-------------|\n| `kn_save` | Save experience with decay |\n| `kn_preference` | Capture a stated user preference at utterance time (longest half-life) |\n| `kn_memories` | Decay-aware experience search |\n| `kn_prune` | Remove expired experiences |\n| `kn_promote_pending` | Promote high-access experiences to permanent nodes |\n\n### Ideas (2)\n\n| Tool | Description |\n|------|-------------|\n| `kn_idea` | Create or update idea |\n| `kn_ideas` | List/filter ideas by status, category |\n\n### Intelligence (5)\n\n| Tool | Description |\n|------|-------------|\n| `kn_learn` | Store knowledge with confidence routing |\n| `kn_recall` | Surface relevant past knowledge |\n| `kn_crossref` | Find similar past solutions in the current workspace |\n| `kn_context` | Keywords → relevant subgraph with progressive disclosure |\n| `kn_related` | Graph traversal (BFS) to find connected nodes |\n\n### Diagnostic (1)\n\n| Tool | Description |\n|------|-------------|\n| `kn_doctor` | Read-only health checks (lock mode, FTS5 parity, promotion backlog, namespace sprawl, orphan edges) - returns structured envelope with per-check verdicts and roll-up summary |\n\n## Resources & Prompts\n\n**Resources** (read-only context for MCP clients):\n- `kn://status` - Graph overview, active project\n- `kn://projects` - All projects with recent progress\n- `kn://memories` - Recent high-relevance experiences\n\n**Prompts** (session management):\n- `kn_bootup` - Load active project, recent progress, and top memories (session start)\n- `kn_review` - Summarize session and suggest next steps (session end)\n\n## How It Works\n\n### Architecture\n\n```\nAny MCP Client (Claude, Cursor, VS Code)\n        │\n        ▼ MCP Protocol (stdio)\nFastMCP Server (22 tools)\n        │\n   ┌────┼────┐\n   ▼    ▼    ▼\nGraph  Memory  Intelligence\nEngine Engine  Layer\n   │    │      │\n   └────┼──────┘\n        ▼\n   SQLite + FTS5\n   (per-workspace)\n```\n\n### Decay Model\n\nExperiences decrease in relevance exponentially:\n\n```\nrelevance(t) = initial_score × e^(-decay_rate × days)\n```\n\n| Type | Half-life | Notes |\n|------|-----------|-------|\n| solution | 120 days | Stable, durable |\n| pattern | 90 days | Architectural knowledge |\n| decision | 100 days | Context-dependent |\n| workaround | 40 days | Temporary fixes fade fast |\n| gotcha | 70 days | Tricky pitfalls stay relevant |\n| preference | 180 days | Durable user preferences - initial estimate, not yet tail-calibrated |\n\nHalf-lives are calibrated against the real access tail of a production experience store, not guessed (one exception: `preference` is a new type with no access history yet, so its value is a documented initial estimate until real data accumulates).\n\n**Confidence routing** via `kn_learn`:\n- `high` → Permanent node + experience (no decay)\n- `medium` → Experience with 2× decay\n- `low` → Experience with 4× decay\n- Auto-promotion: 5+ accesses → permanent node\n- Node access tracking: `kn_recall`, `kn_context`, and `kn_crossref` log which nodes were accessed, feeding the decay and promotion pipeline\n\n## Benchmarks\n\n![Kairn benchmark scorecard: 56.2% overall on LongMemEval-S, 500 questions scored, per-category accuracy from 91.4% down to a published 10.0% weak cell](https://raw.githubusercontent.com/primeline-ai/kairn/main/assets/benchmark-scorecard.png)\n\nKairn scores **56.2% overall on LongMemEval-S** (500/500 questions scored,\nGPT-4o reader + judge, single run, 0 errors). These are the real per-category\nnumbers, including the bad ones - each red cell links to its diagnosis:\n\n| Category | n | Accuracy | Diagnosis |\n|----------|----|----------|-----------|\n| single-session-user | 70 | 91.4% | - |\n| single-session-assistant | 56 | 83.9% | - |\n| knowledge-update | 78 | 70.5% | - |\n| temporal-reasoning | 133 | 42.9% | [why](https://github.com/primeline-ai/kairn/blob/main/BENCHMARKS.md#temporal-reasoning-429) |\n| multi-session | 133 | 41.4% | [why](https://github.com/primeline-ai/kairn/blob/main/BENCHMARKS.md#multi-session-414) |\n| single-session-preference | 30 | 10.0% | [why](https://github.com/primeline-ai/kairn/blob/main/BENCHMARKS.md#single-session-preference-100) |\n\nThe 500 questions include 30 abstention variants (the right answer is to\ndecline); they are counted inside their categories above and scored\nseparately: Kairn declines correctly on **96.7%** of them.\n\nRecall latency is ~1.4 ms per query (FTS5, in-process, no network). Protocol,\nhonesty notes, and reproduction steps: [BENCHMARKS.md](https://github.com/primeline-ai/kairn/blob/main/BENCHMARKS.md).\n\nThis scorecard stays current: every release that touches recall re-publishes\nthese numbers, and a weak cell stays on the board until the number actually\nmoves. No cherry-picked runs, no hidden categories.\n\n## CLI\n\n```bash\nkairn init <path>              # Initialize workspace\nkairn serve <path>             # Start MCP server (stdio)\nkairn status <path>            # Graph stats\nkairn demo <path>              # Interactive tutorial\nkairn benchmark <path>         # Local performance benchmarks (latency, not LongMemEval)\nkairn token-audit <path>       # Audit tool token usage\nkairn import git <path> <repo>...  # Import git commit history (zero-LLM, offline)\nkairn import claude-code <path>    # Import Claude Code session history (zero-LLM, offline)\n```\n\n### Importing your history\n\n`kairn import git <workspace> <repo>...` backfills a Kairn store from one or\nmore local git repositories at $0 - no LLM calls, no network calls. Conventional-commit\nprefixes map to experience types (`fix:` -> solution, `feat:`/`refactor:`/`perf:` -> pattern,\neverything else -> decision); merge commits are skipped. Imported experiences land in a\ndedicated `imported-git` namespace, separate from your organic knowledge, so they're always\ndistinguishable and a bad import is fully reversible.\n\n```bash\nkairn import git ~/brain ~/code/my-project --dry-run   # Preview first\nkairn import git ~/brain ~/code/my-project              # Then import for real\nkairn import git ~/brain ~/code/proj-a ~/code/proj-b --since 2026-01-01\n```\n\nIdempotent - re-running only imports commits that weren't already imported, so it's safe\nto run again as a repo's history grows.\n\n#### Claude Code transcripts\n\n`kairn import claude-code <workspace>` backfills your Kairn store from your existing\nClaude Code session history, also at $0 and fully offline. With no `--root` given it scans\n`~/.claude/projects` (and `~/.claude-secondary/projects` if you have a second account);\n`--root PATH` is a repeatable override. Imported experiences land in their own\n`imported-claude-code` namespace, so they stay distinct from your organic knowledge and a\nbad import is reversible.\n\n```bash\nkairn import claude-code ~/brain --dry-run              # Review exactly what would be stored\nkairn import claude-code ~/brain                        # Import (prompts once before writing)\nkairn import claude-code ~/brain --root ~/other/projects --since 2026-01-01 --yes\n```\n\n**What gets stored (coarse mode):** one experience per session - the session's title plus\nyour first prompt of that session. This is deliberately a low-detail, high-precision summary\nrather than a fine-grained per-decision extraction: a zero-LLM rule-based extractor cannot\nreliably tell a captured decision from ordinary planning chatter, so `import claude-code`\nimports a clean session-level pointer instead of noisy fragments. It is not a full transcript\narchive, and it is not a one-time migration - it is idempotent and meant to be re-run as your\nhistory grows.\n\n**Privacy.** Every stored string is passed through a deterministic secret redactor first\n(API keys, `Authorization`/`Bearer` headers, `password=`/`token=`/`secret=` assignments,\ncommon vendor key shapes, private-key blocks, URL-embedded credentials). Tool outputs and\ntool-call blocks are never read, only your own prompt text. The redactor is defense in depth,\nnot the only control: a real (non-dry-run) run is gated behind an explicit confirmation, and\n`--dry-run` shows you the exact post-redaction text before anything is written. Redaction is\nbounded by its rule set, so `--dry-run` review before a first real import is recommended;\nnothing ever leaves your machine.\n\n## Configuration\n\n```bash\nKAIRN_LOG_LEVEL=INFO|DEBUG|WARNING    # Default: WARNING\nKAIRN_DB_PATH=~/brain/.kairn         # Default: {workspace}/.kairn\nKAIRN_CACHE_SIZE=100                  # LRU cache entries\nKAIRN_JWT_SECRET=<your-secret>        # Required for team features\n```\n\n## Development\n\n```bash\ngit clone https://github.com/primeline-ai/kairn\ncd kairn\npip install -e \".[dev,team]\"\npytest tests/ -v --cov\nruff check src/ && ruff format src/\n```\n\n### Project Structure\n\n```\nsrc/kairn/\n├── server.py              # FastMCP server + 22 tools\n├── cli.py                 # CLI commands\n├── config.py              # Configuration\n├── core/\n│   ├── graph.py           # GraphEngine (6 tools)\n│   ├── memory.py          # ProjectMemory (3 tools)\n│   ├── experience.py      # ExperienceEngine (4 tools)\n│   ├── ideas.py           # IdeaEngine (2 tools)\n│   ├── intelligence.py    # IntelligenceLayer (5 tools)\n│   └── router.py          # ContextRouter\n├── storage/\n│   ├── base.py            # Storage interface\n│   └── sqlite_store.py    # SQLite + FTS5 implementation\n├── models/                # Data models\n├── events/                # Event bus\n└── auth/                  # JWT + RBAC (team feature)\n```\n\n## Performance\n\nMeasure it yourself rather than trusting this table:\n\n```bash\nkairn benchmark ~/brain --nodes 100\n```\n\nOne run of that command, 100 nodes, on an Apple M4 Pro:\n\n| Operation | Measured |\n|-----------|----------|\n| Insert | 0.7ms per node (1,479 ops/sec) |\n| FTS5 query | 0.2ms (5,552 ops/sec) |\n| Graph traversal | 6.0ms (166 ops/sec) |\n\nSingle run on one machine, so treat it as a shape rather than a spec - which is\nwhy the command is above the table. `kn_connect` and `kn_crossref` used to\nappear here with figures the benchmark does not produce; they have been removed\nrather than estimated.\n\n## Used By\n\n| Project | What It Uses Kairn For |\n|---------|----------------------|\n| [Quantum Lens](https://github.com/primeline-ai/quantum-lens) | Persistent insight storage, cross-analysis pattern tracking, lens effectiveness metrics |\n| [Claude Code Starter System](https://github.com/primeline-ai/claude-code-starter-system) | Session memory, project state, learning persistence |\n\n## License\n\nMIT\n\n---\n\n## Part of the PrimeLine Ecosystem\n\n| Tool | What It Does | Deep Dive |\n|------|-------------|-----------|\n| [**Evolving Lite**](https://github.com/primeline-ai/evolving-lite) | Self-improving Claude Code plugin - memory, delegation, self-correction | [Blog](https://primeline.cc/blog/knowledge-architecture) |\n| [**Kairn**](https://github.com/primeline-ai/kairn) | Persistent knowledge graph with context routing for AI | [Blog](https://primeline.cc/blog/knowledge-architecture) |\n| [**tmux Orchestration**](https://github.com/primeline-ai/claude-tmux-orchestration) | Parallel Claude Code sessions with heartbeat monitoring | [Blog](https://primeline.cc/blog/tmux-orchestration) |\n| [**UPF**](https://github.com/primeline-ai/universal-planning-framework) | 3-stage planning with adversarial hardening | [Blog](https://primeline.cc/blog/planning-framework-dsv-reasoning) |\n| [**Quantum Lens**](https://github.com/primeline-ai/quantum-lens) | 7 cognitive lenses for multi-perspective analysis | [Blog](https://primeline.cc/blog/quantum-lens-multi-agent-analysis) |\n| [**PrimeLine Skills**](https://github.com/primeline-ai/primeline-skills) | 5 production-grade workflow skills for Claude Code | [Blog](https://primeline.cc/blog/score-based-auto-delegation) |\n| [**Starter System**](https://github.com/primeline-ai/claude-code-starter-system) | Lightweight session memory and handoffs | [Blog](https://primeline.cc/blog/session-management) |\n\n**[@PrimeLineAI](https://x.com/PrimeLineAI)** · [primeline.cc](https://primeline.cc) · [Free Guide](https://primeline.cc/guide)\n",
  "bytes": 21500,
  "sha": "16858e9441e68781c31642cdefdb2ecefa9c8d0fdc7cf266ef6d80f73dd4ff04",
  "repo_slug": "primeline-ai/kairn",
  "fonte": "repo",
  "truncated": false,
  "api": "https://agentalog.com/api/listings/mcp_io_github_primeline_ai_kairn_667a2b24/readme"
}