Skip to main content
Glama

coolify-mcp

A TypeScript MCP server that drives a self-hosted Coolify instance. Full REST CRUD, deploy/watch, and a flag-gated host-ops tier (SSH + Docker + psql) for live log streaming and ad-hoc access.

Quick Start

# Install from npm
npm install -g @jimrarras/coolify-mcp
# …or run ad-hoc without installing:  npx -y @jimrarras/coolify-mcp doctor
#
# (Or install the latest straight from GitHub: npm install -g github:jimrarras/coolify-mcp)
#
# The published build is a single self-contained bundle with ZERO native/runtime
# dependencies — it installs on any machine with no C/C++ toolchain and runs no
# install scripts. No flags needed.

# Configure — guided wizard writes ~/.coolify-mcp/config.json (recommended)
coolify-mcp init

# …or just set the two required env vars (token format: <id>|<secret>):
export COOLIFY_BASE_URL="https://coolify.example.com"
export COOLIFY_TOKEN="<id>|<secret>"

# Run (API tier only)
coolify-mcp

# Run with host-ops (SSH access) enabled
coolify-mcp --enable-host-ops

# Run with destructive actions allowed (requires confirm:true per-call)
coolify-mcp --enable-host-ops --allow-destructive

Two commands take you from installed to working:

coolify-mcp init      # one-time interactive wizard — writes ~/.coolify-mcp/config.json
coolify-mcp doctor    # verify the setup any time, with a specific fix for each failure

Prefer not to touch a config file? The zero-file env-var mode (just COOLIFY_BASE_URL + COOLIFY_TOKEN) still works for the API tier — init is for a guided setup that also wires up host-ops.

What init asks

  1. Base URL + API token — validated live against your instance before continuing. The token must be <id>|<secret> with scope write + read:sensitive.

  2. Enable host-ops? If yes, it resolves the SSH control host. On a standard single-server install Coolify reports the host's IP as host.docker.internal, so auto-detect can't match it — init then lists your servers and asks you to pick the control host (anti-hijack: it won't silently guess). It substitutes your baseUrl host as the reachable SSH address.

  3. It then auto-discovers a working SSH key — it scans ~/.ssh, tries each OpenSSH key against the host, and prompts (masked) for a passphrase if the key needs one. (A PuTTY .ppk is detected and you're told to export an OpenSSH key first.)

  4. It shows the host's key fingerprint and asks you to confirm before pinning it.

  5. Enable query_coolify_db? If yes, it prints ready-to-run CREATE ROLE … GRANT … REVOKE … SQL (with a generated password) for you to run on your Coolify Postgres.

It writes ~/.coolify-mcp/config.json (backing up any existing one) at mode 0600. By default the secrets you just entered are stored directly in that file, so setup works immediately — no environment variables to set. For example:

{
  "defaultInstance": "default",
  "instances": {
    "default": {
      "baseUrl": "https://coolify.example.com",
      "token": "5|the-actual-token",
      "enableHostOps": true,
      "allowDestructive": false,
      "ssh": {
        "keyPath": "/home/you/.ssh/id_ed25519",
        "hostServer": "<control-server-uuid>",
        "fingerprint": "SHA256:…",
        "passphrase": "the-actual-passphrase"
      }
    }
  }
}

Then just run coolify-mcp doctor to verify — and your MCP client only needs { "command": "coolify-mcp" } (no env block).

Prefer to keep secrets out of the file? Run coolify-mcp init --env-secrets. It writes ${ENV} references instead (token: "${COOLIFY_TOKEN}", passphrase: "${COOLIFY_SSH_KEY_PASSPHRASE}", …) and prints the variables to set in your shell or your MCP client's env block; the references are expanded at startup. (If a referenced variable isn't set, startup fails with a message naming it.)

doctor

doctor runs read-only checks and prints a fix for anything that fails (add --enable-host-ops to include the SSH/DB checks):

$ coolify-mcp doctor --enable-host-ops
── instance: default ──
PASS  api — Coolify 4.1.2 reachable
PASS  control_host — root@coolify.example.com:22 (using baseUrl host)
PASS  ssh — SSH root@coolify.example.com:22 OK
SKIP  db_role — query_coolify_db not configured

It exits non-zero if any check fails, so it's usable as a preflight in scripts.

Add to your MCP client config (e.g. ~/.claude/claude_desktop_config.json):

{
  "mcpServers": {
    "coolify": {
      "command": "coolify-mcp",
      "args": [],
      "env": {
        "COOLIFY_BASE_URL": "https://coolify.example.com",
        "COOLIFY_TOKEN": "<id>|<secret>"
      }
    }
  }
}

Related MCP server: coolify-mcp

Configuration

1. Zero-file quick start

Set two environment variables and run — no config file needed:

export COOLIFY_BASE_URL="https://coolify.example.com"
export COOLIFY_TOKEN="<id>|<secret>"
coolify-mcp

The token format is <id>|<secret> — both parts required. The id is an integer; the secret is an alphanumeric string.

2. Config file

For multi-instance setups or richer per-instance settings, supply a JSON config file.

File resolution order:

  1. --config <path> CLI flag

  2. COOLIFY_CONFIG environment variable

  3. ~/.coolify-mcp/config.json (auto-discovered if present)

  4. Falls back to env-var mode (step 1) if none of the above exists

${ENV} expansion is applied to every string value in the file, including nested ones.
${VAR} — substitutes the environment variable; throws if unset.
${VAR:-default} — uses default when VAR is unset or absent.

Only baseUrl and token are required per instance; everything else is optional and defaults to safe values.

See config.example.json for a full multi-instance example.

3. Host-ops configuration

To enable SSH access, set "enableHostOps": true and provide ssh.keyPath.
The SSH host, user, and port are auto-derived from the Coolify API — no need to set them manually.

Single-server installs (host.docker.internal). Coolify's built-in "localhost" server often reports its ip as host.docker.internal (a Docker-internal alias) that a remote workstation can't SSH to. Two things handle this:

  • Select the control host explicitly with ssh.hostServer (its UUID or name) — required because a non-matching server is not auto-selected (anti-hijack). When the selected server's ip is a non-routable alias, coolify-mcp automatically substitutes the baseUrl host (which is reachable and operator-trusted).

  • Override the SSH address with ssh.host when even the baseUrl host isn't SSH-reachable (e.g. it's behind a proxy/CDN) — set it to the server's real IP/hostname.

Minimal host-ops config for a standard single-server install:

"ssh": { "keyPath": "~/.ssh/id_ed25519", "hostServer": "<server-uuid-or-name>" }

Add "host": "<reachable-ip>" if baseUrl isn't directly SSH-reachable.

"ssh": {
  "keyPath": "~/.ssh/id_ed25519"
}

Tilde (~) is expanded to the home directory. Optional overrides:

Field

Description

ssh.keyPath

Path to the SSH private key (required for host-ops).

ssh.host

Explicit SSH host/IP override. Use when the API-derived address isn't reachable (e.g. it reports host.docker.internal, or baseUrl is behind a proxy). Takes precedence over auto-derivation.

ssh.knownHostsPath

Path to a known_hosts file. Defaults to ~/.ssh/known_hosts.

ssh.fingerprint

SHA-256 host fingerprint (alternative to known_hosts).

ssh.hostServer

UUID or name of the Coolify control server (override when auto-match fails).

ssh.user

SSH user override (else from API).

ssh.port

SSH port override (else from API).

ssh.passphrase

Private key passphrase.

SSH host-key verification is fail-closed. The server will not connect unless the key presented by the remote host matches either ssh.fingerprint (SHA-256, from ssh-keyscan <host> | ssh-keygen -lf -) or the appropriate entry in ssh.knownHostsPath / ~/.ssh/known_hosts. A missing or non-matching entry is an immediate connection refusal. Note: known_hosts matching is literal — wildcard (*.example.com) and hashed (|1|...) entries are not matched; use ssh.fingerprint or a literal host line for those hosts.

Threat-model note (host-ops trusts the Coolify API). The SSH host/user/port are derived from the Coolify API (GET /servers). A compromised Coolify API could therefore influence which host the MCP connects to — but this is bounded by the fail-closed host-key verification above (a redirect to an untrusted host is refused). For the strongest assurance set ssh.fingerprint to pin the control host's key regardless of known_hosts. Connections to remote managed servers run via docker -H ssh://… on the Coolify host, so that hop is governed by the Coolify host's own SSH trust store rather than this client's.

4. query_coolify_db — read-only DB role

Set db.readonlyUser per instance to enable the query_coolify_db tool. The in-code SQL blocklist and output redaction are best-effort defense-in-depth only — they cannot make arbitrary free-form SQL safe. You MUST provision the role so PostgreSQL enforces the constraints:

CREATE ROLE coolify_ro LOGIN PASSWORD '...' NOSUPERUSER NOCREATEDB NOCREATEROLE;
GRANT CONNECT ON DATABASE coolify TO coolify_ro;
GRANT USAGE ON SCHEMA public TO coolify_ro;
GRANT SELECT ON ALL TABLES IN SCHEMA public TO coolify_ro;   -- omit sensitive tables/columns you don't want exposed
REVOKE EXECUTE ON ALL FUNCTIONS IN SCHEMA public FROM coolify_ro;  -- blocks adminpack/dblink/file fns
-- do NOT grant pg_read_server_files / pg_write_server_files / pg_execute_server_program / superuser

Treat query_coolify_db output as "whatever this role may SELECT" — redaction reduces incidental leakage but is not guaranteed.

