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

Persistent, encrypted memory for AI agents. One Rust binary, one file, no cloud.
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-first, air-gap ready, MIT.
curl -sSf https://raw.githubusercontent.com/Perseus-Computing-LLC/perseus-vault/main/scripts/install.sh | sh
That's it. Perseus Vault is installed to ~/.local/bin/perseus-vault. Start it:
perseus-vault serve --db ~/.mimir/data/perseus-vault.db
macOS note (Apple Silicon). A freshly built or copied binary is SIGKILLed on first run (
Killed: 9, no other output) by the OS binary policy — even with no quarantine attribute. The one-line installer and thebootstrap.shbuild-from-source installer ad-hoc code-sign Perseus Vault for you. If you build the binary yourself, sign it once after each rebuild:cargo build --release cp target/release/perseus-vault ~/.local/bin/perseus-vault codesign --force --sign - ~/.local/bin/perseus-vault # required on Apple Silicon; fixes "Killed: 9"
--forcere-signs an already-signed binary (needed after every rebuild); the step is harmless on Intel macOS and unnecessary on Linux/Windows.
Then wire your MCP client(s) — and the full recall/capture loop — in one command:
perseus-vault install-client --hooks --rules
This autodetects Claude Code / Codex / Cursor (pass --client for
claude-desktop, hermes, windsurf, vscode, zed, or generic; --all-detected
wires every detected client), merges the MCP server registration into the
client's config without clobbering anything (a .bak-perseus backup is
written first), points every client at one shared memory database,
registers the session lifecycle hooks (recall injection on SessionStart,
hygiene on session end — the docs/lifecycle-hooks.md contract), and appends
the memory usage rules to CLAUDE.md/AGENTS.md. Re-running is a no-op; add
--dry-run to preview every file it would touch.
Or connect any MCP host by hand (Claude Desktop, Cursor, Hermes Agent, Perseus, etc.):
{
"mcpServers": {
"perseus-vault": {
"command": "perseus-vault",
"args": ["serve", "--db", "~/.mimir/data/perseus-vault.db"]
}
}
}
# Start Perseus Vault
perseus-vault serve --db memory.db &
sleep 1
# Remember a fact (via MCP JSON-RPC on stdio)
echo '{"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.db
# Search for it
echo '{"jsonrpc":"2.0","id":2,"method":"tools/call","params":{"name":"mimir_recall","arguments":{"query":"Hello"}}}' | perseus-vault serve --db memory.db
Perseus Vault is a standard MCP stdio server — the same perseus-vault serve command works
everywhere. Run perseus-vault doctor to validate your install and print this matrix locally.
| Client | Status | Config |
|---|---|---|
| Claude Desktop | ✅ | claude_desktop_config.json |
| Claude Code / Hermes | ✅ | .mcp.json / config.yaml |
| Cursor | ✅ | .cursor/mcp.json |
| Windsurf | ✅ | mcp_config.json |
| VS Code + Continue.dev | ✅ | config.json |
| Zed | ✅ | settings.json |
| Codex CLI | ✅ | ~/.codex/config.toml |
Copy-paste config snippets for each: docs/clients/.
Then wire the recall → work → capture → consolidate loop to your client's session events (SessionStart/Stop hooks for Claude Code, Codex, and Cursor, plus a portable AGENTS.md fallback): docs/lifecycle-hooks.md.
Composing with a memory washer (CoalWash) and a runtime output compactor (Noisegate) for end-to-end context-budget control: docs/integration/context-budget-stack.md.
Perseus Vault is the only memory engine that is simultaneously MCP-native, local-first, zero-dependency, AND agent-first.
Recall quality measured on LongMemEval's official harness, not a home-grown script:
| Memory engine | QA accuracy |
|---|---|
| Perseus Vault | 73.8% |
| Zep | 63.8% (published) |
| Mem0 | 49.0% (published) |
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 →
Our strongest structural differentiator — full SQL:2011 bi-temporal history (transaction-time and valid-time) — measured against a reproducible, fully offline gauntlet. It drives the real shipped binary over MCP stdio through the hard cases single-axis competitors get wrong (retroactive corrections, proactive future-dated facts, out-of-order arrival, belief-vs-truth divergence, closed periods):
| Axis | Question it answers | Checks | Pass |
|---|---|---|---|
valid-time (valid_at) | "what was true in the world at T" | 10 | 10 |
transaction-time (as_of) | "what did we believe at T" | 1 | 1 |
bi-temporal (bitemporal) | "as of belief at T, what was true at V" | 2 | 2 |
| Total | 13 | 13 (100%) |
Reproduce with a single command (no API key, no network, no LLM):
cargo build --release
python benchmark/temporal/gauntlet.py --bin target/release/perseus-vault
The PASS/FAIL verdicts are deterministic (wall-clock timestamps vary, verdicts
do not), so a correct build re-runs to an identical signature_sha256. The
committed gauntlet_report.json is
the reference. Methodology & dataset →
| Perseus Vault | Mem0 | Letta | Zep | |
|---|---|---|---|---|
| Deployment | Single binary | Cloud + self-host | Docker/Postgres | Docker/Neo4j |
| Dependencies | None (SQLite embedded) | Python + vector DB | Postgres + Python | Neo4j + Go (Graphiti) |
| MCP-Native | ✅ 55+ tools | ❌ Not MCP-native | ❌ Not MCP-native | ❌ Not MCP-native |
| Offline/Local | ✅ Fully local | Cloud-dependent | Docker needed | Docker needed |
| Encryption | AES-256-GCM ✅ | ❌ | ❌ | ❌ |
| Hybrid Search | BM25 + Dense + RRF | Vector only | Vector only | Vector + Graph |
| Entity Lifecycle | Decay + Promote + Archive | ❌ | ❌ | ❌ |
| Entity Graph | Link + Traverse | ❌ | ❌ | ✅ |
| Journal Audit Trail | ✅ Immutable | ❌ | ❌ | ❌ |
| State Management | ✅ Key-value + TTL | ❌ | ❌ | ❌ |
| MCP Tools | 55+ | 5 | 8 | 0 |
| License | MIT | Apache 2.0 | Apache 2.0 | Apache 2.0 |
Full comparison: Perseus Vault vs Mem0 → vs Letta → vs Zep →
Perseus Vault handles production workloads on modest hardware. The numbers
below are from the committed artifact
benchmark/scale/report.json: the real release
binary driven over MCP stdio (one persistent process per corpus size), AMD64
16-core, Windows 11, every write durable before the next is sent.
| Metric | 10K | 100K |
|---|---|---|
| Write throughput, sustained (MCP stdio) | 479 docs/s | 40 docs/s |
| Hybrid recall p50 | 19.03 ms | 79.73 ms |
| FTS5 recall p50 | 3.14 ms | 15.67 ms |
Full percentiles, as_of point lookups, temporal recall, and cold-start
numbers are in benchmark/scale/.
Run it yourself: python benchmark/scale/run.py
Speed is table stakes — the question that matters for agent memory is does the
right memory actually surface? Measured on distinct-content corpora (first-party,
reproducible; see benchmark/lambda/), recall@k by mode:
100,000 entities (1×H100, nomic-embed-text on Ollama):
| recall@k | keyword (BM25/FTS5) | dense | hybrid (RRF) |
|---|---|---|---|
| @1 | 0.003 | 0.680 | 0.785 |
| @5 | 0.015 | 0.859 | 1.000 |
| @10 | 0.029 | 0.899 | 1.000 |
At 100K entities, hybrid recall is perfect @5 while keyword search lands ~1.5% of the time — a ~66× gap. And it widens with scale: at 10K entities keyword recall@5 was 0.008 while hybrid was already 1.000; keyword-only memory silently degrades as an agent accumulates history, hybrid (BM25 + dense + reciprocal-rank fusion) does not. This is the core argument for Perseus Vault's hybrid retrieval.
Head-to-head, same box, same corpus, all fully local (1×H100, Ollama — identical fact set, queries, and substring judge for every system):
| System | Recall accuracy | p50 latency | Notes |
|---|---|---|---|
| Perseus Vault (hybrid) | 1.00 | 35.6 ms | single self-contained binary, in-process |
| Letta (archival / pgvector) | 1.00 | 135.5 ms | server + Postgres/pgvector |
| Mem0 (vector) | 0.60 | 37.9 ms | Python + vector DB |
| Zep (Graphiti temporal KG) | 0.20 | 49.7 ms | server + Neo4j; graph extracted by local model |
Every competitor was stood up and run live on the same box against the same
local Ollama (qwen2.5:14b-instruct + nomic-embed-text) — no cloud, no fabricated
numbers. Letta ran as the letta/letta server (bundled Postgres/pgvector) and matched
Perseus Vault at 1.00. Zep's self-hosted Community Edition server is deprecated and its
zep_python memory API is now Zep Cloud-only, so we measured Zep's actual OSS engine —
Graphiti temporal KG on Neo4j — with entity/edge extraction and embeddings on the same
local Ollama. Its 0.20 reflects the honest cost of building a knowledge graph with a
local model (structured extraction is lossy: 5 entities / 2 edges from 6 facts) — not
Zep Cloud, which uses frontier models. Full artifact + methodology:
benchmark/lambda/results/competitors.json.
Cold-start: a bare GPU box reaches its first grounded RAG answer in 3.3s (models staged on disk).
Reproduce: benchmark/lambda/scale_bench.py and
competitors_bench.py.
Deploying beside a model server on a GPU host (vLLM on MI300X/H100)? See the
AMD MI300X deployment reference — measured
co-residency numbers plus the /dev/shm, PID-1, and version-pinning gotchas
that break these stacks in practice.
Ready-to-use adapters that make Perseus Vault the default memory backend for popular AI agent frameworks:
| Framework | Integration | Type |
|---|---|---|
| LangGraph | MimirStore | BaseStore implementation |
| CrewAI | MimirMemoryTool | Agent tool |
| AutoGen | MimirMemory | Memory implementation |
Each adapter:
Any MCP-compatible framework works with Perseus Vault directly. See Awesome Mimir for the full list.
Tool names & the
perseus_vault_prefix. The tables below use the historicalmimir_*names, but by default the server now advertises each tool once, under its canonicalperseus_vault_*name (e.g.perseus_vault_remember). The legacymimir_*andmneme_*names remain fully callable — every prefix dispatches to the same handler — they are just no longer advertised intools/list. This keeps the advertised manifest to one name per tool instead of tripling it (3× alias bloat), so connected clients don't reload a tripled tool-schema payload on every request. To restore the historical behaviour of advertising all three prefixes, setPERSEUS_VAULT_TOOL_ALIASES=all(the legacy envMIMIR_TOOL_ALIASESis also honoured;PERSEUS_VAULT_takes precedence).Client compatibility (#633). Clients that gate on the advertised list — they check
tools/listbefore calling and skip tools they don't see — will silently skip legacymimir_*calls against a 2.x vault even though the call itself would succeed. Known case: theperseusCLI ≤ 1.0.22 hard-codesmimir_recalland degrades to empty local-only recall. Fix either side: upgrade the CLI to ≥ 1.0.23 (calls canonical names, with dynamic fallback), or setPERSEUS_VAULT_TOOL_ALIASES=allon the vault as a bridge while older clients remain deployed.
| Tool | Description |
|---|---|
mimir_remember | Store/update entity. Idempotent by (category, key); a content change snapshots the prior version into history. |
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. |
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. |
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. |
mimir_recall_layer | Recall from a specific biomimetic layer (world, episodic, semantic). |
mimir_recall_when | Proactive just-in-time recall: surface entities whose recall_when triggers match. |
mimir_get_entity | Fetch one entity by ID with full body_json. |
mimir_as_of | Transaction-time time-travel: the version of a fact (category + key) that was believed at a past instant. |
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). |
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. |
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). |
mimir_forget | Soft-delete (archived=1). |
| Tool | Description |
|---|---|
mimir_ask | RAG: recall context, query LLM, return grounded answer with sources. |
mimir_embed | Generate dense vectors via the bundled model, Ollama, or OpenAI-compatible endpoint. |
mimir_semantic_search | Dense-only semantic search shortcut — find entities by meaning, ranked purely by embedding similarity (no keyword fallback). |
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". |
mimir_ingest | Trigger connector syncs (GitHub, file watcher). |
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. |
mimir_extract | Local, deterministic, rule-based knowledge extraction (facts / preferences / temporal events / episodes) from text or a stored entity. Read-only. |
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. |
mimir_memories | Anthropic memory-tool compatible file interface (view/create/str_replace/insert/delete/rename under /memories), backed by vault entities. |
📖 docs/retrieval-modes.md — one enumerated reference for every retrieval mode (keyword · dense · hybrid · graph · GraphRAG · proactive
recall_when· temporalas_of): mechanism, when to use, invocation, and examples.
| Tool | Description |
|---|---|
mimir_link | Create typed relationship links between entities. |
mimir_unlink | Remove entity links. |
mimir_traverse | Walk entity link graph up to configurable depth. |
mimir_communities | GraphRAG community detection over the link graph (deterministic label propagation or greedy-modularity "louvain"; pure Rust, offline). |
mimir_community_summary | Extractive (optionally LLM-polished) summary of one community, materialized as an entity with evidence_for links to members. |
mimir_global_recall | GraphRAG global search: breadth over community summaries, then depth into the best communities' members — holistic answers across clusters. |
| Tool | Description |
|---|---|
mimir_journal | Append structured event with actor attribution. |
mimir_check_failure_pattern | Deja-vu guard: check an action against previously recorded failures (journal + failure/pitfall entities) before retrying it. Read-only. |
mimir_timeline | Query journal by time range with filters. |
| Tool | Description |
|---|---|
mimir_state_set | Set key-value state with optional TTL. |
mimir_state_get | Get state value. Returns null if expired. |
mimir_state_delete | Delete state entry. |
mimir_state_list | List state keys, optionally filtered by prefix. |
| Tool | Description |
|---|---|
mimir_decay | Recalculate Ebbinghaus decay scores (batched 1000-entity transactions). |
mimir_prune | Bulk archive by category, decay threshold, or age. |
mimir_purge | Permanently delete archived entities + VACUUM. Destructive. |
mimir_cohere | Autonomous coherence grooming pass — promote, decay, link, archive. |
mimir_autocohere | Full atomic grooming: cohere → decay → compact in one pass (supports dry-run). |
mimir_compact | Archive entities below decay threshold. |
mimir_reindex | Rebuild FTS5 search index from entities table. |
mimir_consolidate | Merge overlapping/duplicative entities in a category into durable, evidence-tracked observations (mirror image of mimir_conflicts). |
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. |
| Tool | Description |
|---|---|
mimir_score | Assign quality score (0.0-1.0). |
mimir_conflicts | Detect conflicting entities via trigram similarity; opt-in resolve=true invalidates the lower-certainty side into history (reversible, dry-run by default). |
mimir_correct | Structured correction capture for learning from errors. |
mimir_supersede | Mark a new fact as superseding an old one (sets the old entity to deprecated). |
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). |
| Tool | Description |
|---|---|
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. |
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. |
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. |
| Tool | Description |
|---|---|
mimir_vault_export | Export entities to .md files with YAML frontmatter. |
mimir_vault_import | Import from .md vault directory (idempotent). |
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. |
mimir_share | Share one entity (by category + key) into another workspace, preserving content. |
mimir_workspace_list | List all distinct entity categories. |
| Tool | Description |
|---|---|
mimir_stats | Full DB statistics across all tables. |
mimir_health | Server and DB health check. |
mimir_bench | Performance benchmark tracking. |
mimir_maintenance | DB maintenance: dedup, orphan detection, VACUUM, FTS5 reindex (supports dry-run). |
mimir_synthesize | LLM session synthesis — extract lessons from transcripts. |
mimir_migrate | Migrate v0.1.x DB to current schema. |
# Server
perseus-vault serve --db /data/perseus-vault.db
perseus-vault serve --web --port 8767 --encryption-key ~/.mimir/secret.key
perseus-vault serve --llm-endpoint http://localhost:11434/api/generate --llm-model llama3
perseus-vault serve --transport sse --port 8787 --mcp-token my-secret-token
# Maintenance (operate directly on DB, no server needed)
perseus-vault stats --db /data/perseus-vault.db
perseus-vault forget --db /data/perseus-vault.db --category decision --key stale-choice --reason "superseded"
perseus-vault prune --db /data/perseus-vault.db --category junk --min-decay 0.1 --dry-run
perseus-vault purge --db /data/perseus-vault.db --dry-run
perseus-vault decay --db /data/perseus-vault.db
perseus-vault reindex --db /data/perseus-vault.db
perseus-vault vault-export --db /data/perseus-vault.db --vault-dir ./export/
perseus-vault vault-import --db /data/perseus-vault.db --vault-dir ./export/
perseus-vault obsidian-sync ~/obsidian-vault/Perseus Vault/ # one-shot export to an Obsidian vault
perseus-vault obsidian-sync ~/obsidian-vault/Perseus Vault/ --watch # continuous sync on every memory change
# Key management
perseus-vault keygen --key-file ~/.mimir/secret.key
Manual DB edits. The maintenance verbs above and the normal MCP write path keep the FTS5 index in sync automatically. Editing the
entitiestable directly withsqlite3(a manualDELETE/UPDATE) bypasses that sync and can leave orphaned index rows — "ghost" recall hits for content that is already gone. After any direct SQL edit, runperseus-vault maintain --db(orperseus-vault reindex) to reconcile the FTS index.
| Flag | Description |
|---|---|
--db | SQLite database path (default: ~/.mimir/data/perseus-vault.db) |
--web | Start web dashboard |
--port | Dashboard port (default: 8767) |
--web-bind | Dashboard bind address (default: 127.0.0.1) |
--transport | MCP transport: stdio (default), sse, or http |
--mcp-token | Bearer token for SSE/HTTP transport auth |
--encryption-key | AES-256-GCM key file path |
--llm-endpoint | LLM API endpoint for mimir_ask and embeddings |
--llm-model | LLM model name (default: llama3) |
--llm-api-key | API key for LLM endpoints (OpenAI, Azure, etc.) |
--embedding-endpoint | OpenAI-compatible embedding endpoint |
--connectors-config | Path to connectors.yaml |
The canonical database path is:
~/.mimir/data/perseus-vault.db
Always pass --db (or set $MIMIR_DB_PATH) in scripts, MCP host configs, and
cron/harvest jobs so every invocation targets the same file. When neither is
set, Perseus Vault resolves the default in this order and uses the first that
already exists (so upgraders and legacy single-user installs are picked up
instead of silently starting empty):
~/.mimir/data/perseus-vault.db — canonical (current name)~/.mimir/data/mneme.db — pre-rename~/.mimir/data/mimir.db — pre-rename~/mimir.db — legacy single-user install locationIf none exist, it creates ~/.mimir/data/perseus-vault.db. If more than one
of these exists and you did not pass --db/$MIMIR_DB_PATH, Perseus Vault
prints a stderr warning naming the chosen file and the others it ignored, so an
ambiguous multi-database state is visible rather than silent. Setting --db or
$MIMIR_DB_PATH explicitly always wins and suppresses the warning.
Perseus Vault is your AI agent's long-term memory — and it doubles as your second brain. Every entity your agent remembers exports to a plain Markdown note with YAML frontmatter, so your AI's memory becomes a navigable personal knowledge base inside the tools you already use: Obsidian, Logseq, or Notion.
# Export your entire memory to an Obsidian vault as linked Markdown notes
perseus-vault obsidian-sync ~/obsidian-vault/Perseus Vault/
# Keep it live — re-export automatically on every memory change
perseus-vault obsidian-sync ~/obsidian-vault/Perseus Vault/ --watch
Open the vault in Obsidian and you get a graph of your agent's knowledge.
WikiLink backlinks. When one entity links to another (via mimir_link or a
depends_on / implements / references relationship), the exported note gets
a ## Links section with [[WikiLink]] backlinks that resolve natively in
Obsidian's graph view:
---
id: cli-de8dfb8364b6
category: architecture
key: api
type: insight
decay_score: 0.5000
---
{"content":"axum service"}
## Links
- [[cli-99756b494c7d|database]] (depends_on)
Links resolve by entity id (notes are written as .md) so they never
break, and Obsidian shows the human-readable key as the link label. Open the
graph view and your agent's architecture, decisions, and insights become a
clickable knowledge map.
--watch polls Perseus Vault's cheap, deterministic state digest on an interval and
re-exports only when memory actually changes. It naturally catches every
mimir_remember write with no filesystem-watcher dependency and no coupling to
the server. Tune the interval with MIMIR_SYNC_INTERVAL_SECS (default: 2s).
| Tool | How |
|---|---|
| Obsidian | perseus-vault obsidian-sync — WikiLinks resolve in the graph view out of the box. |
| Logseq | Point obsidian-sync at your Logseq graph directory. Logseq reads the same [[WikiLink]] syntax and Markdown frontmatter. |
| Notion | Run perseus-vault vault-export, then use Notion's Import → Markdown & CSV to pull the notes in. |
Unlike cloud-only "second brain" tools, Perseus Vault runs 100% local, is written in Rust, encrypts at rest with AES-256-GCM, and applies decay scoring so stale memories fade — your knowledge base stays yours and stays fresh.
bundled-embeddings feature).mimir_remember embeds each new (or
content-changed) entity synchronously as it is written, using the bundled
model. Single-entity embedding is deterministic and LRU-cached, so it is cheap
and adds no background tasks. Embedding failures are non-fatal (logged to
stderr); the write always succeeds.mimir_recall(query=...) with
no mode flag automatically selects hybrid (dense + keyword fused via RRF)
whenever embeddings exist, and transparently falls back to fts5 keyword
search when none do. No manual mimir_embed step, no flags to remember.mimir_semantic_search(query, limit) — a one-tool shortcut for pure
dense, meaning-based search (no keyword fallback) when you just want "find
things like this"./v1/embeddings endpoint instead of the bundled model, set --llm-endpoint
(and --embedding-endpoint / --llm-api-key as needed). This is entirely
optional; the bundled model is used by default.cargo build --no-default-features — recall then defaults to keyword search
unless a remote embedder is configured.Perseus Vault models memory using three biomimetic layers, inspired by human memory pathways:
You can interact with these layers directly using the mimir_recall_layer tool or by specifying the layer parameter in mimir_remember.
recall_when triggers)The vault is the query layer — it retrieves the few facts a turn needs instead of
handing the host a standing blob to staple into every system prompt.
mimir_context and perseus-vault prepare are recall-first by default:
query (the current task/message) and only entities
whose recall_when triggers or indexed content match it are injected. No query,
no topical injection: the block is a compact retrieval pointer, byte-stable
across unrelated vault writes (prefix-cache friendly).max_context_chars overrides both.always_on: true still works for identity-critical
facts, but the recall-first set is hard-capped (top 5) and overflow emits a
warning steering you to recall_when triggers.mode: "always_inject" (--legacy-context for prepare), unclamped unless
you pass a budget.perseus-vault prepare --task "deploying the payments service" --model claude-sonnet-4-6
perseus-vault prepare --task "..." --max-context-chars 800 # explicit budget
perseus-vault prepare --task "..." --legacy-context # old dump, opt-in
mimir_ask — natural language Q&A over stored memories via any LLM (Ollama, OpenAI, etc.)mimir_embed — generate and store dense vectors via Ollama or OpenAI-compatible /v1/embeddingsbody_json--encryption-key flagperseus-vault keygen subcommand for key generationperseus-vault serve --web --port 8767)127.0.0.1 (use --web-bind 0.0.0.0 to expose).md/.txt/.json files with content-hash dedup--connectors-configPerseus Vault is the default memory backend for Perseus:
mimir:
enabled: true
transport: "stdio"
command: ["perseus-vault", "serve", "--db", "~/.mimir/data/perseus-vault.db"]
timeout_s: 30.0
merge_strategy: "local_first"
fallback_to_local: true
context_categories: ["decision", "architecture", "convention"]
context_limit: 10
Perseus Vault is built for government deployment from the ground up.
| Capability | Status |
|---|---|
| License | MIT — no copyleft, no GPL/AGPL |
| SBOM | Published — NTIA minimum elements |
| Air-gapped | Fully offline — no telemetry, no API calls, no network by default |
| Encryption at rest | AES-256-GCM, transparent, opt-in |
| Audit trail | Immutable journal with chain-of-custody |
| Supply chain | SLSA attestation in progress |
For federal buyers: See docs/federal-buyers.md for procurement information, compliance status, and deployment models (air-gapped, on-premises, classified environments).
Perseus Computing LLC is a US-owned small business. SAM.gov registration in progress. NAICS: 541715, 541511, 541512.
Perseus Vault is a local-first MCP server — it runs entirely on your machine.
--db.mimir_forget), archived (via decay/compact), or permanently purged (mimir_purge).Release binaries are built from tagged commits via GitHub Actions. Every release ships:
| Artifact | Description | Verification |
|---|---|---|
perseus-vault-.tar.gz | Full build (bundled embeddings, glibc) | SHA-256 checksum in .sha256 sidecar |
perseus-vault-lite-.tar.gz | Lean build (--no-default-features, musl/static) | SHA-256 checksum in .sha256 sidecar |
| SLSA provenance attestation | Sigstore-signed build provenance | gh attestation verify --repo Perseus-Computing-LLC/perseus-vault |
# 1. Verify SHA-256 checksum
sha256sum -c perseus-vault-lite-x86_64-unknown-linux-musl.tar.gz.sha256
# 2. Verify SLSA build provenance (requires gh CLI + OIDC session)
gh attestation verify perseus-vault-lite-x86_64-unknown-linux-musl.tar.gz \
--repo Perseus-Computing-LLC/perseus-vault
# 3. Confirm the binary identity
./perseus-vault --version
# Should show both the release version AND the git commit hash, e.g.:
# perseus-vault 2.20.2 (v2.20.2-0-gabcdef1)
# 4. Confirm the doctor reports the same identity
./perseus-vault doctor --db /tmp/test.db | head -1
# perseus-vault doctor — v2.20.2 (v2.20.2-0-gabcdef1)
# The exact same binary (bit-for-bit) requires matching:
# - Rust toolchain version (see rust-toolchain.toml)
# - Locked dependencies: `cargo build --locked`
# - Build flags: `--release` for release builds
cargo build --locked --release
./target/release/perseus-vault --version
MIT — see LICENSE.
Install via CLI
npx mdskills install Perseus-Computing-LLC/perseus-vaultPerseus Vault is a free, open-source AI agent skill. 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
Install Perseus Vault with a single command:
npx mdskills install Perseus-Computing-LLC/perseus-vaultThis downloads the skill files into your project and your AI agent picks them up automatically.
Perseus Vault works with Claude Code, Claude Desktop, Cursor, Vscode Copilot, Windsurf, Continue Dev, Gemini Cli, Amp, Roo Code, Goose. Skills use the open SKILL.md format which is compatible with any AI coding agent that reads markdown instructions.