Homelab
Homelab is an MCP server for managing homelab infrastructure with approval-gated changes and read-only diagnostics.
Inspect module status/health and missing settings (
homelab_modules,homelab_health).Manage Nginx Proxy Manager proxy hosts, HTTP redirections, SSL certificates, and IP access lists.
Manage Docker containers, images, volumes/networks/Portainer stacks, including logs/stats and start/stop/restart/remove/prune.
Manage Cloudflare DNS zones/records and export zone data in BIND format.
Expose or tear down services end-to-end (container check, optional DNS CNAME, NPM proxy host) with dry-run plans.
Get service status, infrastructure overview, and per-hop diagnosis from domain to upstream container.
Enable optional modules for Home Assistant, Uptime Kuma, Cloudflare Tunnel, AdGuard Home, and Authentik.
Use dry runs, approval prompts, approval logging, pre-approval settings, and read-only mode for safe operation.
Manages Cloudflare DNS: list zones, export a zone in BIND format, and list, get, create, update and delete DNS records, e.g. adding the CNAME needed to expose a homelab service.
Controls Docker engines over the local socket or a remote host: lists, inspects, starts, stops, restarts and removes containers, reads logs and stats, pulls, removes and prunes images, and manages volumes and networks.
Optional module for Home Assistant: list, get and search entities, call services or turn entities on/off/toggle, list, trigger and reload automations and scripts, preview new automation YAML, and read system config and check configuration.
Manages Nginx Proxy Manager instances: list, inspect, create, update and delete proxy hosts, HTTP redirections, IP access lists, and request Let's Encrypt SSL certificates, all via the NPM API.
Uses Portainer as an alternative to the Docker socket for container operations, including listing Portainer stacks and reading their compose files.
Click on "Deploy Server".
Wait a few minutes for the server to deploy. Once ready, it will show a "Started" state.
In the chat, type
@followed by the MCP server name and your instructions, e.g., "@Homelabexpose my jellyfin container at jellyfin.example.com with SSL"
That's it! The server will respond to your query, and you can continue using it as needed.
Here is a step-by-step guide with screenshots.
Homelab
Made by Seaynic Labs. Need tools like this built around your own systems? We do that.
Homelab is an MCP server that lets an AI assistant manage Nginx Proxy Manager proxy hosts, Docker containers and Cloudflare DNS records from one place. It covers the path from a container to a public web address. One call, expose_service, checks the container, adds the DNS record and the proxy host, and shows the plan before anything changes. Four more optional modules cover Uptime Kuma, Cloudflare Tunnel, AdGuard Home and Authentik.
It is a bundle: one server made of modules, plus skills that teach the assistant the workflows. You switch on the modules you use. New modules arrive switched off, so an update never changes what your assistant can do until you choose to.
Audience: self-hosters running a homelab.
Module | What it does | Status |
| Nginx Proxy Manager: proxy hosts, redirections, SSL certificates, access lists | On by default |
| Containers, images and volumes through the local Docker socket or Portainer | On by default |
| Cloudflare DNS zones and records, and BIND export | On by default |
| Entities, automations, scripts and system info in Home Assistant | Off by default, turn on with |
| Uptime Kuma monitors: list and read status (read only) | Off by default, turn on with |
| Cloudflare Tunnel routes: list, add and remove | Off by default, turn on with |
| AdGuard Home: filter status, query log and filter rules | Off by default, turn on with |
| Authentik: list applications, create a proxy provider and application for one host | Off by default, turn on with |
The core tools are always on: homelab_modules, homelab_health, expose_service, teardown_service, service_status, infrastructure_overview and diagnose_service.
Homelab works with any MCP client: Claude Desktop, Claude Code, Cursor, VS Code, Sonique, Hermes, OpenClaw and others. It runs on your own machine and keeps no data of its own. It talks only to the services you configure.
Install
Homelab needs Python 3.11 or newer. With uv there is nothing to install ahead of time. Pin the version so updates arrive only when you choose them:
uvx homelab-infra-mcp==2.1.1 --versionOr with pip:
pip install homelab-infra-mcp==2.1.1Upgrading from 2.0? Version 2.1 has no breaking changes. The four new modules are off by default. Read the 2.1.0 section of CHANGELOG.md.
Upgrading from 1.x? Version 2.0 changed the tool names and the environment variable names. Read the migration table in CHANGELOG.md first.
Quick install
Add the server to your MCP client (see Add it to your MCP client), set the variables for the modules you use, and restart the client. Then ask the assistant to call homelab_modules. The response lists each module, whether it is on, and which settings are missing.
Doctor
Run homelab-infra --doctor in a terminal before you start, and after any settings change:
homelab-infra --doctorThe doctor checks each enabled module's settings and reachability, the Docker socket access, and the TLS check. It prints a FIX line for each problem and exits with status 1 when something needs fixing.
Related MCP server: npm-mcp
Settings
Set these as environment variables in your MCP client's config, or put them in a config file (see below). You only need the settings for the modules you use. Homelab starts without any of them and tells you what is missing when you call a tool.
Variable | Module | What it is |
| proxy | Nginx Proxy Manager address. Default |
| proxy | The NPM admin login used for the API |
| docker | Docker engine address. Default |
| docker | Use Portainer instead of the socket. Both are needed. |
| docker | Portainer endpoint id. Default |
| dns | Cloudflare API token with DNS edit permission on the zone |
| dns | Default zone id, so tools can leave |
| home_assistant | Home Assistant address. Default |
| home_assistant | Long-lived access token |
| uptime | Uptime Kuma address |
| uptime | Uptime Kuma API key. Read from |
| tunnel | Cloudflare API token with tunnel edit permission |
| tunnel | Cloudflare account id that owns the tunnel |
| tunnel | Cloudflare Tunnel id |
| dns_filter | AdGuard Home address |
| dns_filter | AdGuard Home login |
| sso | Authentik address |
| sso | Authentik API token |
| sso | Authorization flow slug that new proxy providers use |
| any |
|
| any |
|
| all |
|
| any | Read a secret from a file instead, e.g. |
| core | Path to the config file. Default |
| core | Path to the approval log. Default |
Config file (optional). Homelab also reads ~/.config/homelab/config.toml, or the file named by HOMELAB_CONFIG. Each module has its own table. Environment variables win over the file.
[proxy]
email = "admin@example.com"
password = "change-me"
[dns]
api_token = "your-cloudflare-token"
zone_id = "your-zone-id"Turn a module on in the same file with its enabled key, or with HOMELAB_<MODULE>_ENABLED=true in the environment.
Add it to your MCP client
Most clients use the same JSON shape. Pin the version so the server runs the release you tested. Put the block where your client keeps MCP servers:
{
"mcpServers": {
"homelab": {
"command": "uvx",
"args": ["homelab-infra-mcp==2.1.1"],
"env": {
"HOMELAB_PROXY_EMAIL": "admin@example.com",
"HOMELAB_PROXY_PASSWORD": "change-me",
"HOMELAB_DNS_API_TOKEN": "your-cloudflare-token",
"HOMELAB_DNS_ZONE_ID": "your-zone-id"
}
}
}
}Client | Where the config goes |
Claude Desktop |
|
Claude Code |
|
Cursor |
|
VS Code |
|
Sonique, Hermes, OpenClaw, others | Any client that launches a stdio MCP server: command |
As a Claude Code plugin. The plugin installs the server and the skills together. Its .mcp.json pins homelab-infra-mcp==2.1.1. Set the variables in your environment or in the config file.
Over HTTP. For clients that connect to a URL instead of launching a process:
homelab-infra --transport http --port 8200It serves streamable HTTP at http://127.0.0.1:8200/mcp. It listens only on your own machine by default. Put authentication in front of it before exposing it anywhere else.
Tools
The default install has 16 tools. Each module adds its own tools when you turn it on.
Tool | What it does |
| Which modules are on, which settings are missing, and what each tool does. Call this first. |
| Connectivity and version for every enabled module |
| Check a container, add a DNS record (optional), add a proxy host. One approved plan. |
| Remove a service's proxy host and optional DNS record. One approved plan. |
| One view of a service: container, proxy hosts, DNS records |
| Counts across Docker, the proxy and DNS |
| Read only. Checks each hop from a domain to its service, one row per hop. Returns the first failing hop and its fix. |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| Config, available services, |
|
|
|
|
| Filter status and query and block totals (AdGuard Home, read only) |
| Paged query log (AdGuard Home, read only) |
|
|
|
|
Every tool returns structured data with a published schema, so an assistant can write code against the results. Lists take limit and offset. Every change tool takes dry_run=true, which shows exactly what would change and changes nothing. Errors always look like homelab.<module>.<code>: <message> Fix: <hint>.
Skills
Skills are short guides the assistant reads before a job. Homelab ships them in a skills/ folder for apps that read Agent Skills, and serves each one as an MCP prompt for every other client.
Written for Homelab
Skill | What it covers |
| Which modules are on, the settings each needs, the first checks, how approvals work |
| Put one container on a public name: dry run, approval, per-hop diagnosis, outside check |
| A read-only sweep of modules, containers, certificates, monitors and DNS filtering |
| Root-cause investigation for a failing service, one hypothesis at a time |
| Verify a fix against the original symptom, deploy it, check the live target |
| Status, logs, restarts, stats and images for Docker containers |
| An operational runbook for one service, with facts pulled from the live tools |
| An editable draw.io file from a description |
| A draw.io map of services, Docker networks, the proxy and the DNS path |
Third-party, under their own licenses
Skill | Author | License |
| Jesse Vincent, obra/superpowers | MIT |
| Cloudflare, cloudflare/skills | Apache-2.0 |
| csthink, csthink/dashmotion | MIT |
| Cocoon-AI, architecture-diagram-generator | MIT |
Each third-party skill keeps its license file. See CREDITS.md for the pinned upstream commits.
Try these
Call homelab_modules and tell me which modules are on and which settings are missing.Show every container that is restarting or unhealthy, with its last ten log lines.Dry-run expose_service for wiki-app on wiki.example.com, port 8080, and show me the plan.Diagnose wiki.example.com and fix the first failing hop.Run the homelab health check and give me one table.
Safety
Read-only tools never change anything. The assistant can list, inspect, search and read logs freely.
diagnose_servicemakes read-only calls only.Every change needs your approval. When the assistant asks to change something, Homelab asks you directly through your MCP client (MCP elicitation) and shows the exact change: the domain, the target, the container, the DNS record. The assistant cannot answer for you. No argument it sets counts as approval.
Every decision is logged. Each approve, decline and refusal goes into a local approval log. The default path is
~/.local/state/homelab/approvals.jsonl. SetHOMELAB_APPROVAL_LOGto choose another path.Dry runs show the plan. Every change tool accepts
dry_run=true. It shows what would change and changes nothing.Pre-approve only what you trust.
HOMELAB_<MODULE>_ALLOW_WRITES=truelets the assistant make changes in that module without asking. Use it for modules you are happy to automate, and leave it off for the rest.Some clients can't ask you questions. In those, a change returns
approval_unavailable, and the message names the setting to pre-approve or the setting to leave alone.Read-only mode.
HOMELAB_READ_ONLY=truerefuses all changes, even pre-approved ones.Secrets stay out of responses. Tokens, passwords and keys come from the environment, a file, or the config file.
homelab_modulesreports whether a setting is set, never its value.Docker socket access is root on the host. Mount the socket read-only when you only need to look, and use Portainer if you would rather not mount it at all.
Tunnel and SSO changes reach the public internet. Review each
tunnel_routesandsso_applicationsplan before you approve it.Homelab only calls the services you configure. It sends nothing anywhere else and keeps no data.
See SECURITY.md for the secrets list, the approval log and the reporting process.
Security card | |
Network | Only the services you configure: your Nginx Proxy Manager, your Docker engine or Portainer, api.cloudflare.com (DNS and Tunnel), and the Uptime Kuma, AdGuard Home, Authentik and Home Assistant addresses you set. diagnose_service also opens TCP and TLS connections to your upstreams and public domains. No telemetry. |
Files | Reads its config file ( |
Secrets | API keys, tokens and passwords come from your environment or config file. They are never tool arguments and never returned to the model. |
Read-only tools | 7: |
Needs your approval |
|
Startup cost | about 10,200 tokens (16 tools, 14 skill prompts) |
Changes | Tool descriptions are locked by hash ( |
Develop
uv venv -p 3.11 .venv && uv pip install -e '.[dev]'
.venv/bin/pytest -q
python3 scripts/scan_identifiers.py --patterns <file> .The tests never touch a real network or Docker engine. HTTP goes through httpx.MockTransport, and the Docker client is a fake.
License
MIT. See LICENSE. Third-party skills keep their own licenses; see CREDITS.md.
Built by Seaynic Labs. We build tools like this around a business's own systems: local-first, with a person approving every change. See custom integrations.
Available Tools
16 toolsdiagnose_serviceARead-only
Check each hop between a public domain and its upstream container, and name the first one that fails with the fix for it. Hops: DNS record, tunnel route (if the tunnel module is on), Nginx Proxy Manager host, TLS certificate (expiry and trust), upstream container running (Docker), upstream port answering, uptime monitor (if on), Authentik login in front (if on). Read-only: it changes nothing.
| Name | Required | Description | Default |
|---|---|---|---|
| domain | Yes |
Output Schema
| Name | Required | Description |
|---|---|---|
| hops | No | |
| note | No | |
| domain | Yes | |
| first_failure | No |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint=true and openWorldHint=true, and the description goes further by documenting the ordered diagnostic hops, conditional checks for optional modules, and the behavior of returning the first failure plus a fix. It does repeat the read-only nature, but still adds substantial process context beyond the annotations.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is front-loaded with the core action and then compactly lists the hop sequence. The length is justified by the diagnostic complexity, and every clause contributes useful scope or behavior information.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
The tool has an output schema and explicit read-only/open-world annotations, and the description explains the diagnostic chain well enough to call it correctly. The main remaining gaps are the exact domain input format and explicit routing against similar sibling tools.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 0%, so the schema provides only a bare string parameter named domain. The description partially compensates by specifying that it is a public domain in the context of a domain-to-container diagnostic chain, but it does not clarify format details such as whether to include a scheme, subdomain, or port.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description uses a specific diagnostic verb and resource: it checks every hop between a public domain and its upstream container and names the first failing hop with a fix. It also enumerates the exact check sequence, making the tool's scope and distinction from generic status/list tools clear.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Usage is implied through the troubleshooting workflow: the tool is for diagnosing where a public service path fails. However, it does not explicitly compare against siblings such as service_status, homelab_health, or infrastructure_overview, nor does it state when not to use it.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
dns_recordsADestructive
DNS records. list and get are read-only. create, update and delete change the zone and need the person's approval (or HOMELAB_DNS_ALLOW_WRITES=true). create needs name, record_type and content; update needs record_id and any field to change; delete removes the record permanently.
| Name | Required | Description | Default |
|---|---|---|---|
| ttl | No | ||
| name | No | ||
| page | No | ||
| limit | No | ||
| action | No | list | |
| content | No | ||
| dry_run | No | ||
| proxied | No | ||
| zone_id | No | ||
| record_id | No | ||
| record_type | No |
Output Schema
| Name | Required | Description |
|---|---|---|
| page | No | |
| items | No | |
| change | No | |
| detail | No | |
| has_more | No |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Goes well beyond the annotations by disclosing the approval gate, the environment-variable escape hatch, and that delete is permanent — real operational context an agent cannot get from destructiveHint alone. It stops short of explaining `dry_run`, which is the obvious safeguard for those destructive actions.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Four short sentences, front-loaded with the read-only vs. mutating split, then per-action requirements. No filler or restatement of the title.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Output schema exists, so return values need not be described, and the safety/approval story is fully covered. Gaps remain around pagination (page/limit), whether zone_id is required for scoped actions, and what dry_run does.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 0% across 11 parameters, so the description must carry the burden; it partially does, mapping name/record_type/content to create and record_id to update. It says nothing about zone_id, ttl, proxied, page/limit pagination, or dry_run, leaving over half the parameters unexplained.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
Names the resource (DNS records) and enumerates every action the single `action` enum supports, so an agent knows this is a multi-op CRUD tool for individual records. It does not explicitly contrast with the sibling `dns_zones` (which handles the parent zones), leaving that distinction to inference from the name.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Gives per-action guidance: list/get are read-only, create/update/delete mutate the zone and require approval or HOMELAB_DNS_ALLOW_WRITES=true. That is concrete when-to-use context, but there is no routing guidance toward alternatives such as `dns_zones` or `expose_service`.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
dns_zonesBRead-only
Zones for the Cloudflare account (action=list), or one zone exported in BIND format (action=export).
| Name | Required | Description | Default |
|---|---|---|---|
| page | No | ||
| limit | No | ||
| action | No | list | |
| zone_id | No |
Output Schema
| Name | Required | Description |
|---|---|---|
| page | No | |
| zones | No | |
| action | Yes | |
| export | No | |
| zone_id | No | |
| has_more | No |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already establish that this is a safe read-only, non-open-world operation. The description adds useful modality context by noting BIND export formatting, but it omits details such as pagination behavior or what data the export contains, even though an output schema exists.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is a single compact sentence with no wasted wording. The action-oriented structure is front-loaded and immediately useful.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
The tool is simple and has an output schema plus annotations, so the description does not need to explain return values. Still, with 0% schema description coverage, it should at least clarify pagination parameters and the zone_id requirement for export.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 0%, so the description must carry parameter meaning. It explains the action values and implies zone_id for export, but page, limit, and the explicit role of zone_id remain undocumented.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly identifies the resource (Cloudflare DNS zones) and the two modes (list zones or export one zone in BIND format). It does not explicitly distinguish this tool from sibling tools such as dns_records, which prevents a top score.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The action values imply when to use list versus export, giving some practical guidance. However, it does not state that export requires a zone_id, nor does it compare this tool with relevant alternatives such as dns_records.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
docker_containersADestructive
Containers. list, get, logs and stats are read-only. start, stop, restart, remove and prune change state and need the person's approval (or HOMELAB_DOCKER_ALLOW_WRITES=true). remove deletes a container permanently. prune removes ALL stopped containers. container is a name or id (not needed for list or prune).
| Name | Required | Description | Default |
|---|---|---|---|
| all | No | ||
| tail | No | ||
| limit | No | ||
| since | No | ||
| action | No | list | |
| offset | No | ||
| dry_run | No | ||
| timeout | No | ||
| container | No |
Output Schema
| Name | Required | Description |
|---|---|---|
| logs | No | |
| items | No | |
| stats | No | |
| total | No | |
| change | No | |
| detail | No | |
| has_more | No |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already flag readOnlyHint=false and destructiveHint=true, and the description reinforces this consistently rather than contradicting it. It adds genuinely useful context beyond the annotations: the approval gate, that remove is permanent, and that prune wipes ALL stopped containers. It omits any mention of the dry_run escape hatch, which would have closed the loop.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Compact and front-loaded: the read-only vs mutating split comes before the destructive specifics. The telegraphic sentence fragments are efficient but slightly hurt readability, and one or two sentences on the undocumented parameters could have been added without bloat.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
An output schema exists, so return values need no explanation, and the mutation/destruction story is well covered. However, for a 9-parameter multi-action tool with no schema descriptions, the missing parameter applicability (which params belong to which action, and what dry_run does) leaves the definition incomplete for correct invocation.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 0% across 9 parameters, so the description carries the full burden and covers only 'container' plus the action enum. Nothing explains all, tail, limit, since, offset, timeout, or dry_run — an agent cannot infer that tail/since apply to logs and limit/offset to list.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
Opens with a bare fragment ('Containers.') but immediately enumerates all nine actions, so the resource and operation set become unambiguous. It is distinguishable from docker_images and docker_inventory by the container-specific action list, though it never names those siblings explicitly.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Clearly separates the read-only actions (list, get, logs, stats) from state-changing ones (start, stop, restart, remove, prune) and states the precondition (human approval or HOMELAB_DOCKER_ALLOW_WRITES=true). It also notes 'container' is not needed for list or prune, but gives no guidance on when to reach for docker_images/inventory instead.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
docker_imagesADestructive
Images. list is read-only. pull, remove and prune change the host and need approval (or HOMELAB_DOCKER_ALLOW_WRITES=true). remove deletes an image; prune removes dangling and unused images.
| Name | Required | Description | Default |
|---|---|---|---|
| tag | No | latest | |
| force | No | ||
| image | No | ||
| limit | No | ||
| action | No | list | |
| offset | No | ||
| dry_run | No |
Output Schema
| Name | Required | Description |
|---|---|---|
| items | No | |
| total | No | |
| change | No | |
| has_more | No |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
The annotations already declare destructiveHint=true and readOnlyHint=false, and the description goes beyond them by stating the approval gate and the HOMELAB_DOCKER_ALLOW_WRITES=true escape hatch, plus what each destructive action actually destroys. It does not mention the dry_run flag or whether force changes deletion semantics, so some behavioral surface is uncovered.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Two sentences, no filler, with the read-only versus write distinction front-loaded before the per-action semantics. The only inefficiency is the one-word 'Images.' opener, which conveys little on its own.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
An output schema exists, so return values need not be described. However, for a seven-parameter, multi-action destructive tool with no schema descriptions, the description leaves the pagination and force parameters and the dry_run safety valve undocumented, which is a meaningful gap.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 0%, so the description carries full burden for seven parameters. It only glosses the action values and implicitly image/tag; force, limit, offset, and especially dry_run (a safety-relevant flag) go entirely unexplained in both schema and description.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description names the resource (Docker images) and enumerates the four actions in the enum (list, pull, remove, prune), which makes the tool's scope understandable. The opening fragment 'Images.' is terse and the verb is only implied by the action list, but an agent can still tell this is image management rather than container management.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
It clearly separates the safe read path (list) from the mutating paths (pull, remove, prune) and explains the difference between remove and prune, which is exactly the selection decision an agent needs. It does not say when to prefer docker_inventory or docker_containers over this tool, so sibling routing is left to inference.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
docker_inventoryARead-only
Read-only lists: volumes, networks, or Portainer stacks (stacks need the Portainer backend). Pass stack_id with kind=stacks to get that stack's compose file.
| Name | Required | Description | Default |
|---|---|---|---|
| kind | No | volumes | |
| limit | No | ||
| offset | No | ||
| stack_id | No |
Output Schema
| Name | Required | Description |
|---|---|---|
| kind | Yes | |
| items | No | |
| total | No | |
| backend | Yes | |
| has_more | No | |
| compose_file | No |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint=true and openWorldHint=false, so the 'Read-only' claim is consistent but adds little. The backend dependency for stacks is genuine added context, but pagination behavior (limit default 20, offset) and what happens when stack_id is omitted with kind=stacks are not disclosed.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Two sentences, zero filler, with the resource enumeration front-loaded and the conditional stack behavior immediately after. Every clause carries information.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
An output schema exists and annotations cover the safety profile, so the description only needs to carry invocation logic — which it largely does for kind and stack_id. The remaining gap is the undocumented pagination contract (limit/offset), which matters for a listing tool with a default page size of 20.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 0%, so the description carries the burden: it clarifies kind's three modes and explains that stack_id is meaningful only with kind=stacks. However, limit and offset are never mentioned, and stack_id's default of 0 is left ambiguous (no stack vs. ignored).
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a concrete verb ('lists') and enumerates the exact resources returned: volumes, networks, or Portainer stacks. This distinguishes it from siblings like docker_containers and docker_images by resource type, though it never names those siblings explicitly.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Gives a real prerequisite ('stacks need the Portainer backend') and a conditional mode switch ('Pass stack_id with kind=stacks to get that stack's compose file'), which tells the agent when the stack branch applies. It stops short of explicit exclusions or naming where to go for containers/images instead.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
expose_serviceADestructive
Expose a container: check it runs, add a Cloudflare CNAME to tunnel_hostname (only if given), and add an Nginx Proxy Manager host that forwards domain to forward_host:forward_port. The plan is shown to the person before anything changes.
| Name | Required | Description | Default |
|---|---|---|---|
| domain | Yes | ||
| dry_run | No | ||
| dns_zone_id | No | ||
| forward_host | No | host.docker.internal | |
| forward_port | Yes | ||
| container_name | Yes | ||
| tunnel_hostname | No |
Output Schema
| Name | Required | Description |
|---|---|---|
| note | No | |
| errors | No | |
| dry_run | No | |
| planned | No | |
| success | No | |
| approved_by | No | |
| steps_completed | No |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Beyond the destructiveHint/openWorldHint annotations, the description discloses the pre-flight container check, the conditional CNAME only when tunnel_hostname is supplied, and that a plan is presented before any change is applied. It still omits whether an existing proxy host is overwritten or how DNS records are reconciled, which matters for a destructive, open-world mutation.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Two sentences, zero waste, with the effect chain and the plan-preview guarantee front-loaded. Every clause adds information an agent cannot get from the schema.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
An output schema exists and the annotations carry the safety profile, so the description does not need to describe return values. It is nearly complete for a multi-step, multi-system mutation, with only idempotency/existing-resource behavior and dry_run semantics left open.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 0%, so the description must carry parameter meaning. It usefully explains that tunnel_hostname is optional/conditional and that forward_host:forward_port form the forwarding target, but dry_run, dns_zone_id, and container_name's role are left unexplained.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
Starts with a specific verb+resource ('Expose a container') and enumerates the three concrete side effects: container check, Cloudflare CNAME, Nginx Proxy Manager host. It is clearly distinguishable from the opposite-number sibling teardown_service, though it does not explicitly contrast with proxy_hosts or dns_records.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Usage is implied by the effects described (use when you want a container reachable at a domain), but there is no explicit when-to-use vs. alternatives guidance. The dry_run parameter exists in the schema yet the description never says when to prefer a dry run over a live apply.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
homelab_healthARead-only
Connectivity and version for every enabled module. A module with missing settings reports the variable it needs.
| Name | Required | Description | Default |
|---|---|---|---|
No parameters | |||
Output Schema
| Name | Required | Description |
|---|---|---|
| modules | Yes | |
| version | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint=true and openWorldHint=true, so the safety profile and outbound-network nature are covered. The description adds real behavioral value beyond that: results are scoped to *enabled* modules only, and a module with incomplete configuration surfaces the specific missing variable name rather than failing silently.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Two short sentences with no filler, and the module-scoping constraint is front-loaded. The opening fragment lacks a verb, which costs a little clarity, but nothing is wasted or repeated.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
An output schema exists, so return shape needn't be explained, and annotations cover the safety profile. What remains missing for a diagnostic tool of this kind is when to reach for it (first-line troubleshooting?), whether it performs live network probes with associated latency, and how it relates to infrastructure_overview.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The tool takes zero parameters, so the baseline is 4; there is nothing for the description to disambiguate. The schema is empty and fully described, leaving no gap for the description to fill.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description names the resource (every enabled module) and the two facts returned (connectivity, version), which is specific enough to distinguish it from plain module-listing siblings like homelab_modules. It is a noun phrase with no explicit verb ('reports'/'returns' is implied), which slightly blunts the statement of action.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
There is no guidance on when to call this versus related tools such as infrastructure_overview, service_status, or homelab_modules, and no prerequisites or expected cost (a per-module connectivity sweep is likely slower than a metadata listing). The agent must infer the use case from the name alone.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
homelab_modulesARead-only
Which modules are on, which settings are missing, whether writes are pre-approved, and what each tool does. Pass a module name for its full settings list (values are never shown, only whether they are set).
| Name | Required | Description | Default |
|---|---|---|---|
| module | No |
Output Schema
| Name | Required | Description |
|---|---|---|
| skills | No | |
| modules | Yes | |
| version | Yes | |
| homepage | No | |
| publisher | No | |
| read_only | Yes | |
| core_tools | Yes | |
| config_file | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Beyond readOnlyHint=true and openWorldHint=false, the description adds valuable behavioral context: settings values are never shown, only whether they are set, and it discloses whether writes are pre-approved. It does not cover auth or rate-limit behavior, so it falls short of a 5.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is two sentences and front-loads the main capabilities before giving the parameter instruction. It is efficient, though the phrase 'what each tool does' is slightly ambiguous.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a read-only tool with one optional parameter and an existing output schema, the description covers the key behavioral facts an agent needs: no values are exposed, write pre-approval status is reported, and a module name yields detail. It could be clearer about what happens when no module is passed, but it is largely complete.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
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 explains that passing a module name returns that module's full settings list, which adds meaning beyond the bare string parameter. However, it does not specify valid module names, accepted format, or default behavior when omitted beyond implication.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description states the tool's purpose in terms of the questions it answers: module on/off state, missing settings, write pre-approval, and tool descriptions. It is clear enough to distinguish this as an introspection tool, but it does not explicitly differentiate itself from siblings like infrastructure_overview or homelab_health.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
It gives one usage instruction: pass a module name for its full settings list. However, it does not say when to use this tool versus alternatives, nor when not to use it. Usage is implied rather than explicitly guided.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
infrastructure_overviewARead-only
Counts across Docker, Nginx Proxy Manager and Cloudflare DNS, in one call.
| Name | Required | Description | Default |
|---|---|---|---|
No parameters | |||
Output Schema
| Name | Required | Description |
|---|---|---|
| dns | No | |
| proxy | No | |
| docker | No |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint=true and openWorldHint=true, so the safety profile is covered. The description adds that results are aggregated across three external systems in a single request, but says nothing about freshness, latency, or what happens when one system is unreachable.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
A single short sentence with the scope front-loaded and no filler. It is a fragment rather than a full clause, but nothing wasted.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
An output schema exists, so return values need not be described, and a zero-parameter read-only tool carries little behavioral burden. What remains slightly thin is the framing of what the counts mean (e.g., whether this is a health/summary view).
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The tool takes zero parameters, so there is no parameter semantics for the description to explain. Baseline 4 applies.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
Names a specific verb ('Counts') and the three resources covered (Docker, Nginx Proxy Manager, Cloudflare DNS), which clearly distinguishes it from the sibling tools that each list one resource type. It stops short of saying what exactly is counted (containers? zones? records?).
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
'in one call' implies this is the aggregate/summary entry point rather than a per-resource listing tool, so usage is implied. There is no explicit guidance on when to prefer this over homelab_health or homelab_modules, nor any prerequisite or exclusion.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
proxy_access_listsADestructive
IP access lists. list is read-only. create and delete need approval (or ALLOW_WRITES). allow and deny are comma-separated IPs or CIDRs. Deleting a list affects every proxy host that uses it.
| Name | Required | Description | Default |
|---|---|---|---|
| deny | No | ||
| name | No | ||
| allow | No | ||
| limit | No | ||
| action | No | list | |
| offset | No | ||
| dry_run | No | ||
| list_id | No |
Output Schema
| Name | Required | Description |
|---|---|---|
| items | No | |
| total | No | |
| change | No | |
| has_more | No |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare destructiveHint=true and readOnlyHint=false; the description adds the approval gate for writes and the blast radius of deletion ('affects every proxy host that uses it'), which is exactly the kind of context annotations can't express. It stops short of describing pagination or failure behavior.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Three short sentences, front-loaded with the resource, then safety constraints, then the input format and destructive consequence. No filler.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
An output schema exists, so return values needn't be explained, and the approval/destructive behavior is covered. However, with 8 parameters and zero schema descriptions, the missing coverage for limit/offset/dry_run/list_id leaves the definition meaningfully incomplete for correct invocation.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 0% across 8 parameters, so the description must carry the load. It only clarifies the allow/deny comma-separated IP/CIDR format and implicitly ties name/list_id to create/delete; limit, offset, dry_run, and action semantics are unaddressed. That leaves most parameters undocumented in both structured and prose fields.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description names the resource ('IP access lists') and enumerates the operations (list, create, delete), so an agent can tell this manages proxy ACLs rather than proxy hosts or certificates. It is clear but lacks an explicit 'manage' verb and doesn't contrast itself with the proxy_* siblings beyond resource name.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Explicitly states list is read-only and that create/delete require approval or ALLOW_WRITES, which is actionable when-to-use context. It also warns that deleting a list affects every proxy host using it. It doesn't name alternatives, but for a resource-scoped CRUD tool that's a minor gap.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
proxy_certificatesADestructive
SSL certificates. list is read-only. request asks Let's Encrypt for a new certificate (needs approval, or ALLOW_WRITES). Let's Encrypt must be able to reach the domains.
| Name | Required | Description | Default |
|---|---|---|---|
| limit | No | ||
| action | No | list | |
| offset | No | ||
| dry_run | No | ||
| domain_names | No |
Output Schema
| Name | Required | Description |
|---|---|---|
| items | No | |
| total | No | |
| change | No | |
| has_more | No |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already flag the tool as destructive and non-read-only, but the description adds genuinely non-derivable behavior: the list action is safe while request performs an external Let's Encrypt issuance, issuance is gated behind approval or an ALLOW_WRITES flag, and it will fail if the domains are not publicly reachable. That is real operational context beyond the hints. It does not mention the dry_run escape hatch, which is the one notable omission for a destructive action.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Three short sentences, front-loaded with the resource, then the safe action, then the risky action with its prerequisites. Nothing is padded, though the telegraphic fragments ('SSL certificates.', 'list is read-only.') cost a little readability.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
An output schema exists, so return values need not be described, and the destructive/approval model is covered. What remains missing is how to scope a request (domain_names) and how to preview it (dry_run), which leaves an agent with a destructive tool under-documented at the call site.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 0% across 5 parameters, so the description must carry the burden and it largely does not. It explains the meaning of only one parameter value pair (action=list vs action=request); domain_names, limit, offset, and especially dry_run — the only way to preview a destructive issuance — get no mention at all.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The opening fragment 'SSL certificates' names the resource, and the two following sentences name the two modes of operation (list vs request), so the agent can tell this tool apart from proxy_hosts or dns_zones. It stops short of a single clean verb+resource statement, but the scope is unambiguous.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
It gives clear selection conditions: use list for a read-only view, use request to obtain a new Let's Encrypt certificate. It also states prerequisites (approval or ALLOW_WRITES, and DNS must resolve to reachable domains), which is exactly the context an agent needs before choosing request. It does not name a sibling alternative, so it falls short of a 5.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
proxy_hostsADestructive
Proxy hosts. list/get are read-only. create, update and delete change NPM and need the person's approval (or HOMELAB_PROXY_ALLOW_WRITES=true). dry_run=true previews without asking.
| Name | Required | Description | Default |
|---|---|---|---|
| ssl | No | ||
| limit | No | ||
| action | No | list | |
| offset | No | ||
| dry_run | No | ||
| host_id | No | ||
| force_ssl | No | ||
| domain_names | No | ||
| forward_host | No | ||
| forward_port | No | ||
| block_exploits | No |
Output Schema
| Name | Required | Description |
|---|---|---|
| items | No | |
| total | No | |
| change | No | |
| detail | No | |
| has_more | No |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare destructiveHint=true and readOnlyHint=false. The description adds valuable context beyond annotations: which actions are read-only, that mutations require human approval or a configured override, and that dry_run avoids the approval prompt. It does not detail exactly what data is destroyed or how updates merge with existing settings.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is three compact sentences with no wasted language. Read-only behavior, mutation approval, and dry_run preview are front-loaded in a logical order.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For an 11-parameter tool with 0% schema description coverage, the description is not complete enough about what the individual fields mean or how they affect each action. It covers mutation safety and dry_run well, and an output schema exists, but the substantial parameter documentation gap leaves an agent under-equipped to invoke create or update correctly.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 0% for 11 parameters, so the description must carry the burden. It explains action modes and dry_run meaningfully, but leaves domain_names, forward_host, forward_port, host_id, ssl, force_ssl, block_exploits, limit, and offset undocumented.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description names the resource ('Proxy hosts') and explicitly maps its action modes to read-only versus mutating behavior. It does not differentiate from siblings such as proxy_redirections or proxy_certificates, but an agent can still infer the tool's purpose from the action enum and description.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
It clearly states that list/get are read-only while create/update/delete change NPM and require approval or HOMELAB_PROXY_ALLOW_WRITES=true, and that dry_run=true previews without asking. It does not explain when to choose this tool over sibling proxy tools, but it gives strong operational guidance for the supported actions.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
proxy_redirectionsCDestructive
HTTP redirections. list is read-only; create and delete need approval (or ALLOW_WRITES).
| Name | Required | Description | Default |
|---|---|---|---|
| limit | No | ||
| action | No | list | |
| offset | No | ||
| dry_run | No | ||
| domain_names | No | ||
| preserve_path | No | ||
| forward_domain | No | ||
| forward_scheme | No | https | |
| redirection_id | No |
Output Schema
| Name | Required | Description |
|---|---|---|
| items | No | |
| total | No | |
| change | No | |
| has_more | No |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already flag readOnlyHint=false and destructiveHint=true, so the destructive nature is known structurally. The description adds genuinely new context beyond that: the approval / ALLOW_WRITES gating requirement for create and delete. It does not disclose what a delete removes (the rule only, vs. associated certs/hosts) or whether writes are reversible.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Two short sentences with no filler, and the most decision-relevant fact (approval gating for writes) is stated up front. It is arguably too terse rather than padded, but on the conciseness axis it is efficient.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a 9-parameter, 3-action tool with zero schema documentation, the description should map parameters to actions (e.g., create needs domain_names + forward_domain; delete needs redirection_id). An output schema exists so return values need not be explained, but the per-action parameter requirements and the meaning of dry_run are left entirely to guesswork.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 0% across 9 parameters, so the description carries the full burden and does not meet it. It clarifies only the `action` enum values; `domain_names`, `forward_domain`, `forward_scheme`, `preserve_path`, `redirection_id`, `dry_run`, `limit`, and `offset` are entirely undocumented, including which are required for which action.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
"HTTP redirections" names the resource and the second sentence enumerates the three actions (list/create/delete), which is the key fact that this is a multiplexed action tool. But there is no verb describing what managing a redirection actually entails (e.g., domain forwarding rules), and no differentiation from siblings like proxy_hosts or dns_records beyond the noun.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
It distinguishes the read path from the write paths ("list is read-only; create and delete need approval"), which implies when each action is appropriate. It gives no guidance on when to prefer this tool over proxy_hosts, dns_records, or expose_service, and no prerequisite context for first-time users.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
service_statusCRead-only
One view of a service: the container, the proxy hosts that name the domain, and its DNS records.
| Name | Required | Description | Default |
|---|---|---|---|
| domain | No | ||
| dns_zone_id | No | ||
| container_name | Yes |
Output Schema
| Name | Required | Description |
|---|---|---|
| errors | No | |
| container | No | |
| dns_records | No | |
| proxy_hosts | No |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint=true and openWorldHint=true, so the safety profile is covered. The description adds that the payload spans three related entity types (container, proxy hosts, DNS records), which is useful framing beyond the annotations, but it says nothing about scoping behavior, empty results, or what open-world lookups it performs.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
A single tight sentence that front-loads the core idea and enumerates the three data sources. It wastes no words, though brevity comes partly from omitting information that matters.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
An output schema exists, so return structure needn't be restated. However, a composite lookup tool with three fully undocumented parameters and no sibling differentiation leaves key decisions (which id to pass, what happens when domain is blank) unaddressed.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 0%, so the description carries the full burden, yet it never mentions the three parameters. The phrases 'the container', 'the domain', and 'its DNS records' loosely hint at container_name, domain, and dns_zone_id, but nothing explains optionality, defaults, or how domain/dns_zone_id narrow the aggregate.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description says it is an aggregated view of a service comprising the container, proxy hosts, and DNS records, which conveys the resource. But 'One view of a service' is noun-only, with no verb identifying this as a read/lookup, and nothing distinguishes it from infrastructure_overview or homelab_health.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
There is no statement of when to use this composite view versus querying docker_containers, proxy_hosts, and dns_records separately, and no guidance on when to prefer infrastructure_overview. The agent must infer the selection criteria entirely.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
teardown_serviceADestructive
Reverse expose_service: delete the proxy host for domain (found by name unless proxy_host_id is given) and, if dns_record_id is given, that DNS record. The exact plan is shown to the person first.
| Name | Required | Description | Default |
|---|---|---|---|
| domain | Yes | ||
| dry_run | No | ||
| dns_zone_id | No | ||
| dns_record_id | No | ||
| proxy_host_id | No |
Output Schema
| Name | Required | Description |
|---|---|---|
| note | No | |
| errors | No | |
| dry_run | No | |
| planned | No | |
| success | No | |
| approved_by | No | |
| steps_completed | No |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already flag destructive=true and openWorld=true, so the description's added value is the explicit blast radius (proxy host plus optional DNS record) and the order in which they are removed, plus the note that a plan is presented to the person first. It leaves dry_run unexplained, which matters for a destructive tool with 0% schema coverage.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Two sentences, no filler, and the destructive action is front-loaded ahead of the conditional clauses. Every clause carries information the agent needs.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Output schema exists so return values need no explanation, but for a destructive 5-parameter tool the description should still explain what dry_run does and what dns_zone_id is for. The core destructive semantics are covered; the preview/scope controls are not.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
With 0% schema description coverage the description must compensate, and it does cover three of five parameters: domain lookup by name, proxy_host_id as an override, and dns_record_id as the opt-in for DNS deletion. dry_run and dns_zone_id are never mentioned, so the compensating work is only partial.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb and resources (delete the proxy host and, optionally, the DNS record) and anchors itself to a named sibling by declaring it the reverse of expose_service. An agent can distinguish it from every other sibling without opening the schema.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
"Reverse expose_service" gives a clear selection rule against that specific sibling, and the conditional phrasing tells the agent when the DNS record is also removed. It does not say when NOT to use it (e.g., when only the DNS record should be removed, or when the host was created outside expose_service).
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.
2 tool updates
v2.1.1- Added
diagnose_service - Changed
homelab_modules4 fields changed- added
Output schema / $defs / SkillInfoAdded value: +{ + "properties": { + "description": { + "title": "Description", + "type": "string" + }, + "license": { + "title": "License", + "type": "string" + }, + "name": { + "title": "Name", + "type": "string" + } + }, + "required": [ + "name", + "description", + "license" + ], + "title": "SkillInfo", + "type": "object" +} - added
Output schema / properties / homepageAdded value: +{ + "default": "https://github.com/seayniclabs/homelab-infra-mcp", + "title": "Homepage", + "type": "string" +} - added
Output schema / properties / publisherAdded value: +{ + "default": "Seaynic Labs", + "title": "Publisher", + "type": "string" +} - added
Output schema / properties / skillsAdded value: +{ + "default": [], + "items": { + "$ref": "#/$defs/SkillInfo" + }, + "title": "Skills", + "type": "array" +}
15 tool updates
v2.0.0- First observed
dns_records - First observed
dns_zones - First observed
docker_containers - First observed
docker_images - First observed
docker_inventory - First observed
expose_service - First observed
homelab_health - First observed
homelab_modules - First observed
infrastructure_overview - First observed
proxy_access_lists - First observed
proxy_certificates - First observed
proxy_hosts - First observed
proxy_redirections - First observed
service_status - First observed
teardown_service
TDQS
Scored across 16 tools
Most tools are clearly separated by resource and action: Docker container/image/inventory tools, proxy resource tools, DNS zone/record tools, and diagnostic/overview tools. The main overlap is between high-level composite tools (expose_service, teardown_service, service_status, infrastructure_overview) and the lower-level resource tools, which can require judgment about which abstraction to use.
All names use snake_case, but the convention is mixed: some are plural resource nouns (proxy_hosts, docker_containers, dns_records), some are module/status nouns (homelab_modules, homelab_health, service_status), and some are verb_noun action tools (diagnose_service, expose_service, teardown_service). The names are readable, but there is no single predictable pattern.
Sixteen tools is reasonable for a homelab management server spanning Docker, reverse proxy, DNS, diagnostics, and service lifecycle. The count is slightly high because composite tools coexist with granular resource tools, but each tool still has a plausible role.
The surface covers core homelab workflows well: Docker inspection and lifecycle, proxy hosts/redirections/certificates/access lists, DNS zones/records, diagnostics, exposure/teardown, and status overview. Some gaps remain, such as management operations for tunnels, Authentik, uptime monitoring, and Docker volumes/networks beyond read-only inventory.
Maintenance
Related MCP Connectors
Manage hosts, redirects, SSL, and traffic analytics from Claude and other AI assistants.
Hosting for AI agents: your AI client deploys Docker apps to live HTTPS URLs over MCP.
MCP server for AI agents to plan, verify, and deploy Cloudflare-native apps.
Manage your own cloud with AI: deploy apps, push and ship custom Docker images, manage resources via your AI agent.
Related MCP Servers
- AlicenseNot gradedqualityDmaintenanceEnables AI assistants to manage Nginx Proxy Manager instances through natural language, covering 28 tools for proxy hosts, certificates, streams, and more.23 PyPIMIT
- AlicenseNot gradedqualityDmaintenanceEnables AI assistants to manage Nginx Proxy Manager, including proxy hosts, SSL certificates, streams, and more.1 npmISC
- AlicenseBqualityCmaintenanceEnables AI agents to manage Nginx Proxy Manager (reverse proxies, streams, redirects, and Let's Encrypt certificates) through natural language commands.3016 npmMIT
- AlicenseNot gradedqualityCmaintenanceEnables conversational management of Nginx Proxy Manager, including reverse-proxy routing, TLS certificates, access lists, and stream forwards, with built-in safety guardrails for production use.1MIT