Skip to main content
Glama
euisuh

Caddy MCP

by euisuh

Caddy MCP

MCP server for safely inspecting and operating a local Caddy admin API. Built for homelab and personal-infra workflows where an AI assistant should be able to inspect active routes, validate Caddyfile snippets, and preview admin-API mutations before applying them.

Features

  • FastMCP stdio and SSE transports.

  • Safe default Caddy admin URL: http://127.0.0.1:2019.

  • Read-only tools for active config and reverse-proxy upstream inventory.

  • Caddyfile validation/adaptation helpers using the local caddy binary.

  • Mutating tools default to dry_run=true.

  • Redacted admin API errors.

  • Installable package layout, Dockerfile, Compose sidecar, CI, tests, and client examples.

Related MCP server: porkbun-mcp

Tools

Tool

Purpose

Mutates

get_config

Read active JSON config, optionally below /config/{path}

no

list_reverse_proxy_upstreams

Summarize host matchers and reverse_proxy upstreams

no

validate_caddyfile_text

Validate Caddyfile text with caddy validate

no

adapt_caddyfile_text

Convert Caddyfile text to JSON; dry-run preview by default

no

load_config

Replace active config with POST /load

yes, unless dry-run

patch_config

Patch one config path with PATCH /config/{path}

yes, unless dry-run

stop_caddy

Stop Caddy with POST /stop

yes, unless dry-run

Quick start

git clone https://github.com/euisuh/caddy-mcp.git
cd caddy-mcp
python -m venv .venv
. .venv/bin/activate
pip install -e .
CADDY_ADMIN_URL=http://127.0.0.1:2019 caddy-mcp

For SSE sidecar mode:

MCP_TRANSPORT=sse MCP_HOST=127.0.0.1 MCP_PORT=8000 caddy-mcp

Docker sidecar

docker compose up --build

The Compose file binds the MCP port to localhost and points at host Caddy's admin API via host.docker.internal:2019.

Safety model

  • Caddy's admin API is powerful. Keep it bound to loopback or an internal network.

  • This server does not expose credentials and does not persist tokens.

  • Mutating tools default to dry-run and return the exact method/path/value preview.

  • Use load_config and patch_config only after validating/adapting configs.

  • stop_caddy exists for completeness but also defaults to dry-run.

Development

