ttl.exclusiveMinimum emitted as boolean breaks two dnsProvider tools on Claude clients; tool descriptions are bare route strings
Nobody has claimed this yet.
- Dominant language
- TypeScript
- Stars
- 379
- Forks
- 77
- PR merge metrics
- No merged PRs in 30d
Description
Two problems found while measuring the MCP surface of @dokploy/mcp@0.30.2 against a live Dokploy instance. The first is a hard bug; the second is a usability issue that shows up specifically with LLM clients.
1. dnsProvider-createRecord and dnsProvider-updateRecord are rejected by the Anthropic API
Both tools are dropped at connection time by Claude clients, with:
schema/properties/ttl/exclusiveMinimum must be number
exclusiveMinimum is being emitted as a boolean (JSON Schema draft-04 style, where it modified minimum) instead of a number (draft 2020-12, which the MCP spec and the Anthropic API follow).
Effect: those two tools silently do not exist for any Claude-based client. The rest of the server's 597 tools load fine, so the failure is easy to miss — nothing errors, DNS record creation is just absent from the tool list.
Likely origin: a .positive() / exclusiveMinimum: true on the ttl field surviving a zod-to-json-schema conversion pinned to an older draft. Worth grepping for other numeric constraints emitted the same way — exclusiveMaximum has the identical draft-04/2020-12 split.
2. All 597 tool descriptions are the bare route line
Every description is the HTTP verb plus the tRPC path:
application-create -> "POST /application.create"
application-one -> "GET /application.one"
admin-setupMonitoring -> "POST /admin.setupMonitoring"
Mean description length across all 597 tools: 25 characters. Total: 15 133 chars of description against 222 983 chars of schema.
The problem this creates is concrete. Ask an agent to redeploy a stack and it must choose between compose-deploy, compose-redeploy, compose-start and compose-reload — four tools whose descriptions are four route strings. The name is the only signal, and the names do not disambiguate. Same for application-reload vs application-redeploy vs application-markRunning, and for settings-cleanAll / -cleanDockerPrune / -cleanUnusedImages / -cleanUnusedVolumes / -cleanStoppedContainers.
The agent then either guesses, or spends a turn on docs, or calls the wrong one — and several of these are destructive on a production host.
One sentence per tool would fix it, at roughly 60 chars each:
compose-redeploy -> "Redeploy an existing compose stack, reusing the current build."
compose-reload -> "Restart the running services without redeploying."
That is ~36 KB of descriptions added against 218 KB of schema already being shipped — a small relative cost for the thing that makes the schema usable. Prioritising the destructive and near-synonymous tools first would capture most of the benefit.
Both would also help clients that surface tools through a search step rather than loading all 597 eagerly: search ranks on name and description, and right now there is effectively only the name to rank on.
Environment
@dokploy/mcp@0.30.2vianpx -y, stdio transport- Dokploy server: self-hosted
- Client: Claude Code
Captured with:
{ printf '%s\n' \
'{"jsonrpc":"2.0","id":1,"method":"initialize","params":{"protocolVersion":"2024-11-05","capabilities":{},"clientInfo":{"name":"probe","version":"1"}}}' \
'{"jsonrpc":"2.0","method":"notifications/initialized"}' \
'{"jsonrpc":"2.0","id":2,"method":"tools/list"}'; sleep 25; } \
| DOKPLOY_URL=https://your-instance DOKPLOY_API_KEY=... npx -y @dokploy/mcp > raw.txt
Unrelated but worth saying: DOKPLOY_ENABLED_TAGS is exactly the right escape hatch for the size of this surface, and it works well — 597 tools down to 162 for a deploy-focused tag set. Thanks for shipping it.
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Start by reproducing the tools/list output from @dokploy/mcp@0.30.2 and inspect the ttl schema for dnsProvider-createRecord and dnsProvider-updateRecord. Trace the mentioned zod-to-json-schema conversion, then review how the 597 tool descriptions are generated; done means Claude accepts the numeric constraint and tools have useful, action-specific descriptions.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- typescript
- Domain
- api, backend-api-design
- Issue type
- Bug
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Active
- Clarity
- Mostly clear
- Newbie friendliness
- 48/100