mcp-warden
Local-first credential broker for MCP. AI coding agents (Claude Code, Cursor, Codex…) call APIs, SSH and databases through scoped presets; secrets stay in your OS keychain and never enter the agent's context.
Install / Use
claude mcp add ermoluk -- npx -y github:ermoluk/mcp-wardenIf the server publishes to npm under a different name, use that package instead — check the repo README.
MCP Server
Model Context Protocol server
Quality Score
Category
SecuritySupported Platforms
Our assessment of mcp-warden
mcp-warden scores 84/100 on our quality scale, 840th of 1,104 Security skills we index.
Its MCP Server is 19 KB long, well organised into 13 sections with 13 code examples: a thorough specification that gives an agent plenty to work with.
It has 10 GitHub stars, so there is little community track record yet; judge it on its content.
Maintenance, license and trust
- The repository was last updated today, so mcp-warden is actively maintained.
- It is released under the Apache-2.0 license, a permissive license that allows use, modification and commercial use with attribution.
- Its trust signals score 97/100, with no cautions. These come from repository metadata, not a code audit — read the skill file before letting an agent act on it.
mcp-warden compared with similar skills
All 4 of these similar skills score higher than mcp-warden; compare them before choosing.
| Skill | Score | Stars | Updated | Format |
|---|---|---|---|---|
| mcp-warden (this skill)by ermoluk | 84 | 10 | today | MCP Server |
| Agent-Reachby Panniantong | 100 | 106.6k | 5d ago | CLAUDE.md |
| headroomby headroomlabs-ai | 100 | 78.3k | today | CLAUDE.md |
| CowAgentby zhayujie | 100 | 47.7k | today | CLAUDE.md |
| Scraplingby D4Vinci | 100 | 90.4k | 1d ago | MCP Server |
Frequently asked questions
- How do I install mcp-warden?
- Run
claude mcp add ermoluk -- npx -y github:ermoluk/mcp-warden. The install tabs above show the steps for each supported agent. - Which AI agents does mcp-warden work with?
- It is written for Claude Code, Claude Desktop, Cursor and OpenAI Codex, as a MCP Server file. Other agents that read the same format can often use it too.
- Is mcp-warden safe to use?
- It is Apache-2.0-licensed and scores 97/100 on trust signals. Skills are instructions an agent will follow, so read the file before installing it and do not approve commands you do not understand.
- Is mcp-warden still maintained?
- The repository was last updated today, so mcp-warden is actively maintained.
Skill content
View source on GitHubmcp-warden
A local-first credential broker for the Model Context Protocol — lets any AI coding agent (Claude Code, Cursor, Cline, Codex, Continue, Zed) take real actions without ever seeing your secrets.
The agent calls high-level tools (proxy_http); mcp-warden injects the secret server-side, executes the action, and returns only the result. Your context window stays clean. A leaked transcript leaks nothing useful.