pip install -e . -r requirements-dev.txt
ruff check .
pytest -q
python -m build --sdist --wheel
twine check dist/*

Live smoke against a local Caddy

CADDY_ADMIN_URL=http://127.0.0.1:2019 python - <<'PY'
import asyncio
from fastmcp import Client
from caddy_mcp.server import build_server

async def main():
    async with Client(build_server()) as client:
        print([tool.name for tool in await client.list_tools()])
        print((await client.call_tool('list_reverse_proxy_upstreams', {})).data)

asyncio.run(main())
PY

License

MIT

Available Tools

7 tools
adapt_caddyfile_textB

Convert Caddyfile text to JSON. Defaults to dry_run command preview.

ParametersJSON Schema
NameRequiredDescriptionDefault
dry_runNo
caddyfileYes

Output Schema

ParametersJSON Schema
NameRequiredDescription

No output parameters

TDQS

B3.1/5.0
Behavior2/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

No annotations are provided, so the description carries the full burden. It discloses 'Defaults to dry_run command preview', suggesting a non-destructive default, but fails to state what happens when dry_run is false (e.g., applying changes). It also omits side effects, permissions, or reversibility, which is significant for a tool that may mutate Caddy configuration.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is two sentences with no redundancy. It is front-loaded with the core purpose and includes a useful behavioral note about the dry_run default. Every word earns its place.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness2/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

The description lacks critical behavioral context such as whether dry_run=false applies changes to the live configuration, how this relates to sibling config-modification tools, and what errors might occur. Although an output schema exists, the description does not explain when to use this tool over load_config or patch_config, leaving completeness gaps for an agent.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters2/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is 0% and the description adds limited value. It implicitly identifies caddyfile as the input text and mentions dry_run's default, but does not explain the effect of dry_run=false or any format constraints. The description does not adequately compensate for the lack of schema parameter descriptions.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description clearly states 'Convert Caddyfile text to JSON', using a specific verb and resource. It distinguishes the tool from siblings like validate_caddyfile_text (validation vs conversion) and get_config (retrieval), making the purpose unambiguous.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines2/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

There is no explicit guidance on when to use this tool versus alternatives. The description does not mention validate_caddyfile_text for validation or patch_config/load_config for config modifications. The dry_run hint implies a use case but lacks clear when-to-use or when-not-to-use instructions.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

get_configA

Read Caddy's active JSON config, optionally below /config/{path}.

ParametersJSON Schema
NameRequiredDescriptionDefault
pathNo

TDQS

A4.2/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

No annotations are provided, so the description carries the full burden. It explicitly states 'Read' which discloses the non-destructive nature, and 'active JSON config' indicates the source and format. It does not mention any side effects or special behaviors, but for a read tool this is sufficient transparency.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is a single concise sentence, front-loaded with the verb 'Read'. It contains no filler and every word adds value, making it highly efficient.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

Given the tool's simplicity (one optional parameter, no output schema), the description covers the essential purpose and the meaning of the path. It indicates the output format (JSON config) but does not elaborate on potential errors or response structure, which is acceptable for a straightforward read operation.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

The input schema has one optional path parameter with a default empty string. The description adds meaning by explaining that the path is for reading a subpath below /config/{path}, which clarifies its semantics beyond the schema's bare type/default.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description clearly states the tool reads Caddy's active JSON config with an optional path. It uses a specific verb ('Read') and resource ('Caddy's active JSON config'), and the mention of '/config/{path}' distinguishes it from siblings like load_config and patch_config which imply write operations.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines3/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description provides context that the tool reads configuration, implying it should be used when you need to inspect the current config. However, it does not explicitly state when not to use it or name alternative tools for writing/configuring, leaving the differentiation to the sibling tool names.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

list_reverse_proxy_upstreamsA

Summarize host matchers and reverse_proxy upstreams from the active config.

ParametersJSON Schema
NameRequiredDescriptionDefault

No parameters

Output Schema

ParametersJSON Schema
NameRequiredDescription
resultYes

TDQS

A4/5.0
Behavior3/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

No annotations are provided, so the description carries the full burden. 'Summarize' implies a read-only operation, but it does not explicitly disclose side effects, requirements (e.g., a loaded config must exist), or error behavior. It adds some context but lacks depth.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

A single, concise sentence with no redundant words. It front-loads the verb and resource, making it immediately scannable.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

With no parameters and an output schema present, the description adequately covers the tool's function. 'Active config' could be more explicit, but the sibling tool names (e.g., load_config, get_config) provide the surrounding context. Minimal gap for such a simple tool.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

The tool has zero parameters, so the baseline is 4. The schema already covers everything that could be said about parameters, and the description correctly focuses on behavior rather than inputs.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description uses the specific verb 'Summarize' with a clear resource ('host matchers and reverse_proxy upstreams') scoped to 'the active config'. This distinguishes it from sibling tools like get_config or load_config, which imply broader operations.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines3/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description clearly implies when to use the tool (to obtain a summary of reverse proxy routing), but it does not explicitly state when not to use it or mention alternatives like get_config for full config details. The usage context is inferable but not spelled out.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

load_configB

Replace Caddy's active config via POST /load. Defaults to dry_run.

ParametersJSON Schema
NameRequiredDescriptionDefault
configYes
dry_runNo

TDQS

B3.1/5.0
Behavior2/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

No annotations are provided, so the description must disclose behavioral traits. It only mentions 'Defaults to dry_run,' which repeats schema information (dry_run default: true) and does not explain what dry_run actually does or the impact of replacing the active config. It omits details about destructive effects, success/failure responses, or permissions. The POST /load reference is technical context, not behavior transparency.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is a single sentence of 10 words, immediately stating the core action and key default. It is front-loaded and contains no wasted words. Every piece of information ('replace', 'active config', 'POST /load', 'defaults to dry_run') serves a purpose.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness2/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a tool with only 2 parameters, no output schema, and no annotations, the description is too sparse. It does not explain return values, side effects of replacing config, or the meaning of dry_run (e.g., whether it prevents actual changes). This leaves critical context gaps, especially given the potentially destructive nature of the operation.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters2/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 0%, so the description must compensate. It does not explain the 'config' parameter beyond implying it is the new config. The 'dry_run' default is mentioned but is already in the schema. No additional meaning about formats, structure, or constraints is provided, leaving the agent to guess about the config object's expected content.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description clearly states the tool's function: 'Replace Caddy's active config via POST /load.' This uses a specific verb ('replace') and resource ('active config'), making it distinct from siblings like patch_config (which modifies) and get_config (which reads). The mention of the HTTP endpoint adds technical specificity.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines2/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description provides no guidance on when to use this tool versus alternatives. It does not mention when to choose load_config over patch_config, or any prerequisites or context for full config replacement. Usage must be inferred from the word 'replace' and the siblings list, but no explicit direction is given.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

patch_configA

Patch a config subpath via PATCH /config/{path}. Defaults to dry_run.

ParametersJSON Schema
NameRequiredDescriptionDefault
pathYes
valueYes
dry_runNo

TDQS

A4.2/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

With no annotations, the description carries the full burden. It discloses the dry_run default (a crucial safety behavior) and the HTTP method/path pattern. It does not mention authentication or side effects, but the dry-run disclosure is significant.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is two concise sentences, front-loaded with the verb and resource. Every word earns its place, and the dry_run note is placed in a logical position.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a simple patch tool, the description covers the most critical behavior (dry_run default) and HTTP pattern. It lacks details on return values or the shape of 'value', but given the simplicity and sibling context, it is reasonably complete.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 0%, so the description must explain parameters. It implicitly explains 'path' (config subpath) and 'dry_run' (defaults to true), but the 'value' parameter is left entirely unexplained. This is a notable gap for a required parameter.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description clearly states the action ('Patch'), the target ('a config subpath'), and the HTTP method (PATCH /config/{path}). This distinguishes it from siblings like get_config (read) and load_config (load/replace).

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

It provides a key usage guideline by noting 'Defaults to dry_run,' implying you can preview changes without applying them. It does not explicitly describe when to prefer this over alternatives, but the purpose and sibling names make the context clear.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

stop_caddyA

Stop the Caddy process via POST /stop. Defaults to dry_run.

ParametersJSON Schema
NameRequiredDescriptionDefault
dry_runNo

TDQS

A4/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

With no annotations provided, the description carries the full burden of behavioral disclosure. It reveals the critical default behavior: 'Defaults to dry_run', meaning the tool does not actually stop the process unless dry_run is set to false. This is essential context for safe usage. However, it does not detail what happens when actually stopping (e.g., confirmation, side effects), but the dry_run disclosure is a strong positive.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is a single, concise sentence that front-loads the main action ('Stop the Caddy process') and includes the key default behavior. Every word earns its place with no superfluous information.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a simple tool with one optional parameter and no output schema, the description covers the core purpose and the essential dry_run default. It is complete enough for most usage, but could be enhanced by explicitly stating the effect of setting dry_run to false or noting that stopping is irreversible. Overall, it is adequate but not exhaustive.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

The schema has 0% description coverage for the sole parameter dry_run, so the description must compensate. It mentions 'Defaults to dry_run', which gives the default value and implies the parameter controls whether the stop is simulated. However, it does not explicitly state what setting dry_run to false does (i.e., actually stop the process), leaving some ambiguity for agents unfamiliar with the dry_run convention.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description clearly states the tool stops the Caddy process, using a specific verb ('Stop') and resource ('Caddy process'). It also mentions the HTTP endpoint (POST /stop), which adds specificity. This distinguishes it from sibling tools that deal with configuration and validation.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines3/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description implies the tool is used when you need to stop Caddy, but it does not explicitly provide when-to-use guidance or contrast with alternatives. There is no mention of when to prefer this over other tools. The dry_run default hints at safe usage, but no explicit exclusions or alternative recommendations are given.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

validate_caddyfile_textA

Run caddy validate against Caddyfile text without loading it.

ParametersJSON Schema
NameRequiredDescriptionDefault
caddyfileYes

Output Schema

ParametersJSON Schema
NameRequiredDescription

No output parameters

TDQS

A4.2/5.0
Behavior3/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

No annotations are provided, so the description carries the full burden. It discloses the key behavior 'without loading it', indicating no side effects on current config. However, it does not describe error handling, return values, or what happens on invalid syntax. Since an output schema exists but is not shown, the description adds some behavioral context but lacks completeness.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is a single, efficient sentence that front-loads the action and key qualifier. Every word earns its place, with zero unnecessary detail.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a simple validation tool with one parameter and an existing output schema, the description is nearly complete. It states purpose and side-effect behavior. It could mention that validation results are returned, but the output schema likely covers that. Slightly lacking in explaining error behavior, but overall adequate.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

The schema has no descriptions for its single parameter (`caddyfile`), and coverage is 0%. The description explicitly says 'against Caddyfile text', which clearly conveys that the parameter is the Caddyfile content. This compensates for the lack of schema documentation, though it could be more explicit about format.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description clearly states the tool runs `caddy validate` against Caddyfile text, which is a specific verb-resource pair. It also distinguishes itself from siblings like `adapt_caddyfile_text` and `load_config` by emphasizing it does not load the config.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description provides clear context for when to use the tool: validating Caddyfile text before loading. However, it does not explicitly mention alternatives or when not to use it, so it falls short of a 5. The 'without loading it' implies a safe pre-check, which is useful.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

Tool Schema Changelog

Recent tool additions, removals, and schema changes observed during successful MCP inspections. Dates show when Glama detected each change.

  1. 7 tool updatesv0.1.0
    • First observedadapt_caddyfile_text
    • First observedget_config
    • First observedlist_reverse_proxy_upstreams
    • First observedload_config
    • First observedpatch_config
    • First observedstop_caddy
    • First observedvalidate_caddyfile_text

TDQS

A3.9/5.0
Disambiguation5/5

Each tool targets a distinct config operation: get_config reads the full config, list_reverse_proxy_upstreams extracts a specific view, validate_caddyfile_text and adapt_caddyfile_text are clearly different (validation vs. conversion), and load_config, patch_config, and stop_caddy each handle a unique mutation. The descriptions clearly separate the purposes, leaving no ambiguity.

Naming Consistency5/5

All tool names follow a consistent verb_noun pattern using snake_case (e.g., get_config, validate_caddyfile_text, patch_config). The verbs precisely indicate the action and the nouns specify the target, making the naming predictable and uniform.

Tool Count5/5

Seven tools is a well-scoped set for a Caddy management server, covering reads, transformations, and mutations without bloat or unnecessary redundancy. Each tool earns its place in the collection.

Completeness4/5

The tool surface covers the core config lifecycle: read, validate, adapt, load, patch, and stop. Minor gaps exist, such as no explicit start or status command, but these are reasonable workarounds or may be handled externally, so the surface is largely complete.

Maintenance

ActivitySlowing
ResponsivenessNo issues

Resources

Unclaimed servers have limited discoverability.

Looking for Admin?

If you are the server author, to access and configure the admin panel.

Related MCP Connectors

Related MCP Servers

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/euisuh/caddy-mcp'

If you have feedback or need assistance with the MCP directory API, please join our Discord server