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 can optionally be RFC 3161 timestamped and anchored to an RFC 6962 transparency log.
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.