Local-first memory for AI agents
Most agent memory makes a database the source of truth. We made it your files.
agentcairn inverts the stack: human-readable Markdown with [[wikilinks]] is the truth, and a rebuildable DuckDB index gives your agent fast hybrid retrieval. Hand-edit a fact in Obsidian and the agent picks it up.
$ claude plugin marketplace add ccf/agentcairn
$ claude plugin install agentcairn@agentcairn Vault · source of truth
--- tags: [auth, fix] --- Fixed login by rotating [[jwt-secret]] during [[deploy]].
Index · disposable cache
MCP · recall
cairn recall "how did we fix login?"
Rotated the jwt-secret during deploy.
↳ auth-fix.md
The inversion
Most systems make the database the truth. We made it your files.
Mem0 and Zep keep your memory in a cloud database. Letta and agentmemory keep it in a database too, and treat files — if any — as a one-way export. agentcairn is the only one where the Markdown vault is the source of truth.
So your memory survives a model upgrade, a corrupted index, a schema change — even uninstalling the tool. There is nothing to lose, because the truth was never trapped in the database.
Six differentiators
Obsidian Vault is the source of truth
Human-readable Markdown with frontmatter and [[wikilinks]]. Edit it by hand; the index honors your edits.
The index is disposable
DuckDB is a rebuildable cache. cairn reindex restores everything — zero data loss.
Non-lossy by construction
The full note is always retained. Distillation only adds derived notes that link back.
Redaction before every write
Secrets scrubbed (regex + entropy + URL-cred) before body, title, or tags reach the vault.
A free, deterministic graph
Your [[wikilinks]] are the graph — no LLM extraction, no hallucinated entities.
Daemonless, zero external DB
One embedded DuckDB does vector + BM25 + graph. No server, no Neo4j/Postgres/Qdrant.
How it works
Capture reads your agent's session transcripts out-of-band, then redacts → dedups → importance-gates → distills into the vault. Retrieval fuses BM25 + vectors with RRF, with an optional cross-encoder reranker. The vault and the index reconcile on spawn; the MCP server exposes remember · recall · search · build_context · recent.
Survives uninstall
Delete the index. Reindex. Everything's back.
The index is a cache. The proof is destructive: remove it, rebuild it, lose nothing — because the truth was never in the database.
Benchmarks measured
Retrieval — LoCoMo
| arm | r@5 | r@10 | MRR |
|---|---|---|---|
| BM25 only | 0.527 | 0.604 | 0.459 |
| vector only | 0.536 | 0.637 | 0.433 |
| hybrid (RRF) | 0.562 | 0.648 | 0.477 |
| hybrid + reranker | 0.662 | 0.735 | 0.608 |
LoCoMo retrieval, turn-level macro-avg, FastEmbed nomic-embed-text-v1.5 (the default).
Retrieval — LongMemEval-S
| arm | session r@5 | session MRR | turn r@5 |
|---|---|---|---|
| BM25 only | 0.920 | 0.918 | 0.680 |
| vector only | 0.936 | 0.916 | 0.507 |
| hybrid (RRF) | 0.954 | 0.938 | 0.640 |
| hybrid + reranker | 0.969 | 0.963 | 0.788 |
LongMemEval-S, full 500-instance set. Full turn r@10/MRR in the README.
Context efficiency
| dataset | haystack | recalled | reduction |
|---|---|---|---|
| LoCoMo | 25,646 tok | 529 tok | 51.1× |
| LongMemEval-S | 136,552 tok | 2,207 tok | 64.7× |
Context the default config recalls vs the full history. Estimate (~4 chars/tok).
- No single headline number — these are relative ablation signals.
- graph-boost is inert on chat corpora (no native wikilink graph); it's for real vaults.
- QA-accuracy numbers use an Anthropic judge, not GPT-4o — not comparable to published leaderboards.
Quickstart
# Claude Code plugin (recommended) claude plugin marketplace add ccf/agentcairn claude plugin install agentcairn@agentcairn # Codex plugin codex plugin marketplace add ccf/agentcairn codex plugin add agentcairn@agentcairn # ...or use it directly — standalone CLI + MCP server uv tool install agentcairn # installs the cairn + agentcairn commands uvx agentcairn # ...or run the MCP server ephemerally cairn install cursor # wire the server into another host cairn recall "how did we fix auth?" # hybrid recall cairn savings # context recall has saved you cairn doctor # health-check the index
Use it in any MCP host
First-class in Claude Code, Codex, OpenCode, Hermes, and Antigravity. Portable everywhere else.
Claude Code, Codex, and Antigravity get a first-class plugin — a bundled MCP server, a memory skill, and (on Claude Code and Codex) ambient session hooks (recall at session start, capture at session end). Antigravity has no plugin hooks, so capture runs out-of-band via cairn sweep. Every other MCP host gets the same recall/search/remember tools via the portable server; cairn install wires it in non-destructively (your other servers are preserved, the original backed up to <config>.bak). Hermes Agent gets a native agentcairn MemoryProvider, and the agentcairn-obsidian plugin lets you read and navigate that memory inside Obsidian. One global ~/agentcairn vault, shared across every host.
| host | support | set up with | ambient |
|---|---|---|---|
| Claude Code | Plugin | cairn install claude-code | ✓ |
| Codex | Plugin | cairn install codex | ◐ |
| Cursor | MCP server + skill + ingest | cairn install cursor | ◐ |
| OpenCode | Plugin + MCP + ingest | cairn install opencode | ✓ |
| Hermes Agent | MemoryProvider plugin | see integrations/hermes/ | ✓ |
| Antigravity | Plugin + ingest | cairn install antigravity | ◐ |
| VS Code (Copilot) | MCP server | cairn install vscode | — |
| Claude Desktop | MCP server | cairn install claude-desktop | — |
cairn install # detect installed agents + preview (writes nothing) cairn install codex # install the Codex plugin (shells to `codex plugin …`) cairn install cursor # write MCP config for an MCP host cairn install --all # configure every detected agent
Plugin hosts (Claude Code, Codex, Antigravity) install via the host's own CLI — the MCP server is bundled in the plugin. MCP hosts take a JSON mcpServers entry (VS Code uses its servers key), written non-destructively, idempotent, backup-first. Ambient recall-at-start + capture-at-end is fully wired on Claude Code; on Codex the hooks ship and capture also runs out-of-band via `cairn sweep`, with live recall-at-start being verified. Antigravity has no recognized plugin hooks — capture runs out-of-band via `cairn sweep` (◐). `agy plugin install` takes a local directory (not a git repo), so install with `cairn install antigravity --source <plugin dir>`; it also removes any stale mcp_config.json entry. Cursor has no plugin hooks either — `cairn sweep` ingests sessions out-of-band from Cursor's global `state.vscdb` SQLite store (`cursorDiskKV` user bubbles); Cursor remains an MCP host (not a plugin host), but `cairn install cursor` also installs the `using-agentcairn-memory` skill to `~/.cursor/skills/` alongside writing `~/.cursor/mcp.json`.
Because the vault is plain Markdown, you can read what every agent remembers in Obsidian: the agentcairn-obsidian plugin (on the community store) adds a vault-native Memory view — a filterable list with provenance and currency, plus a d3-force memory graph of related: links, colored by project and sized by importance.
Trust & security
Redaction before write
regex + entropy + URL-credential
Localhost-only MCP
READ_ONLY queries, no exposed ports
No telemetry
nothing phones home
Index outside the vault
the .duckdb cache is never synced