Skip to main content
warden-mcp speaks MCP on one side and Warden’s HTTP data plane on the other. It runs as a subprocess of the agent host (Claude Code, Claude Desktop, or anything else that speaks MCP over stdio).
The shim deliberately contains no enforcement logic. It knows nothing about parsing, classification, policy, scoping, masking, or approval — all of which happen inside the gateway process, where an agent cannot route around them. Someone who reads every line of the shim learns the shape of the API and none of the product. That is also why publishing it is safe.

Configuration

Environment only, so a key never appears in a process list:

The tools

Takes statement (SQL) or command (a document, for engines without a query language), plus params, and a required reason a human may read. Optional task_id, step_index, plan_hash, idempotency_key, and mode.The tool description tells the agent how to read each status: expired and stale did not run and may be retried; rejected and denied will not succeed; replayed had already run; proposed is waiting for a human. If the result carries an approval object, a person approved it, and the agent is told to say so when reporting.
Takes operation_id and an optional wait_seconds (default 30, capped at 60). Returns proposed while a human is still deciding, and otherwise the final outcome, exactly as warden_query would have returned it. See approvals.
Returns only the resources policy permits this agent, with descriptions and legal enum values. Worth calling early in a task: it is how an agent learns that a write will need approval before proposing one, rather than discovering it mid-task.A schema listing is reconnaissance, so the catalog is filtered rather than dumped.
Reports the agent’s ID, connection, owner, and the scope its access is restricted to. The fastest way to confirm a key and a config are wired correctly.

Why refusals come back as content

A denial is returned as tool content, not an MCP error. An agent that sees an error object tends to abandon the task; one that sees {"status":"rejected","message":…} can reason about what to do instead. Only an unreachable gateway is reported as a transport failure — because that genuinely is one, and the agent must not treat it as a refusal to work around.

Verifying a wiring

The repository ships a backtest that drives the shim over stdio against a running gateway and asserts every answer — tools offered, scope enforced, masking under an alias, DDL refused, a change that waits for a human, the approver named in the response, and a retry that replays:

Install

warden-mcp ships in the same Homebrew formula and release archive as the gateway.