Nginx Proxy Manager MCP
Enables requesting and renewing Let's Encrypt certificates through Nginx Proxy Manager, including creating HTTPS-forced proxy hosts with certificates.
Provides tools for managing Nginx Proxy Manager reverse-proxy hosts, redirection hosts, streams, SSL certificates, and access lists via the NPM API, including dry-run previews and one-shot HTTPS proxy host creation.
Nginx Proxy Manager MCP
An MCP server for Nginx Proxy Manager. It lets Claude and other MCP clients manage reverse-proxy hosts, Let's Encrypt certificates, and access lists through typed tools instead of clicking through the NPM admin UI.
"Point blog.example.com at the container on port 3000 with HTTPS"
│
▼
Claude / MCP client ──► Nginx Proxy Manager MCP ──HTTP + JWT──► NPM API
The demo calls create_proxy_host_with_letsencrypt(dry_run=True) against a mocked NPM API and prints both request previews. No real NPM instance or credentials are used. To record it again, install the development dependencies and VHS, then run vhs docs/demo.tape from the repository root; docs/demo.py uses the same respx mocking approach as the tests.
Why this exists
Reverse-proxy changes are repetitive homelab work: create a host, point it at a container, attach a certificate, maybe restrict it to an access list. That is exactly the kind of operational task an AI assistant can handle well when it has narrow, typed tools and a local admin boundary.
This server runs either:
as an SSE Docker sidecar next to an existing NPM container, or
as a stdio MCP server for local clients.
Related MCP server: MCP Manager
Features
30 MCP tools for common NPM operations.
dry_runon all mutating tools to preview NPM requests before applying them;One-shot
create_proxy_host_with_letsencryptrequests a certificate, then creates an HTTPS-forced proxy host.JWT auth against the NPM API with in-memory token caching and automatic re-authentication on
401.Docker sidecar deployment that binds the MCP port to localhost by default.
Offline pytest suite with mocked NPM API responses.
Ruff quality gate and contributor templates for public maintenance.
Python wheel build validation and MCP directory metadata for promotion readiness.
No token persistence and no hardcoded credentials.
Tools
Category | Tools |
Workflows |
|
Proxy hosts |
|
Redirection hosts |
|
Streams |
|
SSL certs |
|
Access lists |
|
All mutating tools expose dry_run=True. Previews contain method and path, plus json when the request has a body; the HTTPS workflow returns two previews in steps. The flag suppresses mutating requests, though some previews read current state. Update tools send only the fields in NPM's PUT schema (fixes #19); this is covered by mocked tests and not yet checked against a live NPM instance.
Compared to other NPM MCP servers
Competitor facts below come only from their linked READMEs fetched with gh api repos/<owner>/nginx-proxy-manager-mcp/readme on 2026-10-13. “not documented” means the README does not establish the capability, not that it is absent. Auth guard means inbound MCP client authentication, distinct from NPM API login.
Repository | Tool count documented | Dry-run support | Transport | Auth guard |
30 |
| stdio, SSE | Optional SSE bearer token ( | |
14 named tools (13 catalog rows plus | not documented | stdio, HTTP | HTTP bearer token ( | |
66 | DELETE without | stdio, Streamable HTTP | Optional bearer token ( | |
4 named tools ( | Changes show what will be sent and require | not documented | not documented |
This server's implementations expose dry_run on every mutating tool, provide the one-shot create_proxy_host_with_letsencrypt workflow, and publish the Docker sidecar at 127.0.0.1:8000:8000. These are verified in tools/, server.py, and docker-compose.yml. They do not establish that other servers lack equivalent capabilities.
Quick start: Docker sidecar
The bundled docker-compose.yml starts both Nginx Proxy Manager and this MCP sidecar from source. If you already run NPM, copy only the nginx-proxy-manager-mcp service into your existing compose file.
git clone https://github.com/euisuh/nginx-proxy-manager-mcp.git
cd nginx-proxy-manager-mcp
cp .env.example .env
# edit .env — NPM_EMAIL / NPM_PASSWORD must be an existing NPM admin account
docker compose up -dNPM_URL defaults to http://app:81, the NPM admin API on the internal Docker network. Leave it as-is when both services share a compose stack; point it at your NPM host otherwise.
To use the published GHCR image instead of building locally:
services:
nginx-proxy-manager-mcp:
image: ghcr.io/euisuh/nginx-proxy-manager-mcp:latest
restart: unless-stopped
environment:
NPM_URL: http://app:81
NPM_EMAIL: ${NPM_EMAIL}
NPM_PASSWORD: ${NPM_PASSWORD}
MCP_TRANSPORT: sse
MCP_HOST: 0.0.0.0
MCP_PORT: 8000
MCP_BEARER_TOKEN: ${MCP_BEARER_TOKEN:-}
ports:
- "127.0.0.1:8000:8000"Register the SSE server with Claude Code:
claude mcp add npm http://localhost:8000/sseOr add it manually to an MCP client config:
{
"mcpServers": {
"nginx-proxy-manager": {
"url": "http://localhost:8000/sse"
}
}
}More examples live in examples/: Claude Desktop, Claude Code, Cursor, and Windsurf.
Quick start: uvx / pipx
If you do not want Docker, run it from PyPI (package nginx-proxy-manager-mcp-server):
NPM_URL=http://localhost:81 \
NPM_EMAIL=admin@example.com \
NPM_PASSWORD=... \
MCP_TRANSPORT=stdio \
uvx nginx-proxy-manager-mcp-serverOr from a local checkout:
git clone https://github.com/euisuh/nginx-proxy-manager-mcp.git
cd nginx-proxy-manager-mcp
NPM_URL=http://localhost:81 \
NPM_EMAIL=admin@example.com \
NPM_PASSWORD=... \
MCP_TRANSPORT=stdio \
uvx --from . nginx-proxy-manager-mcpOr install it into an isolated environment:
pipx install nginx-proxy-manager-mcp-serverQuick start: stdio
Use stdio when you want the MCP client to launch the server process directly instead of talking to a sidecar.
python -m venv .venv
. .venv/bin/activate
pip install -e .
NPM_URL=http://localhost:81 \
NPM_EMAIL=admin@example.com \
NPM_PASSWORD=... \
MCP_TRANSPORT=stdio \
nginx-proxy-manager-mcpExample client config:
{
"mcpServers": {
"nginx-proxy-manager": {
"command": "/path/to/nginx-proxy-manager-mcp/.venv/bin/python",
"args": ["-m", "nginx_proxy_manager_mcp.server"],
"env": {
"NPM_URL": "http://localhost:81",
"NPM_EMAIL": "admin@example.com",
"NPM_PASSWORD": "...",
"MCP_TRANSPORT": "stdio"
}
}
}
}Configuration
Variable | Required | Default | Description |
| yes | — | Base URL of the NPM admin API ( |
| yes | — | NPM admin account email |
| yes | — | NPM admin account password |
| no |
| MCP transport: |
| no |
| Bind address for SSE mode; Docker Compose sets |
| no |
| Bind port for SSE mode |
| no | — | Optional bearer token required for SSE HTTP requests |
Missing required variables make the server exit with a clear error at startup rather than fail on the first API call.
SSE mode also exposes GET /healthz, an unauthenticated liveness endpoint that returns a small JSON response. It does not contact NPM or validate credentials; use it for container and reverse-proxy health checks only.
Architecture
┌───────────────┐ MCP over SSE/stdio ┌──────────────────────────┐
│ Claude/Cursor │ ─────────────────────► │ Nginx Proxy Manager MCP │
│ / MCP client │ │ server.py + tools/ │
└───────────────┘ └───────────┬──────────────┘
│ HTTP + Bearer JWT
▼
┌──────────────────────────┐
│ Nginx Proxy Manager API │
│ app:81 / localhost:81 │
└──────────────────────────┘nginx_proxy_manager_mcp/server.pyvalidates required env vars, builds the FastMCP app, registers every tool module, and serves either SSE or stdio.nginx_proxy_manager_mcp/npm_client.pywrapshttpx, exchanges the admin email/password for a JWT on first use, caches the token in memory, and re-authenticates on401.nginx_proxy_manager_mcp/tools/keeps one module per NPM resource. Adding a resource means adding oneregister_*_tools(mcp, client)function and one registration line.
Development
python -m venv .venv
. .venv/bin/activate
pip install -e . -r requirements-dev.txt
pytest -qTests mock the NPM API with respx, so the suite runs offline and touches no real infrastructure. CI runs the same command on every push and pull request.
Releases
Tagged releases (vX.Y.Z) publish the nginx-proxy-manager-mcp-server package to PyPI via trusted publishing (.github/workflows/publish.yml) and multi-architecture Docker images to GitHub Container Registry:
ghcr.io/euisuh/nginx-proxy-manager-mcp:<version>for tags such asv0.2.0ghcr.io/euisuh/nginx-proxy-manager-mcp:<major>.<minor>for semver tagsghcr.io/euisuh/nginx-proxy-manager-mcp:latestfor the newest tagged release
The Docker workflow also builds pull requests without pushing an image, so packaging changes are validated before release.
Security
Anything that can reach this MCP server has admin-level control over your proxy hosts and certificates.
Do not expose the MCP endpoint publicly.
Keep the Docker port bound to
127.0.0.1unless you have another trusted network boundary.Bare SSE runs bind to
127.0.0.1by default; setMCP_HOST=0.0.0.0only behind a trusted network boundary.Set
MCP_BEARER_TOKENfor SSE deployments that can be reached by anything beyond the local machine, and configure clients to sendAuthorization: Bearer YOUR_TOKEN.Use environment variables or a secrets manager for NPM credentials; do not commit
.env.The NPM admin JWT lives in process memory and is never written to disk.
The container runs as a non-root user.
See SECURITY.md for reporting and deployment guidance.
Roadmap
See ROADMAP.md. Near-term priorities are PyPI publishing, MCP directory submission, broader NPM resource coverage, and integration tests.
Directory metadata
smithery.yamldescribes stdio launch configuration for Smithery-style MCP directories.glama.jsondeclares the repository maintainer for Glama MCP registry verification.
Limitations
Covers proxy hosts, redirection hosts, streams, certificates, and access lists only. 404 hosts, users, audit log, and settings are not implemented yet.
Certificate creation supports Let's Encrypt HTTP-01 only — no DNS-01 challenge and no custom certificate upload yet.
One NPM instance per server process; there is no multi-tenant or multi-host routing.
Optional SSE bearer-token auth protects the HTTP endpoint, but there is no per-tool authorization after a client is authenticated.
/healthzreports only process liveness, not NPM reachability.Written against the NPM v2 API; older or forked NPM builds may differ.
Contributing
Issues and pull requests are welcome. See CONTRIBUTING.md. Adding a new NPM resource follows a fixed shape:
Create
nginx_proxy_manager_mcp/tools/<resource>.pywith aregister_<resource>_tools(mcp, client)function.Register it in
build_server()innginx_proxy_manager_mcp/server.py.Add
tests/test_<resource>.pycovering each tool with respx-mocked NPM responses.Run
ruff check .andpytest -q.
Commits follow Conventional Commits.
Author
Built and maintained by Euisuh Jeong to manage a homelab reverse proxy from Claude Code.
License
MIT — see LICENSE.
Available Tools
30 toolscreate_access_listCreate Access ListA
Create an access list containing optional IP allow/deny rules and basic-auth users. Use this to define access controls for hosts; use update_access_list to change an existing list. NPM stores the rules and credentials, while item passwords are write-only and cannot be read back. Returns the created list object with its ID, name, and rules. Set dry_run=True to preview the exact request without changing NPM.
| Name | Required | Description | Default |
|---|---|---|---|
| name | Yes | Human-readable name for this access list. | |
| items | No | Basic-auth users as username/password pairs; passwords are write-only in NPM. | |
| clients | No | IP or network rules; each directive must be allow or deny. | |
| dry_run | No | When True, return the exact request preview without changing NPM. | |
| pass_auth | No | Whether NPM passes basic-auth credentials upstream. | |
| satisfy_any | No | Whether satisfying any configured access rule is sufficient. |
Output Schema
| Name | Required | Description |
|---|---|---|
No output parameters | ||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations, the description carries the full behavioral burden and does well: it discloses that NPM stores rules and credentials, that item passwords are write-only and cannot be read back, that the created object is returned, and what dry_run does. It does not state permission/auth requirements or whether the operation can fail partway, which is the only notable gap.
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 tight sentences, front-loaded with purpose, then routing, then behavioral caveat, then the dry_run escape hatch. Every sentence contributes and nothing is padded.
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 the return-value sentence is mild redundancy rather than a necessity, but the write-only password and dry_run notes are genuinely useful for a mutation tool. Auth/permission prerequisites are the one omission for a create operation with no annotations.
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 100%, so every parameter already carries its own description; the baseline is 3. The description reinforces two of them (write-only passwords, dry_run preview) but adds no syntax, format, or constraint detail beyond the schema.
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 resource ('Create an access list') and immediately specifies its contents (IP allow/deny rules and basic-auth users). It explicitly names the sibling update_access_list as the tool for an existing list, so an agent can distinguish it without opening either 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?
Names the alternative explicitly ('use update_access_list to change an existing list') and gives the selecting condition, plus a preview path (dry_run=True) for verifying before committing. Nothing about when to pick this over its sibling 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.
create_letsencrypt_certCreate Letsencrypt CertA
Request a new Let's Encrypt certificate for the supplied domains. Use this when a certificate is needed without creating a proxy host; create_proxy_host_with_letsencrypt also creates an HTTPS-forced host. This sends a certificate request to NPM and may contact Let's Encrypt. Returns the certificate object with its ID, domains, and status. Set dry_run=True to preview the exact request without changing NPM.
| Name | Required | Description | Default |
|---|---|---|---|
| Yes | Email address supplied to Let's Encrypt for certificate requests. | ||
| dry_run | No | When True, return the exact request preview without changing NPM. | |
| domain_names | Yes | Domain names routed by this host or certificate. | |
| dns_challenge | No | Use DNS validation instead of HTTP validation for the certificate request. |
Output Schema
| Name | Required | Description |
|---|---|---|
No output parameters | ||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
No annotations, so the description carries the full burden: it discloses that the request is sent to NPM, may contact Let's Encrypt, what is returned (cert object with ID, domains, status), and that dry_run previews without mutating. It omits auth/permission requirements, idempotency on re-request, and Let's Encrypt rate-limit implications, which matter for a certificate-issuance tool.
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 tight sentences, front-loaded with purpose followed by routing guidance, behavior, and return shape. Slightly crowded by the return-value sentence, which is redundant with the output 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?
For a mutation tool with no annotations and an existing output schema, the description covers purpose, alternative, external side effects, and preview mode. Remaining gaps are low-severity (permissions, rate limits, failure behavior) but not blocking for correct selection.
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 100%, so all four parameters are already documented, and the description only restates dry_run semantics already present in the schema. It adds no syntax, constraints, or interaction details (e.g. dns_challenge vs email) beyond structured data.
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?
Specific verb+resource ('Request a new Let's Encrypt certificate for the supplied domains') with an explicit statement of what it does not do, and it names the closest sibling create_proxy_host_with_letsencrypt so the agent can distinguish the two without reading schemas.
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 an explicit when-to-use condition ('when a certificate is needed without creating a proxy host') and names the alternative plus its differentiating behavior (create_proxy_host_with_letsencrypt also creates an HTTPS-forced host). No inference required.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
create_proxy_hostCreate Proxy HostA
Create a proxy host that routes the supplied domains to an HTTP or HTTPS upstream. Use this when configuring proxying without requesting a certificate; use create_proxy_host_with_letsencrypt to request one and force HTTPS. NPM stores the host configuration and applies it through its normal config handling. Returns the created host object with its ID, domains, and forwarding settings. Set dry_run=True to preview the exact request without changing NPM.
| Name | Required | Description | Default |
|---|---|---|---|
| dry_run | No | When True, return the exact request preview without changing NPM. | |
| ssl_forced | No | Whether NPM redirects HTTP requests to HTTPS. | |
| domain_names | Yes | Domain names routed by this host or certificate. | |
| forward_host | Yes | Upstream hostname or IP address. | |
| forward_port | Yes | Upstream TCP port number. | |
| access_list_id | No | NPM access-list ID to attach; omit for no access list. | |
| block_exploits | No | Whether NPM enables its exploit-blocking option. | |
| certificate_id | No | NPM certificate ID to attach; omit for no certificate. | |
| forward_scheme | Yes | Upstream scheme: http or https. | |
| caching_enabled | No | Whether NPM enables proxy caching. | |
| allow_websocket_upgrade | No | Whether NPM allows WebSocket upgrades. |
Output Schema
| Name | Required | Description |
|---|---|---|
No output parameters | ||
TDQS
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 that NPM persists the host config and applies it through normal config handling, that dry_run returns a preview without changing NPM, and what the response contains. It stops short of permission/auth requirements or reversibility, but the mutation behavior and non-destructive escape hatch are clearly conveyed.
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 sentences, each earning its place: purpose, tool selection, persistence/return behavior, and preview mode. The most decision-relevant routing rule is front-loaded right after the purpose.
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 mutation tool with an output schema present, the agent needs purpose, selection rule, and mutation semantics, and all are supplied. Return values are described even though the output schema already covers them, so nothing required to invoke it correctly is missing.
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 100%, so all 11 parameters are already documented in the schema and the baseline is 3. The description only reinforces dry_run behavior and the no-certificate framing, adding little beyond what the schema already says.
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 resource ('Create a proxy host') plus the routing scope ('routes the supplied domains to an HTTP or HTTPS upstream'). It explicitly names the sibling create_proxy_host_with_letsencrypt as the contrasting option, so an agent can distinguish the two without opening schemas.
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 direct selection rule: use this when configuring proxying without a certificate, otherwise use create_proxy_host_with_letsencrypt to request one and force HTTPS. It also explains the dry_run preview path, so both the choice-of-tool and the safe-invocation path are covered.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
create_proxy_host_with_letsencryptCreate Proxy Host With LetsencryptA
Request a Let's Encrypt certificate, then create a proxy host using that certificate with HTTPS forced. Use this for a new TLS-enabled proxy; use create_proxy_host when a certificate already exists or HTTPS forcing is not wanted. This triggers a certificate request before creating the host; failures report failed_step and any created certificate. Returns ok plus certificate and proxy_host objects on success. Set dry_run=True to preview the exact request without changing NPM.
| Name | Required | Description | Default |
|---|---|---|---|
| Yes | Email address supplied to Let's Encrypt for certificate requests. | ||
| dry_run | No | When True, return the exact request preview without changing NPM. | |
| domain_names | Yes | Domain names routed by this host or certificate. | |
| forward_host | Yes | Upstream hostname or IP address. | |
| forward_port | Yes | Upstream TCP port number. | |
| access_list_id | No | NPM access-list ID to attach; omit for no access list. | |
| block_exploits | No | Whether NPM enables its exploit-blocking option. | |
| forward_scheme | Yes | Upstream scheme: http or https. | |
| caching_enabled | No | Whether NPM enables proxy caching. | |
| allow_websocket_upgrade | No | Whether NPM allows WebSocket upgrades. |
Output Schema
| Name | Required | Description |
|---|---|---|
No output parameters | ||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations, the description carries the burden and does well: it discloses the certificate request side effect, failure reporting via failed_step and created certificate, the success return shape, and dry_run preview behavior. It omits auth/rate-limit context, which would matter for a Let's Encrypt operation, but the core behavioral traits are covered.
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?
Front-loads the composite purpose, then usage, then behavioral details in a tight set of sentences. Every sentence earns its place and nothing is redundant.
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 10-parameter mutation with a certificate side effect, no annotations, and an existing output schema, the description covers purpose, alternative selection, failure behavior, return summary, and dry_run. Missing auth and Let's Encrypt rate-limit notes are minor gaps given the output schema handles return values.
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 100%, so the schema already documents all 10 parameters thoroughly. The description mentions dry_run semantics but adds no parameter meaning beyond what the schema provides, consistent with the baseline of 3 when structured data does the work.
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 composite resource: request a Let's Encrypt certificate then create a proxy host with HTTPS forced. It explicitly distinguishes itself from create_proxy_host, so an agent can select it without opening either 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?
Gives explicit when-to-use guidance and names the alternative create_proxy_host with the exact conditions that favor it: a certificate already exists or HTTPS forcing is not wanted. No inference is required.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
create_redirection_hostCreate Redirection HostA
Create a host that redirects requests for domains to a destination using the selected HTTP status. Use this for URL redirection; use create_proxy_host to forward requests to an upstream server. NPM stores the redirect configuration; an attached certificate ID is referenced without requesting a certificate. Returns the created host object with its ID and redirect settings. Set dry_run=True to preview the exact request without changing NPM.
| Name | Required | Description | Default |
|---|---|---|---|
| dry_run | No | When True, return the exact request preview without changing NPM. | |
| ssl_forced | No | Whether NPM redirects HTTP requests to HTTPS. | |
| domain_names | Yes | Domain names routed by this host or certificate. | |
| preserve_path | No | Whether to preserve the original request path in the redirect. | |
| block_exploits | No | Whether NPM enables its exploit-blocking option. | |
| certificate_id | No | NPM certificate ID to attach; omit for no certificate. | |
| forward_scheme | No | Scheme of the redirect destination: http or https. | https |
| forward_http_code | No | HTTP redirect status: 301, 302, 307, or 308. | |
| forward_domain_name | Yes | Destination hostname or URL for redirected requests. |
Output Schema
| Name | Required | Description |
|---|---|---|
No output parameters | ||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations, the description carries the full burden and does add value — it discloses that no certificate is requested when a certificate_id is referenced, and that dry_run previews without changing NPM. However, it omits permissions/auth requirements, whether the operation is reversible, and side effects of creation, which are material for an un-annotated mutation tool.
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?
Five sentences with the purpose front-loaded ahead of the sibling routing and behavioral notes. Slightly redundant with schema on dry_run, but generally tight and well-ordered.
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 the return-value sentence is supplementary rather than required; the description nonetheless acknowledges the returned host object. For a 9-param mutation tool with no annotations, it is nearly complete, missing only permission/prerequisite context.
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 100%, so baseline is 3; the schema documents all nine parameters including defaults and valid HTTP codes. The description reinforces the cert-reference and dry_run semantics but adds little beyond what the schema already provides.
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+resource ('Create a host that redirects requests for domains to a destination') and immediately contrasts with the sibling create_proxy_host. An agent can distinguish it from create_proxy_host and create_stream without opening a 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?
Explicitly routes usage: 'Use this for URL redirection; use create_proxy_host to forward requests to an upstream server.' The condition selecting the alternative is stated clearly. It does not cover the other redirection-host lifecycle siblings, but the core when-to-use vs alternative is fully specified.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
create_streamCreate StreamA
Create a TCP/UDP port forward from an incoming port to a destination host and port. Use this for raw TCP or UDP forwarding; use proxy-host tools for HTTP/HTTPS domain routing. NPM stores the stream configuration and applies it through normal config handling. Returns the created stream object with its ID, ports, and protocol flags. Set dry_run=True to preview the exact request without changing NPM.
| Name | Required | Description | Default |
|---|---|---|---|
| dry_run | No | When True, return the exact request preview without changing NPM. | |
| incoming_port | Yes | Public TCP/UDP port number accepted by this stream. | |
| tcp_forwarding | No | Whether this stream forwards TCP traffic. | |
| udp_forwarding | No | Whether this stream forwards UDP traffic. | |
| forwarding_host | Yes | Hostname or IP address receiving stream traffic. | |
| forwarding_port | Yes | Destination TCP/UDP port number. |
Output Schema
| Name | Required | Description |
|---|---|---|
No output parameters | ||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
No annotations are provided, so the description carries the full behavioral burden. It discloses that NPM stores the configuration and applies it through normal config handling, that it returns the created object with ID/ports/protocol flags, and that dry_run previews without mutating. It omits auth/permission requirements and any restart or propagation behavior, but that is a modest gap for a straightforward create.
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 tight sentences, front-loaded with the core action before the routing alternative and the return/dry-run notes. Slightly redundant in restating the return payload and dry_run behavior that the schema and output schema already convey.
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 explaining the return object is optional, and the create is a single flat mutation with fully documented parameters. What remains thin is permission/prerequisite context, which matters for a create tool with no annotations.
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 100%, so every parameter is already documented in the input schema, establishing a baseline of 3. The description only echoes dry_run semantics (already in the schema) and refers generically to 'protocol flags' rather than adding new meaning to tcp_forwarding/udp_forwarding defaults.
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 (Create) plus resource (TCP/UDP port forward) and the exact scope (incoming port to destination host and port). It explicitly distinguishes itself from the sibling proxy-host tools by naming the alternative category for HTTP/HTTPS domain routing.
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 an explicit selection rule: use this for raw TCP or UDP forwarding, use proxy-host tools for HTTP/HTTPS domain routing. It also names the dry_run preview mode as a safe alternative to committing the create, so the agent knows both the routing decision and the pre-flight option.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
delete_access_listDelete Access ListA
Permanently delete an access list by ID from NPM. Use update_access_list to retain the list and change its rules; confirm the ID with list_access_lists first. Deletion cannot be undone and may affect hosts that reference the list. Returns True on success. Set dry_run=True to preview the exact request without changing NPM.
| Name | Required | Description | Default |
|---|---|---|---|
| id | Yes | ID of the access list, from the matching list tool. | |
| dry_run | No | When True, return the exact request preview without changing NPM. |
Output Schema
| Name | Required | Description |
|---|---|---|
| result | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations, the description carries the full burden and does so: it declares the operation is permanent and irreversible, warns that referencing hosts may be affected, states the return value (True on success), and documents the dry_run preview behavior. This is exactly the destructive-operation context an agent needs.
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 tight sentences, each earning its place: action, alternative, prerequisite, consequences, return value, and preview flag. The destructive action is front-loaded, followed by the safe alternative.
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 description still notes the True-on-success return, and all the operational risk of an irreversible delete is disclosed. Nothing needed to invoke this tool safely is missing.
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 100% and both parameters are already documented in the schema, including dry_run's preview semantics and the ID's origin. The description reinforces this but adds no syntax or format detail beyond what the schema provides, so baseline 3 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?
States a specific verb+resource combination ('Permanently delete an access list by ID from NPM') and explicitly distinguishes itself from update_access_list and list_access_lists. An agent can select this tool without opening any sibling 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?
Gives explicit routing: use update_access_list to keep the list and change rules, and confirm the ID with list_access_lists first. Both the 'when to use this' and the 'when to use something else' conditions are stated, plus a prerequisite step.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
delete_proxy_hostDelete Proxy HostA
Permanently delete a proxy host by ID, removing its configured domain routing from NPM. Use disable_proxy_host to stop routing while keeping the host; list_proxy_hosts helps confirm the ID. Deletion cannot be undone and NPM applies the configuration change. Returns True on success. Set dry_run=True to preview the exact request without changing NPM.
| Name | Required | Description | Default |
|---|---|---|---|
| id | Yes | ID of the proxy host, from the matching list tool. | |
| dry_run | No | When True, return the exact request preview without changing NPM. |
Output Schema
| Name | Required | Description |
|---|---|---|
| result | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations, the description carries the full burden and does well: it discloses irreversibility ("cannot be undone"), the external side effect ("NPM applies the configuration change"), the return value, and a safe-preview mode via dry_run. It stops short of stating required permissions or auth, but the destructive/reversibility profile is fully covered.
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 tight sentences with the destructive action front-loaded, then the alternative, then the safety valve. Every sentence carries information an agent needs; 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?
For a two-parameter destructive tool with an output schema present, the description covers the destructive semantics, the alternative path, the ID source, and the dry-run escape hatch. Nothing required for correct invocation is missing.
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 100%, so the baseline is 3. The description's notes on id (confirm via the list tool) and dry_run (preview the exact request) largely restate what the schema already documents, adding no new syntax, format, or constraint detail.
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 a specific verb and resource ("Permanently delete a proxy host by ID") and clarifies scope by stating it removes "its configured domain routing from NPM." An agent can distinguish it from update_proxy_host or disable_proxy_host without opening any 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?
It explicitly routes to the alternative ("Use disable_proxy_host to stop routing while keeping the host") and names a helper for obtaining the required ID ("list_proxy_hosts helps confirm the ID"). When-to-use, when-not-to-use, and an alternative are all present.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
delete_redirection_hostDelete Redirection HostA
Permanently delete a redirection host by ID, removing its redirect configuration from NPM. Use disable_redirection_host to retain it while stopping redirects; list_redirection_hosts helps verify the ID. Deletion cannot be undone and applies the NPM configuration change. Returns True on success. Set dry_run=True to preview the exact request without changing NPM.
| Name | Required | Description | Default |
|---|---|---|---|
| id | Yes | ID of the redirection host, from the matching list tool. | |
| dry_run | No | When True, return the exact request preview without changing NPM. |
Output Schema
| Name | Required | Description |
|---|---|---|
| result | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
No annotations are provided, so the description carries the full burden and does so richly: irreversible ('cannot be undone'), applies an NPM config change, returns True on success, and a dry_run preview mode. This is exactly the behavioral context an agent needs for a destructive 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?
Three tightly packed sentences: action/effect front-loaded, then alternatives, then reversibility/return/preview. No filler; every clause earns its place.
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 destructive single-resource delete with an output schema present, the description covers irreversibility, alternatives, ID sourcing, return value, and dry-run preview. Nothing an agent needs to call it correctly is missing.
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 100%, so parameters are fully documented in the schema. The description still adds value by explaining the dry_run semantics ('preview the exact request without changing NPM') and the id source, slightly above the baseline 3.
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 (delete) and resource (redirection host) with the scope clarified as 'by ID' and the effect stated precisely ('removing its redirect configuration from NPM'). Clearly distinguishable from siblings like disable_redirection_host.
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 names the non-destructive alternative (disable_redirection_host to retain while stopping redirects) and points to list_redirection_hosts to resolve the ID. This gives clear when-to-use-this-vs-that guidance.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
delete_streamDelete StreamA
Permanently delete a TCP/UDP stream by ID; NPM stops forwarding that port immediately and this cannot be undone. List streams first to confirm the ID. Returns True on success. Set dry_run=True to preview the exact request without changing NPM.
| Name | Required | Description | Default |
|---|---|---|---|
| id | Yes | ID of the stream, from the matching list tool. | |
| dry_run | No | When True, return the exact request preview without changing NPM. |
Output Schema
| Name | Required | Description |
|---|---|---|
| result | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations, the description carries the full behavioral burden and does so well: permanent deletion, immediate cessation of port forwarding, irreversibility, and a dry_run preview path. It omits auth/permission requirements and any side effects on related configuration, which keeps it below 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?
Front-loaded with verb and resource, then risk, then prerequisite, then return and preview behavior — each clause earns its place with 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?
For a destructive tool with no annotations, the description covers irreversibility, immediate effect, safe-preview option, and a confirmation step; an output schema already documents the return value. Nothing essential for correct invocation is missing.
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 100%, so both id and dry_run are already documented in the schema; the description largely restates the dry_run preview behavior. It adds only the minor hint that the ID comes from the matching list tool. Baseline 3 is appropriate when the schema does the heavy lifting.
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, resource (delete a TCP/UDP stream by ID), and the concrete effect on NPM. An agent can immediately distinguish this from delete_proxy_host, delete_access_list, and delete_redirection_host by the resource named.
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?
'List streams first to confirm the ID' gives an explicit prerequisite step pointing at the list_streams sibling, which routes the agent correctly. There is no explicit when-not or alternative-selection guidance, but the context for use is clear.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
disable_proxy_hostDisable Proxy HostA
Disable a proxy host by ID while retaining its configuration. Use delete_proxy_host to remove it; use list_proxy_hosts to check its current status. This changes NPM host state and stops that host from serving traffic. Returns the updated host object. Set dry_run=True to preview the exact request without changing NPM.
| Name | Required | Description | Default |
|---|---|---|---|
| id | Yes | ID of the proxy host, from the matching list tool. | |
| dry_run | No | When True, return the exact request preview without changing NPM. |
Output Schema
| Name | Required | Description |
|---|---|---|
No output parameters | ||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations, the description carries the full burden and does well: it discloses the mutation ('changes NPM host state'), the operational consequence ('stops that host from serving traffic'), the reversibility profile ('retaining its configuration'), and a safe preview mode. It does not mention permission/auth requirements or idempotency, which is the only remaining gap.
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?
Five short, front-loaded sentences with no filler; the core action leads. The final dry_run sentence largely duplicates the schema's own description, which is the only wasted motion.
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 two-parameter mutation with full schema coverage and an output schema, nothing needed for correct invocation is missing. Return-value explanation is unnecessary given the output schema, and the description's one-line note about the updated host object is a harmless bonus.
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 100%, so both parameters (id, dry_run) are already fully documented in the schema; the description's restatement of dry_run adds no new syntax or format detail. Baseline 3 is correct when the schema does the heavy lifting.
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 resource ('Disable a proxy host by ID') plus the key semantic distinction from the obvious sibling: configuration is retained rather than removed. An agent can immediately tell it apart from delete_proxy_host and from enable_proxy_host.
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 routes to alternatives with conditions: delete_proxy_host for removal, list_proxy_hosts to check status, dry_run=True to preview. This is exactly the when/when-not/alternatives structure that removes inference.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
disable_redirection_hostDisable Redirection HostA
Disable a redirection host by ID while keeping its configuration in NPM. Use delete_redirection_host to remove it; use list_redirection_hosts to check status. This stops the redirect from being served and applies the configuration change. Returns the updated host object. Set dry_run=True to preview the exact request without changing NPM.
| Name | Required | Description | Default |
|---|---|---|---|
| id | Yes | ID of the redirection host, from the matching list tool. | |
| dry_run | No | When True, return the exact request preview without changing NPM. |
Output Schema
| Name | Required | Description |
|---|---|---|
No output parameters | ||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations, the description carries the behavioral burden and does well: it discloses that the configuration is preserved, that the redirect stops being served, that the change is applied to NPM, and that dry_run previews without mutating. It does not mention required permissions, reversibility via enable_redirection_host, or side effects on dependent hosts, leaving modest gaps.
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?
Front-loaded with the action and its key distinction, then the alternative tools, then the side effect and return value. Slightly redundant: 'stops the redirect from being served' and 'applies the configuration change' cover overlapping ground, and the return-value sentence is unnecessary given the output 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?
For a two-parameter mutation with full schema coverage and an output schema, the description supplies everything the agent needs: the effect, the config-retention semantics, sibling routing, and the dry_run safety valve.
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 100%, so both id and dry_run are already documented in the schema, and the description's dry_run explanation largely restates the schema text. The phrase 'by ID' confirms the identifier's role but adds no format or sourcing detail beyond what the schema provides, so the baseline of 3 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?
States a specific verb and resource ('Disable a redirection host by ID') and immediately clarifies the semantic distinction from deletion: configuration is retained in NPM while the redirect stops being served. This separates it cleanly from delete_redirection_host without needing siblings opened.
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?
Explicit routing is provided: use delete_redirection_host to remove the host, list_redirection_hosts to check status, and this tool to disable it. The dry_run option is also framed as a preview path, so an agent has clear when-to-use and when-not-to-use guidance.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
disable_streamDisable StreamA
Disable a TCP/UDP stream by ID while retaining its forwarding configuration. Use delete_stream to remove it; list_streams shows current status. NPM stops forwarding this stream while disabled. Returns the updated stream object. Set dry_run=True to preview the exact request without changing NPM.
| Name | Required | Description | Default |
|---|---|---|---|
| id | Yes | ID of the stream, from the matching list tool. | |
| dry_run | No | When True, return the exact request preview without changing NPM. |
Output Schema
| Name | Required | Description |
|---|---|---|
No output parameters | ||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations, the description carries the full burden and does a good job: it discloses that NPM stops forwarding while disabled, that configuration is retained, that the updated stream object is returned, and that dry_run gives a no-op preview. Auth/permission requirements and rate limits are not mentioned, keeping it out of the top tier.
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?
Front-loaded with the primary action and scope, then alternatives, then the dry_run escape hatch. Every sentence carries distinct information with no redundancy or 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 need no explanation, and the description still names the returned object. The main residual gap is the absence of any note on required permissions or the effect on in-flight connections, but for a simple toggle this 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 100%, so the schema already documents both id and dry_run. The description restates dry_run's preview behavior but adds no syntax or format detail beyond the schema, making the baseline 3 correct.
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+resource ('Disable a TCP/UDP stream by ID') plus the key scope detail that forwarding configuration is retained. It explicitly contrasts with delete_stream (removal) and list_streams (status), so an agent can place it precisely among its siblings.
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?
Names delete_stream as the alternative for permanent removal and list_streams for checking status, which gives clear routing guidance. It omits the symmetrical when-to-re-enable guidance and any prerequisites, so it falls just short of the full when/when-not treatment.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
enable_proxy_hostEnable Proxy HostA
Enable a disabled proxy host by ID so NPM serves its configured domain routing again. Use update_proxy_host to change host settings; use list_proxy_hosts to confirm status and ID. This changes NPM host state and applies its configuration. Returns the updated host object. Set dry_run=True to preview the exact request without changing NPM.
| Name | Required | Description | Default |
|---|---|---|---|
| id | Yes | ID of the proxy host, from the matching list tool. | |
| dry_run | No | When True, return the exact request preview without changing NPM. |
Output Schema
| Name | Required | Description |
|---|---|---|
No output parameters | ||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations, the description carries the full burden and does well: it discloses that this mutates NPM host state, that the configuration is applied, that the updated host object is returned, and that dry_run=True previews the request without changing NPM. It omits permission/auth requirements and idempotency behavior, leaving some behavioral gaps.
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 tight sentences, front-loaded with the primary action and effect before the alternative-tool routing. The 'Returns the updated host object' sentence is slightly redundant given the output schema exists, but overall there is little waste.
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 explained, and the description still covers mutation effect, dry_run preview, and tool routing. For a two-parameter mutation tool with no annotations, this is nearly sufficient, with only auth/permission context missing.
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 100%, so both parameters are already documented in the schema; the description restates the ID and dry_run preview without adding format or edge-case detail. Baseline 3 is appropriate when the schema does the heavy lifting.
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 (enable) and resource (proxy host), scoped by ID, with the effect spelled out: NPM resumes serving the configured domain routing. It clearly contrasts with update_proxy_host and list_proxy_hosts, so an agent can pick it apart from siblings without opening a 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?
Names two alternatives and their conditions ('use update_proxy_host to change host settings; use list_proxy_hosts to confirm status and ID'), giving clear routing context. It stops short of an explicit exclusion against the obvious complement, disable_proxy_host, so it's strong but not fully exhaustive.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
enable_redirection_hostEnable Redirection HostA
Enable a disabled redirection host by ID so NPM serves its redirect again. Use update_redirection_host to edit destination or redirect code; list_redirection_hosts shows status. This changes NPM host state and applies its configuration. Returns the updated host object. Set dry_run=True to preview the exact request without changing NPM.
| Name | Required | Description | Default |
|---|---|---|---|
| id | Yes | ID of the redirection host, from the matching list tool. | |
| dry_run | No | When True, return the exact request preview without changing NPM. |
Output Schema
| Name | Required | Description |
|---|---|---|
No output parameters | ||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations, the description carries the burden and does well: it discloses that this mutates NPM state and applies configuration, that it returns the updated host object, and that dry_run previews the exact request. It omits permission/authorization requirements and reversibility specifics (e.g., whether disable_redirection_host undoes it), keeping it 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?
Front-loads the core action, then alternatives, then behavioral notes and the dry_run escape hatch. Each sentence earns its place, though the return-value and dry_run statements slightly overlap with structured fields, preventing a full 5.
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-value detail is not strictly required, and the change semantics plus dry_run preview give an agent enough to call it correctly. Minor gap is the absence of permission/reversibility notes for a mutation tool with no annotations.
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 100%, so both id and dry_run are already fully documented in the schema, giving a baseline of 3. The description echoes the dry_run preview behavior and the id's likely source (matching list tool), adding marginal value but no syntax or format detail beyond the schema.
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+resource (enable a disabled redirection host by ID) and explicitly explains the effect: NPM serves its redirect again. It also names what it is not, routing editing to update_redirection_host and status checks to list_redirection_hosts, so an agent can distinguish it from siblings without opening schemas.
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 names alternatives and their conditions: update_redirection_host for destination/redirect-code edits and list_redirection_hosts for status, with the implicit condition that it applies to a currently disabled host. It also flags dry_run as the preview path, covering when-not-to-mutate.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
enable_streamEnable StreamA
Enable a disabled TCP/UDP stream by ID so NPM forwards its incoming port again. Use update_stream to change ports or protocol flags; list_streams shows current status. This changes the stream state in NPM. Returns the updated stream object. Set dry_run=True to preview the exact request without changing NPM.
| Name | Required | Description | Default |
|---|---|---|---|
| id | Yes | ID of the stream, from the matching list tool. | |
| dry_run | No | When True, return the exact request preview without changing NPM. |
Output Schema
| Name | Required | Description |
|---|---|---|
No output parameters | ||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations, the description carries the full burden and does disclose the mutation ('changes the stream state in NPM'), the return value, and a dry_run preview that avoids changing NPM. It omits permission/auth requirements and whether the operation is idempotent on an already-enabled stream.
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?
Front-loaded with the action and effect, followed by routing and the dry_run tip. Efficient overall, though 'This changes the stream state in NPM' partly restates the opening sentence.
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 details are covered, and the description still notes the updated stream object is returned. For a two-parameter mutation with no annotations, it supplies the safety and routing context an agent needs, lacking only auth/idempotency details.
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 100% and both parameters are documented in the schema, so the schema does the heavy lifting. The description adds the practical meaning of dry_run (preview the exact request) but nothing about the id format beyond what the schema says.
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 (Enable), resource (TCP/UDP stream), and the effect (NPM forwards its incoming port again). It also names the sibling tools it is not (update_stream, list_streams), so an agent can distinguish it without opening schemas.
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?
Routes the agent explicitly: use update_stream for ports/protocol flags and list_streams to check status. It implies the trigger condition (a disabled stream) but does not spell out when to prefer disable_stream over enable_stream beyond the name.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_access_listGet Access ListA
Fetch one access list by ID, including its client rules and basic-auth user metadata. Use this for detailed rules; use list_access_lists to discover IDs. NPM does not return stored item passwords, so password values cannot be read back. Returns the access-list object with name, clients, and user entries.
| Name | Required | Description | Default |
|---|---|---|---|
| id | Yes | ID of the access list, from the matching list tool. |
Output Schema
| Name | Required | Description |
|---|---|---|
No output parameters | ||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations, the description carries the burden and adds a key behavioral constraint: 'NPM does not return stored item passwords, so password values cannot be read back.' It also implies a read-only fetch and describes the return structure. It does not cover authentication or error behavior, but for a read-only getter this is a strong disclosure.
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 efficiently packs purpose, usage guidance, a limitation, and return details into four sentences. The final sentence listing return fields is somewhat redundant given the output schema, but otherwise every sentence earns its place.
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?
Given a simple one-parameter getter with an output schema, the description covers purpose, when to use it, a runtime limitation, and expected content. Nothing an agent needs to invoke it correctly is missing.
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 100%, so the schema already fully documents the sole 'id' parameter. The description reinforces that an ID is required but adds no syntax, format, or sourcing details beyond what the schema provides, making the baseline 3 appropriate.
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 a specific verb ('Fetch'), resource ('access list'), and scope ('by ID'), and explicitly differentiates from the sibling list_access_lists by directing discovery use there. It also specifies the contents returned (client rules, basic-auth user metadata), leaving no ambiguity about what the tool does.
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 states exactly when to use this tool ('for detailed rules') and names the alternative ('use list_access_lists to discover IDs'), providing the condition that selects between them. No inference is required to choose the right tool.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_proxy_hostGet Proxy HostA
Fetch one proxy host by ID, including its configured fields and current status. Use this for details about one host; use list_proxy_hosts to find IDs or inspect all hosts. This is read-only and does not reload Nginx. Returns the NPM host object, including domains, forwarding settings, and status.
| Name | Required | Description | Default |
|---|---|---|---|
| id | Yes | ID of the proxy host, from the matching list tool. |
Output Schema
| Name | Required | Description |
|---|---|---|
No output parameters | ||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations provided, the description carries the burden and does good work: it declares read-only behavior and the important side-effect guarantee that it 'does not reload Nginx' (a meaningful trait for a reverse-proxy config tool). It omits error behavior for an unknown ID and any auth/permission context, keeping it 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?
Three sentences, each earning its place: purpose, sibling routing, and behavioral/return disclosure. Front-loaded with the primary action and no redundant 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?
For a single-parameter read tool with full schema coverage and an output schema, the definition covers purpose, alternative routing, safety profile, and return contents. Nothing an agent needs in order to call it correctly is missing.
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 100% and the single id parameter is documented in the schema as coming 'from the matching list tool.' The description adds no syntax or format beyond that, so the baseline 3 for schema-driven parameter documentation 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?
States a specific verb and resource ('Fetch one proxy host by ID') plus the scope of returned data (configured fields and current status). It explicitly distinguishes itself from the sibling list_proxy_hosts, so an agent can route correctly without opening either 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?
Gives an explicit when-to-use ('details about one host') and names the alternative with its own condition ('use list_proxy_hosts to find IDs or inspect all hosts'). The selection logic between the two tools is fully spelled out.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_redirection_hostGet Redirection HostA
Fetch one redirection host by ID with its configured destination and status. Use this for a single redirect; use list_redirection_hosts to discover IDs or inspect all redirects. This is read-only and does not change NPM. Returns the host object with domains, destination, redirect code, and status.
| Name | Required | Description | Default |
|---|---|---|---|
| id | Yes | ID of the redirection host, from the matching list tool. |
Output Schema
| Name | Required | Description |
|---|---|---|
No output parameters | ||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations, the description carries the safety burden and does so by declaring 'This is read-only and does not change NPM.' It also enumerates the returned fields (domains, destination, redirect code, status), which adds context. It stops short of stating auth requirements or what happens when the ID is invalid/missing.
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 tight sentences with zero waste: purpose first, then routing guidance, then behavior and return shape. Everything is front-loaded.
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 the description needn't detail return values, and the one required parameter is fully documented. For a simple read-only single-fetch tool, nothing an agent needs to invoke it correctly is missing.
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 100% and the single id parameter is already documented with its source ('from the matching list tool'), so the schema does the heavy lifting. The description adds no extra format or constraint details beyond that, so baseline 3 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?
States a specific verb (Fetch) and resource (one redirection host) plus the key data it carries (destination and status). It explicitly distinguishes itself from list_redirection_hosts, so an agent can route between single-fetch and discovery without opening schemas.
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 direct when-to-use rule ('Use this for a single redirect') and names the alternative tool plus the reason to prefer it ('to discover IDs or inspect all redirects'). No ambiguity about which sibling to call.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_streamGet StreamA
Fetch one TCP/UDP stream by ID, including its forwarding ports and protocol settings. Use this for one stream; use list_streams to find IDs or inspect all streams. This is read-only and does not change NPM. Returns the stream object with incoming port, destination, protocol flags, and status.
| Name | Required | Description | Default |
|---|---|---|---|
| id | Yes | ID of the stream, from the matching list tool. |
Output Schema
| Name | Required | Description |
|---|---|---|
No output parameters | ||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
No annotations are provided, so the description carries the behavioral burden, and it does declare the safety profile ('read-only and does not change NPM'). It still omits error behavior for a nonexistent/invalid ID, which matters for a fetch-by-ID tool with no annotation 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?
Three tight sentences, purpose front-loaded before the sibling routing. The final return-field sentence partially duplicates the existing output schema, so it does not fully earn its place.
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 are covered structurally; combined with purpose, sibling routing, and the read-only declaration, an agent has everything needed to call this 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?
The single parameter is fully documented in the schema (100% coverage) including its origin ('from the matching list tool'), so the schema does the heavy lifting. The description adds only 'by ID', which is baseline-level value.
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?
Specific verb (Fetch) plus resource (one TCP/UDP stream by ID) with the returned content named (forwarding ports, protocol settings). It is immediately distinguishable from list_streams and from the update/delete stream siblings.
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 scopes itself to a single stream and names the alternative: 'use list_streams to find IDs or inspect all streams.' The condition selecting the sibling is stated, not implied.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
list_access_listsList Access ListsA
List access lists configured in NPM. Use this to find IDs before fetching, updating, or deleting a list; use get_access_list for one list with its rules. This is read-only and does not expose stored passwords. Returns access-list objects with IDs and names.
| Name | Required | Description | Default |
|---|---|---|---|
No parameters | |||
Output Schema
| Name | Required | Description |
|---|---|---|
| result | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
No annotations are provided, so the description carries the full burden and does disclose two meaningful traits: it is read-only and does not expose stored passwords. It stops short of covering pagination, result limits, or ordering for a potentially large collection.
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 tight sentences with no filler; the core action is front-loaded, followed by ID-lookup guidance and the read-only disclosure. Every sentence earns its place.
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-value documentation is unnecessary and the brief mention of returned access-list objects suffices. The read-only/password note compensates for the absent annotations, leaving only minor gaps around result volume or paging.
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 nothing to document and the baseline is 4. The description adds no parameter details, but none are needed.
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 resource ('List access lists configured in NPM') and immediately distinguishes itself from the sibling get_access_list, which returns one list with its rules. An agent can tell the two apart without opening either 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?
Explicitly states when to use it ('to find IDs before fetching, updating, or deleting a list') and names the alternative with its selecting condition ('use get_access_list for one list with its rules'). This routes the agent correctly with no inference required.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
list_certificatesList CertificatesA
List SSL certificates known to NPM, including expiry information when provided by NPM. Use this to inspect available certificates; create_letsencrypt_cert requests a new certificate and renew_certificate renews an existing one. This is read-only and makes no certificate request. Returns certificate objects with IDs, domains, provider, and expiry fields.
| Name | Required | Description | Default |
|---|---|---|---|
No parameters | |||
Output Schema
| Name | Required | Description |
|---|---|---|
| result | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations provided, the description carries the full burden, and it does disclose that the operation is read-only and makes no certificate request — an important disambiguation from its write siblings. It also previews the return shape, though it omits any pagination or volume limits.
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 core purpose followed by usage routing and then the behavioral/safety note. Every sentence earns its place.
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 explained, yet the description still summarizes the returned fields. For a zero-parameter read tool this is 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?
The tool takes zero parameters, so per the baseline this is a 4. There is nothing parameter-related the description needs to compensate for.
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 resource ('List SSL certificates known to NPM') plus scope detail on expiry information. It clearly distinguishes itself from the sibling write tools create_letsencrypt_cert and renew_certificate by 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 tells the agent to use this to inspect available certificates and names the two alternatives with their roles ('requests a new certificate', 'renews an existing one'). This fully routes the agent between the read and write paths.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
list_proxy_hostsList Proxy HostsA
List proxy hosts configured in NPM, including their current status. Use this to find host IDs before get, update, enable, disable, or delete operations. It does not change NPM or request a certificate. Returns a list of host objects with IDs, domains, forwarding settings, and status.
| Name | Required | Description | Default |
|---|---|---|---|
No parameters | |||
Output Schema
| Name | Required | Description |
|---|---|---|
| result | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations, this description carries the full burden and does so reasonably: it declares the operation is non-mutating ('does not change NPM or request a certificate'), effectively a read-only hint. It also sketches the return payload, though it omits pagination/rate-limit behavior for what could be a large list.
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 sentences, each earning its place: purpose, usage/routing, and non-goals/returns. Front-loaded with the core verb+resource so an agent grasps it immediately.
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 zero-parameter list tool with an output schema, the description covers purpose, routing, and safety. Return-value detail is partly redundant given the output schema, and pagination/volume behavior is unaddressed, but nothing critical is missing 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?
The tool takes zero parameters, so there is nothing for the description to disambiguate; the 4 baseline applies. No misleading parameter claims are made.
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 resource ('List proxy hosts configured in NPM') plus the scope of returned data ('including their current status'). This clearly separates it from get_proxy_host (single), create_proxy_host, and the other list_* siblings for certificates/access lists/streams.
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 gives the primary use case: 'find host IDs before get, update, enable, disable, or delete operations', which names the downstream siblings that depend on this output. It also excludes non-goals ('does not change NPM or request a certificate'), though it never names an alternative list tool or when NOT to use this one.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
list_redirection_hostsList Redirection HostsA
List configured redirection hosts and their current status. Use this to find IDs before fetching, changing, enabling, disabling, or deleting a redirect; proxy hosts handle upstream reverse proxying. This is read-only and does not request certificates. Returns host objects with domains, destination, redirect code, and status.
| Name | Required | Description | Default |
|---|---|---|---|
No parameters | |||
Output Schema
| Name | Required | Description |
|---|---|---|
| result | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations, the description carries the full behavioral burden and does so in part: it declares 'This is read-only and does not request certificates,' which tells the agent there are no side effects or certificate issuance. It also discloses the returned fields, though it omits pagination or result-size behavior for a potentially unbounded list.
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 sentences, front-loaded with the core action, then usage routing, then a return summary. Every sentence adds distinct information with no filler or repetition 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?
An output schema exists, so the description is not obliged to detail return values, yet it briefly previews them ('domains, destination, redirect code, and status') as a convenience. Combined with the read-only guarantee and ID-discovery guidance, nothing an agent needs to call this correctly is missing.
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, which per the rubric sets a baseline of 4. There is nothing for the description to clarify beyond confirming this is an unfiltered list, and it does not misrepresent any input.
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 a specific verb and resource ('List configured redirection hosts') plus the scope of what is returned ('their current status'). It also distinguishes itself from the sibling domain of proxy hosts by noting 'proxy hosts handle upstream reverse proxying,' so an agent can separate list_redirection_hosts from list_proxy_hosts without reading either 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?
It gives an explicit when-to-use workflow: 'Use this to find IDs before fetching, changing, enabling, disabling, or deleting a redirect,' which maps directly onto the sibling get/update/enable/disable/delete redirection tools. The proxy-host exclusion sentence further sharpens the boundary between alternatives.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
list_streamsList StreamsA
List configured TCP/UDP streams and their current status. Use this to find stream IDs before fetching, changing, enabling, disabling, or deleting a port forward. This is read-only and does not change NPM. Returns stream objects with IDs, incoming and forwarding ports, protocols, and status.
| Name | Required | Description | Default |
|---|---|---|---|
No parameters | |||
Output Schema
| Name | Required | Description |
|---|---|---|
| result | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations, the description carries the full burden and does well: "This is read-only and does not change NPM" declares the safety profile, and it names the return fields (IDs, ports, protocols, status). It omits auth requirements or pagination/result-size limits, which would matter for a list endpoint against a large config.
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 sentences, each earning its place: what it lists, when to use it, and what it returns / its safety profile. The most decision-relevant information (scope and the ID-lookup purpose) is front-loaded.
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 parameterless read-only list tool this is complete: purpose, usage trigger, safety profile, and return contents are all covered, and an output schema exists so return values need no further elaboration in the description.
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 parameter-related the description could add or omit; the 100% schema coverage is trivially satisfied by an empty object.
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 resource ("List configured TCP/UDP streams") plus the scope detail "and their current status," which separates it cleanly from the single-item sibling get_stream. An agent can tell what it retrieves 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?
Explicitly says to use it "to find stream IDs before fetching, changing, enabling, disabling, or deleting a port forward," which routes the agent from this lookup tool to the downstream mutation siblings. It doesn't name any sibling tool directly (e.g. get_stream for a single stream), so it stops short of the full 5.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
renew_certificateRenew CertificateA
Request renewal of an existing certificate by ID. Use this for a certificate already managed by NPM; use create_letsencrypt_cert to request a new certificate. This triggers NPM certificate renewal processing and may contact the certificate provider. Returns the certificate operation result, including available certificate fields. Set dry_run=True to preview the exact request without changing NPM.
| Name | Required | Description | Default |
|---|---|---|---|
| id | Yes | ID of the certificate to renew, from list_certificates. | |
| dry_run | No | When True, return the exact request preview without changing NPM. |
Output Schema
| Name | Required | Description |
|---|---|---|
No output parameters | ||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations, the description carries the burden and does well: it discloses that renewal triggers NPM certificate renewal processing, may contact the certificate provider, returns the operation result, and that dry_run previews without changing NPM. It omits auth/permission requirements and idempotency or rate-limit behavior, so it falls short of full transparency.
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 sentences, front-loaded with the core action and the sibling routing, and each sentence carries information. The dry_run behavior is stated once in the description and once in the schema, a mild redundancy that keeps it from a 5.
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 2-parameter mutation with an output schema, the description covers side effects, provider contact, dry_run preview, and return shape, so an agent has what it needs. Auth/permission expectations are the only notable omission.
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 100%, so both parameters are already documented in the schema (id sourced from list_certificates, dry_run preview behavior). The description restates both without adding syntax or format detail, so the baseline 3 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?
States a specific verb and resource ('Request renewal of an existing certificate by ID') and explicitly names the sibling tool create_letsencrypt_cert that handles the new-certificate case. An agent can distinguish it from siblings like create_letsencrypt_cert and list_certificates without opening any 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?
Gives explicit routing: use this for a certificate already managed by NPM, use create_letsencrypt_cert to request a new certificate. The condition that selects this tool over the alternative is unambiguous.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
update_access_listUpdate Access ListA
Update writable fields on an existing access list by ID, including client rules and basic-auth users. Use this to edit access controls; use delete_access_list to remove a list. NPM receives the merged writable fields; item passwords are write-only and cannot be read back. Returns the updated list object with its name and rules. Set dry_run=True to preview the exact request without changing NPM.
| Name | Required | Description | Default |
|---|---|---|---|
| id | Yes | ID of the access list, from the matching list tool. | |
| name | No | Human-readable name for this access list. For updates, omit to keep the current value. | |
| items | No | Basic-auth users as username/password pairs; passwords are write-only in NPM. For updates, omit to keep the current value. | |
| clients | No | IP or network rules; each directive must be allow or deny. For updates, omit to keep the current value. | |
| dry_run | No | When True, return the exact request preview without changing NPM. | |
| pass_auth | No | Whether NPM passes basic-auth credentials upstream. For updates, omit to keep the current value. | |
| satisfy_any | No | Whether satisfying any configured access rule is sufficient. For updates, omit to keep the current value. |
Output Schema
| Name | Required | Description |
|---|---|---|
No output parameters | ||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations, the description carries the full burden and does well: it discloses that NPM receives merged writable fields, that item passwords are write-only and unreadable, that dry_run previews the request, and that the updated object is returned. It omits auth/permission requirements needed to perform the update.
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 tightly scoped sentences, front-loaded with purpose then alternative then behavior. Minor redundancy between the items/clients mention in sentence one and the schema-level detail, but 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?
For a 7-param mutation tool with an output schema, the description covers the operation, merge semantics, write-only constraint, and dry_run. The only real gap is permission/auth prerequisites, which annotations would normally supply but here are absent.
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 100%, so all seven parameters are already documented — including write-only passwords, dry_run, and the 'omit to keep current value' semantics. The description largely restates items/clients and the dry_run behavior, adding little beyond the schema baseline.
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 ('Update'), resource ('an existing access list by ID'), and the writable surface ('client rules and basic-auth users'), so an agent can immediately distinguish it from list/get/create siblings.
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 routes the agent: 'Use this to edit access controls; use delete_access_list to remove a list,' and adds a dry_run preview path. It stops short of contrasting with create_access_list, but 'existing access list by ID' implies the boundary.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
update_proxy_hostUpdate Proxy HostA
Update writable settings on an existing proxy host by ID. Use this to change routing or options; use enable_proxy_host or disable_proxy_host for status only. NPM receives the merged writable host fields, without requesting a certificate. Returns the updated host object with its ID and current settings. Set dry_run=True to preview the exact request without changing NPM.
| Name | Required | Description | Default |
|---|---|---|---|
| id | Yes | ID of the proxy host, from the matching list tool. | |
| dry_run | No | When True, return the exact request preview without changing NPM. | |
| ssl_forced | No | Whether NPM redirects HTTP requests to HTTPS. For updates, omit to keep the current value. | |
| domain_names | No | Domain names routed by this host or certificate. For updates, omit to keep the current value. | |
| forward_host | No | Upstream hostname or IP address. For updates, omit to keep the current value. | |
| forward_port | No | Upstream TCP port number. For updates, omit to keep the current value. | |
| access_list_id | No | NPM access-list ID to attach. Omit to keep the current value. | |
| block_exploits | No | Whether NPM enables its exploit-blocking option. For updates, omit to keep the current value. | |
| certificate_id | No | NPM certificate ID to attach. Omit to keep the current value. | |
| forward_scheme | No | Upstream scheme: http or https. For updates, omit to keep the current value. | |
| caching_enabled | No | Whether NPM enables proxy caching. For updates, omit to keep the current value. | |
| allow_websocket_upgrade | No | Whether NPM allows WebSocket upgrades. For updates, omit to keep the current value. |
Output Schema
| Name | Required | Description |
|---|---|---|
No output parameters | ||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations, the description carries the disclosure burden well: it explains that NPM receives merged writable fields (partial-update semantics), that no certificate is requested, and that the updated host object is returned. It does not cover permission/auth requirements or whether the change is reversible, which is the only remaining gap.
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 tight sentences, front-loaded with the verb+resource, then the alternative routing, then behavioral facts. No filler and nothing 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?
All 12 parameters are documented in the schema, an output schema exists so return values need not be explained, and the description adds the key merged-update and no-cert behaviors. Only auth/permission prerequisites are absent, which is minor for this tool size.
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 100% and each parameter already documents 'omit to keep the current value', so the baseline is 3. The description reinforces the merge semantics with 'merged writable host fields' and highlights dry_run, but adds no syntax or format detail beyond the schema.
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, resource, and scoping ('Update writable settings on an existing proxy host by ID'), and explicitly distinguishes itself from the enable/disable siblings. An agent can route to the correct tool without opening any 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?
Gives explicit when-to-use ('change routing or options') versus when-not ('status only' -> enable_proxy_host/disable_proxy_host), and names the alternatives directly. The dry_run preview hint adds a further condition for safe invocation.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
update_redirection_hostUpdate Redirection HostA
Update writable settings on an existing redirection host by ID. Use this to change domains, destination, or redirect behavior; use enable_redirection_host or disable_redirection_host for status only. NPM receives the merged writable fields. Returns the updated host object with its redirect settings. Set dry_run=True to preview the exact request without changing NPM.
| Name | Required | Description | Default |
|---|---|---|---|
| id | Yes | ID of the redirection host, from the matching list tool. | |
| dry_run | No | When True, return the exact request preview without changing NPM. | |
| ssl_forced | No | Whether NPM redirects HTTP requests to HTTPS. For updates, omit to keep the current value. | |
| domain_names | No | Domain names routed by this host or certificate. For updates, omit to keep the current value. | |
| preserve_path | No | Whether to preserve the original request path in the redirect. For updates, omit to keep the current value. | |
| block_exploits | No | Whether NPM enables its exploit-blocking option. For updates, omit to keep the current value. | |
| certificate_id | No | NPM certificate ID to attach. Omit to keep the current value. | |
| forward_scheme | No | Scheme of the redirect destination: http or https. For updates, omit to keep the current value. | |
| forward_http_code | No | HTTP redirect status: 301, 302, 307, or 308. For updates, omit to keep the current value. | |
| forward_domain_name | No | Destination hostname or URL for redirected requests. For updates, omit to keep the current value. |
Output Schema
| Name | Required | Description |
|---|---|---|
No output parameters | ||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations, the description carries the full burden and does well: it discloses merge semantics ('NPM receives the merged writable fields'), the dry_run preview capability, and the shape of the result. It does not mention permissions or reversibility, which would be the remaining gap for a mutation tool.
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 tight sentences with no filler; the core operation, the sibling routing, and the dry_run escape hatch are each front-loaded in priority 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 a 10-parameter, single-required-id update tool with an output schema present, the description covers operation, alternatives, merge behavior, and the dry_run preview. Nothing an agent needs to invoke it correctly is missing, and return values are handled by the output schema.
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 100% and each field already documents its 'omit to keep the current value' behavior, so the description's merge note largely restates the schema. It adds only the high-level framing of which settings are relevant (domains, destination, redirect behavior) rather than new parameter detail.
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 resource with scope ('Update writable settings on an existing redirection host by ID') and immediately contrasts with the status-only siblings enable_redirection_host and disable_redirection_host. An agent can distinguish this from the enable/disable/delete redirection tool variants without opening a 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?
Explicitly says what to use it for ('change domains, destination, or redirect behavior') and names the alternatives for the adjacent case ('use enable_redirection_host or disable_redirection_host for status only'). This is a clear when-to-use and when-not-to-use routing statement.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
update_streamUpdate StreamA
Update writable port, destination, or protocol fields on an existing stream by ID. Use this to edit forwarding; use enable_stream or disable_stream to change status only. NPM receives the merged writable fields, preserving omitted values. Returns the updated stream object with its forwarding settings. Set dry_run=True to preview the exact request without changing NPM.
| Name | Required | Description | Default |
|---|---|---|---|
| id | Yes | ID of the stream, from the matching list tool. | |
| dry_run | No | When True, return the exact request preview without changing NPM. | |
| incoming_port | No | Public TCP/UDP port number accepted by this stream. For updates, omit to keep the current value. | |
| tcp_forwarding | No | Whether this stream forwards TCP traffic. For updates, omit to keep the current value. | |
| udp_forwarding | No | Whether this stream forwards UDP traffic. For updates, omit to keep the current value. | |
| forwarding_host | No | Hostname or IP address receiving stream traffic. For updates, omit to keep the current value. | |
| forwarding_port | No | Destination TCP/UDP port number. For updates, omit to keep the current value. |
Output Schema
| Name | Required | Description |
|---|---|---|
No output parameters | ||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations, the description carries the full burden and does meaningful work: it discloses patch/merge semantics (omitted writable fields are preserved, NPM receives the merged set), the dry_run preview behavior, and the return shape. It stops short of stating permission requirements, reversibility, or error behavior on invalid IDs.
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 tight sentences, zero filler: scope and field list first, then routing to siblings, then merge behavior, then the dry_run affordance. Every sentence earns its place and the most decision-relevant information is front-loaded.
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 7-parameter mutation tool with no annotations but a full schema and an output schema, the description covers scope, merge semantics, preview mode, and sibling routing, so an agent can call it correctly. The only real gap is operational context such as permissions or failure modes.
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 100%, so every parameter including dry_run is already documented in the schema, and the description's merge note largely restates the schema's 'omit to keep the current value'. It adds only the implicit constraint that some fields are non-writable. Baseline 3 is appropriate when the schema does the heavy lifting.
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 (update), resource (existing stream by ID) and the exact field families in scope (writable port, destination, protocol). It explicitly names enable_stream/disable_stream as the status-only siblings, so an agent can separate this from those without opening a 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?
Gives both the when ('edit forwarding') and the when-not with the alternative named ('use enable_stream or disable_stream to change status only'). It also adds a safe-preview route (dry_run=True) for agents that need to verify intent before mutating.
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.
25 tool updates
v0.5.2- Changed
create_access_list6 fields changed- added
Input schema / properties / clients / descriptionAdded value: +"IP or network rules; each directive must be allow or deny." - added
Input schema / properties / dry_run / descriptionAdded value: +"When True, return the exact request preview without changing NPM." - added
Input schema / properties / items / descriptionAdded value: +"Basic-auth users as username/password pairs; passwords are write-only in NPM." - added
Input schema / properties / name / descriptionAdded value: +"Human-readable name for this access list." - added
Input schema / properties / pass_auth / descriptionAdded value: +"Whether NPM passes basic-auth credentials upstream." - added
Input schema / properties / satisfy_any / descriptionAdded value: +"Whether satisfying any configured access rule is sufficient."
- Changed
create_letsencrypt_cert4 fields changed- added
Input schema / properties / dns_challenge / descriptionAdded value: +"Use DNS validation instead of HTTP validation for the certificate request." - added
Input schema / properties / domain_names / descriptionAdded value: +"Domain names routed by this host or certificate." - added
Input schema / properties / dry_run / descriptionAdded value: +"When True, return the exact request preview without changing NPM." - added
Input schema / properties / email / descriptionAdded value: +"Email address supplied to Let's Encrypt for certificate requests."
- Changed
create_proxy_host11 fields changed- added
Input schema / properties / access_list_id / descriptionAdded value: +"NPM access-list ID to attach; omit for no access list." - added
Input schema / properties / allow_websocket_upgrade / descriptionAdded value: +"Whether NPM allows WebSocket upgrades." - added
Input schema / properties / block_exploits / descriptionAdded value: +"Whether NPM enables its exploit-blocking option." - added
Input schema / properties / caching_enabled / descriptionAdded value: +"Whether NPM enables proxy caching." - added
Input schema / properties / certificate_id / descriptionAdded value: +"NPM certificate ID to attach; omit for no certificate." - added
Input schema / properties / domain_names / descriptionAdded value: +"Domain names routed by this host or certificate." - added
Input schema / properties / dry_run / descriptionAdded value: +"When True, return the exact request preview without changing NPM." - added
Input schema / properties / forward_host / descriptionAdded value: +"Upstream hostname or IP address." - added
Input schema / properties / forward_port / descriptionAdded value: +"Upstream TCP port number." - added
Input schema / properties / forward_scheme / descriptionAdded value: +"Upstream scheme: http or https." - added
Input schema / properties / ssl_forced / descriptionAdded value: +"Whether NPM redirects HTTP requests to HTTPS."
- Changed
create_proxy_host_with_letsencrypt10 fields changed- added
Input schema / properties / access_list_id / descriptionAdded value: +"NPM access-list ID to attach; omit for no access list." - added
Input schema / properties / allow_websocket_upgrade / descriptionAdded value: +"Whether NPM allows WebSocket upgrades." - added
Input schema / properties / block_exploits / descriptionAdded value: +"Whether NPM enables its exploit-blocking option." - added
Input schema / properties / caching_enabled / descriptionAdded value: +"Whether NPM enables proxy caching." - added
Input schema / properties / domain_names / descriptionAdded value: +"Domain names routed by this host or certificate." - added
Input schema / properties / dry_run / descriptionAdded value: +"When True, return the exact request preview without changing NPM." - added
Input schema / properties / email / descriptionAdded value: +"Email address supplied to Let's Encrypt for certificate requests." - added
Input schema / properties / forward_host / descriptionAdded value: +"Upstream hostname or IP address." - added
Input schema / properties / forward_port / descriptionAdded value: +"Upstream TCP port number." - added
Input schema / properties / forward_scheme / descriptionAdded value: +"Upstream scheme: http or https."
- Changed
create_redirection_host9 fields changed- added
Input schema / properties / block_exploits / descriptionAdded value: +"Whether NPM enables its exploit-blocking option." - added
Input schema / properties / certificate_id / descriptionAdded value: +"NPM certificate ID to attach; omit for no certificate." - added
Input schema / properties / domain_names / descriptionAdded value: +"Domain names routed by this host or certificate." - added
Input schema / properties / dry_run / descriptionAdded value: +"When True, return the exact request preview without changing NPM." - added
Input schema / properties / forward_domain_name / descriptionAdded value: +"Destination hostname or URL for redirected requests." - added
Input schema / properties / forward_http_code / descriptionAdded value: +"HTTP redirect status: 301, 302, 307, or 308." - added
Input schema / properties / forward_scheme / descriptionAdded value: +"Scheme of the redirect destination: http or https." - added
Input schema / properties / preserve_path / descriptionAdded value: +"Whether to preserve the original request path in the redirect." - added
Input schema / properties / ssl_forced / descriptionAdded value: +"Whether NPM redirects HTTP requests to HTTPS."
- Changed
create_stream6 fields changed- added
Input schema / properties / dry_run / descriptionAdded value: +"When True, return the exact request preview without changing NPM." - added
Input schema / properties / forwarding_host / descriptionAdded value: +"Hostname or IP address receiving stream traffic." - added
Input schema / properties / forwarding_port / descriptionAdded value: +"Destination TCP/UDP port number." - added
Input schema / properties / incoming_port / descriptionAdded value: +"Public TCP/UDP port number accepted by this stream." - added
Input schema / properties / tcp_forwarding / descriptionAdded value: +"Whether this stream forwards TCP traffic." - added
Input schema / properties / udp_forwarding / descriptionAdded value: +"Whether this stream forwards UDP traffic."
- Changed
delete_access_list2 fields changed- added
Input schema / properties / dry_run / descriptionAdded value: +"When True, return the exact request preview without changing NPM." - added
Input schema / properties / id / descriptionAdded value: +"ID of the access list, from the matching list tool."
- Changed
delete_proxy_host2 fields changed- added
Input schema / properties / dry_run / descriptionAdded value: +"When True, return the exact request preview without changing NPM." - added
Input schema / properties / id / descriptionAdded value: +"ID of the proxy host, from the matching list tool."
- Changed
delete_redirection_host2 fields changed- added
Input schema / properties / dry_run / descriptionAdded value: +"When True, return the exact request preview without changing NPM." - added
Input schema / properties / id / descriptionAdded value: +"ID of the redirection host, from the matching list tool."
- Changed
delete_stream2 fields changed- added
Input schema / properties / dry_run / descriptionAdded value: +"When True, return the exact request preview without changing NPM." - added
Input schema / properties / id / descriptionAdded value: +"ID of the stream, from the matching list tool."
- Changed
disable_proxy_host2 fields changed- added
Input schema / properties / dry_run / descriptionAdded value: +"When True, return the exact request preview without changing NPM." - added
Input schema / properties / id / descriptionAdded value: +"ID of the proxy host, from the matching list tool."
- Changed
disable_redirection_host2 fields changed- added
Input schema / properties / dry_run / descriptionAdded value: +"When True, return the exact request preview without changing NPM." - added
Input schema / properties / id / descriptionAdded value: +"ID of the redirection host, from the matching list tool."
- Changed
disable_stream2 fields changed- added
Input schema / properties / dry_run / descriptionAdded value: +"When True, return the exact request preview without changing NPM." - added
Input schema / properties / id / descriptionAdded value: +"ID of the stream, from the matching list tool."
- Changed
enable_proxy_host2 fields changed- added
Input schema / properties / dry_run / descriptionAdded value: +"When True, return the exact request preview without changing NPM." - added
Input schema / properties / id / descriptionAdded value: +"ID of the proxy host, from the matching list tool."
- Changed
enable_redirection_host2 fields changed- added
Input schema / properties / dry_run / descriptionAdded value: +"When True, return the exact request preview without changing NPM." - added
Input schema / properties / id / descriptionAdded value: +"ID of the redirection host, from the matching list tool."
- Changed
enable_stream2 fields changed- added
Input schema / properties / dry_run / descriptionAdded value: +"When True, return the exact request preview without changing NPM." - added
Input schema / properties / id / descriptionAdded value: +"ID of the stream, from the matching list tool."
- Changed
get_access_list1 field changed- added
Input schema / properties / id / descriptionAdded value: +"ID of the access list, from the matching list tool."
- Changed
get_proxy_host1 field changed- added
Input schema / properties / id / descriptionAdded value: +"ID of the proxy host, from the matching list tool."
- Changed
get_redirection_host1 field changed- added
Input schema / properties / id / descriptionAdded value: +"ID of the redirection host, from the matching list tool."
- Changed
get_stream1 field changed- added
Input schema / properties / id / descriptionAdded value: +"ID of the stream, from the matching list tool."
- Changed
renew_certificate2 fields changed- added
Input schema / properties / dry_run / descriptionAdded value: +"When True, return the exact request preview without changing NPM." - added
Input schema / properties / id / descriptionAdded value: +"ID of the certificate to renew, from list_certificates."
- Changed
update_access_list7 fields changed- added
Input schema / properties / clients / descriptionAdded value: +"IP or network rules; each directive must be allow or deny. For updates, omit to keep the current value." - added
Input schema / properties / dry_run / descriptionAdded value: +"When True, return the exact request preview without changing NPM." - added
Input schema / properties / id / descriptionAdded value: +"ID of the access list, from the matching list tool." - added
Input schema / properties / items / descriptionAdded value: +"Basic-auth users as username/password pairs; passwords are write-only in NPM. For updates, omit to keep the current value." - added
Input schema / properties / name / descriptionAdded value: +"Human-readable name for this access list. For updates, omit to keep the current value." - added
Input schema / properties / pass_auth / descriptionAdded value: +"Whether NPM passes basic-auth credentials upstream. For updates, omit to keep the current value." - added
Input schema / properties / satisfy_any / descriptionAdded value: +"Whether satisfying any configured access rule is sufficient. For updates, omit to keep the current value."
- Changed
update_proxy_host12 fields changed- added
Input schema / properties / access_list_id / descriptionAdded value: +"NPM access-list ID to attach. Omit to keep the current value." - added
Input schema / properties / allow_websocket_upgrade / descriptionAdded value: +"Whether NPM allows WebSocket upgrades. For updates, omit to keep the current value." - added
Input schema / properties / block_exploits / descriptionAdded value: +"Whether NPM enables its exploit-blocking option. For updates, omit to keep the current value." - added
Input schema / properties / caching_enabled / descriptionAdded value: +"Whether NPM enables proxy caching. For updates, omit to keep the current value." - added
Input schema / properties / certificate_id / descriptionAdded value: +"NPM certificate ID to attach. Omit to keep the current value." - added
Input schema / properties / domain_names / descriptionAdded value: +"Domain names routed by this host or certificate. For updates, omit to keep the current value." - added
Input schema / properties / dry_run / descriptionAdded value: +"When True, return the exact request preview without changing NPM." - added
Input schema / properties / forward_host / descriptionAdded value: +"Upstream hostname or IP address. For updates, omit to keep the current value." - added
Input schema / properties / forward_port / descriptionAdded value: +"Upstream TCP port number. For updates, omit to keep the current value." - added
Input schema / properties / forward_scheme / descriptionAdded value: +"Upstream scheme: http or https. For updates, omit to keep the current value." - added
Input schema / properties / id / descriptionAdded value: +"ID of the proxy host, from the matching list tool." - added
Input schema / properties / ssl_forced / descriptionAdded value: +"Whether NPM redirects HTTP requests to HTTPS. For updates, omit to keep the current value."
- Changed
update_redirection_host10 fields changed- added
Input schema / properties / block_exploits / descriptionAdded value: +"Whether NPM enables its exploit-blocking option. For updates, omit to keep the current value." - added
Input schema / properties / certificate_id / descriptionAdded value: +"NPM certificate ID to attach. Omit to keep the current value." - added
Input schema / properties / domain_names / descriptionAdded value: +"Domain names routed by this host or certificate. For updates, omit to keep the current value." - added
Input schema / properties / dry_run / descriptionAdded value: +"When True, return the exact request preview without changing NPM." - added
Input schema / properties / forward_domain_name / descriptionAdded value: +"Destination hostname or URL for redirected requests. For updates, omit to keep the current value." - added
Input schema / properties / forward_http_code / descriptionAdded value: +"HTTP redirect status: 301, 302, 307, or 308. For updates, omit to keep the current value." - added
Input schema / properties / forward_scheme / descriptionAdded value: +"Scheme of the redirect destination: http or https. For updates, omit to keep the current value." - added
Input schema / properties / id / descriptionAdded value: +"ID of the redirection host, from the matching list tool." - added
Input schema / properties / preserve_path / descriptionAdded value: +"Whether to preserve the original request path in the redirect. For updates, omit to keep the current value." - added
Input schema / properties / ssl_forced / descriptionAdded value: +"Whether NPM redirects HTTP requests to HTTPS. For updates, omit to keep the current value."
- Changed
update_stream7 fields changed- added
Input schema / properties / dry_run / descriptionAdded value: +"When True, return the exact request preview without changing NPM." - added
Input schema / properties / forwarding_host / descriptionAdded value: +"Hostname or IP address receiving stream traffic. For updates, omit to keep the current value." - added
Input schema / properties / forwarding_port / descriptionAdded value: +"Destination TCP/UDP port number. For updates, omit to keep the current value." - added
Input schema / properties / id / descriptionAdded value: +"ID of the stream, from the matching list tool." - added
Input schema / properties / incoming_port / descriptionAdded value: +"Public TCP/UDP port number accepted by this stream. For updates, omit to keep the current value." - added
Input schema / properties / tcp_forwarding / descriptionAdded value: +"Whether this stream forwards TCP traffic. For updates, omit to keep the current value." - added
Input schema / properties / udp_forwarding / descriptionAdded value: +"Whether this stream forwards UDP traffic. For updates, omit to keep the current value."
30 tool updates
v0.5.1- First observed
create_access_list - First observed
create_letsencrypt_cert - First observed
create_proxy_host - First observed
create_proxy_host_with_letsencrypt - First observed
create_redirection_host - First observed
create_stream - First observed
delete_access_list - First observed
delete_proxy_host - First observed
delete_redirection_host - First observed
delete_stream - First observed
disable_proxy_host - First observed
disable_redirection_host - First observed
disable_stream - First observed
enable_proxy_host - First observed
enable_redirection_host - First observed
enable_stream - First observed
get_access_list - First observed
get_proxy_host - First observed
get_redirection_host - First observed
get_stream - First observed
list_access_lists - First observed
list_certificates - First observed
list_proxy_hosts - First observed
list_redirection_hosts - First observed
list_streams - First observed
renew_certificate - First observed
update_access_list - First observed
update_proxy_host - First observed
update_redirection_host - First observed
update_stream
TDQS
Scored across 30 tools
Each tool targets a distinct resource (proxy host, certificate, access list, redirection host, stream) and action (list, get, create, update, delete, enable, disable, renew). Overlaps are explicitly handled by descriptions, e.g. create_proxy_host vs create_proxy_host_with_letsencrypt and update vs enable/disable. An agent can reliably select the correct tool.
All tools use a predictable snake_case verb_noun pattern with resource names consistently pluralized for list operations and singular for get/update/delete. Deviations are only necessary qualifiers like with_letsencrypt, which remain readable and consistent. No mixed conventions.
At 30 tools, the surface is heavy for the NPM domain. While many operations are distinct, the count exceeds the rubric's 25+ threshold for 'too many' and includes several similar enable/disable variants that could potentially be collapsed.
The server covers full CRUD and lifecycle for proxy hosts, redirection hosts, streams, and access lists, plus certificate listing, creation, and renewal. Minor gaps include no certificate deletion or single-certificate retrieval, but core workflows are well covered.
Maintenance
Related MCP Connectors
MCP server for Superserve sandboxes: create, exec, and manage Firecracker microVMs
MCP server for mandates, delegation, policy-gated execution, credential grants, and audit.
MCP server for AI agents to plan, verify, and deploy Cloudflare-native apps.
Related MCP Servers
- AlicenseBqualityCmaintenanceEnables management of Nginx Proxy Manager instances for configuring proxy hosts, requesting Let's Encrypt SSL certificates, and managing access lists. It allows users to control their web proxy infrastructure through natural language commands in MCP-compatible environments.503MIT
- AlicenseNot gradedqualityBmaintenanceSelf-hosted MCP proxy and aggregation platform. Register multiple upstream MCP servers and expose them through a single unified endpoint with namespace routing, multi-transport support (HTTP/SSE, stdio, OpenAPI→MCP), per-tool overrides, and a web admin UI.18MIT
- AlicenseCqualityCmaintenanceMCP server that abstracts the Nginx Proxy Manager API, enabling management of proxy hosts, redirections, streams, certificates, access lists, and users through natural language.5414 npm1AGPL 3.0
- AlicenseNot gradedqualityCmaintenanceMCP server for managing SWAG reverse-proxy configurations, including config generation, backups, logs, and health checks. Enables managing nginx subdomain configs for SWAG through a unified action router.6MIT