Skip to content

vault_run

vault_run is the core tool. It decrypts the requested secrets locally, spawns a subprocess with them as env vars, and returns only the exit code and output. The plaintext values are zeroed from memory immediately after the process exits.

Each call runs against the (app, env) pair resolved and verified from the project’s .ov.yaml. Since OV-305 the vault daemon enforces that environment end-to-end — previously it was bridge-verified only, and the daemon silently served its start-time env. If the environment no longer exists in the app, the call fails closed with ENV_NOT_FOUND.


ParameterTypeRequiredDescription
commandstring[]YesThe command to run as an argv array
secretsstring[]NoNames of secrets to inject. If omitted, injects all secrets in the active app
work_dirstringNoWorking directory for the command. Defaults to the current directory
timeout_secondsnumberNoTimeout in seconds. Default: 300

{
"exit_code": 0,
"stdout": "migrations: 3 applied",
"stderr": "",
"secrets_injected": ["DATABASE_URL"],
"timed_out": false
}
FieldDescription
exit_codeProcess exit code
stdoutCaptured standard output
stderrCaptured standard error
secrets_injectedNames of secrets that were injected (never values)
timed_outtrue if the process was killed due to timeout

The response never contains secret values — only process output and metadata.


Run database migrations:

vault_run({
"command": ["go", "run", "./cmd/migrate"],
"secrets": ["DATABASE_URL"]
})

Run tests with multiple secrets:

vault_run({
"command": ["npm", "test"],
"secrets": ["DATABASE_URL", "STRIPE_SECRET_KEY", "OPENAI_API_KEY"]
})

Run a deploy script with all secrets in the active app:

vault_run({
"command": ["npm", "run", "deploy"]
})

When Claude Code calls vault_run, it typically says something like:

“I’ll run the database migrations using vault_run with your DATABASE_URL secret.”

Then calls the tool. The MCP response comes back with exit code and stdout. Claude never sees the actual database URL — only the result of using it.


ErrorMeaning
secret_not_foundOne or more requested secrets don’t exist. Use vault_list_secrets to check available secrets.
decryption_failedKEK/DEK mismatch — session may have expired. Re-authenticate.
command_timeoutCommand exceeded the timeout. Increase timeout_seconds or check the command.
vault_run blockedThe command was blocked by the inbound interceptor — it could exfiltrate injected secrets.