Give your agents memory that survives the session, so they stop re-deriving what they already learned and stop repeating past mistakes. Hybrid recall (BM25 + dense + RRF), bi-temporal history, and AES-256-GCM at rest, exposed as 55+ MCP tools that work with any host. 73.8% on LongMemEval's official harness (vs Zep 63.8%, Mem0 49.0%). One binary. One file. No Docker. No Postgres. No cloud. Local-fi
Add this skill
npx mdskills install Perseus-Computing-LLC/perseus-vault@Perseus-Computing-LLC? Sign in with GitHub to claim this listing.Production-grade MCP memory server with hybrid search, encryption, and exceptional benchmarks
1<div align="center">2 <img src=".github/banner.png" alt="Perseus Vault — Persistent Memory. Encrypted, local-first, one portable file." width="100%">3</div>45# Perseus Vault67<!-- mcp-name: io.github.Perseus-Computing-LLC/perseus-vault -->89> **Persistent, encrypted memory for AI agents. One Rust binary, one file, no cloud.**1011[](./LICENSE)12[](https://rust-lang.org)13[](https://github.com/Perseus-Computing-LLC/perseus-vault/releases)14[](integrations/langgraph/)15[](integrations/crewai/)16[](integrations/autogen/)17[]()18[](https://mcpservers.org/servers/perseus-computing-llc/perseus-vault)1920Give your agents memory that survives the session, so they stop re-deriving what they21already learned and stop repeating past mistakes. Hybrid recall (BM25 + dense + RRF),22bi-temporal history, and **AES-256-GCM** at rest, exposed as **55+ MCP tools** that work23with any host. **73.8% on LongMemEval's official harness** (vs Zep 63.8%, Mem0 49.0%).24**One binary. One file. No Docker. No Postgres. No cloud.** Local-first, air-gap ready, MIT.2526## One-Line Install2728```bash29curl -sSf https://raw.githubusercontent.com/Perseus-Computing-LLC/perseus-vault/main/scripts/install.sh | sh30```3132That's it. Perseus Vault is installed to `~/.local/bin/perseus-vault`. Start it:3334```bash35perseus-vault serve --db ~/.mimir/data/perseus-vault.db36```3738> **macOS note (Apple Silicon).** A freshly built or copied binary is39> SIGKILLed on first run (`Killed: 9`, no other output) by the OS binary40> policy — even with no quarantine attribute. The one-line installer and the41> `bootstrap.sh` build-from-source installer ad-hoc code-sign Perseus Vault for42> you. If you build the binary yourself, sign it once **after each rebuild**:43>44> ```bash45> cargo build --release46> cp target/release/perseus-vault ~/.local/bin/perseus-vault47> codesign --force --sign - ~/.local/bin/perseus-vault # required on Apple Silicon; fixes "Killed: 9"48> ```49>50> `--force` re-signs an already-signed binary (needed after every rebuild); the51> step is harmless on Intel macOS and unnecessary on Linux/Windows.5253Then wire your MCP client(s) — and the full recall/capture loop — in one command:5455```bash56perseus-vault install-client --hooks --rules57```5859This autodetects Claude Code / Codex / Cursor (pass `--client <name>` for60claude-desktop, hermes, windsurf, vscode, zed, or generic; `--all-detected`61wires every detected client), merges the MCP server registration into the62client's config without clobbering anything (a `.bak-perseus` backup is63written first), points every client at **one shared memory database**,64registers the session lifecycle hooks (recall injection on SessionStart,65hygiene on session end — the `docs/lifecycle-hooks.md` contract), and appends66the memory usage rules to `CLAUDE.md`/`AGENTS.md`. Re-running is a no-op; add67`--dry-run` to preview every file it would touch.6869Or connect any MCP host by hand (Claude Desktop, Cursor, Hermes Agent, Perseus, etc.):7071```json72{73 "mcpServers": {74 "perseus-vault": {75 "command": "perseus-vault",76 "args": ["serve", "--db", "~/.mimir/data/perseus-vault.db"]77 }78 }79}80```8182## 30-Second Quickstart8384```bash85# Start Perseus Vault86perseus-vault serve --db memory.db &87sleep 18889# Remember a fact (via MCP JSON-RPC on stdio)90echo '{"jsonrpc":"2.0","id":1,"method":"tools/call","params":{"name":"mimir_remember","arguments":{"category":"demo","key":"hello","body_json":"{\"text\":\"Hello from Perseus Vault!\"}"}}}' | perseus-vault serve --db memory.db9192# Search for it93echo '{"jsonrpc":"2.0","id":2,"method":"tools/call","params":{"name":"mimir_recall","arguments":{"query":"Hello"}}}' | perseus-vault serve --db memory.db94```9596## Works With Every MCP Client9798Perseus Vault is a standard MCP **stdio** server — the same `perseus-vault serve` command works99everywhere. Run `perseus-vault doctor` to validate your install and print this matrix locally.100101| Client | Status | Config |102|---|---|---|103| Claude Desktop | ✅ | `claude_desktop_config.json` |104| Claude Code / Hermes | ✅ | `.mcp.json` / `config.yaml` |105| Cursor | ✅ | `.cursor/mcp.json` |106| Windsurf | ✅ | `mcp_config.json` |107| VS Code + Continue.dev | ✅ | `config.json` |108| Zed | ✅ | `settings.json` |109| Codex CLI | ✅ | `~/.codex/config.toml` |110111Copy-paste config snippets for each: **[docs/clients/](docs/clients/)**.112113Then wire the **recall → work → capture → consolidate** loop to your client's114session events (SessionStart/Stop hooks for Claude Code, Codex, and Cursor,115plus a portable AGENTS.md fallback): **[docs/lifecycle-hooks.md](docs/lifecycle-hooks.md)**.116117Composing with a memory washer (CoalWash) and a runtime output compactor118(Noisegate) for end-to-end context-budget control:119**[docs/integration/context-budget-stack.md](docs/integration/context-budget-stack.md)**.120121## Why Perseus Vault122123Perseus Vault is the **only** memory engine that is simultaneously MCP-native,124local-first, zero-dependency, AND agent-first.125126### LongMemEval QA (official harness)127128Recall quality measured on LongMemEval's **official** harness, not a home-grown script:129130| Memory engine | QA accuracy |131|---|---|132| **Perseus Vault** | **73.8%** |133| Zep | 63.8% (published) |134| Mem0 | 49.0% (published) |135136`longmemeval_s` (500 questions), gpt-4o-2024-08-06 answerer + LongMemEval's official judge; competitor numbers are their published values. Perseus Vault's 73.8% is the plain mean of 3 runs; 79.0% with official CoT. [Methodology & content-hashed (sha256) results →](benchmark/longmemeval/COMPARISON.md)137138### Bi-temporal time-travel (three-axis)139140Our strongest structural differentiator — full **SQL:2011 bi-temporal** history141(transaction-time *and* valid-time) — measured against a reproducible,142**fully offline** gauntlet. It drives the real shipped binary over MCP stdio143through the hard cases single-axis competitors get wrong (retroactive144corrections, proactive future-dated facts, out-of-order arrival, belief-vs-truth145divergence, closed periods):146147| Axis | Question it answers | Checks | Pass |148|---|---|---|---|149| **valid-time** (`valid_at`) | "what was true in the world at T" | 10 | 10 |150| **transaction-time** (`as_of`) | "what did we believe at T" | 1 | 1 |151| **bi-temporal** (`bitemporal`) | "as of belief at T, what was true at V" | 2 | 2 |152| **Total** | | **13** | **13 (100%)** |153154Reproduce with a single command (no API key, no network, no LLM):155156```bash157cargo build --release158python benchmark/temporal/gauntlet.py --bin target/release/perseus-vault159```160161The PASS/FAIL verdicts are deterministic (wall-clock timestamps vary, verdicts162do not), so a correct build re-runs to an identical `signature_sha256`. The163committed [`gauntlet_report.json`](benchmark/temporal/gauntlet_report.json) is164the reference. [Methodology & dataset →](benchmark/temporal/README.md)165166### Comparison Matrix167168| | Perseus Vault | Mem0 | Letta | Zep |169|---|---|---|---|---|170| **Deployment** | Single binary | Cloud + self-host | Docker/Postgres | Docker/Neo4j |171| **Dependencies** | None (SQLite embedded) | Python + vector DB | Postgres + Python | Neo4j + Go (Graphiti) |172| **MCP-Native** | ✅ 55+ tools | ❌ Not MCP-native | ❌ Not MCP-native | ❌ Not MCP-native |173| **Offline/Local** | ✅ Fully local | Cloud-dependent | Docker needed | Docker needed |174| **Encryption** | AES-256-GCM ✅ | ❌ | ❌ | ❌ |175| **Hybrid Search** | BM25 + Dense + RRF | Vector only | Vector only | Vector + Graph |176| **Entity Lifecycle** | Decay + Promote + Archive | ❌ | ❌ | ❌ |177| **Entity Graph** | Link + Traverse | ❌ | ❌ | ✅ |178| **Journal Audit Trail** | ✅ Immutable | ❌ | ❌ | ❌ |179| **State Management** | ✅ Key-value + TTL | ❌ | ❌ | ❌ |180| **MCP Tools** | 55+ | 5 | 8 | 0 |181| **License** | MIT | Apache 2.0 | Apache 2.0 | Apache 2.0 |182183[Full comparison: Perseus Vault vs Mem0 →](docs/comparison/mimir-vs-mem0.md)184[vs Letta →](docs/comparison/mimir-vs-letta.md)185[vs Zep →](docs/comparison/mimir-vs-zep.md)186187### Stress Test: 100K Entities188189Perseus Vault handles production workloads on modest hardware. The numbers190below are from the committed artifact191[`benchmark/scale/report.json`](benchmark/scale/report.json): the real release192binary driven over MCP stdio (one persistent process per corpus size), AMD6419316-core, Windows 11, every write durable before the next is sent.194195| Metric | 10K | 100K |196|---|---|---|197| **Write throughput, sustained (MCP stdio)** | 479 docs/s | 40 docs/s |198| **Hybrid recall p50** | 19.03 ms | 79.73 ms |199| **FTS5 recall p50** | 3.14 ms | 15.67 ms |200201Full percentiles, `as_of` point lookups, temporal recall, and cold-start202numbers are in [`benchmark/scale/`](benchmark/scale/README.md).203204Run it yourself: `python benchmark/scale/run.py`205206### Recall Accuracy at Scale: Keyword Collapses, Hybrid Holds207208Speed is table stakes — the question that matters for agent memory is *does the209right memory actually surface?* Measured on distinct-content corpora (first-party,210reproducible; see [`benchmark/lambda/`](benchmark/lambda/)), recall@k by mode:211212**100,000 entities** (1×H100, `nomic-embed-text` on Ollama):213214| recall@k | keyword (BM25/FTS5) | dense | **hybrid (RRF)** |215|---|---|---|---|216| @1 | 0.003 | 0.680 | **0.785** |217| @5 | 0.015 | 0.859 | **1.000** |218| @10 | 0.029 | 0.899 | **1.000** |219220At 100K entities, hybrid recall is **perfect @5 while keyword search lands ~1.5%221of the time** — a **~66× gap**. And it *widens* with scale: at 10K entities keyword222recall@5 was 0.008 while hybrid was already 1.000; keyword-only memory silently223degrades as an agent accumulates history, hybrid (BM25 + dense + reciprocal-rank224fusion) does not. This is the core argument for Perseus Vault's hybrid retrieval.225226**Head-to-head, same box, same corpus, all fully local** (1×H100, Ollama —227identical fact set, queries, and substring judge for every system):228229| System | Recall accuracy | p50 latency | Notes |230|---|---|---|---|231| **Perseus Vault** (hybrid) | **1.00** | 35.6 ms | single self-contained binary, in-process |232| Letta (archival / pgvector) | 1.00 | 135.5 ms | server + Postgres/pgvector |233| Mem0 (vector) | 0.60 | 37.9 ms | Python + vector DB |234| Zep (Graphiti temporal KG) | 0.20 | 49.7 ms | server + Neo4j; graph extracted by local model |235236Every competitor was **stood up and run live** on the same box against the same237local Ollama (`qwen2.5:14b-instruct` + `nomic-embed-text`) — no cloud, no fabricated238numbers. Letta ran as the `letta/letta` server (bundled Postgres/pgvector) and matched239Perseus Vault at 1.00. Zep's self-hosted Community Edition server is deprecated and its240`zep_python` memory API is now Zep Cloud-only, so we measured Zep's actual OSS engine —241Graphiti temporal KG on Neo4j — with entity/edge extraction *and* embeddings on the same242local Ollama. Its 0.20 reflects the honest cost of building a knowledge graph with a243**local** model (structured extraction is lossy: 5 entities / 2 edges from 6 facts) — not244Zep Cloud, which uses frontier models. Full artifact + methodology:245[`benchmark/lambda/results/competitors.json`](benchmark/lambda/results/competitors.json).246247**Cold-start:** a bare GPU box reaches its **first grounded RAG answer in 3.3s**248(models staged on disk).249250Reproduce: [`benchmark/lambda/scale_bench.py`](benchmark/lambda/scale_bench.py) and251[`competitors_bench.py`](benchmark/lambda/competitors_bench.py).252253Deploying beside a model server on a GPU host (vLLM on MI300X/H100)? See the254[AMD MI300X deployment reference](docs/deployment-amd-mi300x.md) — measured255co-residency numbers plus the `/dev/shm`, PID-1, and version-pinning gotchas256that break these stacks in practice.257258## Framework Integrations259260Ready-to-use adapters that make Perseus Vault the default memory backend for261popular AI agent frameworks:262263| Framework | Integration | Type |264|---|---|---|265| [**LangGraph**](integrations/langgraph/) | `MimirStore` | `BaseStore` implementation |266| [**CrewAI**](integrations/crewai/) | `MimirMemoryTool` | Agent tool |267| [**AutoGen**](integrations/autogen/) | `MimirMemory` | `Memory` implementation |268269Each adapter:270- Connects via MCP stdio subprocess (persistent session)271- Maps the framework's memory interface to Perseus Vault tools272- Comes with a README quickstart (5 minutes to working)273- Has passing tests with mocked MCP transport274275Any MCP-compatible framework works with Perseus Vault directly. See276[Awesome Mimir](awesome-mimir.md) for the full list.277278## 55+ MCP Tools279280> **Tool names & the `perseus_vault_` prefix.** The tables below use the281> historical `mimir_*` names, but by default the server now advertises each tool282> **once**, under its canonical `perseus_vault_*` name (e.g. `perseus_vault_remember`).283> The legacy `mimir_*` and `mneme_*` names remain fully *callable* — every prefix284> dispatches to the same handler — they are just no longer advertised in285> `tools/list`. This keeps the advertised manifest to one name per tool instead286> of tripling it (3× alias bloat), so connected clients don't reload a tripled287> tool-schema payload on every request. To restore the historical behaviour of advertising all three288> prefixes, set `PERSEUS_VAULT_TOOL_ALIASES=all` (the legacy env289> `MIMIR_TOOL_ALIASES` is also honoured; `PERSEUS_VAULT_` takes precedence).290>291> **Client compatibility (#633).** Clients that *gate on the advertised list* —292> they check `tools/list` before calling and skip tools they don't see — will293> silently skip legacy `mimir_*` calls against a 2.x vault even though the call294> itself would succeed. Known case: the `perseus` CLI **≤ 1.0.22** hard-codes295> `mimir_recall` and degrades to empty local-only recall. Fix either side:296> upgrade the CLI to **≥ 1.0.23** (calls canonical names, with dynamic297> fallback), or set `PERSEUS_VAULT_TOOL_ALIASES=all` on the vault as a bridge298> while older clients remain deployed.299300### Entity CRUD301| Tool | Description |302|---|---|303| `mimir_remember` | Store/update entity. Idempotent by (category, key); a content change snapshots the prior version into history. |304| `mimir_recall` | Search with FTS5/dense/hybrid modes, filters, stemming expansion. Query contract (#562): `query=""` is match-all enumeration (the "list all" path); `"*"` and other wildcards are literal FTS5 terms, **not** globs — `"*"` matches nothing. |305| `mimir_scan` | Deterministic paginated enumeration of a category or the whole store (#562): immutable `id ASC` keyset pages with a `next_cursor`/`has_more` contract, so export/sync/reset callers can walk every entity exactly once. Read-only — no retrieval-count/decay side-effects, no offset cap. |306| `mimir_hygiene` | Read-only startup-memory hygiene report (#675): scores active memories by "actionability" (concrete anchors — issue keys, #refs, paths, URLs, decisions — vs vague/date-only/short) and lists the worst offenders with reasons, for archive/consolidate curation. |307| `mimir_recall_layer` | Recall from a specific biomimetic layer (world, episodic, semantic). |308| `mimir_recall_when` | Proactive just-in-time recall: surface entities whose `recall_when` triggers match. |309| `mimir_get_entity` | Fetch one entity by ID with full `body_json`. |310| `mimir_as_of` | Transaction-time time-travel: the version of a fact (category + key) that was *believed* at a past instant. |311| `mimir_valid_at` | Valid-time lookup: the version that was *actually true in the world* at an instant, per current knowledge (SQL:2011 APPLICATION_TIME). |312| `mimir_bitemporal` | Full 2-axis bi-temporal query: "as of transaction time T, what did we believe was true at valid time V" — the exact rectangle cell. |313| `mimir_history` | List superseded versions of a fact (category + key), newest first — paginated (`limit` default 20, plus `offset`); `total` reports the full trail size (companion to `mimir_as_of`). |314| `mimir_forget` | Soft-delete (archived=1). |315316### Search & RAG317| Tool | Description |318|---|---|319| `mimir_ask` | RAG: recall context, query LLM, return grounded answer with sources. |320| `mimir_embed` | Generate dense vectors via the bundled model, Ollama, or OpenAI-compatible endpoint. |321| `mimir_semantic_search` | Dense-only semantic search shortcut — find entities by meaning, ranked purely by embedding similarity (no keyword fallback). |322| `mimir_context` | Pre-formatted markdown block for session injection. Recall-first by default: pass `query` (the current task/message) and only topically relevant entities are injected, clamped to a per-model budget; the legacy unconditional dump requires `mode: "always_inject"`. |323| `mimir_ingest` | Trigger connector syncs (GitHub, file watcher). |324| `mimir_ingest_file` | Locally extract a document's text (plaintext/markdown always; DOCX/PDF with the `multimodal` feature) and store it as a recallable entity. |325| `mimir_extract` | Local, deterministic, rule-based knowledge extraction (facts / preferences / temporal events / episodes) from text or a stored entity. Read-only. |326| `mimir_capture` | Opt-in in-session capture (#520): distill a transcript/insight payload (text, markdown, or JSONL) into durable entities (root-cause / pitfall / decision / pattern / takeaway) the moment a problem is solved. Local rule-based distiller by default, optional `llm: true` with graceful fallback; near-dup merging stays ON plus a per-invocation cap (anti-flood). Also a CLI verb: `perseus-vault capture`. |327| `mimir_memories` | Anthropic memory-tool compatible file interface (`view`/`create`/`str_replace`/`insert`/`delete`/`rename` under `/memories`), backed by vault entities. |328329> 📖 **[docs/retrieval-modes.md](docs/retrieval-modes.md)** — one enumerated reference for every retrieval mode (keyword · dense · hybrid · graph · GraphRAG · proactive `recall_when` · temporal `as_of`): mechanism, when to use, invocation, and examples.330331### Graph332| Tool | Description |333|---|---|334| `mimir_link` | Create typed relationship links between entities. |335| `mimir_unlink` | Remove entity links. |336| `mimir_traverse` | Walk entity link graph up to configurable depth. |337| `mimir_communities` | GraphRAG community detection over the link graph (deterministic label propagation or greedy-modularity "louvain"; pure Rust, offline). |338| `mimir_community_summary` | Extractive (optionally LLM-polished) summary of one community, materialized as an entity with `evidence_for` links to members. |339| `mimir_global_recall` | GraphRAG global search: breadth over community summaries, then depth into the best communities' members — holistic answers across clusters. |340341### Journal342| Tool | Description |343|---|---|344| `mimir_journal` | Append structured event with actor attribution. |345| `mimir_check_failure_pattern` | Deja-vu guard: check an action against previously recorded failures (journal + failure/pitfall entities) before retrying it. Read-only. |346| `mimir_timeline` | Query journal by time range with filters. |347348### State349| Tool | Description |350|---|---|351| `mimir_state_set` | Set key-value state with optional TTL. |352| `mimir_state_get` | Get state value. Returns null if expired. |353| `mimir_state_delete` | Delete state entry. |354| `mimir_state_list` | List state keys, optionally filtered by prefix. |355356### Lifecycle357| Tool | Description |358|---|---|359| `mimir_decay` | Recalculate Ebbinghaus decay scores (batched 1000-entity transactions). |360| `mimir_prune` | Bulk archive by category, decay threshold, or age. |361| `mimir_purge` | Permanently delete archived entities + VACUUM. Destructive. |362| `mimir_cohere` | Autonomous coherence grooming pass — promote, decay, link, archive. |363| `mimir_autocohere` | Full atomic grooming: cohere → decay → compact in one pass (supports dry-run). |364| `mimir_compact` | Archive entities below decay threshold. |365| `mimir_reindex` | Rebuild FTS5 search index from entities table. |366| `mimir_consolidate` | Merge overlapping/duplicative entities in a category into durable, evidence-tracked observations (mirror image of `mimir_conflicts`). |367| `mimir_dream` | Sleep-time LLM consolidation: reflect over clusters of related episodic memories via the configured LLM and write back durable semantic insights, provenance-linked to every source. Idempotent (evidence-set hash), contradiction-aware, bounded; requires `--llm-endpoint`. |368369### Quality370| Tool | Description |371|---|---|372| `mimir_score` | Assign quality score (0.0-1.0). |373| `mimir_conflicts` | Detect conflicting entities via trigram similarity; opt-in `resolve=true` invalidates the lower-certainty side into history (reversible, dry-run by default). |374| `mimir_correct` | Structured correction capture for learning from errors. |375| `mimir_supersede` | Mark a new fact as superseding an old one (sets the old entity to `deprecated`). |376| `mimir_follow` | Record whether an entity was actually FOLLOWED or MISSED — follow-rate efficacy signal that feeds both decay scoring and outcome-weighted recall ranking (#681). |377378### Keystones (policy rules)379| Tool | Description |380|---|---|381| `mimir_keystone_set` | Author a Keystone — a mandatory policy rule that survives context compaction (#683). Scoped (tenant/fleet/agent), weight-ranked, crypto-chained on every mutation; authoring is trust-tier-gated. |382| `mimir_keystone_get` | Fetch the merged Keystones for a scope, ordered by weight (highest first) then scope specificity — the deterministic session-start counterpart to recall. A renderer injects these ahead of all other context. |383| `mimir_agent` | Register/update or look up an agent in the multi-agent registry (#684): identity + trust tier (0-3) + fleet. Trust tier gates sensitive ops (e.g. authoring keystones needs tier ≥ 2) and drives visibility enforcement on recall. |384385### Vault & Federation386| Tool | Description |387|---|---|388| `mimir_vault_export` | Export entities to .md files with YAML frontmatter. |389| `mimir_vault_import` | Import from .md vault directory (idempotent). |390| `mimir_federate` | Copy entities between workspaces. This is a local export / workspace-rename / re-import (file based, no network peers); the Windows-safe default path is tracked in #704. |391| `mimir_share` | Share one entity (by category + key) into another workspace, preserving content. |392| `mimir_workspace_list` | List all distinct entity categories. |393394### Metrics & Ops395| Tool | Description |396|---|---|397| `mimir_stats` | Full DB statistics across all tables. |398| `mimir_health` | Server and DB health check. |399| `mimir_bench` | Performance benchmark tracking. |400| `mimir_maintenance` | DB maintenance: dedup, orphan detection, VACUUM, FTS5 reindex (supports dry-run). |401| `mimir_synthesize` | LLM session synthesis — extract lessons from transcripts. |402| `mimir_migrate` | Migrate v0.1.x DB to current schema. |403404## CLI405406```bash407# Server408perseus-vault serve --db /data/perseus-vault.db409perseus-vault serve --web --port 8767 --encryption-key ~/.mimir/secret.key410perseus-vault serve --llm-endpoint http://localhost:11434/api/generate --llm-model llama3411perseus-vault serve --transport sse --port 8787 --mcp-token my-secret-token412413# Maintenance (operate directly on DB, no server needed)414perseus-vault stats --db /data/perseus-vault.db415perseus-vault forget --db /data/perseus-vault.db --category decision --key stale-choice --reason "superseded"416perseus-vault prune --db /data/perseus-vault.db --category junk --min-decay 0.1 --dry-run417perseus-vault purge --db /data/perseus-vault.db --dry-run418perseus-vault decay --db /data/perseus-vault.db419perseus-vault reindex --db /data/perseus-vault.db420perseus-vault vault-export --db /data/perseus-vault.db --vault-dir ./export/421perseus-vault vault-import --db /data/perseus-vault.db --vault-dir ./export/422perseus-vault obsidian-sync ~/obsidian-vault/Perseus Vault/ # one-shot export to an Obsidian vault423perseus-vault obsidian-sync ~/obsidian-vault/Perseus Vault/ --watch # continuous sync on every memory change424425# Key management426perseus-vault keygen --key-file ~/.mimir/secret.key427```428429> **Manual DB edits.** The maintenance verbs above and the normal MCP write path430> keep the FTS5 index in sync automatically. Editing the `entities` table431> **directly** with `sqlite3` (a manual `DELETE`/`UPDATE`) bypasses that sync and432> can leave orphaned index rows — "ghost" recall hits for content that is already433> gone. After any direct SQL edit, run `perseus-vault maintain --db <path>` (or434> `perseus-vault reindex`) to reconcile the FTS index.435436### Flags437438| Flag | Description |439|---|---|440| `--db` | SQLite database path (default: `~/.mimir/data/perseus-vault.db`) |441| `--web` | Start web dashboard |442| `--port` | Dashboard port (default: 8767) |443| `--web-bind` | Dashboard bind address (default: 127.0.0.1) |444| `--transport` | MCP transport: `stdio` (default), `sse`, or `http` |445| `--mcp-token` | Bearer token for SSE/HTTP transport auth |446| `--encryption-key` | AES-256-GCM key file path |447| `--llm-endpoint` | LLM API endpoint for `mimir_ask` and embeddings |448| `--llm-model` | LLM model name (default: llama3) |449| `--llm-api-key` | API key for LLM endpoints (OpenAI, Azure, etc.) |450| `--embedding-endpoint` | OpenAI-compatible embedding endpoint |451| `--connectors-config` | Path to connectors.yaml |452453### Database location454455The **canonical** database path is:456457```458~/.mimir/data/perseus-vault.db459```460461Always pass `--db` (or set `$MIMIR_DB_PATH`) in scripts, MCP host configs, and462cron/harvest jobs so every invocation targets the same file. When neither is463set, Perseus Vault resolves the default in this order and uses the **first that464already exists** (so upgraders and legacy single-user installs are picked up465instead of silently starting empty):4664671. `~/.mimir/data/perseus-vault.db` — canonical (current name)4682. `~/.mimir/data/mneme.db` — pre-rename4693. `~/.mimir/data/mimir.db` — pre-rename4704. `~/mimir.db` — legacy single-user install location471472If none exist, it creates `~/.mimir/data/perseus-vault.db`. If **more than one**473of these exists and you did not pass `--db`/`$MIMIR_DB_PATH`, Perseus Vault474prints a stderr warning naming the chosen file and the others it ignored, so an475ambiguous multi-database state is visible rather than silent. Setting `--db` or476`$MIMIR_DB_PATH` explicitly always wins and suppresses the warning.477478## Your AI Memory in Obsidian479480Perseus Vault is your AI agent's long-term memory — and it doubles as **your** second481brain. Every entity your agent remembers exports to a plain Markdown note with482YAML frontmatter, so your AI's memory becomes a navigable personal knowledge483base inside the tools you already use: **Obsidian, Logseq, or Notion.**484485```bash486# Export your entire memory to an Obsidian vault as linked Markdown notes487perseus-vault obsidian-sync ~/obsidian-vault/Perseus Vault/488489# Keep it live — re-export automatically on every memory change490perseus-vault obsidian-sync ~/obsidian-vault/Perseus Vault/ --watch491```492493Open the vault in Obsidian and you get a graph of your agent's knowledge.494495**WikiLink backlinks.** When one entity links to another (via `mimir_link` or a496`depends_on` / `implements` / `references` relationship), the exported note gets497a `## Links` section with `[[WikiLink]]` backlinks that resolve natively in498Obsidian's graph view:499500```markdown501---502id: cli-de8dfb8364b6503category: architecture504key: api505type: insight506decay_score: 0.5000507---508509{"content":"axum service"}510511## Links512513- [[cli-99756b494c7d|database]] (depends_on)514```515516Links resolve **by entity id** (notes are written as `<id>.md`) so they never517break, and Obsidian shows the human-readable `key` as the link label. Open the518graph view and your agent's architecture, decisions, and insights become a519clickable knowledge map.520521**`--watch`** polls Perseus Vault's cheap, deterministic state digest on an interval and522re-exports only when memory actually changes. It naturally catches every523`mimir_remember` write with no filesystem-watcher dependency and no coupling to524the server. Tune the interval with `MIMIR_SYNC_INTERVAL_SECS` (default: 2s).525526### Other PKM tools527528| Tool | How |529|---|---|530| **Obsidian** | `perseus-vault obsidian-sync <vault>` — WikiLinks resolve in the graph view out of the box. |531| **Logseq** | Point `obsidian-sync` at your Logseq graph directory. Logseq reads the same `[[WikiLink]]` syntax and Markdown frontmatter. |532| **Notion** | Run `perseus-vault vault-export`, then use Notion's *Import → Markdown & CSV* to pull the notes in. |533534Unlike cloud-only "second brain" tools, Perseus Vault runs **100% local**, is written in535**Rust**, encrypts at rest with **AES-256-GCM**, and applies **decay scoring** so536stale memories fade — your knowledge base stays yours and stays fresh.537538## Features539540### Semantic Search (on by default)541- **Bundled, in-process embeddings** — a quantized all-MiniLM-L6-v2 model542 (384-dim) is compiled into the binary, so dense/semantic search works with543 **zero config and zero network**: no Ollama, no API key, no model download.544 This is the default build (`bundled-embeddings` feature).545- **Auto-embed on write (#271)** — `mimir_remember` embeds each new (or546 content-changed) entity **synchronously** as it is written, using the bundled547 model. Single-entity embedding is deterministic and LRU-cached, so it is cheap548 and adds no background tasks. Embedding failures are non-fatal (logged to549 stderr); the write always succeeds.550- **Hybrid is the default recall mode (#271)** — `mimir_recall(query=...)` with551 no `mode` flag automatically selects **hybrid** (dense + keyword fused via RRF)552 whenever embeddings exist, and transparently falls back to **fts5** keyword553 search when none do. No manual `mimir_embed` step, no flags to remember.554- **`mimir_semantic_search(query, limit)`** — a one-tool shortcut for pure555 dense, meaning-based search (no keyword fallback) when you just want "find556 things like this".557- **Optional alternate embedder** — to use **Ollama** or any OpenAI-compatible558 `/v1/embeddings` endpoint instead of the bundled model, set `--llm-endpoint`559 (and `--embedding-endpoint` / `--llm-api-key` as needed). This is entirely560 optional; the bundled model is used by default.561- Build a lean binary without bundled embeddings via562 `cargo build --no-default-features` — recall then defaults to keyword search563 unless a remote embedder is configured.564565### Hybrid Search internals566- **FTS5 keyword search** with LIKE fallback and Porter stemming expansion567- **Dense vector search** via cosine similarity on stored embeddings568- **Reciprocal Rank Fusion (RRF)** — combine keyword + vector results569- **Query expansion** — automatic stemming variants for broader recall570### Memory Lifecycle571572Perseus Vault models memory using three biomimetic layers, inspired by human memory pathways:573574- **World (Core):** Slow-decaying, global facts about the environment.575- **Episodic (Buffer):** Fast-decaying, session-specific interaction history.576- **Semantic (Working):** Medium-decaying, general knowledge and learned concepts.577578You can interact with these layers directly using the `mimir_recall_layer` tool or by specifying the `layer` parameter in `mimir_remember`.579580- **Ebbinghaus decay** — memories naturally fade unless retrieved (refresh on access)581- **Layer promotion** — buffer → working → core based on access frequency582- **Automatic archival** — stale entities archive; purge to permanently delete + VACUUM583- **Always-on entities** — pin identity-critical memories for session injection (hard-capped under recall-first; prefer `recall_when` triggers)584585### Recall-First Context Injection586587The vault is the query layer — it retrieves the few facts a turn needs instead of588handing the host a standing blob to staple into every system prompt.589`mimir_context` and `perseus-vault prepare` are **recall-first by default**:590591- **Relevance gating** — pass `query` (the current task/message) and only entities592 whose `recall_when` triggers or indexed content match it are injected. No query,593 no topical injection: the block is a compact retrieval pointer, byte-stable594 across unrelated vault writes (prefix-cache friendly).595- **Per-model recall budget** — output is clamped to a character budget resolved596 from the host model: default/lean profile 1500 chars; large-window ("opus")597 profile 6000 chars; `max_context_chars` overrides both.598- **Capped always-on** — `always_on: true` still works for identity-critical599 facts, but the recall-first set is hard-capped (top 5) and overflow emits a600 warning steering you to `recall_when` triggers.601- **Legacy opt-in** — the old unconditional top-N dump is still available with602 `mode: "always_inject"` (`--legacy-context` for `prepare`), unclamped unless603 you pass a budget.604605```bash606perseus-vault prepare --task "deploying the payments service" --model claude-sonnet-4-6607perseus-vault prepare --task "..." --max-context-chars 800 # explicit budget608perseus-vault prepare --task "..." --legacy-context # old dump, opt-in609```610611### RAG & Embeddings612- **`mimir_ask`** — natural language Q&A over stored memories via any LLM (Ollama, OpenAI, etc.)613- **`mimir_embed`** — generate and store dense vectors via Ollama or OpenAI-compatible `/v1/embeddings`614- Supports single-entity and batch-category embedding615616### Encryption617- **AES-256-GCM** transparent encryption for entity `body_json`618- Opt-in via `--encryption-key` flag619- `perseus-vault keygen` subcommand for key generation620- FTS5 index stays plaintext for search621622### Web Dashboard623- Built-in Axum HTTP server (`perseus-vault serve --web --port 8767`)624- Dark-themed dashboard with search, entity table, vis.js graph, timeline625- Default bind: `127.0.0.1` (use `--web-bind 0.0.0.0` to expose)626- Separate SQLite connection in WAL mode for concurrent reads627628### External Connectors629- **GitHub issues connector** — ingest issues/PRs by repo, rate-limit aware630- **File watcher** — scan directories for `.md`/`.txt`/`.json` files with content-hash dedup631- YAML-based connector config via `--connectors-config`632633### Multi-Transport634- **stdio** (default) — zero-config, works with any MCP host635- **SSE** — Server-Sent Events for HTTP-based MCP clients636- **HTTP** — REST-style MCP endpoint637- **Bearer token auth** — for SSE/HTTP transports638639## Perseus Integration640641Perseus Vault is the default memory backend for [Perseus](https://perseus.observer):642643```yaml644mimir:645 enabled: true646 transport: "stdio"647 command: ["perseus-vault", "serve", "--db", "~/.mimir/data/perseus-vault.db"]648 timeout_s: 30.0649 merge_strategy: "local_first"650 fallback_to_local: true651 context_categories: ["decision", "architecture", "convention"]652 context_limit: 10653```654655## Government & Federal Procurement656657Perseus Vault is built for government deployment from the ground up.658659| Capability | Status |660|---|---|661| **License** | MIT — no copyleft, no GPL/AGPL |662| **SBOM** | [Published](./docs/SBOM.md) — NTIA minimum elements |663| **Air-gapped** | Fully offline — no telemetry, no API calls, no network by default |664| **Encryption at rest** | AES-256-GCM, transparent, opt-in |665| **Audit trail** | Immutable journal with chain-of-custody |666| **Supply chain** | SLSA attestation in progress |667668**For federal buyers:** See [docs/federal-buyers.md](./docs/federal-buyers.md) for669procurement information, compliance status, and deployment models (air-gapped,670on-premises, classified environments).671672Perseus Computing LLC is a US-owned small business. SAM.gov registration in progress.673NAICS: 541715, 541511, 541512.674675## Privacy Policy676677Perseus Vault is a **local-first MCP server** — it runs entirely on your machine.678679### Data Collection680- **No data collection.** Perseus Vault does not collect, transmit, or phone home any user data, usage statistics, or telemetry.681- All data remains in your local SQLite database file.682683### Data Usage & Storage684- All memory entities, journal entries, and state are stored locally in a SQLite database at the path you specify via `--db`.685- Optional **AES-256-GCM encryption at rest** is available — when enabled, entity bodies are encrypted before storage.686- No data is shared with Perseus Computing LLC or any third party.687688### Third-Party Sharing689- **None.** Perseus Vault is fully air-gapped by default. No API calls, no cloud services, no external network requests.690- The optional dense vector embeddings feature uses a locally-compiled model — no external embedding API is called.691692### Data Retention693- You control retention: entities can be soft-deleted (`mimir_forget`), archived (via decay/compact), or permanently purged (`mimir_purge`).694- No automatic off-machine backup is performed.695696### Contact697- **Email:** privacy@perseus.observer698- **GitHub:** [Perseus-Computing-LLC/perseus-vault](https://github.com/Perseus-Computing-LLC/perseus-vault)699700## Release Verification701702Release binaries are built from tagged commits via [GitHub Actions](.github/workflows/release.yml). Every release ships:703704| Artifact | Description | Verification |705|----------|-------------|-------------|706| `perseus-vault-<target>.tar.gz` | Full build (bundled embeddings, glibc) | SHA-256 checksum in `.sha256` sidecar |707| `perseus-vault-lite-<target>.tar.gz` | Lean build (`--no-default-features`, musl/static) | SHA-256 checksum in `.sha256` sidecar |708| SLSA provenance attestation | Sigstore-signed build provenance | `gh attestation verify <archive> --repo Perseus-Computing-LLC/perseus-vault` |709710### Verify a release binary711712```bash713# 1. Verify SHA-256 checksum714sha256sum -c perseus-vault-lite-x86_64-unknown-linux-musl.tar.gz.sha256715716# 2. Verify SLSA build provenance (requires gh CLI + OIDC session)717gh attestation verify perseus-vault-lite-x86_64-unknown-linux-musl.tar.gz \718 --repo Perseus-Computing-LLC/perseus-vault719720# 3. Confirm the binary identity721./perseus-vault --version722# Should show both the release version AND the git commit hash, e.g.:723# perseus-vault 2.20.2 (v2.20.2-0-gabcdef1)724725# 4. Confirm the doctor reports the same identity726./perseus-vault doctor --db /tmp/test.db | head -1727# perseus-vault doctor — v2.20.2 (v2.20.2-0-gabcdef1)728```729730### Build reproducibly from source731732```bash733# The exact same binary (bit-for-bit) requires matching:734# - Rust toolchain version (see rust-toolchain.toml)735# - Locked dependencies: `cargo build --locked`736# - Build flags: `--release` for release builds737738cargo build --locked --release739./target/release/perseus-vault --version740```741742## License743744MIT — see [LICENSE](./LICENSE).745
Full transparency — inspect the skill content before installing.