MCP server by Elraian
mcpvault
Local, encrypted credential vault for AI agents. Keep many accounts per service (Supabase, GitHub, Vercel, Stripe), and let Claude / Cursor / Codex pick the right one mid-conversation.
"I'm working on the Acme project today — switch me to that Supabase account and list the projects."
The agent calls a vault tool, the right credentials are loaded, the request executes against the real API. No restart, no manual token-swapping.
Install
npm i -g @elraian/mcpvault
Requires Node 20+. Works on Windows, macOS, Linux. The CLI command after install is just
mcpvault(also aliased asmvaultandmcp-vault).
Setup in 3 commands
mcpvault init # create vault, set master password
mcpvault add supabase # paste a PAT — validated immediately against the API
mcpvault setup # auto-wire into Claude Code / Desktop / Cursor
Then restart your chat client. That's it.
Day-to-day
| Command | What it does |
|---|---|
| mcpvault add <service> | Add an account. Validates the token live, suggests a label. |
| mcpvault list | See all accounts. The currently active one is marked ● per service. |
| mcpvault update <svc> <label> | Rotate a token, edit description/tags. |
| mcpvault remove <svc> <label> | Delete an account (with type-the-label confirmation). |
| mcpvault activate <svc> <label> | Set the active account. Wrappers pick it up on next call. |
| mcpvault active | Show what's active per service. |
| mcpvault status / lock / unlock | Vault lock state. |
| mcpvault doctor | Diagnose vault / keyring / file issues. |
| mcpvault setup | Re-run to wire additional clients later. |
mcpvault, mvault, and mcp-vault all work — they're aliases.
What you can ask the agent
After mcpvault setup + restart, your agent has these tools available:
vault (control plane)
unlock_vault, lock_vault, vault_status, list_accounts, find_account, get_active, activate_account, add_account, update_account, delete_account, export_redacted
vault-supabase
supabase_list_projects, supabase_list_organizations, supabase_run_sql, supabase_list_tables, supabase_get_logs
vault-github
github_list_repos, github_get_repo, github_list_issues, github_create_issue, github_list_pulls, github_get_file, github_search_code
vault-vercel
vercel_list_projects, vercel_list_deployments, vercel_get_deployment, vercel_list_domains
vault-stripe (read-only by design — no writes)
stripe_list_customers, stripe_retrieve_customer, stripe_list_charges, stripe_list_subscriptions, stripe_retrieve
Example flow
You: Switch to the Acme Supabase account and list its projects.
Agent: [find_account "Acme"] → matched "client-acme"
[activate_account supabase client-acme]
[supabase_list_projects]
Active is now client-acme. 3 projects: acme-prod, acme-staging, acme-internal.
You: Now switch to my personal one and show me its orgs.
Agent: [activate_account supabase personal]
[supabase_list_organizations]
Personal account has 1 org: my-projects.
Same wrapper process. Zero restart between switches.
Security model
| Layer | Mechanism |
|---|---|
| Vault file on disk | AES-256-GCM, Argon2id KDF (m=64 MiB, t=3, p=1) |
| Master password | Never written to disk; held in memory after unlock |
| Session key (after unlock) | OS keyring (Windows Credential Manager / macOS Keychain / libsecret on Linux). Survives reboots so you don't re-type your password daily. |
| Wrapper MCP processes | Read decrypted creds from keyring per request. Credentials never returned through MCP — only the API result is. |
| Stripe wrapper | Read-only by design. No create_charge, no refund. |
| Audit log | ~/.mcpvault/vault.log records which account was used per request, never the credential. |
If you want stricter behavior (re-enter master password every boot), run mcpvault lock before shutdown, or call lock_vault through your agent.
Files on disk
~/.mcpvault/
├── vault.enc # AES-256-GCM, Argon2id-derived key
├── active.json # plain JSON, only labels — no secrets
└── vault.log # append-only audit log
The legacy paths
~/.mcp-vault/and~/.mvault/are also recognized for existing users — auto-detected from disk.
Architecture
Chat client (Claude Code / Desktop / Cursor)
│
├── spawns: mcpvault server ← control plane (list/find/activate/add)
├── spawns: mcpvault wrap supabase ← per-service wrapper
├── spawns: mcpvault wrap github
├── spawns: mcpvault wrap vercel
└── spawns: mcpvault wrap stripe
│
├── reads: ~/.mcpvault/active.json (which label per service)
└── reads: ~/.mcpvault/vault.enc (encrypted creds)
│
decrypted with key from
OS keyring (cached at unlock)
Each wrapper re-reads the active label on every tool call, so switching accounts is instant — no process restart.
Development
git clone https://github.com/Elraian/mcpvault.git
cd mcpvault
npm install
npm run build
npm test # ~22 unit + e2e tests
npm link # exposes `mcpvault` globally for local testing
Why this exists
Most MCP servers are locked to one account at startup. If you have 10 Supabase projects across 4 clients, you either register the Supabase MCP 10 times or constantly swap tokens by hand. mcpvault lets the agent search and switch accounts naturally during a conversation. Same idea applies to any service Anthropic / Cursor / etc. don't natively multi-account.
Roadmap
- v2: OAuth-based services (Gmail, Drive, Slack — needs refresh logic)
- v3: 1Password / Bitwarden CLI integration
- v3: Account "contexts" — switch Supabase + GitHub + Vercel + Stripe atomically per project
- v4: Web UI (Tauri / system tray)
Credits
- Site: https://mcpvault.online
- Source: https://github.com/Elraian/mcpvault
- npm: https://www.npmjs.com/package/@elraian/mcpvault
If this saves you time, a star on the repo costs you nothing and helps a lot.
License
MIT — see LICENSE.