5. Multi-instance + per-call instance selector

A single coolify-mcp process can drive multiple Coolify instances simultaneously.
Every tool exposes an optional instance argument; omit it to use the default instance.

// config.json
{
  "defaultInstance": "prod",
  "instances": {
    "prod":    { "baseUrl": "https://coolify.prod.example.com",    "token": "${PROD_TOKEN}" },
    "staging": { "baseUrl": "https://coolify.staging.example.com", "token": "${STAGING_TOKEN}" }
  }
}

Example tool call routing to the non-default instance:

{ "tool": "list_resources", "arguments": { "instance": "staging", "type": "applications" } }

enableHostOps/allowDestructive are per-instance — you can allow destructive actions on staging while keeping them blocked on prod.

Managing instances

init merges into your existing ~/.coolify-mcp/config.json — re-run it to add another instance (it asks for a name, whether to make it the default, and confirms before overwriting an existing one; your other instances are left untouched).

coolify-mcp instances                 # list configured instances (* = default); never prints secrets
coolify-mcp instances default <name>  # set the default instance
coolify-mcp instances rm <name>       # remove an instance (alias: `remove`)
coolify-mcp instances edit <name>     # interactive edit — Enter keeps each current value
coolify-mcp instances set <name> <field> [value]   # one-shot field edit (see fields below)
coolify-mcp instances unset <name> <field>         # clear an optional field, or a whole ssh/db block

instances rm refuses to remove the only instance, and refuses to remove the current default while several remain (set a new default first with instances default <name>); removing the default when a single instance is left auto-promotes the survivor.

Editing an instance. instances set accepts these fields: baseUrl, token, enableHostOps, allowDestructive, pinnedCoolifyVersion, ssh.keyPath, ssh.host, ssh.hostServer, ssh.user, ssh.port, ssh.fingerprint, ssh.knownHostsPath, ssh.passphrase, db.readonlyUser, db.readonlyPassword. Omit the value for a secret field (token, ssh.passphrase, db.readonlyPassword) to be prompted with hidden input — keeps the secret out of shell history:

coolify-mcp instances set prod allowDestructive on
coolify-mcp instances set prod token              # prompts hidden — token rotation in one line
coolify-mcp instances unset prod ssh              # drop host-ops SSH config entirely

After every change the instance is re-verified (API health always, SSH when ssh fields changed); skip with --no-verify. set/unset keep the write on a failed verification and point at the .bak backup; instances edit verifies changed credentials before writing and aborts untouched on failure. Values stored as ${ENV} references are shown and preserved verbatim — editing never silently inlines a referenced secret. Run coolify-mcp help instances for the full reference.

6. CLI flags + back-compat

When no config file is used, the legacy flags and environment variables still work and map onto the synthesized default instance:

Flag / Variable

Maps to

--enable-host-ops

instances.default.enableHostOps = true

--allow-destructive

instances.default.allowDestructive = true

COOLIFY_SSH_KEY_PATH

instances.default.ssh.keyPath

COOLIFY_SSH_HOST

instances.default.ssh.host

COOLIFY_SSH_KNOWN_HOST_FINGERPRINT

instances.default.ssh.fingerprint

COOLIFY_SSH_KNOWN_HOSTS_PATH

instances.default.ssh.knownHostsPath

COOLIFY_SSH_USER

instances.default.ssh.user

COOLIFY_SSH_PORT

instances.default.ssh.port

COOLIFY_SSH_KEY_PASSPHRASE

instances.default.ssh.passphrase

COOLIFY_SSH_HOST_SERVER

instances.default.ssh.hostServer

COOLIFY_DB_READONLY_USER

instances.default.db.readonlyUser

COOLIFY_DB_READONLY_PASSWORD

instances.default.db.readonlyPassword

COOLIFY_PINNED_VERSION

instances.default.pinnedCoolifyVersion

--header "K: V"

instances.default.extraHeaders (repeatable)

When a config file is loaded, --enable-host-ops and --allow-destructive are ignored (a warning is printed); per-instance gating comes from the file.

7. HTTP transport (optional)

By default the server speaks MCP over stdio. To serve it over Streamable HTTP instead, pass --http [port] (default 3000) or set COOLIFY_MCP_HTTP_PORT:

export COOLIFY_MCP_HTTP_TOKEN="<a long random secret>"   # required
coolify-mcp --http 3000

Variable

Description

COOLIFY_MCP_HTTP_PORT

Enable HTTP on this port (or use --http <port>).

COOLIFY_MCP_HTTP_TOKEN

Required (min 16 chars). Bearer token clients must send as Authorization: Bearer <token>. The server refuses to start an unauthenticated endpoint, or one with a token shorter than 16 characters.

COOLIFY_MCP_HTTP_HOST

Bind address. Defaults to 127.0.0.1; a non-localhost bind prints a warning.

COOLIFY_MCP_HTTP_ALLOWED_HOSTS

Comma-separated host:port allowlist for the Host header (DNS-rebinding defense), enforced on non-loopback binds. Defaults to the bind host:port; set this to your client-facing host:port when binding 0.0.0.0.

The host-ops tier is never exposed over HTTP. ssh_exec, docker_op, query_coolify_db, read_host_file, and stream_logs are root-level operations registered only on the stdio transport — over HTTP the server serves the API tier (read/write/destructive) only, regardless of enableHostOps. Keep the bind on 127.0.0.1, keep the bearer token secret, and treat any non-localhost bind as internet-facing.

Token Scope Guidance

Coolify tokens carry full-account permissions. For read-only use (monitoring, querying), prefer creating a dedicated read-only token in Coolify's settings if the feature is available for your version. For write operations, use a token scoped to the team/project you intend to manage. Never share the same token across environments.

Tools

Tools are grouped by tier. Tier determines what flags must be set for the tool to be registered and callable.

Tier

Meaning

Required flags

R (read)

Non-mutating reads: list, get, inspect

none

W (write)

Creates and updates

none (but Coolify token must have write access)

D (destructive)

Deletes and stop/restart/kill operations

--allow-destructive and confirm: true in the call

host

SSH, Docker, psql, file reads

--enable-host-ops

Destructive host actions (docker rm/rmi/stop/kill/prune/exec) additionally require --allow-destructive and confirm: true. The host tier is root-level read access by design: read-only docker_op actions (inspect, logs, …) and read_host_file can surface container configuration including environment variables/secrets — treat their output as sensitive. docker_args rejects shell metacharacters and {} template braces, but plain docker inspect <container> still returns that container's full config; only enable --enable-host-ops for trusted callers.

Deploy

Tool

Tier

Description

deploy

W

Trigger a deployment for a resource by UUID or tag.

deploy_watch

W

Trigger and poll until a terminal deploy status, emitting MCP progress.

get_deployments

R

List active deployments or fetch deployment history for an application.

cancel_deployment

D

Cancel a running deployment.

Resources (Applications, Databases, Services)

Tool

Tier

Description

list_resources

R

List all resources of a given kind with summary fields.

get_resource

R

Fetch full details for a single resource by UUID.

create_resource

W

Create an application (public/private-github-app/private-deploy-key/dockerfile/dockerimage), database, or service.

update_resource

D

Update an existing resource's settings via the fields object (see below). Fenced: requires --allow-destructive + confirm: true (fields can rewrite deploy/start commands).

control_resource

W/D

Start/stop/restart a resource (stop/restart require --allow-destructive).

delete_resource

D

Permanently delete a resource. Requires --allow-destructive + confirm: true.

manage_storage

W/D

List, create, update, or delete persistent storage volumes for a resource. Create/update take a fields object.

manage_backups

W/D

List, create, update, or delete backup schedules for databases. Create/update take a fields object.

manage_scheduled_tasks

W/D

List, create, update, or delete scheduled tasks for apps/services.

The fields pass-through (update_resource, create_resource, manage_storage, manage_backups)

Pass request-body fields in the fields object; they are forwarded verbatim to the corresponding Coolify endpoint (e.g. PATCH /api/v1/applications/{uuid}), so any field the endpoint accepts works:

{
  "type": "applications",
  "uuid": "abc123",
  "fields": { "post_deployment_command": "php artisan migrate --force" },
  "confirm": true
}

The declared fields parameter exists because some MCP clients enforce strict input schemas and silently strip undeclared top-level properties, which previously reached Coolify as an empty PATCH body (HTTP 400 "Empty JSON"). Top-level extra properties are still accepted from permissive clients; on a key conflict, fields wins. If no updatable field is provided at all, the tool returns invalid_input instead of calling the API. For clients whose strict schema handling also empties nested free-form objects, every fields-taking tool additionally accepts fields_json — the same object JSON-encoded as a string (mutually exclusive with fields).

update_resource is fenced: it requires --allow-destructive at startup and confirm: true per call (dry_run: true previews which fields would change), because fields can rewrite the commands Coolify executes on deploy.

Commonly updated application fields: name, description, domains (comma-separated URL list — do not send fqdn, which Coolify rejects; the tool remaps fqdn to domains defensively), git_branch, build_pack, install_command, build_command, start_command, ports_exposes, base_directory, publish_directory, docker_registry_image_name, docker_registry_image_tag, pre_deployment_command, post_deployment_command, health_check_enabled, health_check_path (and the other health_check_* settings), custom_docker_run_options, watch_paths. Applications with build_pack: "dockercompose" cannot use domains — set per-service domains via docker_compose_domains, e.g. { "fields": { "docker_compose_domains": [{ "name": "web", "domain": "https://app.example.com" }] } }.

