Skip to content

Claude Code

import { Steps, Aside } from ‘@astrojs/starlight/components’;

OpaqueVault is designed first and foremost for Claude Code. This guide covers the full setup.


Terminal window
brew install opaquevault-brew/tap/ov
ov login

Terminal window
ov secret set DATABASE_URL
ov secret set OPENAI_API_KEY
ov secret set STRIPE_SECRET_KEY

Claude Code reads MCP server configuration from ~/.claude/claude_desktop_config.json.

{
"mcpServers": {
"opaquevault": {
"command": "ov",
"args": ["mcp", "serve"]
}
}
}

Save the file and restart Claude Code. You should see OpaqueVault listed in the MCP servers panel.


In Claude Code, ask:

“Check the OpaqueVault status.”

Claude will call vault_status and respond with your session info, secret count, and interceptor status.


Claude Code can now:

Run commands with secrets:

“Run the database migrations using my DATABASE_URL secret.”

Check what secrets are available:

“What secrets do I have stored in OpaqueVault?”

Store a new secret:

“Store my new Stripe key as STRIPE_SECRET_KEY.”


You: Run the database migrations.
Claude: I'll run the database migrations using your DATABASE_URL secret.
[Calls vault_run({ command: "go run ./cmd/migrate", secrets: ["DATABASE_URL"] })]
Result: exit_code: 0, stdout: "migrations: 3 applied"
Claude: The migrations ran successfully — 3 migrations were applied.

The database URL never appeared. Not in Claude’s thinking, not in the response, not in logs.


If you accidentally paste a raw secret into the Claude Code chat:

You: Here's the connection string for debugging: postgres://admin:[email protected]/app
Claude: [OpaqueVault] Potential secret intercepted (postgres-dsn). Message blocked.
Store this value with 'ov secret set DATABASE_URL' instead.

The interceptor caught it before Claude saw the value. The interception is logged to your audit trail.


OpaqueVault not showing in MCP servers:

  • Verify ov is in your PATH: which ov
  • Check the config file path and JSON syntax
  • Restart Claude Code completely (quit and reopen)

vault_run returns secret_not_found:

  • Run vault_list_secrets to see what’s stored
  • Secret names are case-sensitive — DATABASE_URLdatabase_url

Interceptor blocking legitimate content:

  • Check OV_INTERCEPT_MODE=warn to see what’s being flagged without blocking
  • High-entropy false positives can be tuned — file an issue on GitHub