VaultZero
VaultZero lets an AI agent store encrypted facts and recall them by semantic similarity within permitted scopes.
Store a fact with
remember_factusingfact_textand a permittedscope, with optionalretention(default30d).Recall relevant encrypted memories with
recall_contextusing aqueryand permittedscopes, with optionallimit(default5).Encryption and decryption happen locally; the server stores ciphertext and vectors, and recalled text is framed as untrusted data.
The agent cannot choose tenant, user, or key, and cannot grant itself a scope.
Allows configuring an OpenAI-compatible embeddings endpoint, such as text-embedding-3-small, to generate vector embeddings for stored memories and recall queries.
VaultZero Client
An MCP server that gives an AI agent long-term memory it cannot read. VaultZero is a privacy-first memory vault: this package embeds and encrypts every memory on your machine before it is sent, so the server stores ciphertext and vectors and never holds a key.
This repository is the trusted, customer-side client: the SDK, the crypto, the embedding adapters, and the Model Context Protocol server. It is the only code that ever sees plaintext or holds payload keys.
The server stores ciphertext, vector embeddings (which can be partially inverted to text), scope labels, record sizes and timestamps. It cannot read your memories, but it is not "a server that knows nothing". See the trust model below.
MCP server
Two tools, so an agent can remember across sessions and recall by meaning rather than by key:
Tool | What it does |
| Encrypts a fact locally and stores it under a scope you permit. |
| Embeds the query, retrieves the nearest ciphertext envelopes, verifies each one, and decrypts locally. |
The model never chooses a tenant, a user, or a key, and cannot grant itself a scope. Remembered text comes back explicitly framed as untrusted data, so a stored instruction cannot become a command.
Install
Requires Python 3.10 or newer.
pip install vaultzero # or: uv tool install vaultzeroConfigure a client
{
"mcpServers": {
"vaultzero": {
"command": "uvx",
"args": ["--from", "vaultzero", "vaultzero-mcp"],
"env": {
"VZ_BASE_URL": "https://api.vaultzero.cc",
"VZ_CREDENTIAL": "<your 64-hex-character bearer credential>",
"VZ_KEY_STORE_PATH": "~/.vaultzero/keys.json",
"VZ_EMBEDDING_BASE_URL": "https://<your-embeddings-endpoint>/v1"
}
}
}
}--from vaultzero is not optional. vaultzero-mcp is the console script inside the
vaultzero package, not a package name, so uvx vaultzero-mcp fails with "Because
vaultzero-mcp was not found in the package registry". The flag tells uvx which package to
install before running that script.
VZ_BASE_URL and VZ_CREDENTIAL are required. The other three are strongly recommended and
are described under Configuration.
Docker
docker build -t vaultzero-mcp .
docker run -i --rm \
-e VZ_BASE_URL=https://api.vaultzero.cc \
-e VZ_CREDENTIAL=... \
-v vaultzero-keys:/keys -e VZ_KEY_STORE_PATH=/keys/keys.json \
vaultzero-mcp-i without -t: stdio transport needs a raw stdin, not a TTY. The image runs as UID 10001
and ships no pip.
Related MCP server: Decay Memory
Configuration
Variable | Required | Purpose |
| yes | Bare HTTPS origin of the VaultZero API. |
| yes | Bearer credential. Secret. |
| recommended | Where payload keys persist. Without it keys live in memory and every memory becomes unreadable when the process exits. |
| recommended | OpenAI-compatible embeddings endpoint, ideally customer-controlled. Without it a hashing test provider is used, which gives no meaningful retrieval. |
| no | Bearer token for the embeddings endpoint. Secret. |
| no | Pin the embedding space. Changing any of them changes the vectors and makes existing memories unsearchable. |
| no | Comma-separated scopes this process may use. Defaults to |
| no | Retention values offered to the model. Defaults to |
Trust model
What the server can and cannot see, stated precisely:
It cannot read a memory: payloads are AES-256-GCM ciphertext, and keys exist only in this process's key store.
It can see vector embeddings, which are partially invertible to text. Treat the embeddings endpoint and the API origin as part of your data path.
It can see the shape of your data: scope labels, record sizes, timestamps, and identifiers.
Memory contents are only as safe as the key store. Losing every copy of a key makes its
memories unrecoverable by design; production hosts should use FileKeyStore or a
KMS/keychain adapter, not the in-memory default.
Contents
SDK (
vaultzero.client.sdk): HTTP lifecycle, retries, key lookup, and local decryption.Crypto (
vaultzero.client.crypto): AES-256-GCM envelope encryption with authenticated associated data.Embeddings (
vaultzero.client.embeddings): embedding-provider adapters with pinned embedding-space configuration.MCP host (
vaultzero.client.mcp_server): a Model Context Protocol server exposingremember_factandrecall_contexttools to an agent.
Layout
vaultzero/client/ SDK, MCP adapter, crypto, embedding providers
tests/unit/ golden vectors and unit tests for the clientInstalling the SDK
Requires Python 3.10 or newer.
pip install vaultzeroThe dependencies (cryptography, httpx, mcp) are installed with the package: this is an
MCP server first, so there is no extra to remember. It installs the vaultzero-mcp console
script and makes vaultzero.client.sdk.VaultZeroClient importable.
SDK usage
import asyncio
from vaultzero.client.embeddings import EmbeddingSpace, OpenAICompatibleEmbeddings
from vaultzero.client.sdk import FileKeyStore, VaultZeroClient
async def main() -> None:
client = VaultZeroClient(
base_url="https://api.example.com",
credential="<64-hex-character bearer secret>",
key_store=FileKeyStore("~/.vaultzero/keys.json"),
embedding_provider=OpenAICompatibleEmbeddings(
space=EmbeddingSpace(
space_id="my-space-v1",
model="text-embedding-3-small",
revision="1",
preprocessing="nfc-strip-v1",
),
base_url="https://<customer-controlled-embeddings>",
api_key=None,
),
)
memory_id = await client.remember_fact("prefers oat milk in coffee", scope="preferences")
results = await client.recall_context("coffee milk", scopes=["preferences"])
await client.delete(memory_id)
await client.aclose()
asyncio.run(main())Keys: one active key per scope, resolved only from the bound subject's trusted key store and
reused across writes until rotated. Losing every copy of a key makes its memories
unrecoverable, so production hosts must use a persistent store (FileKeyStore or a
KMS/keychain adapter).
MCP host
Run the MCP host (the trusted process that holds keys and sees plaintext):
VZ_BASE_URL=https://... VZ_CREDENTIAL=<secret> VZ_KEY_STORE_PATH=~/.vaultzero/keys.json \
VZ_EMBEDDING_BASE_URL=https://<customer-controlled-embeddings> vaultzero-mcpWithout VZ_KEY_STORE_PATH keys live in memory and every memory becomes unreadable when the
process exits. Optional: VZ_PERMITTED_SCOPES, VZ_RETENTION_CHOICES (add forever only
for credentials with a retention grant), VZ_SERVERLESS_TOKEN for IAM-protected endpoints.
Security model
Local encryption: AES-256-GCM; the associated data binds every envelope to its exact tenant, user, agent, subject epoch, memory id, scope, entity token, key id, embedding space, and expiration.
No plaintext to the server: the SDK embeds and encrypts before sending anything.
Integrity on recall: every recalled envelope is re-checked against the authenticated request context before decryption; tampered or mismatched envelopes raise
IntegrityError.No redirects: the HTTP client never forwards credentials to a redirect target.
Golden vectors live in tests/unit/golden_vectors.json; any other SDK implementation must
reproduce them.
Tests
uv run --python .venv/bin/python -m pytestAvailable Tools
2 toolsrecall_contextC
Recall encrypted memories most similar to a query across permitted scopes.
| Name | Required | Description | Default |
|---|---|---|---|
| limit | No | ||
| query | Yes | ||
| scopes | Yes |
Output Schema
| Name | Required | Description |
|---|---|---|
| result | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations, the description carries the full disclosure burden. It does add two useful facts — memories are encrypted and results are constrained to 'permitted scopes' (an authorization filter) — but it says nothing about result ordering, default limit behavior, or what happens when no scopes are permitted.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
One sentence, front-loaded with the core action, with no filler or redundancy. It is efficient, but the brevity comes at the cost of the missing parameter and scoping detail noted elsewhere.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
An output schema exists, so return values need not be explained, but the tool still has three undocumented parameters and zero annotations. The single sentence does not cover the 'limit' semantics, the expected format of 'scopes', or result ordering, which an agent needs in order to invoke it correctly.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 0%, so the description must compensate for all three parameters. It clarifies 'query' as semantic similarity search and hints that 'scopes' is an access-permission list, but the 'limit' parameter (default 5) is never mentioned anywhere, leaving a third of the input surface undocumented.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description gives a specific verb and resource ('Recall ... memories') plus a meaningful qualifier ('encrypted', 'most similar to a query'). Read against the sibling remember_fact, the retrieve-vs-store distinction is evident without opening either schema, though the tool never names the sibling explicitly.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Usage is only implied: an agent can infer it should call this when it has a query and wants semantically similar prior memories. There is no explicit when-to-use/when-not statement, no mention of limits or scope prerequisites, and no routing guidance against remember_fact.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
remember_factC
Store a fact in encrypted memory under a permitted scope.
| Name | Required | Description | Default |
|---|---|---|---|
| scope | Yes | ||
| fact_text | Yes | ||
| retention | No | 30d |
Output Schema
| Name | Required | Description |
|---|---|---|
| result | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
No annotations are supplied, so the description carries the full burden and mostly doesn't. "Encrypted memory" and "permitted scope" hint at security and permission constraints, but nothing is said about required auth, what happens to existing similar facts (overwrite/dedupe/append), retention expiry behavior, or failure modes for an unpemitted scope.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
A single front-loaded sentence with zero filler or redundancy. Its terseness is a completeness problem rather than a verbosity problem, so it scores well here.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a mutation tool with no annotations, zero schema coverage, and an opaque required "scope" string, this is under-specified. The output schema removes the need to describe return values, but key input semantics (scope vocabulary, retention effect) and write behavior remain unknown.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 0% across three parameters, so the description must compensate and largely fails. "Fact" and "permitted scope" loosely map to fact_text and scope (the latter gaining only the vague qualifier "permitted"), while the retention parameter and its 30d default are never mentioned and no valid scope values are given.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb ("Store") and resource ("a fact in encrypted memory"), which is far better than a tautology. The store-vs-recall split against the sibling recall_context is strongly implied but never made explicit.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
There is no when-to-use, when-not-to-use, or named alternative; recall_context is never referenced. The agent must infer the write-vs-read division of labor from the verb alone.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
Tool Schema Changelog
Recent tool additions, removals, and schema changes observed during successful MCP inspections.
2 tool updates
v0.1.2- First observed
recall_context - First observed
remember_fact
TDQS
Scored across 2 tools
The two tools have clearly distinct purposes: remember_fact is a write/store operation and recall_context is a similarity-based read/query operation. There is no realistic scenario in which an agent would confuse which one to call.
Both names follow a verb_noun pattern (remember_fact, recall_context) in snake_case, which is consistent and readable. The nouns differ in style (fact vs context) slightly muddying the symmetry, but the pattern holds.
Two tools is thin for a memory server; store and retrieve are the core pair, but a domain like this typically warrants at least a delete/forget operation. It is borderline rather than clearly wrong, since the surface is minimal by design.
The write/read pair covers the basic memory lifecycle, but there is no way to forget, update, or correct a stored fact, and no listing or scope-management operation. These are notable gaps that could cause dead ends when memories become stale or incorrect.
Maintenance
Related MCP Connectors
Cloud-hosted MCP server for durable AI memory
Persistent memory for AI assistants — one shared, OAuth-secured vault for every MCP client.
Hosted memory for AI agents over MCP. One memory shared by all your agents.
Token-efficient MCP memory for Markdown vaults. Tiered search, GraphRAG, AI memories.
Related MCP Servers
- AlicenseAqualityAmaintenanceA local-first MCP server that gives AI coding agents persistent memory and controlled commands. Features a git-backed markdown knowledge vault with FTS5 search, surgical section edits, token-aware context budgeting, and a sandboxed command engine with human approval gates. Works with Claude Code, Cursor, Copilot, Gemini, and more.5854 npm1Apache 2.0
- AlicenseNot gradedqualityDmaintenanceAn MCP server that gives AI agents persistent, forgetting memory with layered decay, semantic search via token overlap, and zero external dependencies.MIT
- AlicenseNot gradedqualityBmaintenanceZero-knowledge, self-hostable MCP server providing encrypted durable memory for AI agents, with tools to save, recall, search, list, and delete memories.432 npm68MIT
- AlicenseAqualityCmaintenanceA tiny MCP server that wraps Perseus Vault to provide persistent, encrypted, local-first memory for OpenAI Codex agents, enabling them to remember project conventions, decisions, and context across sessions.5MIT