Dokploy / Dokploy/mcp

ttl.exclusiveMinimum emitted as boolean breaks two dnsProvider tools on Claude clients; tool descriptions are bare route strings

Open
#80 0 comments 0 reactions 0 assignees View on GitHub

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.2 via npx -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

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. 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

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.