Vault MCP
Model Context Protocol (MCP) Server for HashiCorp Vault secret management
Ask AI about Vault MCP
Powered by Claude Β· Grounded in docs
I know everything about Vault MCP. Ask me about installation, configuration, usage, or troubleshooting.
0/500
Reviews
Documentation
Vault MCP
MCP server for credential isolation in LLM agents. Your bot uses passwords and API keys β but never sees them in its context window.
The Problem
User LLM Website
β β β
β "password: MyP@ss!" β β
βββββββββββββββββββββββββΊβ β
β βββββ MyP@ss! βββββββββββΊβ
β β β
β ββββββ 200 OK ββββββββββββ
β β β
βΌ βΌ βΌ
ββββββββββββββββ
β MyP@ss! is β
β now stored β
β in LLM β
β context, β
β conversation β
β history, β
β session logs β
ββββββββββββββββ
The Solution
User Browser Form Vault MCP LLM Website
β (localhost) β β β
β ββββββββ β β β β
ββββββββββββββββΊβ β β β
β βββ encrypt ββββββΊβ β β
β β ββββ vault_login ββ€ β
β β βββ fill form ββββββββββββββββββββΊβ
β β ββββββ 200 OK ββββββββββββββββββββ€
β β βββ { status: ok }ββΊβ β
β β β β β
βΌ βΌ βΌ βΌ βΌ
ββββββββββββββββ ββββββββββββββββ
β Password: β β LLM context: β
β AES-256-GCM β β β
β encrypted β β "status: ok" β
β on disk β β (no password)β
ββββββββββββββββ ββββββββββββββββ
Scenarios
Scenario 1: First-time Login (vault_add β vault_login)
The agent needs credentials it doesn't have. It calls vault_add() β a browser form opens where you enter the password. Then vault_login() fills the form via Chrome.
User Claude Code Vault MCP Chrome
β β β β
β "Log me into β β β
β Jira" β β β
βββββββββββββββββββββΊβ β β
β βββ vault_list() βββββΊβ β
β βββ { credentials:[] }β€ β
β β β β
β βββ vault_add ββββββββΊβ β
β β { site: "jira" } β β
β β β β
β ββββββββββββββββββββββββββββββ β β
β β Browser opens β β β
β β localhost:9900/add β β β
β β β β β
β β Site ID: [jira] β β β
β β Email: [me@work.com] β β β
β β Password: [ββββββββββ] β β β
β β URL: [jira.com/login]β β β
β β β β β
β β [Add to Vault] β β β
β ββββββββββββββ¬ββββββββββββββββ β β
β β β β
β βββ POST (encrypted) βββββΊβ β
β β β
β βββ { status: ok } ββββ€ β
β β site_id: "jira" β β
β β β β
β β (no password β β
β β in this response) β β
β β β β
β βββ vault_login ββββββΊβ β
β β { site: "jira" } βββ decrypt βββ β
β β βββββββββββββββ β
β β βββ fill email βββββΊβ
β β βββ fill pass βββββΊβ
β β βββ click submit βββΊβ
β β βββ page loaded ββββ€
β β βββ clear pass βββββΊβ
β β β β
β βββ { status: ok, ββββ€ β
β β title: "Jira β β
β β Dashboard" } β β
β β β β
ββββ "You're logged β β β
β into Jira!" β β β
Scenario 2: API Key Proxy (vault_api_request)
The agent makes an API call. Vault injects the API key into headers β the key never appears in the LLM context.
Claude Code Vault MCP Stripe API
β β β
βββ vault_api_request βΊβ β
β service: "stripe" β β
β url: "/v1/charges" β β
β method: "GET" β β
β βββ decrypt API key β
β β β
β βββ GET /v1/charges βββββββββΊβ
β β Authorization: β
β β Bearer sk-live-**** β
β β β
β ββββ { data: [...] } ββββββββ€
β β β
β βββ scan response β
β β for leaked key β
β β (replace with ***) β
β β β
ββββ { status: ok, ββββ€ β
β body: "..." } β β
β β β
β (API key NOT in β β
β this response) β β
Scenario 3: Returning User (credentials already stored)
If credentials already exist, the agent skips vault_add and goes straight to vault_login:
User Claude Code Vault MCP Chrome
β β β β
β "Open GitHub" β β β
βββββββββββββββββββββΊβ β β
β βββ vault_list() βββββΊβ β
β βββ [{ siteId: ββ€ β
β β "github", β β
β β active: true }] β β
β β β β
β βββ vault_login ββββββΊβ β
β β { site: "github" }βββ decrypt ββββ β
β β ββββββββββββββββ β
β β βββ CDP login ββββββΊβ
β β βββ success ββββββββ€
β βββ { status: ok } ββββ€ β
β β β β
ββββ "Done!" β β β
Scenario 4: Credential Revocation
Remove access instantly β the agent can no longer use the credential:
Admin (CLI) Vault MCP Claude Code
β β β
βββ vault-mcp remove β β
β "jira" β β
β βββ delete from store β
β βββ audit: removed β
ββββ "Removed: jira" β β
β β β
β β ... later ... β
β β β
β ββββ vault_login βββββββ€
β β { site: "jira" } β
β β β
β βββ { status: FAIL, βββΊβ
β β "Credential not β
β β found: jira" } β
β β β
Scenario 5: Audit Trail
Every credential use is logged with a tamper-proof hash chain:
~/.vault-mcp/audit.jsonl
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β evt_001 β credential.created β jira β success β hash_1 β
β β β β β β β
β evt_002 β credential.used β jira β success β β β
β β bot: claude β β β βΌ β
β β β β prevHash: hash_1 β
β β β β β hash_2 β
β β β β β β β
β evt_003 β credential.used β jira β success β βΌ β
β β bot: claude β β prevHash: hash_2 β
β β β β β hash_3 β
β β β β β β β
β evt_004 β credential.removed β jira β success β βΌ β
β β β β prevHash: hash_3 β
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
Modify any entry β hash chain breaks β tamper detected
$ vault-mcp audit
Chain integrity: VALID (4 entries)
Quickstart
# 1. Clone and build
git clone https://github.com/Chill-AI-Space/vault-mcp.git
cd vault-mcp
npm install
npm run build
# 2. Register with Claude Code
claude mcp add -s user vault -- node ~/path/to/vault-mcp/dist/index.js
# 3. Use in Claude Code
# "Log me into GitHub" β
# Claude calls vault_add("github") β browser form opens β you enter password
# Claude calls vault_login("github") β Chrome logs in via CDP
# Claude sees only { status: "success" }
Or add credentials via CLI (outside of Claude Code):
vault-mcp add --site github --email you@example.com --url https://github.com/login
# Password is prompted interactively (masked with *)
MCP Tools
| Tool | What it does | What the LLM sees |
|---|---|---|
vault_add(site_id?) | Opens browser form for secure credential entry | { status, site_id } |
vault_login(site_id) | Logs into website via Chrome CDP | { status, page_title } |
vault_api_request(service, url, ...) | Makes API call with injected credentials | { status, body } |
vault_list() | Lists stored credentials | [{ siteId, type, active }] |
vault_status(site_id) | Shows credential metadata + audit stats | { siteId, active, lastUsed } |
What the LLM never sees: passwords, API keys, emails, tokens, encrypted data.
CLI Commands
vault-mcp add # Interactive: add credential (password masked)
vault-mcp add --site X --email Y # Semi-interactive
vault-mcp list # List credentials (no secrets)
vault-mcp remove <site_id> # Remove credential
vault-mcp audit [site_id] # View audit log + chain integrity
vault-mcp dashboard # Web UI on localhost:9900
vault-mcp serve # Start MCP server (for debugging)
Architecture
vault-mcp/
βββ src/
β βββ index.ts ββ Entry: CLI or MCP mode (auto-detect)
β βββ server.ts ββ MCP server, 5 tools registered
β βββ cli.ts ββ CLI commands (commander + inquirer)
β βββ tools/
β β βββ vault-add.ts ββ Opens browser form, waits for submit
β β βββ vault-login.ts ββ Decrypt β CDP β fill form β status
β β βββ vault-api.ts ββ Decrypt β inject headers β fetch β sanitize
β β βββ vault-list.ts ββ Return metadata only
β β βββ vault-status.ts ββ Metadata + audit stats
β βββ store/
β β βββ encrypted-store.ts ββ AES-256-GCM CRUD, JSON file backend
β β βββ keychain.ts ββ Master key: env var or auto-generate
β βββ browser/
β β βββ cdp-bridge.ts ββ Playwright connectOverCDP, form fill
β βββ audit/
β β βββ logger.ts ββ Append-only JSONL, SHA-256 hash chain
β βββ dashboard/
β βββ server.ts ββ HTTP server (127.0.0.1:9900 only)
β βββ index.html ββ Full dashboard (CRUD + audit viewer)
β βββ add.html ββ Focused add-credential form (for vault_add)
βββ test/ ββ 29 tests including credential sanitization
Configuration
| Env Variable | Default | Description |
|---|---|---|
VAULT_MASTER_KEY | (auto-generated) | Encryption key. Without it, a random key is saved to ~/.vault-mcp/.master-key |
VAULT_CDP_URL | http://localhost:9222 | Chrome DevTools Protocol endpoint |
# Register with env vars
claude mcp add -s user vault \
-e VAULT_MASTER_KEY=my-secret-key \
-e VAULT_CDP_URL=ws://localhost:9222 \
-- node ~/path/to/vault-mcp/dist/index.js
Storage
~/.vault-mcp/
βββ credentials.json ββ Encrypted credentials (AES-256-GCM, unique IV per entry)
βββ audit.jsonl ββ Append-only log with SHA-256 hash chain
βββ .master-key ββ Auto-generated master key (mode 0600)
Security
See SECURITY.md for full threat model.
Protects against Does NOT protect against
βββββββββββββββββ ββββββββββββββββββββββββ
β LLM context leakage β User typing password in chat
β Plaintext credential storage β Compromised host (root access)
β Audit log tampering β Malicious MCP client
β Accidental exposure in logs β Browser-level memory attacks
Testing
npm test # 29 tests
npm run test:watch # Watch mode
Tests verify: encryption round-trip, wrong-key rejection, credential sanitization in all tool responses, hash chain integrity, tamper detection, full lifecycle flows.
License
MIT