Databases accept their own PATCH fields (e.g. name, description, image, is_public, public_port, engine credential fields). Credential values echoed back in the update response are redacted before being returned. Services accept only name, description, instant_deploy, docker_compose_raw, connect_to_docker_network, urls, force_domain_override, and is_container_label_escape_enabled; service URLs are set via urls: [{ "name": "<compose-service-name>", "url": "https://..." }] — services have no domains field.

All three resource types also accept instant_deploy: true in fields, which queues a deployment immediately after the update is saved — omit it (the default) to change configuration without deploying.

For create_resource, git-based applications (public, private-github-app, private-deploy-key) require build_pack (now a declared parameter); any less common create-body field can go in fields. manage_storage create requires fields.type and fields.mount_path (plus name, host_path, content, is_directory, fs_path as needed). manage_backups create requires fields.frequency (cron), and accepts enabled, save_s3, s3_storage_uuid, databases_to_backup, dump_all, backup_now, database_backup_retention_*, timeout.

Environment Variables

Tool

Tier

Description

manage_env

W/D

List, upsert-bulk, or delete environment variables for a resource.

Projects

Tool

Tier

Description

manage_projects

R/W/D

List, get, create, update, or delete projects and their environments.

Instances

Tool

Tier

Description

list_instances

R

List configured Coolify instances (names, base URLs, default, tier flags). Never returns secrets.

Servers & Keys

Tool

Tier

Description

get_servers

R

List servers or get a single server with validation/resource info.

manage_server

W/D

Create, update, or delete servers.

provision_hetzner

W

Provision a new Hetzner cloud server via Coolify.

hetzner_inventory

R

List Hetzner locations, server types, images, or SSH keys.

manage_keys

W/D

Manage Coolify private keys and cloud provider tokens.

Logs

Tool

Tier

Description

get_logs

R / host

Snapshot logs for an application (REST API). For databases and services, falls back to docker logs --tail via host-ops.

stream_logs

host

Live-tail Docker logs via SSH/HostOps. Sends MCP progress every 25 lines. Hard cap: 1000 lines / 15 min.

Host Ops

Tool

Tier

Description

ssh_exec

host

Run a shell command on a server over SSH. Returns stdout, stderr, exit code.

docker_op

host

Run a Docker CLI sub-command on a server. Mutating actions require --allow-destructive + confirm: true.

query_coolify_db

host

Execute a read-only SELECT query against the Coolify PostgreSQL database.

read_host_file

host