How it works
- You store a credential once in the OS keychain via the
mcp-wardenCLI. - You define presets — named, scoped actions (e.g.
github-read,stripe-charges). - The AI agent connects to
mcp-wardenas an MCP server (stdio). - When the agent wants to act, it calls
proxy_httpwith a preset name and a path/method. mcp-wardenvalidates the request against the preset's allow-list, injects the credential, executes, and returns only the response.- Sensitive presets trigger an approval prompt: a native dialog on macOS and Windows, a desktop notification with Approve / Deny on Linux, or a Telegram message on any OS — where
/lockalso works as a kill switch from your phone. Opt in to time-boxed approvals per preset so one OK can cover a short burst of follow-up calls without re-prompt spam. - Every action lands in a local SQLite audit log — including a
windoweddecision for calls authorised by an active approval window, arefuseddecision (with the raw requested path or command) for calls the allow-list turned away, and afaileddecision when the approval prompt could not be shown.
The agent's context window contains zero secrets.
Install
Every option installs the same single binary — no background service, no auto-updater, no telemetry. To update, run the same tool again.
macOS and Linux — Homebrew
brew install ermoluk/tap/mcp-warden
Windows — Scoop
scoop bucket add ermoluk https://github.com/ermoluk/scoop-bucket
scoop install ermoluk/mcp-warden
A winget package (ermoluk.mcp-warden) and an AUR package (mcp-warden-bin) are coming but not listed yet. Until they are, use Scoop on Windows, and Homebrew or the install script below on Arch Linux; on Linux the script installs the static musl build.
Nix (builds from source)
nix profile install github:ermoluk/mcp-warden
npm — for MCP clients configured with npx. The package is scoped: the unscoped mcp-warden on npm is an unrelated project.
{ "mcpServers": { "mcp-warden": { "command": "npx", "args": ["-y", "@mcp-warden/cli", "mcp"] } } }
The binary for your platform comes from an optional dependency; nothing is downloaded at install or run time. npx @mcp-warden/cli init and the other subcommands work the same way.
Rust — prebuilt with cargo-binstall, or from source (Rust 1.89+):
cargo binstall mcp-warden
cargo install --locked mcp-warden
Install script — downloads the release archive for your machine, refuses it unless it matches the release's SHA256SUMS, and puts the binary in ~/.local/bin (Windows: %LOCALAPPDATA%\Programs\mcp-warden\bin). No sudo, and it changes neither your PATH nor your shell profile. Read it first if you like: install.sh, install.ps1.
curl -fsSL https://github.com/ermoluk/mcp-warden/releases/latest/download/install.sh | sh
irm https://github.com/ermoluk/mcp-warden/releases/latest/download/install.ps1 | iex
Claude Desktop — download the .mcpb bundle for your platform from the latest release and open it. The bundle contains only the server; install the CLI with one of the options above to create presets and store secrets.
By hand — every GitHub release has archives for macOS (arm64, x86_64), Linux (x86_64, aarch64; static musl builds, plus an x86_64 glibc build) and Windows (x86_64), a combined SHA256SUMS, and a build-provenance attestation for each archive:
gh attestation verify mcp-warden-aarch64-apple-darwin.tar.gz --repo ermoluk/mcp-warden
The macOS binaries are not notarized. Homebrew, npm, cargo and the install script don't mark them as downloaded, but an archive or bundle saved from a browser may be blocked by Gatekeeper until you run xattr -d com.apple.quarantine on it.
There is no Docker image, on purpose: the OS keychain — macOS Keychain, Windows Credential Manager, the Linux kernel keyring — isn't reachable from inside a container, and mcp-warden never falls back to keeping secrets in a file.
90-second quickstart
mcp-warden init
mcp-warden secret add gh_pat # paste your GitHub PAT when prompted
mcp-warden preset add github-read \
--type http \
--base-url https://api.github.com \
--auth-bearer gh_pat \
--allowed-methods GET \
--allowed-paths /user/repos \
--approval auto --confirm-auto
The preset auto-approves only GET /user/repos; any other path is refused before the token is touched. To let the agent read more, widen the allow-list (e.g. --allowed-paths '/user/repos,/repos/OWNER/[^/]+') and prefer a fine-grained PAT limited to specific repos. Patterns match the whole path, as exact strings or regexes anchored as ^(?:…)$, never as prefixes; [^/]+ is safer than .* for one segment. They see the percent-decoded path, so %2F is a separator: a GitLab-style id like /projects/group%2Fproject needs /projects/[^/]+/[^/]+. An HTTP preset with no allowed_paths allows every path under base_url — preset add and doctor warn about it, and the built-in github-read / gitea-read / stripe-read templates ship with approval = "prompt" for that reason.
Wire mcp-warden into your agent — see docs/claude-code-setup.md or docs/cursor-setup.md.
In your agent: ask "list my GitHub repos via mcp-warden". Watch the agent call list_presets, then proxy_http — and watch your PAT stay out of the prompt.
mcp-warden audit --last 5 # see what the agent did
Find and fix plaintext keys
Keys pasted into MCP client configs sit on disk in plaintext, where the agent, a synced dotfile or a screenshot can pick them up. Three commands fix that:
mcp-warden scan # where are plaintext keys? (shows type + length, never values)
mcp-warden import # move them into the keychain and rewire the client entries
mcp-warden run github # what the rewired entry runs: the server, with its key injected
scan reads Claude Code, Claude Desktop, Cursor, Windsurf, VS Code and Codex configs plus .mcp.json / .env files in the current directory (--path DIR for more). import handles keys in a stdio server's env; for keys in arguments, headers, URLs or .env files, scan says what to do instead. To wrap a server by hand: mcp-warden server add github --env GITHUB_PERSONAL_ACCESS_TOKEN -- npx -y @modelcontextprotocol/server-github (the value is read from stdin). Details: docs/scan-and-import.md.
CLI reference
| Command | Description |
|--------------------------------------------|----------------------------------------------------------|
| mcp-warden init | Create the config directory and a template config |
| mcp-warden secret add <name> | Store a secret (value read from stdin, never argv) |
| mcp-warden secret list | List secret names (never values) |
| mcp-warden secret remove <name> | Delete a secret from the keychain |
| mcp-warden preset add <name> ... | Define a preset (--confirm-auto required for auto) |
| mcp-warden preset list | Show all presets |
| mcp-warden preset test <name> | Validate a preset against the current keychain |
| mcp-warden preset test <name> GET /path | Policy simulator: would this call be allowed, and why? Sends nothing (--command, --get/--put, --query for other tools) |
| mcp-warden preset grant <name> --for 1h | Time-limited access: calls are refused after the window (--permanent clears it) |
| mcp-warden preset revoke <name> | End access to a preset now (next server start; lock for immediately) |
| mcp-warden lock [--reason …] | Kill switch: every MCP server refuses every call from its next one on (or send /lock to the Telegram bot) |
| mcp-warden approval telegram-test | Check the Telegram setup: token, chat, a test prompt you answer |
| mcp-warden unlock | Remove the lock after a human approves it in the dialog / Telegram |
| mcp-warden scan | Find plaintext keys in MCP client configs and .env files (never prints values) |
| mcp-warden import | Move the keys scan found into the keychain and point the client at mcp-warden run |
| mcp-warden server add <name> --env VAR -- <cmd…> | Wrap another MCP server; its key is read from stdin into the keychain |
| mcp-warden run <name> | Launch a wrapped MCP server with its keys injected (use as the client's command) |
| mcp-warden preset scaffold <template> (v0.3.0) | Generate a preset from a built-in template (--list to discover) |
| mcp-warden preset from-openapi <src> (v0.3.0) | Bootstrap a preset from an OpenAPI 3.x spec (URL or file) |
| mcp-warden approval <preset> <policy> [--window N] | Set approval policy; --window N (sec) enables time-boxed approvals for prompt |
| mcp-warden audit [--last N \| --since T] [--decision D]… | Read-only view of the audit log (append-only by design), with what the agent asked for — including refused calls — and which MCP client and session made each call. --decision refused --decision failed shows only those decisions; --window N shows approval #N and every call that ran inside the window it opened |
| mcp-warden doctor [--deep] (v0.3.0 for --deep) | Diagnostic summary; --deep runs safe read-only HTTP probes per preset |
| mcp-warden web [--port N] (v0.3.0) | Local read-only web UI (binds 127.0.0.1 only) |
| mcp-warden mcp | Run the MCP server over stdio (consumed by the AI agent) |
MCP tools exposed
list_presets— read-only catalogue of available actions.proxy_http— execute an HTTP request through a preset; allow-list validation runs before credential injection.ssh_exec(v0.2.0) — run a shell command on an SSH host; command must match preset's anchored regex allow-list; key-based auth + host-key verification.sftp_transfer(v0.2.0) — get/put a file over SFTP; remote path matches preset'ssftp_allowed_paths, local path under$HOMEor/tmp.db_query(v0.2.0) — run a NAMED QUERY against PostgreSQL / MySQL / Redis. S
Truncated for display — read the full file on GitHub.
Related Skills
Agent-Reach
106.6kGive your AI agent eyes to see the entire internet. Read & search Twitter, Reddit, YouTube, GitHub, Bilibili, XiaoHongShu — one CLI, zero API fees.
headroom
78.3kCompress tool outputs, logs, files, and RAG chunks before they reach the LLM. 20% fewer tokens for coding agents, 60-95% fewer tokens for JSON, same answers. Library, proxy, MCP server.
CowAgent
47.7kOpen-source personal AI assistant & Agent Harness. Plans tasks, runs tools and skills, self-evolves with memory and knowledge. Multi-agent, multi-model, multi-channel. Lightweight, extensible, one-line install.
Scrapling
90.4k🕷️ The BEST Web Scraping framework that handles everything from a single request to a full-scale crawl! Don't be shy, join here: https://discord.gg/EMgGbDceNQ and follow here for daily tips and tricks: https://x.com/Scrapling_dev
Languages
Trust signals
From repository metadata: license, adoption, age and documentation. Not a code audit — see the Safety scan above for what the skill file itself contains.
