caddy-mcp has 7 tools with clear verb-noun naming (get_, list_, validate_, adapt_, load_, patch_, stop_). All tools have descriptions (avg 95 chars, within 10-1024 range). However, input schemas lack parameter descriptions for most tools, only 'caddyfile' and 'path' have descriptions; 'config', 'value', and boolean flags lack them. Output schemas are undocumented. Error handling is minimal: no recovery guidance, no categorization of retryable vs fatal errors. Dry-run defaults are good for safety, but destructive operations (stop_caddy, load_config, patch_config) lack confirmation patterns beyond dry_run. No tool annotations (readOnlyHint, destructiveHint) present.
Convert Caddyfile text to JSON. Defaults to dry_run command preview.
Read Caddy's active JSON config, optionally below /config/{path}.
Summarize host matchers and reverse_proxy upstreams from the active config.
Replace Caddy's active config via POST /load. Defaults to dry_run.
Patch a config subpath via PATCH /config/{path}. Defaults to dry_run.
Stop the Caddy process via POST /stop. Defaults to dry_run.
Run `caddy validate` against Caddyfile text without loading it.
Missing parameter descriptions for 'config', 'value', and boolean 'dry_run' flags across load_config, patch_config, and stop_caddy. LLMs cannot infer what 'value' means or why 'dry_run' exists without explicit text.
No output schemas documented. Tools return dicts with varying structures (e.g., get_config returns raw JSON, validate_caddyfile returns {valid, stdout, stderr, returncode}). LLMs cannot plan downstream calls without knowing response fields.
Destructive operations (load_config, patch_config, stop_caddy) lack error recovery guidance. If a PATCH fails, the tool returns a CaddyAPIError with status code but no hint on whether to retry, ask user, or abort. No categorization of retryable vs fatal errors.
| Scored | Grade | Overall | Spec posture | Rubric |
|---|---|---|---|---|
| 2026-09-23 | D | 55 | 2026-07-28+ | v2 |
No tool annotations (readOnlyHint, destructiveHint, idempotentHint) present. Clients cannot distinguish read-only tools from destructive ones without parsing descriptions. This violates current MCP spec (2026-07-28) which expects tool annotations for safety.
CaddyAdminClient._request() redacts response bodies on error ('Response body redacted') but does not provide actionable guidance. E.g., 'Caddy admin API PATCH /config/apps/http failed with 400. Response body redacted.' does not tell the LLM what to do next.