Spec Driven Development
MCP Server that facilitates spec-driven development workflows, not just Vibe Coding.
คำอธิบายจากผู้ทำ (ภาษาอังกฤษตามต้นฉบับ)
MCP server for managing Caddy web servers via the admin API
สามเรื่องนี้ไม่รวมเป็นคะแนนเดียว เพราะความเห็น การวัด และความนิยม เป็นคนละเรื่องกัน
ตัวนี้ยังไม่ได้เรียบเรียงเป็นภาษาไทย ด้านล่างคือข้อเท็จจริงที่เราอ่านจาก registry
เลือกโปรแกรม AI ที่คุณใช้ แล้วคัดลอกค่าตั้งไปวาง
ต้องเตรียมก่อน
คุณใช้แอปไหน
เลือกแอปด้านบน เราจำไว้ให้ ครั้งหน้าปุ่มจะขึ้นว่า “ติดตั้งลง …”
เปิด Claude Desktop → Settings → Developer → Edit Config แล้ววางค่านี้ในไฟล์ claude_desktop_config.json
{
"mcpServers": {
"caddy": {
"command": "npx",
"args": [
"-y",
"@yawlabs/caddy-mcp"
]
}
}
}พิมพ์คำสั่งนี้ใน Terminal
claude mcp add caddy -- npx -y @yawlabs/caddy-mcpวางในไฟล์ .cursor/mcp.json ของโปรเจกต์ หรือ ~/.cursor/mcp.json
{
"mcpServers": {
"caddy": {
"command": "npx",
"args": [
"-y",
"@yawlabs/caddy-mcp"
]
}
}
}เบราว์เซอร์จะถามก่อนเปิดแอป จากนั้นแอปแสดงค่าตั้งให้ตรวจแล้วกดยืนยัน ช่อง key เว้นว่างไว้ให้คุณใส่เอง
วางในไฟล์ .vscode/mcp.json ของโปรเจกต์
{
"servers": {
"caddy": {
"type": "stdio",
"command": "npx",
"args": [
"-y",
"@yawlabs/caddy-mcp"
]
}
}
}เบราว์เซอร์จะถามก่อนเปิดแอป จากนั้นแอปแสดงค่าตั้งให้ตรวจแล้วกดยืนยัน ช่อง key เว้นว่างไว้ให้คุณใส่เอง
ตัวนี้รันในเครื่องคุณ แต่ ChatGPT ต่อได้เฉพาะ server บนอินเทอร์เน็ต ลองเลือกแอปอื่น
ตัวเลือกเก็บในคุกกี้บนเครื่องนี้ ไม่ต้องมีบัญชี
ค่าตั้งนี้สร้างจากข้อมูลใน registry ของผู้ทำ ถ้าไม่ตรงกับ README ให้เชื่อ README
รันในเครื่องคุณ รายการเครื่องมือจะขึ้นในแอป AI หลังติดตั้ง
เราตรวจจากข้อมูลที่ใครก็เปิดดูได้ ยังไม่ได้อ่านโค้ด ข้อที่ไม่เกี่ยวกับตัวนี้ไม่นับในตัวหาร · ตรวจเมื่อ 7 พ.ย. 2569
ชื่อใน registry ยืนยันด้วยบัญชี GitHub YawLabs ซึ่งเป็นเจ้าของ repo
ยังไม่ได้อ่านข้อมูล repo จาก GitHub
ยังไม่ได้อ่านข้อมูล repo จาก GitHub
ตัวนี้รันบนเครื่องคุณ ไม่มี endpoint บนอินเทอร์เน็ต
ตัวนี้รันบนเครื่อง ใช้ค่าที่ตั้งในเครื่องแทน
รันในเครื่องคุณ เราอ่านรายการเครื่องมือได้เฉพาะตัวที่มี endpoint บนอินเทอร์เน็ต
เทียบกับทุก server ที่ยังใช้งานในหมวดนี้ทั้งทะเบียน ดาวนับเฉพาะเมื่อผู้ลงทะเบียนเป็นเจ้าของ repo
จากการตรวจเบื้องต้นของเรา ผ่าน 1 จาก 1 ข้อที่ตรวจได้ เรายังไม่ได้อ่านโค้ด ก่อนใส่กุญแจหรือ token ให้ดูว่า server ขอสิทธิ์อะไร และเลือกกุญแจที่ทำได้เท่าที่จำเป็น
registry ไม่ได้ระบุว่าต้องใช้กุญแจ แต่บางตัวจะขอให้ล็อกอินตอนใช้ครั้งแรก
รันบนเครื่องของคุณ โปรแกรม AI จะเปิด server ขึ้นมาเองเมื่อใช้ ข้อมูลไม่ต้องผ่านเซิร์ฟเวอร์ของผู้ทำ (ยกเว้นตัวที่ไปเรียกบริการออนไลน์ต่อ)
repo บน GitHub มีการแก้โค้ดล่าสุด – และส่งรุ่นล่าสุด (2.6.1) เข้า registry 7 วันที่ผ่านมา
โปรแกรมที่รองรับ MCP เช่น Claude Desktop, Claude Code, Cursor และ VS Code ตัวนี้ต้องมี Node.js ในเครื่องด้วย
ในหมวดเดียวกันมี Spec Driven Development, Remote Desktop Commander, Asset Notation
server หมวดเดียวกันจากผู้ทำคนอื่น เรียงตามดาว
อ่านการ์ด:★ ดาว GitHubiสามเสา: รีวิว · ผลตรวจ · การใช้งานiอัปเดต = วันที่ส่งรุ่นล่าสุดเข้า registryi
MCP Server that facilitates spec-driven development workflows, not just Vibe Coding.
Remote Desktop Commander: use files, terminal and processes on your own computers from any AI app.
Read and maintain an Asset Notation file on disk: net worth, holdings, valuations, CSV import.
ส่วนนี้คัดจาก repo ของผู้ทำตามต้นฉบับ PopNx MCP ไม่ได้ตรวจหรือรับรองเนื้อหา ตัด HTML รูปภาพ และสคริปต์ออกแล้ว ลิงก์จะพาออกนอกเว็บ
One click adds this to your local Yaw MCP config so it's available in every Yaw Terminal session. Or install manually below.
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.
Other Caddy MCP servers wrap half the admin API and silently swallow errors. This one doesn't.
/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 use caddy_metrics with filter: "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).If-Match) so your changes never silently overwrite someone else's. Surfaces HTTP 412 Precondition Failed as a clear message, not a cryptic error.caddy_config_set defaults to idempotent overwrite (PATCH), not append (POST). Calling twice doesn't duplicate your route. A write to the config root — which replaces the *entire* config, admin endpoint included — is refused without confirm=true and snapshotted first, like caddy_load.caddy_list_routes never crashes on malformed config, even if routes are null, handlers are strings, or matchers are non-arrays. Regression-tested.CADDY_ADMIN_URL contains a token in the path/query, the connect-failed message shows only the origin.readOnlyHint, destructiveHint, and idempotentHint, so MCP clients can skip confirmations for safe ops.node_modules install.@id values, server names, and CA ids are all regex-validated with length caps. Blocks CRLF header injection and ReDoS.1. Enable the Caddy admin API
Caddy ships with the admin API enabled on localhost:2019 by default. If you're running Caddy in Docker or on a remote host, expose it via CADDY_ADMIN_URL.
2. Create `.mcp.json` in your project root
macOS / Linux / WSL:
{
"mcpServers": { "caddy": { "command": "npx", "args": ["-y", "@yawlabs/caddy-mcp@latest"] } } }
Windows:
{
"mcpServers": { "caddy": { "command": "cmd", "args": ["/c", "npx", "-y", "@yawlabs/caddy-mcp@latest"] } } }
Why the extra step on Windows? Since Node 20,
child_process.spawncannot directly execute.cmdfiles (that's whatnpxis on Windows). Wrapping withcmd /cis the standard workaround. This file is safe to commit — it contains no secrets.
3. Restart and approve
Restart Claude Code (or your MCP client) and approve the Caddy MCP server when prompted.
That's it. Now ask your AI assistant:
"Proxy api.local to localhost:3000"
"What routes are configured on srv0?"
"Show me the Prometheus metrics"
| Environment variable | Default | Description |
|---|---|---|
CADDY_ADMIN_URL | http://localhost:2019 | Caddy admin API URL. Set to http://caddy:2019 inside Docker, or an https URL for an admin endpoint behind a TLS-terminating reverse proxy — see Troubleshooting for the Host / Origin rules Caddy applies to anything that is not its own loopback address. Caddy's native remote admin listener (admin.remote, default :2021) is not supported: it requires a TLS client certificate, which caddy-mcp does not present. Also accepts a unix socket, in either unix:///var/run/caddy-admin.sock or Caddy's own unix//var/run/caddy-admin.sock spelling — see below. |
CADDY_API_TOKEN | (none) | Optional Bearer token, sent as Authorization: Bearer on every request. Caddy's admin API has no token auth of its own and ignores this header — it matters only to an authenticating proxy in front of the admin endpoint, so leave it unset when caddy-mcp reaches Caddy directly. If the header does arrive at the admin listener, Caddy 2.0 through 2.11.2 writes it in clear into the admin.api "received request" log line, at INFO — on every path except /metrics, which has logged at DEBUG since 2.2.1. Run Caddy 2.11.3 or later, which logs it as REDACTED, or have the proxy strip the header once it has authenticated (Caddy: header_up -Authorization; nginx: proxy_set_header Authorization "";). |
CADDY_MCP_SNAPSHOT_DIR | (none) | Directory for persisting caddy_revert snapshots. Unset, snapshots live in memory only and are lost when this server restarts. Snapshots are full Caddy configs and can contain secrets, so the location is opt-in rather than defaulted, and on POSIX a directory the server creates is 0700 and each snapshot file 0600. |
CADDY_MAX_RETRIES | 2 | Number of retries on transient failures: network errors, and 502/503/504 (which only a proxy in front of Caddy sends). Caddy's own 500s are deterministic rejections and never retry, nor do 4xx and 412. Requests a replay could change the outcome of also skip retry: POSTs to /config/* and /id/* (they append, or replace an existing key -- retrying could duplicate routes), and a PUT or DELETE at an array index such as .../routes/0 (a replay would insert a second route, or remove the one that slid into that index), including a PUT to a bare /id/ , which Caddy resolves to the identified element's array index. Those match however the path is spelled — with trailing slashes, or with the trailing /... segment Caddy strips before it picks a method, so .../routes/0/... and PUT /id/ /... are covered too. A config change whose timeout fired is never retried (see CADDY_LOAD_TIMEOUT). A refused connection retries for every method, since nothing was sent. POSTs to /load, /adapt, /stop still retry. Hard-capped at 5; values above the cap log a one-time stderr notice so the clamp is visible. Set to 0 to disable. Anything but a plain non-negative integer (after trimming) means the default, 2. |
CADDY_TIMEOUT | 10000 | Timeout in ms for admin API requests that do not change the config: GETs, /adapt, /stop, PKI, upstreams and metrics. Config changes use CADDY_LOAD_TIMEOUT. Non-numeric, <= 0, or fractional values below 1ms fall back to the default. |
CADDY_LOAD_TIMEOUT | 55000 | Timeout in ms for every request that changes the config: POST /load, and every POST/PUT/PATCH/DELETE under /config/* and /id/*. Each is a full synchronous reload inside Caddy, which can legitimately run long -- Caddy sleeps through apps.http.shutdown_delay inside the reload whenever a change closes a listener, and a change can wait behind another reload. A timeout here is never retried: Caddy keeps applying a change after the client gives up, so the error says the outcome is unknown and to re-read the config before retrying (caddy_load and caddy_revert keep their snapshot in that case). Keep it below your MCP client's request timeout (60 s by default in the MCP SDK), or that error arrives after the client has given up and is never shown; the default sits 5 s under it. Non-numeric, <= 0, or fractional values below 1ms fall back to the default. |
Unix socket admin endpoints:
Caddy's recommended hardening is to move the admin API off a loopback port and onto a unix socket, where access is governed by filesystem permissions:
{
admin unix//var/run/caddy-admin.sock }
Point CADDY_ADMIN_URL at the same path (unix:///var/run/caddy-admin.sock) and requests are sent over the socket instead of TCP. The process running caddy-mcp needs read/write permission on the socket file. Leave CADDY_API_TOKEN unset here unless an authenticating proxy actually listens on that socket: over a unix path caddy-mcp is usually talking to Caddy's own socket, where the token does nothing — and, before Caddy 2.11.3, is logged in clear.
Runtime (oam or Node):
The caddy-mcp command prefers oam when it finds a usable one and otherwise runs on Node. It never serves on an oam older than 0.19.1.
| Environment variable | Default | Description |
|---|---|---|
CADDY_MCP_RUNTIME | auto | auto: the newest oam at 0.19.1 or newer, else Node. oam: oam or exit with an error. node: always Node -- the escape hatch when a problem only shows up under oam. Trimmed and case-insensitive. |
CADDY_MCP_SANDBOX | (unset) | 1 or true (any case) runs the server under oam's --permission sandbox: network limited to the CADDY_ADMIN_URL host and port, filesystem limited to CADDY_MCP_SNAPSHOT_DIR, no child processes. Needs oam; under auto a machine without one runs unsandboxed, so pair it with CADDY_MCP_RUNTIME=oam when the sandbox has to hold. A unix-socket CADDY_ADMIN_URL is not reachable under the sandbox yet. Any other non-empty value leaves the sandbox off and warns on stderr. |
OAM_BIN | (unset) | Path to the oam binary to use. Otherwise the launcher checks OAM_INSTALL_DIR, the installed locations (~/.oam/bin, and %LOCALAPPDATA%\oam\bin on Windows) and PATH, and takes the newest. |
An outdated oam is fixed with oam self-update. Under Yaw MCP, which runs servers on oam by default, yaw-mcp set runtime=node switches this server to Node.
Alternate MCP clients:
| Client | Config file |
|---|---|
| Claude Code | .mcp.json (project root) or ~/.claude.json (global) |
| Claude Desktop | ~/Library/Application Support/Claude/claude_desktop_config.json (macOS) |
| Cursor | ~/.cursor/mcp.json |
| Windsurf | ~/.codeium/windsurf/mcp_config.json |
| VS Code | .vscode/mcp.json |
Use the same JSON block shown above in any of these.
overwrite (PATCH, default, idempotent; the key must exist, and the whole subtree at the path is replaced), append (POST: appends to an array, but replaces an existing non-array key and cannot create missing parents), insert (PUT: inserts at an array position, or strictly creates a key along with any missing parents and fails with 409 if it exists — the way to create a server or app, even on an instance with no config). append at a path ending in /... (e.g. apps/http/servers/srv0/routes/...) with an array value appends every element in one request — all or nothing, one reload; without the /..., an array value is added as a single element and Caddy rejects the load for typed arrays like routes or listen. A path that addresses the config root (`ตัดมาแค่ช่วงต้น อ่านต่อใน repo