caddy-mcpCAUTION
Caddy admin API MCP server, complete coverage of config, routes, reverse proxies, TLS, PKI, and metrics, ETag-safe
Overview
From the repository's own README, as read at the audited commit. Badges and raw HTML are left out.
[](https://yaw.sh/mcp/install?name=Caddy&command=npx&args=-y%2C%40yawlabs%2Fcaddy-mcp&description=Manage%20Caddy%20web%20servers%20-%20config%2C%20routes%2C%20TLS%2C%20PKI&source=https%3A%2F%2Fgithub.com%2FYawLabs%2Fcaddy-mcp)
One click adds this to your local Yaw MCP config so it's available in every Yaw Terminal session. Or install manually below.
[](https://www.npmjs.com/package/@yawlabs/caddy-mcp) [](https://opensource.org/licenses/MIT) [](https://github.com/YawLabs/caddy-mcp/stargazers)
Manage Caddy web servers from Claude Code, Cursor, and any MCP client. 18 tools + 4 resources covering every endpoint in Caddy's admin API reference — config, routes, reverse proxies, TLS, PKI, metrics, snapshots.
Built and maintained by Yaw Labs.
Why this one?
Other Caddy MCP servers wrap half the admin API and silently swallow errors. This one doesn't.
- Complete admin API coverage — every endpoint in Caddy's admin API reference:
/load,/config/*,/id/*,/stop,/adapt,/pki/ca/*,/reverse_proxy/upstreams,/metrics. No placeholder tools that 404. Caddy's Go runtime debug endpoints (/debug/pprof/*,/debug/vars) are deliberately not wrapped — for leak trends usecaddy_metricswithfilter: "go_goroutines"or"go_memstats", which come from the same admin registry; for stack dumps, CPU profiles and traces, curl the admin endpoint directly (Caddy profiling docs). - Safe concurrent writes — uses ETags (
If-Match) so your changes never silently overwrite someone else's. SurfacesHTTP 412 Precondition Failedas a clear message, not a cryptic error. - **Safe-by-default mutati
49846756e638OBSERVED · 2026-10-10Connect
Built from this server's own package name, version and transport as found in its source — not copied from anyone's documentation, so it cannot drift against a page we do not control. Replace the environment placeholders with a token scoped to the least it needs.
claude mcp add caddy-mcp -- npx -y @yawlabs/[email protected]
Exposed tools (18)
12 read · 4 write · 2 destructive. Blast radius: 2 tools can delete or overwrite — an agent that can be talked into calling a tool can be talked into calling this one.
| Tool | Risk | Description |
|---|---|---|
caddy_adapt | read | Convert a config in any registered adapter format to Caddy JSON without loading it. Useful for previewing what a Caddyfile produces, or for porting from nginx/yaml configs when Caddy is built with the matching adapter module ( |
caddy_add_route | write | Add a route with full control over match conditions and handlers. Supports any Caddy handler (reverse_proxy, file_server, static_response, redirect, encode, headers, etc.). |
caddy_config_by_id | read | Access config by @id tag. Any config object with an |
caddy_config_delete | destructive | Delete config at a JSON path. Removes the config node at the specified path. Deleting a parent node also deletes every descendant -- e.g. deleting |
caddy_config_get | read | Read Caddy config at any JSON path. Returns the full config when path is empty, or a subtree at a specific path (e.g., |
caddy_config_set | write | Write config at a JSON path. Mode |
caddy_list_routes | read | List all routes on a Caddy HTTP server with a human-readable summary of matchers and handlers, followed by the raw route JSON. |
caddy_list_servers | read | List all configured HTTP servers with their names, listen addresses, route counts, and TLS status. Use this to discover server names before calling route tools. |
caddy_load | read | Replace the entire Caddy configuration atomically. Accepts a JSON config object, or a Caddyfile string with format= |
caddy_metrics | read | Get Prometheus metrics from Caddy. Shows request counts, durations, TLS handshake stats, active connections, and more. |
caddy_pki | read | Get PKI certificate authority info or the CA certificate chain. |
caddy_remove_route | destructive | Remove a route. Target by @id (preferred — stable across reorderings) or by array index on a specific server. Index-based removal is a two-step read-then-delete and can race against concurrent edits; prefer @id when possible. |
caddy_reverse_proxy | write | Add a reverse proxy route. The most common operation — just specify where traffic comes from and where it goes. Example: from= |
caddy_revert | read | Manage config snapshots for rollback. Snapshots are auto-captured before caddy_load, and before a caddy_config_delete |
caddy_status | read | Check Caddy connectivity and get a config summary: servers, routes, listen addresses, and TLS status. |
caddy_stop | write | Gracefully shut down the Caddy server. Requires confirm=true to prevent accidental shutdown. |
caddy_tls | read | Get or configure TLS/HTTPS settings. Actions: |
caddy_upstreams | read | Caddy |
Trust audit
CAUTIONgrade B · trust 85/100 Install with care. The audit found things worth knowing before you trust its output.
| Layer | What it checks | Result |
|---|---|---|
| L0 | Provenance & inventory | PASS |
| L1 | Static analysis of the code | FAIL |
| L2 | Instruction surface (what it tells the agent) | PASS |
| L3 | Class-specific surface | WARN |
| L4 | Behavioural (sandbox) | SKIPPED |
What the source does
- Filesystem
- declared (2 observation(s))
- Network
- declared (7 observation(s))
- Shell
- declared (5 observation(s))
- Dependencies
- not all pinned
- Secrets in source
- none-found
Findings (16)
const SSH = "ssh -i ~/.ssh/gh_woods -o IdentitiesOnly=yes";
caddy_config_delete, caddy_remove_route
return new Function(`${pieces}\nreturn runtimePlan;`)() as RuntimePlan;return new Function(`${pieces}\nreturn { pickNewest, floor: OAM_MIN };`)() as {const res = await api.configByIdGet("my-route", "../../load");["configByIdSet", (a: typeof import("../api.js")) => a.configByIdSet("my-route", {}, "PATCH", "../../load")],["configByIdDelete", (a: typeof import("../api.js")) => a.configByIdDelete("my-route", "../../stop")],{ apps: { http: { servers: { "../../..": { "@id": "deep", listen: [":18887"], routes: [] } } } } },routes: [{ handle: [{ handler: "vars", "../../../../../../../../../load": { "@id": "toload" } }] }],`CADDY_ADMIN_URL` (default `http://127.0.0.1:2019`) with host and port both
process.env.CADDY_ADMIN_URL = `http://127.0.0.1:${port}`;process.env.CADDY_ADMIN_URL = `http://127.0.0.1:${port}`;expect(res.error).toBe(`Cannot connect to Caddy admin API at http://127.0.0.1:${srv.port} — is Caddy running?`);expect(res.error).toBe(`Cannot connect to Caddy admin API at http://127.0.0.1:${port} — is Caddy running?`);@modelcontextprotocol/sdk, zod, @biomejs/biome, @types/node, esbuild, postject, tsup, typescript
SDK's OAuth client could send credentials to an authorization server chosen by
Gates applied: no_behavioural_pass.
49846756e638full audit observations/trust-audit/mcp-server/yawlabs__caddy-mcp.json · Report an issue / request a re-scanAudit history
Every audit this server has had. A grade with a past is a grade somebody is still checking.
| Date | Source | Verdict | Grade | Score | Change |
|---|---|---|---|---|---|
| 2026-10-10 | 49846756e638 | CAUTION | B | 85 | first audit |
Questions
What is the caddy-mcp MCP server?
Caddy admin API MCP server, complete coverage of config, routes, reverse proxies, TLS, PKI, and metrics, ETag-safe
What tools does caddy-mcp expose?
18 in total: 12 read-only, 4 that write, and 2 that can delete or overwrite (caddy_config_delete, caddy_remove_route). Every one is listed on this page with its risk.
Is caddy-mcp safe to connect to an agent?
With care. The audit graded it B (85/100) and found 16 things worth knowing before you trust this server, listed below with the exact line each was found on. Separately from the audit: 2 of its tools can destroy data, so scope the token you give it to what you actually need.
What credentials does caddy-mcp need?
It reads CADDY_API_TOKEN, GH_TOKEN and GITHUB_TOKEN from the environment. Give it a token scoped to the least it needs — an agent that can be talked into calling a tool can be talked into calling it with your credentials.
How does caddy-mcp run?
It speaks stdio, so it runs as a local process your client starts. It is published on npm as @yawlabs/caddy-mcp at 2.6.0.
How current is this page?
The grade is for one exact copy of the source (49846756e638), read on 2026-10-10. The repository is watched and re-audited when it changes.