OpaqueVault is a zero-knowledge secret manager with a local MCP integration for AI coding workflows. It encrypts secret names and values on your machine and lets an agent request authenticated commands without receiving the credentials in a tool response.
We built OpaqueVault. This article describes our implementation; it does not claim that OpaqueVault is the only zero-knowledge or agent-oriented secrets product.
What does an MCP secret manager return?
The response is the important boundary. A tool that returns a credential to an agent can put that value into model context, transcripts, or downstream logs. OpaqueVault’s MCP tools return names, status, and operation metadata, rather than stored secret values.
The current MCP surface has eight tools:
| Tool | Purpose |
|---|---|
vault_run |
Run a command with selected secrets injected into its environment |
vault_list_secrets |
List names and metadata, without values |
vault_secret_exists |
Check whether a named secret exists |
vault_create_secret |
Store a new encrypted secret |
vault_update_secret |
Update a secret |
vault_delete_secret |
Delete a secret with confirmation |
vault_status |
Check session and context status |
vault_check_context |
Verify the intended app and environment |
There is no tool for retrieving a stored secret value. Enter new values through a trusted local workflow rather than pasting them into an AI conversation.
What happens when the agent calls vault_run?
The local daemon decrypts the selected credentials and injects them into the child process. The MCP response contains the exit code and run metadata. Since v0.16.0, it omits both stdout and stderr; output goes to the daemon terminal or agent log for the user.
Agent requests a command by secret name → Local daemon decrypts selected credentials → Child process receives its environment → Agent receives exit code and run metadataFor example, a request can name a credential without containing its value:
{ "command": ["npm", "test"], "secret_names": ["DATABASE_URL"], "expected_app": "myapp", "expected_env": "dev"}See the vault_run reference for the full request and response contract.
Where does decryption happen?
The local ov agent daemon holds the unlocked key material and performs secret operations. The ov mcp serve bridge connects the MCP client to that daemon. The remote API stores encrypted secret data without the keys needed to decrypt it.
This is not a promise that the service knows nothing about an account. It also handles operational metadata, including account information, app and environment slugs, and audit records. See the security model for that boundary.
How are secrets encrypted?
OpaqueVault uses Argon2id for password-based key derivation and AES-256-GCM for envelope encryption. The CLI enforces TLS 1.3 with the ML-KEM-768 + X25519 hybrid exchange for connections to its API. That transport protection is separate from the encryption of stored data.
The server’s lack of decryption keys and the MCP response boundary address different risks. Neither removes the need to trust the local machine and the programs that receive credentials.
What are the limits?
A child process intentionally receives plaintext credentials and can use them. Its output, local logs, files, and network behavior need appropriate controls. Omitting output from an MCP response does not sandbox the command or prevent another tool with filesystem access from reading a log.
Environment inheritance runs from parent to child. Injecting a credential into a child does not place it in the parent agent’s environment. Launching the agent itself inside a secret-bearing environment does expose that credential to the agent process.
How do I get started?
Follow the quickstart to install the CLI, authenticate, start the daemon, create an app and environment, and connect your MCP client. Use the documented context checks to keep each command scoped to its intended project.
Updated October 23, 2026: removed exclusivity language and aligned the tool list, daemon architecture, and output behavior with the current implementation.