Read an allowed file on the Coolify host (restricted to /data/coolify/**).

Security Notes

Never-Exposed Endpoints (Lockout Policy)

The following Coolify API endpoints are intentionally never exposed as tools, because calling them from an automated agent risks locking out all access to the Coolify UI:

  • GET /enable — enables Coolify

  • GET /disable — disables Coolify

  • POST /mcp/enable — enables Coolify's own MCP endpoint

  • POST /mcp/disable — disables Coolify's own MCP endpoint

  • IP-allowlist mutation endpoints

Destructive Operations

All destructive operations follow a deny-by-default, double-confirmation model:

  1. The server must be started with --allow-destructive.

  2. Each individual call must include confirm: true in its arguments.

  3. You can pass dry_run: true to preview what would be executed without performing it.

Host-Ops Tier

When enableHostOps: true is set for an instance (or --enable-host-ops in env mode), the server opens an SSH connection to the Coolify host on first use. Commands run as the configured SSH user (typically root). File access is restricted to /data/coolify/** prefixes. SQL access is restricted to read-only SELECT statements.

SSH host-key verification is fail-closed. The server refuses to connect unless the key presented by the remote host matches either ssh.fingerprint (SHA-256, from ssh-keyscan <host> | ssh-keygen -lf -) or the appropriate entry in ssh.knownHostsPath / ~/.ssh/known_hosts. A missing or non-matching entry is an immediate connection refusal.

Development

npm install
npm test              # vitest
npm run build         # esbuild -> single self-contained dist/cli/index.js bundle
npm run probe         # scripts/probe.ts (requires COOLIFY_TEST_BASE_URL / COOLIFY_TEST_TOKEN)

Note — dist/ is committed. npm run build bundles the CLI, the MCP server, and all runtime deps (ssh2, the MCP SDK, …) into a single dist/cli/index.js via esbuild, with ssh2's native bindings externalized (it falls back to pure-JS crypto). The result has zero runtime dependencies, so npm install github:… compiles nothing and runs no install scripts on the user's machine. Because no build runs at install time, the bundle is checked into git: run npm run build and commit the updated dist/cli/index.js (and the regenerated THIRD-PARTY-NOTICES.txt) whenever you change anything under src/. (Runtime libs live in devDependencies since they're bundled, not installed by consumers.) CI runs git diff --exit-code dist/ THIRD-PARTY-NOTICES.txt so a stale committed bundle fails the build.

License

MIT. The published single-file bundle inlines third-party packages (ssh2, the MCP SDK, ajv, …); their license and copyright notices are reproduced in THIRD-PARTY-NOTICES.txt, regenerated at build time.

Available Tools

22 tools
cancel_deploymentA

Cancel an in-progress deployment by its deployment UUID (fenced). Requires --allow-destructive and confirm:true.

ParametersJSON Schema
NameRequiredDescriptionDefault
confirmNoMust be true to confirm this destructive operation.
dry_runNoIf true, show what would be cancelled without performing the action.
instanceNoCoolify instance name (omit for the default).
deployment_uuidYesCoolify deployment UUID to cancel (alphanumeric).

TDQS

A3.9/5.0
Behavior3/5

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

With no annotations provided, the description must disclose behavior on its own. It indicates the operation is destructive by requiring --allow-destructive and confirm:true. It also scopes the action to 'in-progress' deployments. Yet it does not explain side effects, the 'fenced' term, or what happens to the deployment afterward, so transparency is adequate but not thorough.

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

Conciseness5/5

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

The description is two sentences, front-loaded with the primary action and resource, and contains no filler. Every word adds value, making it highly concise and effective.

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

Completeness3/5

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

Considering there is no output schema and no annotations, the description covers the essential purpose and prerequisites but omits details like the meaning of 'fenced', behavior when the deployment is not in progress, and the return value. It is minimally sufficient for a simple cancellation tool but leaves some gaps for the agent to infer.

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

Parameters3/5

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

Schema description coverage is 100%, so the schema already documents all parameters. The description adds only minor value by reinforcing that confirm:true is required for destructive operations and that the deployment is identified by UUID. This is a baseline 3 with a small amount of extra context.

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

Purpose5/5

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

The description clearly states the tool cancels an in-progress deployment by UUID, using the verb 'cancel' and specifying the exact resource type. This distinguishes it from sibling tools like deploy (which starts deployments) and delete_resource (which removes entire resources).

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

Usage Guidelines4/5

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

The description gives clear context that the tool is for cancelling in-progress deployments and specifies the required confirm flag and --allow-destructive. However, it does not explicitly mention when not to use it or compare it to alternatives, keeping it at a 4.

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

control_resourceA

Start, stop (fenced), or restart (fenced) a Coolify resource. stop and restart are destructive — they require --allow-destructive and confirm:true. For applications, start/restart return a deployment_uuid that can be used to track progress.

ParametersJSON Schema
NameRequiredDescriptionDefault
typeYes
uuidYesThe Coolify UUID of the resource.
actionYes
confirmNoMust be true to confirm destructive operations (stop, restart).
dry_runNoIf true, show what would happen without performing the action (stop, restart).
instanceNoCoolify instance name (omit for the default).
instant_deployNoApplications only: skip the build queue.

TDQS

A3.6/5.0
Behavior3/5

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

The description warns that stop and restart are destructive and require confirm:true, and notes deployment_uuid returns for applications. However, it mentions an '--allow-destructive' flag not present in the schema and uses 'fenced' without definition, causing confusion. No annotations exist, so the burden is on the description.

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

Conciseness4/5

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

Three succinct sentences with front-loaded purpose; no waste except for the unexplained 'fenced' and stray CLI flag. It's concise but not perfectly clean.

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

Completeness3/5

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

Given no output schema and no annotations, the description should cover return behavior and prerequisites more thoroughly. It explains start/restart return for apps but not for databases/services, and doesn't clarify the 'fenced' qualifier or the allow-destructive flag. It covers the main safety and return aspects but remains incomplete for a 7-param tool.

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

Parameters4/5

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

The description adds meaning to the action parameter by clarifying which actions are destructive and their confirmation requirement, and adds return-value semantics for applications. The schema already covers uuid, confirm, dry_run, instance, and instant_deploy; the description goes beyond these by explaining action-specific behavior, though the '--allow-destructive' reference is confusing.

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

Purpose5/5

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

The description clearly states 'Start, stop, or restart a Coolify resource', naming the verb and resource type, and differentiates from sibling tools like delete_resource, deploy, and update_resource. The term 'fenced' is unclear but doesn't obscure the core purpose.

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

Usage Guidelines2/5

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

No explicit guidance on when to use this tool versus alternatives like deploy or delete_resource. It only notes destructive actions require confirm, not when to choose this lifecycle tool.

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

create_resourceA

Create a new Coolify resource. kind discriminates: application (with source sub-discriminator), database (with engine), or service (with service_type XOR docker_compose_raw base64). FENCED: requires --allow-destructive and confirm:true (code/credential write).

ParametersJSON Schema
NameRequiredDescriptionDefault
kindYesThe type of resource to create.
nameNoName for the new resource.
engineNoRequired when kind=database.
fieldsNoAdditional create-body fields (e.g. ports_exposes, domains, base_directory, destination_uuid), sent verbatim as the request body — any field the Coolify endpoint accepts is allowed.
sourceNoRequired when kind=application. Determines which Coolify endpoint is called.
confirmNoMust be true to confirm resource creation (destructive: code/credential write).
dry_runNoIf true, show what would be created without performing the action.
instanceNoCoolify instance name (omit for the default).
build_packNoBuild pack. REQUIRED by Coolify for the public, private-github-app, and private-deploy-key sources.
dockerfileNoDockerfile content (for dockerfile source).
git_branchNoGit branch (for git-based apps).
fields_jsonNoJSON-encoded alternative to `fields` (mutually exclusive) for clients whose strict schema handling strips free-form object contents.
server_uuidNoUUID of the target server.
docker_imageNoDocker image reference (for dockerimage source).
project_uuidNoUUID of the target project.
service_typeNoRequired when kind=service and not using docker_compose_raw. Mutually exclusive with docker_compose_raw.
git_repositoryNoGit repository URL (for git-based apps).
instant_deployNoTrigger deploy immediately after creation.
github_app_uuidNoGitHub App UUID (for private-github-app source).
environment_nameNoName of the Coolify environment.
private_key_uuidNoPrivate key UUID (for private-deploy-key source).
docker_compose_rawNoBase64-encoded docker-compose content. Required when kind=service and not using service_type. Mutually exclusive with service_type.

TDQS

A4.5/5.0
Behavior4/5

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

No annotations are provided, so the description carries the full burden. It discloses that the tool is FENCED, requires --allow-destructive and confirm:true, and characterizes the write as code/credential write. This is significant safety-relevant behavior. It does not detail all side effects, but the critical guardrails 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.

Conciseness5/5

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

Two sentences pack a large amount of high-value information: the core purpose, the discriminating logic, and the critical fencing requirement. The description is front-loaded and wastes no words.

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

Completeness4/5

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

Given 22 parameters and no output schema, the description does not explain each parameter but relies on the rich schema. It does provide the essential high-level decision tree and safety context. It omits some conditional nuances (e.g., build_pack requirements), but the schema covers individual fields, making this sufficient for a create tool.

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

Parameters5/5

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

Schema coverage is 100%, so the baseline is 3. The description adds relational semantics beyond individual field docs: it explains that `kind` discriminates among three types, `source` is a sub-discriminator for applications, `engine` is for databases, and `service_type` XOR `docker_compose_raw` (base64) applies to services. This helps the agent correctly combine parameters.

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

Purpose5/5

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

The description states a specific verb and resource: 'Create a new Coolify resource.' It clearly distinguishes from sibling tools like update_resource and delete_resource by using 'create' and explaining the resource-kind discriminator. This makes the tool's purpose unambiguous.

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

Usage Guidelines4/5

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

The description clearly implies the tool is for creation and provides a decision tree via `kind` (application/database/service) with sub-discriminators. It does not explicitly state when not to use it or compare with alternatives, but the context is clear and no exclusions are needed beyond obvious creation tasks.

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

delete_resourceA

Delete a Coolify resource permanently. Requires confirm:true and --allow-destructive flag.

ParametersJSON Schema
NameRequiredDescriptionDefault
typeYes
uuidYes
confirmNoMust be true to execute.
dry_runNoReturn preview without deleting.
instanceNoCoolify instance name (omit for the default).

TDQS

A4/5.0
Behavior4/5

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

The description explicitly discloses the permanent, irreversible nature of the delete and the mandatory confirm parameter, which is critical for a destructive operation. It also mentions the --allow-destructive flag, indicating an extra safety gate. However, it does not elaborate on associated data loss or the exact scope of deletion, and it omits mention of dry_run's preview capability, leaving some behavioral aspects to the schema.

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

Conciseness5/5

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

The description is a single, focused sentence that front-loads the action and highlights the critical confirm requirement. It contains no filler and every word adds value, making it appropriately concise.

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

Completeness4/5

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

For a destructive tool with no annotations, the description adequately warns about permanence and the confirmation requirement, which are the most critical operational details. The schema covers parameter enumerations and dry_run behavior, so the description complements rather than duplicates it. However, the lack of any mention of return behavior or the meaning of `uuid` leaves minor gaps, but overall it is sufficient for safe invocation.

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

Parameters3/5

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

The schema describes confirm, dry_run, and instance, but type and uuid lack descriptions, giving 60% coverage. The tool description reinforces confirm's necessity but adds no new meaning for type, uuid, or dry_run, and introduces an external flag not present in the schema. Thus, it does not significantly compensate for the undocumented parameters.

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

Purpose5/5

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

The description clearly identifies the tool's function with the verb 'Delete' and specifies the target as 'a Coolify resource,' emphasizing permanence. The action is distinct from sibling tools like create_resource, update_resource, and control_resource, so the purpose is unambiguous.

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

Usage Guidelines3/5

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

The description provides a key usage requirement—confirm:true and the --allow-destructive flag—which is essential for executing a destructive operation. However, it does not explicitly differentiate when to use this tool versus alternatives like control_resource for temporary changes, nor does it mention dry_run as a safe preview option. The guidance is limited to prerequisites, not broader usage context.

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

deployA

Trigger a new deployment for an application (by UUID or tag). Optionally force-rebuild or deploy a pull-request preview. FENCED: requires --allow-destructive and confirm:true (code/credential write).

ParametersJSON Schema
NameRequiredDescriptionDefault
prNoPull-request number for preview deployments.
tagNoDeploy all resources sharing this tag.
uuidNoCoolify application UUID to deploy (alphanumeric, e.g. abc123).
forceNoForce a rebuild without cache.
confirmNoMust be true to confirm this deployment (destructive: triggers production change).
dry_runNoIf true, show what would be deployed without triggering.
instanceNoCoolify instance name (omit for the default).

TDQS

A4.2/5.0
Behavior4/5

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

With no annotations provided, the description carries the burden of disclosure. It clearly states the FENCED requirement: 'requires --allow-destructive and confirm:true (code/credential write)', providing critical safety and permission context beyond the schema. This adds value without contradicting any annotations.

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

Conciseness5/5

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

The description is two sentences, front-loaded with the primary action, and cleanly separates the safety note. Every word earns its place without unnecessary elaboration.

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

Completeness4/5

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

Given 7 parameters, no output schema, and no annotations, the description covers the core action, selection methods, options, and a critical safety constraint. It does not explain dry_run or return values, but the schema covers parameters, and the absence of output schema does not require over-explanation.

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

Parameters3/5

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

Schema coverage is 100%, so the baseline is 3. The description adds minor semantic grouping ('by UUID or tag', 'force-rebuild', 'pull-request preview') that maps to uuid/tag, force, and pr parameters, but it does not provide additional syntax or details beyond the already-rich schema.

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

Purpose5/5

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

The description uses the specific verb 'Trigger a new deployment' and identifies the target resource as 'an application (by UUID or tag)'. It also mentions optional force-rebuild and pull-request preview, distinguishing it clearly from siblings like cancel_deployment or get_deployments.

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

Usage Guidelines4/5

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

The description gives clear context for when to use the tool: to trigger a deployment, optionally with force rebuild or PR preview. It does not explicitly mention alternatives or exclusions, but the purpose is unambiguous and distinct from deployment-related siblings.

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

deploy_watchA

Trigger a deployment and block until it reaches a terminal state (finished/failed/cancelled/skipped). Emits MCP progress notifications while polling. Returns per-resource final statuses and a logs tail on failure. FENCED: requires --allow-destructive and confirm:true (code/credential write).

ParametersJSON Schema
NameRequiredDescriptionDefault
prNoPull-request number for preview deployments.
tagNoDeploy all resources sharing this tag.
uuidNoCoolify application UUID to deploy (alphanumeric).
forceNoForce a rebuild without cache.
confirmNoMust be true to confirm this deployment (destructive: triggers production change).
dry_runNoIf true, show what would be deployed without triggering.
instanceNoCoolify instance name (omit for the default).
timeout_secondsNoMaximum seconds to wait before returning 'unknown'. Default 1800.

TDQS

A4/5.0
Behavior4/5

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

With no annotations provided, the description carries the full burden. It discloses blocking behavior, progress notifications, return content (per-resource statuses and logs tail on failure), and the FENCED requirement for --allow-destructive and confirm:true. This is substantial useful context, though it doesn't mention timeout behavior explicitly or what happens on internal errors.

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

Conciseness5/5

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

The description is compact: three sentences, each providing valuable information. It front-loads the primary purpose, then adds behavioral details and safety constraints without redundancy or fluff.

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

Completeness4/5

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

For a tool with 8 parameters, no output schema, and no annotations, the description provides a good deal of context: blocking behavior, terminal states, progress notifications, return values, failure logs, and destructive-confirmation requirements. It would be slightly more complete if it explicitly addressed timeout return behavior, but the schema covers that, and the overall picture is well-rounded.

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

Parameters3/5

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

The schema description coverage is 100%, so the input schema already documents all 8 parameters with descriptions. The description adds little parameter-specific meaning beyond what the schema already provides (e.g., confirm being mandatory and dry_run behavior are already in the schema). Thus, the description adds no significant extra parameter semantics, warranting the baseline score.

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

Purpose5/5

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

The description states a specific verb+resource: 'Trigger a deployment and block until it reaches a terminal state'. It clearly distinguishes this tool from siblings by emphasizing blocking behavior and terminal-state outcomes, and it enumerates the terminal states (finished/failed/cancelled/skipped), 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.

Usage Guidelines3/5

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

The description implies the use case: when you need to trigger a deployment and wait for its final outcome, with progress notifications and status/logs. However, it does not explicitly compare to sibling tools like 'deploy' or state when NOT to use this tool, and it lacks concrete alternative guidance.

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

get_deploymentsA

List active deployments (no args) or the deployment history for a specific application (app_uuid). Supports pagination with skip/take.

ParametersJSON Schema
NameRequiredDescriptionDefault
skipNoNumber of records to skip (pagination). Only used with app_uuid.
takeNoNumber of records to return (pagination). Only used with app_uuid.
app_uuidNoApplication UUID whose deployment history to retrieve. Omit for all active deployments.
instanceNoCoolify instance name (omit for the default).

TDQS

A4.4/5.0
Behavior4/5

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

With no annotations, the description carries the burden. It discloses the two operational modes and pagination support. It doesn't explicitly state read-only status, but 'List' implies it. Slight ambiguity about pagination applying only to history mode is resolved by schema.

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

Conciseness5/5

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

Two sentences, front-loaded with the main action, no wasted words. Perfectly concise.

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

Completeness4/5

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

The description covers the core behaviors and parameter usage. It doesn't describe return format, but for a list tool without output schema, this is acceptable. The tool is adequately scoped for selection and invocation.

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

Parameters4/5

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

Schema already documents all parameters (100% coverage). The description adds the semantic distinction that app_uuid toggles modes and skip/take are pagination controls, which is valuable beyond the schema.

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

Purpose5/5

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

Clear verb 'List' with specific resource 'deployments', and distinguishes two modes: active deployments (no args) or history for a specific app (app_uuid). This differentiates it from siblings like list_resources and get_logs.

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

Usage Guidelines4/5

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

Provides clear context on when to use each mode and pagination parameters. However, it doesn't explicitly mention alternatives or when not to use this tool, so not a 5.

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

get_logsA

Fetch a log snapshot for a Coolify resource. • application: uses GET /applications/{uuid}/logs?lines= (REST API). • database / service: requires --enable-host-ops; the docker logs fallback is wired in Task 31.

ParametersJSON Schema
NameRequiredDescriptionDefault
kindYesResource type whose logs to fetch.
uuidYesResource UUID.
linesNoNumber of log lines to retrieve (default 100). Applies to application kind.
instanceNoCoolify instance name (omit for the default).

TDQS

A3.9/5.0
Behavior3/5

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

With no annotations provided, the description carries the full burden. It discloses the API endpoint and the host-ops requirement, implying a read operation. However, it does not describe the return format, size limits, or potential side effects. The reference to 'Task 31' is an implementation detail that does not clarify behavior for an agent.

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

Conciseness4/5

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

The description is front-loaded with the purpose and uses bullet points for clarity. It is relatively concise, though the trailing 'wired in Task 31' is irrelevant and adds noise. Overall, the structure is efficient.

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

Completeness2/5

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

The description lacks critical context for an agent to fully understand the tool's behavior without relying on external knowledge. It does not explain the return value structure, how 'instance' affects the request, or clarify the ambiguous '--enable-host-ops' requirement. Since there is no output schema and no annotations, this is insufficient.

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

Parameters4/5

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

While the schema already describes all parameters (100% coverage), the description adds meaningful context: it ties the 'lines' parameter to the API query string, and clarifies that 'database' and 'service' kinds have additional prerequisites. This goes beyond the schema definitions.

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

Purpose5/5

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

The description clearly states the tool fetches a log snapshot for a Coolify resource, with a specific verb and resource type. It distinguishes from sibling tools like get_resource or get_deployments by focusing on logs, and further differentiates between application, database, and service kinds.

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

Usage Guidelines4/5

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

The description gives clear context on when to use the tool by explaining kind-specific behavior: applications use a REST API endpoint, while databases/services require --enable-host-ops. It does not explicitly mention exclusions or alternatives, but the prerequisites are useful for selection.

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

get_resourceA

Get full details of a specific Coolify resource by type and UUID.

ParametersJSON Schema
NameRequiredDescriptionDefault
typeYesThe resource type.
uuidYesThe Coolify UUID of the resource.
instanceNoCoolify instance name (omit for the default).

TDQS

A3.6/5.0
Behavior3/5

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

The description indicates a read-only 'Get' operation, but with no annotations provided, it carries the full burden of behavioral disclosure. It does not mention what happens when the UUID is invalid, whether authentication/instance selection is needed, or confirm that no modifications occur. The read-only implication is clear, but no additional behavioral context is disclosed.

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

Conciseness5/5

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

The description is a single, direct sentence that conveys purpose and scope without redundancy. It is appropriately sized for a simple getter tool.

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

Completeness4/5

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

For a simple read operation with fully documented parameters and no output schema, the description is adequate: it names the resource types generically, but does not detail the response shape. Since 'full details' implies a comprehensive return, and format is not explained, there is a minor gap. However, the overall simplicity keeps completeness high.

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

Parameters3/5

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

The input schema fully describes all parameters (100% coverage), including the enum for type and descriptions for uuid and instance. The description adds little beyond restating 'by type and UUID'—it does not explain the instance parameter or the meaning of each resource type. With high schema coverage, the baseline of 3 applies and the description provides no extra value.

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

Purpose5/5

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

The description clearly states the operation ('Get full details') and the target ('a specific Coolify resource'), with precise scoping ('by type and UUID'). It is distinct from sibling tools like list_resources (lists all resources) and get_logs/get_deployments (which target other aspects). The verb and resource are specific and unambiguous.

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

Usage Guidelines2/5

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

No guidance is provided about when to use this tool versus alternatives. It does not mention that list_resources should be used to discover UUIDs, or that get_logs/get_deployments serve different purposes. The description implies its own use but offers no explicit context or exclusions.

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

get_serversA

Query Coolify servers. Actions: list (summary fields by default; include:true for full), get, validate, resources, domains.

ParametersJSON Schema
NameRequiredDescriptionDefault
uuidNoServer UUID (required for get, validate, resources, domains).
actionNoOperation to perform. Defaults to list.
includeNoIf true, return full server objects instead of summary fields (list only).
instanceNoCoolify instance name (omit for the default).

TDQS

A3.9/5.0
Behavior3/5

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

With no annotations provided, the description carries the full burden. It implies read-only behavior via 'Query' and discloses the default summary/list behavior and 'include:true' modifier. However, it does not explicitly state that no data is modified, nor does it mention pagination, errors, or authentication requirements—adequate but with clear gaps.

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

Conciseness5/5

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

The description is two sentences, front-loaded with the main purpose, and every word contributes to understanding the tool's scope and actions. There is no redundancy or filler.

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

Completeness3/5

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

The tool is moderately complex (4 parameters, 5 actions, no output schema). The description lists the action names but does not explain what each action returns or any other behavioral details. Since there is no output schema, the description should compensate by clarifying each action, but it only elaborates on 'list'. This leaves 'get', 'validate', 'resources', and 'domains' underspecified, though their names are reasonably self-explanatory.

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

Parameters3/5

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

Schema coverage is 100%, so each parameter is already described in the schema. The description's note 'list (summary fields by default; include:true for full)' adds no new information beyond the schema's own descriptions for 'action' and 'include'. It meets the baseline but provides no extra semantic value.

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

Purpose5/5

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

The description clearly states the tool queries Coolify servers and enumerates specific actions (list, get, validate, resources, domains), distinguishing it from sibling tools like 'get_resource' and 'list_resources' which target resources generally. The verb 'Query' plus the resource and action list make the purpose unambiguous.

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

Usage Guidelines4/5

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

'Query Coolify servers' provides clear context for when to use this tool, and the action list (e.g., list, get, validate) indicates common operations. However, it does not explicitly mention when not to use it or name alternatives, so it falls one step short of full guidance.

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

hetzner_inventoryA

Browse Hetzner Cloud resource catalog exposed by Coolify. Use before provision_hetzner to pick a server type and location.

ParametersJSON Schema
NameRequiredDescriptionDefault
instanceNoCoolify instance name (omit for the default).
resourceNoResource type to list. Defaults to server-types.

TDQS

A4/5.0
Behavior3/5

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

No annotations are provided, so the description carries the full burden. 'Browse' implies a read-only listing operation, and 'resource catalog' indicates it returns data, but it does not disclose return format, pagination, error behavior, or any potential side effects. This is basic but incomplete behavioral transparency.

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

Conciseness5/5

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

The description is two sentences, no filler, and front-loads the purpose. Every word earns its place, making it highly concise and well-structured.

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

Completeness4/5

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

The tool is simple with good schema coverage, and the description adds key workflow context. However, since there is no output schema, the description could have briefly mentioned the return format (e.g., a list of resources). Still, the current description is largely complete for a browsing tool.

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

Parameters3/5

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

Schema description coverage is 100% (both instance and resource have descriptions). The description adds a workflow hint ('server type and location') that maps to enum values, but it does not add meaning beyond what the schema already provides. Baseline 3 is appropriate.

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

Purpose5/5

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

The description clearly states the tool's function ('Browse Hetzner Cloud resource catalog') and explicitly ties it to the provisioning workflow ('Use before provision_hetzner to pick a server type and location'). This distinguishes it from generic list tools and clarifies its specific scope.

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

Usage Guidelines4/5

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

'Use before provision_hetzner to pick a server type and location' provides clear, explicit when-to-use guidance within the provisioning workflow. However, it does not name alternatives or state when not to use it, so it falls slightly short of a 5.

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

list_instancesA

List the Coolify instances this server is configured to drive (names, base URLs, default, and per-instance host-ops/destructive flags). Never returns tokens or other secrets. Pass an instance name as the 'instance' arg to any other tool to route to it.

ParametersJSON Schema
NameRequiredDescriptionDefault
instanceNoNot used for routing here — the instance list is server-global. Pass an instance name to any OTHER tool to target a specific Coolify instance.

TDQS

A4.3/5.0
Behavior4/5

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

With no annotations, the description carries the burden and explicitly notes that it 'Never returns tokens or other secrets,' adding a behavioral guarantee beyond the schema. It also discloses the scope (server-global) and the content of the list, providing adequate transparency for a read-only list operation.

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

Conciseness5/5

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

Three short sentences front-load the main purpose, then add a safety note and a routing tip. No waste.

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

Completeness5/5

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

For a simple discovery tool with no output schema, the description mentions all relevant return fields and the safety constraint. It is complete enough for an agent to know what the tool returns and how to use the result.

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

Parameters3/5

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

The single optional 'instance' parameter is fully documented in the schema, and the description reinforces that it is not used for routing here. Since schema coverage is 100%, the description adds no new parameter syntax but usefully repeats the cross-tool routing advice.

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

Purpose5/5

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

The description uses the specific verb 'List' and identifies the resource as 'Coolify instances this server is configured to drive,' with the fields returned ('names, base URLs, default, and per-instance host-ops/destructive flags'). This distinguishes it from sibling tools like list_resources or get_servers by focusing on instances and their routing configuration.

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

Usage Guidelines4/5

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

The description states that the instance list is server-global and directs users to pass an instance name to any other tool for routing, which gives clear usage context. It does not explicitly list when not to use this tool or name alternative list tools, but the routing instruction serves as practical guidance.

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

list_resourcesA

List all Coolify resources (applications, databases, services) across all projects. Optionally filter by type.

ParametersJSON Schema
NameRequiredDescriptionDefault
typeNoOptional filter by resource type.
instanceNoCoolify instance name (omit for the default).

TDQS

A3.7/5.0
Behavior3/5

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

With no annotations, the description carries the full burden. It discloses the broad scope and optional filter but omits behavioral details such as the read-only nature, the effect of the instance parameter, pagination, or permission requirements. Some context is added, but it is not rich.

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

Conciseness5/5

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

The description is two short, front-loaded sentences with a parenthetical enumeration. Every word contributes, and there is no filler or repetition.

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

Completeness3/5

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

For a simple list tool, the description covers the main purpose and type filter, but fails to mention the instance parameter, which is important for multi-instance setups. Although the schema fills the gap, the description's ambiguity about instance scoping leaves room for misinterpretation.

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

Parameters3/5

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

The schema already has 100% coverage for both parameters. The description only redundantly mentions the type filter and does not describe the instance parameter at all, so it adds little over the schema.

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

Purpose5/5

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

The description states a specific verb ('List'), a specific resource ('Coolify resources'), the scope ('across all projects'), and enumerates the resource types. It also notes the optional type filter, which distinguishes it from more specific tools like get_resource or list_instances.

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

Usage Guidelines3/5

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

The description implies use for listing resources but does not explicitly contrast with alternatives or specify when not to use it. No exclusions or alternative tool names are mentioned, so the usage guidance is only implied by the task description.

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

manage_backupsA

List, create, update, or delete database backup schedules and executions. Only applicable to databases. For create/update, pass the schedule fields in fields (create requires frequency, a cron expression; also enabled, save_s3, s3_storage_uuid, databases_to_backup, dump_all, backup_now, database_backup_retention_*, timeout).

ParametersJSON Schema
NameRequiredDescriptionDefault
uuidYesDatabase UUID.
actionYes
fieldsNoBackup schedule fields for create/update (create requires frequency; also enabled, save_s3, s3_storage_uuid, databases_to_backup, dump_all, backup_now, database_backup_retention_*, timeout), sent verbatim as the request body — any field the Coolify endpoint accepts is allowed.
confirmNoRequired for delete and delete_execution.
dry_runNo
instanceNoCoolify instance name (omit for the default).
backup_uuidNoRequired for update, delete, executions, delete_execution.
fields_jsonNoJSON-encoded alternative to `fields` (mutually exclusive) for clients whose strict schema handling strips free-form object contents.
execution_uuidNoRequired for delete_execution.

TDQS

A3.8/5.0
Behavior2/5

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

With no annotations provided, the description carries the full burden for behavioral disclosure. It mentions that the tool can create, update, and delete, implying mutability, but provides no details on side effects, permissions, reversibility, or confirmation requirements. The confirmation requirement for delete is only present in the input schema, not the description, so the agent is left without warning about destructive actions.

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

Conciseness4/5

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

The description is compact at two sentences, front-loading the core purpose. The second sentence is somewhat dense with a long list of fields, but each item adds relevant detail. It avoids unnecessary filler, so it remains appropriately sized for the tool's complexity.

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

Completeness3/5

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

Given the tool's complexity (9 parameters, multiple actions, nested objects, no output schema), the description gives a high-level overview but misses some important distinctions. For example, it does not clarify the difference between 'list' (schedules) and 'executions', nor between 'delete' and 'delete_execution'. However, the input schema covers many required-field constraints, so the description does not need to repeat those. Still, the ambiguity around action applicability leaves gaps.

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

Parameters4/5

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

The description adds meaning beyond the schema by explaining that `fields` holds backup schedule parameters and lists which ones are required or optional for create/update. It specifically notes that `frequency` is a cron expression and includes the wildcard `database_backup_retention_*`, which is not obvious from the schema alone. This compensates for the 78% schema coverage by clarifying usage of the `fields` object.

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

Purpose5/5

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

The description clearly states the tool's function: 'List, create, update, or delete database backup schedules and executions.' It names a specific resource (database backup schedules/executions) and distinct verbs for each action. The qualifier 'Only applicable to databases' further narrows scope, differentiating it from sibling tools like manage_scheduled_tasks.

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

Usage Guidelines4/5

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

The description provides clear context by specifying that the tool is 'Only applicable to databases,' which serves as an exclusion criterion. It also gives actionable guidance for create/update by stating that schedule fields go in `fields` and that `frequency` is required. However, it does not explicitly name alternative tools or state when not to use this tool beyond the database scope.

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

manage_envA

Manage environment variables for a Coolify resource (application, database, or service). action=list returns all vars with a redaction_hint when any value appears empty or masked. action=set upserts one var ({ key, value }) or many ({ vars: [{key,value},...] }) via bulk API. action=delete (fenced) removes a single var by its env_uuid (UUID returned from list); requires --allow-destructive and confirm:true.

ParametersJSON Schema
NameRequiredDescriptionDefault
keyNoVariable name. Required for action=set with a single var.
typeYesThe resource type.
uuidYesThe Coolify UUID of the resource.
varsNoArray of { key, value } pairs for bulk set (action=set).
valueNoVariable value. Required for action=set with a single var.
actionYesOperation to perform on environment variables.
confirmNoMust be true to confirm destructive operations (action=delete).
dry_runNoIf true, show what would be deleted without performing the action (action=delete).
env_uuidNoUUID of the env var to delete. Required for action=delete.
instanceNoCoolify instance name (omit for the default).

TDQS

A4.5/5.0
Behavior4/5

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

With no annotations, the description carries the full burden. It discloses key behavioral traits: list returns a redaction_hint, set upserts via bulk API, delete is destructive and requires confirmation, and dry_run is supported. However, it does not mention side effects beyond deletion, error conditions, or authentication/rate limits, which are common gaps but not required given the tool's purpose.

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

Conciseness5/5

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

The description is around 70 words, front-loaded with the main purpose, and uses action= prefixes to organize behavior. Every sentence adds concrete information without redundancy, achieving high information density in a compact form.

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

Completeness4/5

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

Given no output schema and 10 parameters, the description does well: it explains list's output, set's bulk capability, and delete's requirements. It falls short by not describing return values for set/delete or error behaviors, and it omits that type and uuid are required across all actions (but that is in the schema). Overall, it covers the core operational context.

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

Parameters5/5

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

Although schema coverage is 100%, the description adds crucial relational meaning: it links action=set to key/value and vars, explains env_uuid comes from list, and ties confirm/dry_run to delete. This goes far beyond the schema's static descriptions and helps the agent choose the correct parameters per action.

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

Purpose5/5

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

The description starts with a clear verb+resource statement: 'Manage environment variables for a Coolify resource (application, database, or service).' It then enumerates the three actions (list, set, delete) with specific behavioral details, making it distinct from sibling tools like manage_storage or manage_backups.

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

Usage Guidelines4/5

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

The description provides clear context for when to use each action (list for viewing, set for upserting, delete for removal) and specifies prerequisites like env_uuid from list. It also states that delete requires confirm:true. However, it does not explicitly compare with alternative tools or mention when not to use this tool, so it misses the explicit exclusion guidance that would earn a 5.

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

manage_keysA

Manage Coolify SSH private keys (security keys). Actions: list, get, create (fenced), update (fenced), delete (fenced). create and update are credential writes — they require --allow-destructive and confirm:true. Note: update uses a collection-level PATCH — uuid is passed in the body.

ParametersJSON Schema
NameRequiredDescriptionDefault
nameNoKey display name.
uuidNoKey UUID (required for get, update, delete).
actionYesOperation to perform.
confirmNoMust be true to confirm create, update, or delete.
dry_runNoPreview the action without executing (create, update, delete).
instanceNoCoolify instance name (omit for the default).
descriptionNoOptional description.
private_keyNoPEM-encoded private key (required for create).
is_git_relatedNoMark as a git-related key.

TDQS

A4.4/5.0
Behavior4/5

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

With no annotations, the description carries the transparency burden. It discloses that create/update are credential writes, requires confirmation, and mentions the collection-level PATCH nuance for update (uuid in body). This adds valuable non-obvious behavioral context, though it doesn't explain what 'fenced' means or potential side effects of delete.

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

Conciseness5/5

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

The description is three sentences, front-loaded with the purpose, then a concise action list, then critical operational details. No filler or redundant content.

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

Completeness4/5

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

Given the tool complexity (9 params, 5 actions) and no output schema, the description covers essential warnings and nuances but could elaborate on return values or per-action behavior. However, the rich schema descriptions compensate, making the description adequate.

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

Parameters4/5

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

Schema coverage is 100%, so the baseline is 3. The description adds extra meaning by linking confirm to credential writes and explaining that update uses a collection-level PATCH with uuid in the body. This goes beyond the schema field descriptions.

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

Purpose5/5

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

The description clearly states the tool manages Coolify SSH private keys and enumerates the supported actions (list, get, create, update, delete). This is a specific verb+resource and distinguishes it from sibling tools like manage_server or manage_storage.

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

Usage Guidelines4/5

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

The description provides context on how to perform actions, notably that create/update are fenced credential writes requiring --allow-destructive and confirm:true. It doesn't explicitly name alternatives, but the tool's scope is clear relative to siblings.

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

manage_projectsC

Manage Coolify projects and their environments. Actions: list, get, create, update, delete (fenced), list_environments, create_environment, get_environment, delete_environment (fenced).

ParametersJSON Schema
NameRequiredDescriptionDefault
nameNoProject name (required for create; optional for update) or environment name (required for create_environment).
uuidNoProject UUID (required for get, update, delete, list_environments, create_environment, get_environment, delete_environment).
actionYesThe operation to perform.
confirmNoMust be true to confirm destructive operations (delete, delete_environment).
dry_runNoIf true, show what would be deleted without performing the action (delete, delete_environment).
instanceNoCoolify instance name (omit for the default).
descriptionNoProject description (optional for create/update).
environmentNoEnvironment name or UUID (required for get_environment, delete_environment).

TDQS

C2.9/5.0
Behavior2/5

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

With no annotations, the description carries the full burden, but it only hints at destructive operations with '(fenced)' without explaining what that entails. It fails to disclose side effects, required permissions, or behavior of actions like delete. The schema covers the confirm flag, but the description adds little beyond a vague safety signal.

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

Conciseness4/5

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

The description is concise, front-loads the purpose, and uses a compact action list. It is not overly verbose, though the actions could be presented in a more structured way (e.g., categorizing by resource type).

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

Completeness2/5

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

Given the tool's complexity (8 parameters, 9 actions) and lack of output schema, the description is incomplete. It does not explain what each action returns, mention prerequisites (e.g., needing a UUID for get), or provide context beyond the action names. The schema compensates for some parameter details but not overall workflow context.

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

Parameters3/5

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

Schema description coverage is 100%, so the structured field descriptions already document all parameters. The description adds no additional parameter semantics beyond what the schema provides, maintaining the baseline.

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

Purpose4/5

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

Clearly identifies the resource (Coolify projects and their environments) and enumerates specific actions (list, get, create, update, delete). The verb 'Manage' is generic, but the action list provides specificity and distinguishes it from sibling tools like manage_env or manage_server.

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

Usage Guidelines2/5

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

Provides no guidance on when to use this tool versus alternatives. It does not mention that environment-specific tools (e.g., manage_env) should be used for environment variables, nor any prerequisites or contexts for the various actions.

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

manage_scheduled_tasksA

List, create (fenced), update (fenced), delete (fenced), or view executions of scheduled tasks on an application or service. create and update are code-execution writes — they require --allow-destructive and confirm:true.

ParametersJSON Schema
NameRequiredDescriptionDefault
nameNo
typeYes
uuidYes
actionYes
commandNo
confirmNoRequired for create, update, and delete.
dry_runNoIf true, show preview without performing the action (create, update, delete).
enabledNoWhether the task is enabled (Coolify default true).
timeoutNoTask timeout in seconds (Coolify default 300).
instanceNoCoolify instance name (omit for the default).
containerNoContainer (within a compose app/service) the command runs in.
frequencyNoCron expression.
task_uuidNoRequired for update, delete, executions.

TDQS

A4.1/5.0
Behavior4/5

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

With no annotations, the description carries the transparency burden. It meaningfully discloses that create/update are code-execution writes with special safety requirements, and the 'fenced' label hints at guarded behavior. However, it does not clarify whether delete also requires confirm (schema says yes) or explain what 'fenced' actually means, 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.

Conciseness5/5

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

The description is two crisp sentences. The first sentence front-loads the action list and resource; the second adds a targeted safety note. No wasted words.

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

Completeness3/5

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

Given the tool's complexity (13 parameters, 5 actions, no annotations or output schema), the description is adequate but not complete. It lists the actions and flags important safety, but leaves 'fenced' undefined and doesn't mention dry_run or the fact that delete also requires confirm per the schema.

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

Parameters3/5

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

Schema description coverage is 62%, leaving some parameters (name, command, uuid) undocumented. The description adds value by explaining the confirm requirement for create/update, but it omits delete's confirm requirement and does not help clarify the undocumented parameters.

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

Purpose5/5

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

The description opens with a clear list of specific actions (List, create, update, delete, view executions) tied to a specific resource (scheduled tasks on an application or service). This distinguishes it from sibling tools like manage_storage or manage_backups.

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

Usage Guidelines4/5

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

The description gives clear context for when the tool is relevant (scheduled tasks on applications/services) and provides a key usage constraint (create/update are code-execution writes requiring --allow-destructive and confirm:true). However, it does not explicitly name alternatives or state when not to use this tool.

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

manage_serverC

Create, update, or delete (fenced) a Coolify server.

ParametersJSON Schema
NameRequiredDescriptionDefault
ipNoServer IP address (required for create).
nameNoServer display name.
portNoSSH port (default 22).
userNoSSH user (required for create).
uuidNoServer UUID (required for update, delete).
actionYesOperation to perform.
confirmNoMust be true to confirm delete.
dry_runNoPreview delete without executing.
instanceNoCoolify instance name (omit for the default).
descriptionNoOptional description.
is_build_serverNoMark as build server.
instant_validateNoValidate immediately after create.
private_key_uuidNoUUID of the private key to use (required for create).

TDQS

C2.9/5.0
Behavior2/5

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

With no annotations provided, the description carries the full burden of disclosing behavior. It doesn't mention that delete is destructive, requires confirmation, or that there are dry-run capabilities. The 'fenced' term is unexplained, adding confusion rather than transparency.

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

Conciseness5/5

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

The description is a single concise sentence with no filler. It's appropriately short and front-loads the action verbs, making it easy to parse.

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

Completeness2/5

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

This is a complex multi-action tool with 13 parameters and no output schema, yet the description is only 9 words. It doesn't clarify the 'fenced' concept, how operations differ in required fields, or what the tool returns. The minimal description is inadequate for such a complex tool.

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

Parameters3/5

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

The schema already describes all 13 parameters with 100% coverage, so the description doesn't need to repeat that. However, the description adds no additional meaning about parameter relationships or operation-specific requirements, so it stays at the baseline of 3.

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

Purpose4/5

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

The description clearly states the tool's function with the verbs 'create, update, or delete' targeting a 'Coolify server'. However, the term 'fenced' is ambiguous and no differentiation from sibling tools like create_resource or get_servers is provided, so it's not a perfect 5.

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

Usage Guidelines2/5

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

The description provides no guidance on when to use this tool versus alternatives like create_resource or get_servers. There's no mention of required parameter combinations for each operation or any prerequisites, leaving usage context fully to the schema and agent inference.

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

manage_storageB

List, create, update, or delete persistent volume storage for an application, database, or service. For create/update, pass the storage fields in fields (create requires type and mount_path; also name, host_path, content, is_directory, fs_path).

ParametersJSON Schema
NameRequiredDescriptionDefault
typeYes
uuidYes
actionYes
fieldsNoStorage fields for create/update (create requires type and mount_path; also name, host_path, content, is_directory, fs_path), sent verbatim as the request body — any field the Coolify endpoint accepts is allowed.
confirmNoRequired for delete.
dry_runNo
instanceNoCoolify instance name (omit for the default).
fields_jsonNoJSON-encoded alternative to `fields` (mutually exclusive) for clients whose strict schema handling strips free-form object contents.
storage_uuidNoRequired for update and delete.

TDQS

B3.2/5.0
Behavior2/5

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

No annotations are provided, so the description must bear the full responsibility for behavioral disclosure. It states the tool can 'delete' storage, implying destructiveness, but it does not warn about permanence, permissions, or confirm requirements. It also omits the `dry_run` option and output behavior. This is a significant transparency gap for a mutating operation.

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

Conciseness5/5

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

The description is two sentences, front-loaded with the primary purpose, and the second sentence adds actionable field guidance. No wasted words.

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

Completeness2/5

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

The tool has 9 parameters and 4 actions, no output schema, and no annotations. The description covers core purpose and create/update field requirements, but omits critical context: return values, deletion semantics, how `dry_run` works, and the distinction between `fields` and `fields_json`. This is incomplete for an agent to confidently invoke all actions.

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

Parameters3/5

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

The description reinforces key parameter requirements: 'For create/update, pass the storage fields in `fields`' and lists required and optional subfields. While this mirrors the schema's description for `fields`, it brings the information to the top level. However, it does not elaborate on `confirm`, `dry_run`, `storage_uuid`, or `instance`, which the schema partially explains. Given 56% schema coverage, the description adds some but not enough compensation.

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

Purpose4/5

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

The description opens with a clear multi-verb statement: 'List, create, update, or delete persistent volume storage for an application, database, or service.' This identifies both the actions and the resource type. However, it does not explicitly differentiate this from sibling tools like create_resource or manage_env, so it loses a point on sibling distinction.

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

Usage Guidelines3/5

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

The description gives some situational guidance: it notes that create requires `type` and `mount_path`, and that storage fields go in `fields`. However, it doesn't explain when to choose this tool over alternatives, nor does it mention that deletion requires confirmation (only in the schema). Usage is implied rather than explicitly laid out.

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

provision_hetznerA

Provision a new server on Hetzner Cloud via Coolify (destructive — creates billable infrastructure). Requires --allow-destructive flag and confirm:true.

ParametersJSON Schema
NameRequiredDescriptionDefault
ipNoOverride the provisioned IP (advanced).
nameYesDisplay name for the new server.
portNoSSH port (default 22).
userNoSSH user (default root).
confirmNoMust be true to proceed.
dry_runNoPreview without provisioning.
instanceNoCoolify instance name (omit for the default).
locationYesHetzner datacenter location (e.g. nbg1). Use hetzner_inventory to browse.
descriptionNoOptional description.
coolify_tokenNoCoolify cloud token UUID for the account.
instant_validateNoValidate connectivity immediately.
private_key_uuidNoSSH private key UUID to install on the new server.
hetzner_api_tokenNoHetzner API token (if not configured server-side).
hetzner_server_typeYesHetzner server type (e.g. cx11). Use hetzner_inventory to browse.

TDQS

A4.1/5.0
Behavior4/5

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

With no annotations, the description carries the burden. It discloses that the action is destructive and creates billable infrastructure, along with required confirmation flags. This is significant, but it does not describe what happens after provisioning (e.g., return value, connectivity checks) or irreversible consequences beyond 'destructive'.

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

Conciseness5/5

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

Two sentences, front-loaded with the main purpose, followed by safety requirements. Every word earns its place with no filler.

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

Completeness3/5

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

This is a complex tool with 14 parameters and no output schema. The description covers the core purpose and safety gate, but it does not explain the provisioning workflow, what the response looks like, or how to use the hetzner_inventory sibling for browsing types/locations (which the schema property descriptions reference). It is minimally viable but lacks depth for such a complex operation.

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

Parameters3/5

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

Schema description coverage is 100%, so baseline is 3. The description adds context about the confirm parameter and the --allow-destructive flag, but this is already partially captured in the schema (confirm: 'Must be true to proceed'). No new parameter semantics are added beyond what the schema provides.

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

Purpose5/5

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

States clearly that it provisions a new server on Hetzner Cloud via Coolify, using a specific verb and resource. This distinguishes it from sibling tools like manage_server and hetzner_inventory, which handle existing servers or inventory.

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

Usage Guidelines4/5

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

Implies usage for creating new servers by the phrase 'Provision a new server' and provides explicit prerequisites (--allow-destructive flag and confirm:true). However, it does not explicitly contrast with alternatives like manage_server for existing servers, so it misses the 'when-not' guidance.

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

update_resourceA

Update configuration fields of an existing Coolify resource. FENCED: requires --allow-destructive and confirm:true (fields can rewrite deploy/start commands — a code-execution write). Pass the fields to change in fields (or fields_json); they are sent verbatim as the PATCH body. Applications commonly accept: name, description, domains (comma-separated URL list — NOT fqdn; dockercompose apps must use docker_compose_domains [{name, domain}] instead of domains), git_branch, build_pack, install_command, build_command, start_command, ports_exposes, base_directory, publish_directory, docker_registry_image_name, docker_registry_image_tag, pre_deployment_command, post_deployment_command, health_check_* settings, custom_docker_run_options, watch_paths. instant_deploy: true additionally queues an immediate redeploy after saving. Services accept only: name, description, instant_deploy, docker_compose_raw, connect_to_docker_network, urls [{name, url}], force_domain_override, is_container_label_escape_enabled.

ParametersJSON Schema
NameRequiredDescriptionDefault
typeYes
uuidYesThe Coolify UUID of the resource.
fieldsNoResource fields to update, sent verbatim as the request body — any field the Coolify endpoint accepts is allowed.
confirmNoMust be true to confirm the update (destructive: code-execution write).
dry_runNoIf true, preview which fields would be updated without performing the action.
instanceNoCoolify instance name (omit for the default).
fields_jsonNoJSON-encoded alternative to `fields` (mutually exclusive) for clients whose strict schema handling strips free-form object contents.

TDQS

A4.8/5.0
Behavior5/5

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

With no annotations, the description carries full burden, and it excels: it discloses the destructive code-execution write, the need for confirm:true, that fields are sent verbatim as the PATCH body, and that instant_deploy queues an immediate redeploy. It also highlights type-specific constraints, providing a clear behavioral profile.

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

Conciseness4/5

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

The description is dense but well-structured: it starts with the critical warning, then explains field passing, then details per-type accepted fields. It is longer than ideal but every sentence adds value. The use of lists and parentheticals aids readability. Slight deduction for length, but it is appropriately sized for the tool's complexity.

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

Completeness4/5

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

Given the tool's complexity (multiple resource types, 7 params, no output schema), the description covers a lot: usage, field lists, and type-specific rules. However, it omits guidance for databases (the third type) and does not mention what the response looks like or expected outcomes on success/failure. These gaps prevent a perfect score.

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

Parameters5/5

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

The schema covers 86% of parameters, but the description adds substantial meaning: it explains how `fields` works (verbatim PATCH body), the purpose of `fields_json` as an alternative for strict schema clients, and lists common field names with specifics (e.g., domains format, docker_compose_domains). This goes well beyond the schema's basic property descriptions.

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

Purpose5/5

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

The description clearly states the tool's purpose: 'Update configuration fields of an existing Coolify resource.' The verb 'update' and resource are specific, and it distinguishes from siblings like create_resource, delete_resource, and control_resource by focusing on configuration field updates. The resource types (applications, databases, services) are also noted.

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

Usage Guidelines5/5

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

Provides explicit when-to-use guidance: requires --allow-destructive and confirm:true, and explains the destructive nature (code-execution write). It also gives detailed field usage per resource type (applications vs services), clarifies common pitfalls (e.g., use docker_compose_domains instead of domains for dockercompose apps), and notes instant_deploy behavior. This is rich guidance beyond generic usage.

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.

  1. 22 tool updatesv0.3.0
    • First observedcancel_deployment
    • First observedcontrol_resource
    • First observedcreate_resource
    • First observeddelete_resource
    • First observeddeploy
    • First observeddeploy_watch
    • First observedget_deployments
    • First observedget_logs
    • First observedget_resource
    • First observedget_servers
    • First observedhetzner_inventory
    • First observedlist_instances
    • First observedlist_resources
    • First observedmanage_backups
    • First observedmanage_env
    • First observedmanage_keys
    • First observedmanage_projects
    • First observedmanage_scheduled_tasks
    • First observedmanage_server
    • First observedmanage_storage
    • First observedprovision_hetzner
    • First observedupdate_resource

TDQS

A3.6/5.0

Scored across 22 tools

Disambiguation4/5

Most tools are clearly separated by resource type (resources, deployments, storage, backups, env vars, servers, keys, projects, instances). However, deploy vs deploy_watch both trigger deployments with only blocking behavior differing, and get_servers vs list_instances could be confused, though descriptions help.

Naming Consistency3/5

Naming is mixed: verb_noun style (list_resources, create_resource, cancel_deployment) coexists with manage_* tools (manage_storage, manage_env, manage_projects) and unique names like control_resource, provision_hetzner. Snake_case is consistent, but the verb pattern is not uniform.

Tool Count4/5

22 tools is on the higher end, but Coolify is a broad platform covering resources, deployments, servers, projects, env vars, storage, backups, scheduled tasks, keys, and instances. Each tool earns its place, making the count appropriate for the scope.

Completeness4/5

The tool surface covers CRUD and lifecycle for most domains: resources, deployments, servers, projects, env vars, storage, backups, scheduled tasks, and keys. Minor gaps exist, such as no update_environment action and no single-deployment detail fetch (only list), but core workflows are supported.

Maintenance

ActivityMaintained
ResponsivenessNo issues

Related MCP Connectors

Related MCP Servers

  • A
    license
    B
    quality
    D
    maintenance
    MCP server that integrates with Coolify to let AI assistants manage Coolify instances via a clean toolkit wrapping the official REST API.
    35
    139 npm
    6
    MIT
  • A
    license
    B
    quality
    A
    maintenance
    MCP server for Coolify API that enables full deployment workflows from zero to production, including project, server, and application management.
    65
    73 npm
    3
    MIT
  • A
    license
    A
    quality
    A
    maintenance
    One MCP server to manage self-hosted Coolify instances: verify connectivity, discover servers, deploy applications, tail logs, diagnose incidents, and run emergency ops from any MCP client.
    19
    32 npm
    MIT