Build on governed memory.
Context Vault gives your agents a memory that is time-correct, access-filtered and provable. Read through it before you act; write through it after. Everything below runs against the open-core package — start in-memory on a laptop, move to a durable store when you ship.
Install
Context Vault is a Python package with an optional MCP server. The fastest path is the MCP on-ramp — it starts on an ephemeral in-memory backend with zero database setup, exposing two verbs, remember and recall.
# run the MCP server (stdio) — zero database setup $ uvx --from context-vault-ai context-vault-mcp # or install the library into your project $ pip install "context-vault-ai[embeddings]"
VAULT_STORE=neo4j for the durable store. Semantic ranking needs the embeddings extra; without it, recall falls back to keyword matching.Principals & access
Every call is made as a principal — an identity with a role and a set of labels. The Vault is deny-by-default: a principal sees a claim only if its clearance covers that claim's visibility labels. The same query returns different facts for different agents.
from context_vault.app import build_vault from context_vault.sdk import VaultClient from context_vault.models.principal import Principal vault = build_vault(); vault.init() # a principal-scoped client — role + need-to-know labels client = VaultClient(vault, Principal( id="advisor-7", role="agent", labels=["team:risk"]))
- Roles (
admin,agent,user,reader) gate which operations a principal may invoke. Unknown roles get no permissions — least privilege. - Labels gate which claims a principal may read. This visibility axis is separate from roles and can only ever add denials, never widen a read.
Assert — write a fact
Write a subject–predicate–object claim. The Vault decides how it fits existing knowledge — never a silent overwrite. Pass validity bounds for time-correct facts and visibility labels for access control.
client.assert_fact("cust:8841", "risk_rating", "elevated", valid_from=datetime(2026, 5, 20), visibility=["team:risk"], confidence=0.9) # -> CONTRADICTION vs "low" @ apr 2 -> resolved by trust/recency # write many at once client.assert_batch([ {"subject": "cust:8841", "predicate": "segment", "object": "private banking"}, ])
Resolve — read what's true
Retrieve only the claims that are current and authorized for the calling principal. Pass as_of to time-travel — resolve the belief state exactly as it stood on any past date.
# current, authorized belief state for claim in client.resolve("risk for cust:8841", top_k=5): print(claim.edge_str()) # time-travel: what did the agent see on May 5? past = client.resolve("risk for cust:8841", as_of=datetime(2026, 5, 5))
A reader-role principal resolves under the same ACL but is denied every mutation — useful for read-only analytics or audit tooling.
Reconcile — resolve conflicts
On every write, an incoming claim is classified against what's already known. A six-way taxonomy decides what the new fact means so memory never silently corrupts:
- Contradiction — conflicting values over overlapping validity; resolved by source-trust → confidence → recency, or escalated.
- Supersession — a clean update over time; the old claim moves to history and is still resolvable in the past.
- Refinement — more specific, not contradictory; both kept and linked.
- Duplicate — semantically identical; deduped, with the re-assertion still recorded.
- Independent — unrelated; stored fresh as a new current claim.
- Ambiguous — below the confidence margin; routed to a human review queue.
Decay — keep memory clean
Confidence fades over time and stale history compresses, so quality doesn't rot as volume grows. Decay-family verbs (archive, compress, consolidate) are themselves permission-gated and audited.
# archive the principal's own matching claims (gated: DECAY permission) vault.forget_matching("kyc_refresh_due for cust:8841", principal=admin)
Audit — prove what was known
Every read and write is recorded on an append-only, hash-chained log. Replay reconstructs exactly what any principal could see at any moment — with a cryptographic receipt.
# reconstruct a principal's belief state at a past instant rows = client.audit_replay( as_of=datetime(2026, 5, 5), principal_id="advisor-7")
The chain is RFC 3161 timestamped and can be anchored to an RFC 6962 transparency log. See Security for the full tamper-evidence model.
MCP server
Connect Context Vault to Claude Code, Cursor, or any MCP client. The headline tools are the two verbs; lower-level vault_* tools remain for structured use.
remember(text, user)— extract claims from natural language and assert them, each conflict-checked. NeedsANTHROPIC_API_KEY.recall(query, user)— governed retrieval: time-correct, ACL-filtered context. Works without an API key.
{
"mcpServers": {
"context-vault": {
"command": "uvx",
"args": ["--from", "context-vault-ai", "context-vault-mcp"],
"env": { "ANTHROPIC_API_KEY": "sk-..." }
}
}
}Each user gets its own private principal automatically — no register-first step.
Backends
Pick a store with the VAULT_STORE environment variable. The operation surface is identical across all three — agent code never changes.
memory— default. Ephemeral, single-process. Trials, tests, air-gapped demos.sqlite— a durable single-file store for local self-hosting with no server.neo4j— the durable graph store for production, with the full bitemporal model.
SDKs
The Python SDK (VaultClient) is in-process for the MVP and maps cleanly onto the HTTP/MCP transport, so agent code is portable. A TypeScript SDK mirrors the same surface.
- Python —
context_vault.sdk.VaultClient:assert_fact,assert_batch,resolve,extract,audit_replay. - TypeScript — the same verbs over the HTTP API, for agents running in Node.
- HTTP API — language-neutral REST for everything else.