Manage Coolify from Claude, Cursor, or any MCP client: 44 consolidated tools for deploying, debugging, and operating your self-hosted PaaS in plain English.
$ npx -y skills add StuMason/coolify-mcp --agent claude-code
Run the curl in your terminal, the rest in Claude Code.
Repo: StuMason/coolify-mcp
What's inside
Manage Coolify from Claude, Cursor, or any MCP client: 44 consolidated tools for deploying, debugging, and operating your self-hosted PaaS in plain English.
📖 coolify-mcp.stumason.dev: what it does, how to install it, and why it is safe to point at production.
This README is the full reference: every tool, every gotcha, every parameter.
You need a running Coolify v4 instance and an API token (Coolify → Settings → API).
Claude Desktop, one-click: download coolify-mcp.mcpb and drag it into Settings → Extensions. You'll be prompted for your Coolify URL and token. No Node install, no JSON editing.
Claude Code:
claude mcp add coolify \
-e COOLIFY_BASE_URL="https://your-coolify-instance.com" \
-e COOLIFY_ACCESS_TOKEN="your-api-token" \
-- npx @masonator/coolify-mcp@latest
Any MCP client (JSON config):
{
"mcpServers": {
"coolify": {
"command": "npx",
"args": ["-y", "@masonator/coolify-mcp"],
"env": {
"COOLIFY_BASE_URL": "https://your-coolify-instance.com",
"COOLIFY_ACCESS_TOKEN": "your-api-token"
}
}
}
}
Behind Cloudflare Access or an auth proxy? Add --header "Key: Value" args (repeatable). The same config works in Cursor, Claude Code and any other MCP client, and can be repeated for multiple Coolify instances.
| Category | Tools |
|---|---|
| Infrastructure | get_infrastructure_overview, get_mcp_version, get_version, system (health, list_resources, enable/disable API) |
| Diagnostics | diagnose_app, diagnose_server, find_issues |
| Batch Operations | restart_project_apps, bulk_env_update, stop_all_apps, redeploy_project |
| Servers | list_servers, get_server, validate_server, server_resources, server_domains |
| Projects | projects (list, get, create, update, delete via action param) |
| Environments | environments (list, get, create, delete via action param) |
| Applications | list_applications, get_application, application (CRUD + delete_preview) |
| Databases | list_databases, get_database, database (create 8 types, delete), database_backups (CRUD schedules, executions incl. delete) |
| Services | list_services, get_service, service (create, update, delete, list_containers; per-container update_application + start/stop/restart_application, Coolify v4.2+) |
| Control | control (start/stop/restart for apps, databases, services) |
| Logs | logs (container logs for app, database, service; services need container), application_logs (superseded by logs) |
| Tags | tags (list, attach, detach for apps, databases, services; tag resources then deploy them together; Coolify v4.2+) |
| Env Vars | env_vars (CRUD + bulk_update for application, service, and database env vars) |
| Storages | storages (list, create, update, delete persistent/file storages for apps, databases, services) |
| Scheduled Tasks | scheduled_tasks (list, create, update, delete, list_executions, run_once for apps and services) |
| Deployments | list_deployments, deploy (incl. wait-to-terminal-status), deployment (get, cancel, list_for_app) |
| Private Keys | private_keys (list, get, create, update, delete via action param) |
| GitHub Apps | github_apps (list, get, create, update, delete, list_repos, list_branches) |
| Teams | teams (list, get, get_members, get_current, get_current_members) |
| Cloud Tokens | cloud_tokens (Hetzner/DigitalOcean: list, get, create, update, delete, validate) |
| Hetzner Cloud | hetzner (list_locations, list_server_types, list_images, list_ssh_keys, create_server) |
| Documentation | search_docs (full-text search across Coolify docs) |
Every tool takes an action parameter; run one with no arguments and it lists what it accepts.
list_* tools return uuid/name/status projections, 90–99% smaller than the raw API measured against a real 21-app estate. get_* tools fetch full detail for one resource.diagnose_app takes a UUID, name, or domain; diagnose_server takes a UUID, name, or IP._actions hints (view logs, restart, next page) so the assistant knows the logical next step without extra tokens.deploy with wait: true polls to a terminal status and returns a log tail on failure, instead of "the site returns 200 so it probably worked".Destructive operations pause and ask you, not the model, on clients that support elicitation: Claude Code and VS Code Copilot today. The prompt states the blast radius before you answer:
EMERGENCY STOP: take down 12 running applications
(api, worker, cockpit, umami, scheduler, mailer, search, billing and 4 more)
across 3 servers?
Confirmation is asked for on stop_all_apps, redeploy_project, restart_project_apps, system disable_api, application / database / service / project / environment deletes, the credential deletes (private_keys, cloud_tokens, github_apps, none recoverable from Coolify once gone), and bulk_env_update across more than three apps. Routine deletes (storages, scheduled tasks, individual env vars, backup schedules) deliberately stay unprompted: a dialog on every delete is how dialogs stop being read. Deleting a resource spells out whether its persistent volumes go with it. delete_volumes defaults to true upstream, so leaving the flag unset is the destructive choice, not the cautious one.
Prompts are skipped where there is nothing to confirm: an emergency stop on an idle estate, or a redeploy of an empty project, just runs.
This is progressive enhancement, not a new requirement: clients without elicitation support (Claude Desktop, claude.ai) behave exactly as before. Once a client does advertise support, a decline, a cancel or a timeout all abort the call.
These tools also carry the MCP destructiveHint annotation, so on a client that honours annotations and supports elicitation you may answer two dialogs in a row: the client's own permission prompt, then this one. That is the client's prompt plus the server's, not a bug. Allowlisting the tool in your client removes the first and leaves this one as the gate.
Set COOLIFY_MCP_ELICITATION=off to turn the confirmations off entirely. It exists for the case where a client advertises elicitation support but does not actually implement it. Without it, every guarded tool would return could not confirm with the user with no way to recover. It is an escape hatch, not a normal setting.
If confirmations time out before you can answer them, raise your client's MCP tool timeout. The prompt runs inside the tool call, and the MCP SDK's default request timeout is 60 seconds. The server aborts cleanly when the client gives up (nothing runs behind your back), but you will see the call fail rather than the dialog you were reading.
Secrets are masked at the API boundary. A client granted "list" access never sees plaintext credentials unless you explicitly opt in with reveal: true:
env_vars: variable values return as ***system list_resources (full mode): webhook HMAC secrets, basic-auth and database passwords, internal/external_db_url connection strings, compose bodies, Traefik labels, nested env varsget_database / get_service: the same credential fields are masked on the detail endpoints, and any embedded server row is projected down to uuid/name/ip so its sentinel token and log-drain config never leave the clientget_server: sentinel and log-drain credentials are always masked, with no revealprivate_keys: key material is never returned, with no reveal; name, fingerprint and public key identify a keydeployment get: the raw upstream payload (server settings, log-drain tokens, webhook secrets) never leaves the client; responses are projectedLog output (logs, application_logs, deployment logs) is wrapped in a tamper-evident untrusted-data boundary so a poisoned log line reads as data, not instructions.
Destructive operations also ask a human first; see Ask before it hurts above.
Works against Coolify v4.0 through v4.2+. Two v4.2 changes are worth knowing about:
reveal: true can return a variable with no value at all. That is the server withholding it, not a bug here; issue a token with sensitive-read scope if you need plaintext back.State-changing endpoints also moved from GET to POST in v4.2. The client handles this for you across both eras, so no action is needed.
Give me an overview of my infrastructure
Diagnose my stuartmason.co.uk app
Find any issues in my infrastructure
Deploy application {uuid} and wait for it to finish
Update the DATABASE_URL env var for application {uuid}
Create a staging environment in project {uuid}
Restart all applications in project {uuid}
How do I fix a 502 Bad Gateway error in Coolify?
git clone https://github.com/StuMason/coolify-mcp.git
cd coolify-mcp && npm install
npm run build && npm test
COOLIFY_BASE_URL="https://your-coolify.com" COOLIFY_ACCESS_TOKEN="token" node dist/index.js
Because tool descriptions are prompts, evals/ measures whether a model picks the right tool from this surface and whether attacker-controlled tool output can make it misbehave. Deterministic contract snapshots gate every PR; tool-selection and prompt-injection evals run a real model against a mock Coolify backend; a promptfoo red-team battery runs on a schedule. Nothing touches production. See evals/README.md.
Contributions welcome; see CONTRIBUTING.md and the architecture notes in CLAUDE.md.
I'm Stu Mason. I build MCP servers, AI integrations and agentic systems for agencies, SMEs and enterprise. This repo is what that work looks like in the open.
White-label under your own name if you're an agency. And if a job doesn't need AI, I'll say so before anyone's paid for anything.
📮 hey@stumason.dev · stumason.dev · coolify-mcp.stumason.dev
io.github.StuMason/coolifyMIT © Stu Mason. If this is useful, ⭐ the repo.
.claude/
commands/
smoke-test.md
.dockerignore
.github/
CODEOWNERS
dependabot.yml
ISSUE_TEMPLATE/
bug_report.yml
config.yml
feature_request.yml
PULL_REQUEST_TEMPLATE.md
workflows/
ci.yml
claude-code-review.yml
claude.yml
dependabot-auto-merge.yml
evals.yml
hidden-agenda.yml
openapi-drift.yml
publish.yml
redteam.yml
site.yml
.gitignore
.husky/
pre-commit
.lintstagedrc.json
.markdownlint-cli2.jsonc
.mcpbignore
.prettierignore
.prettierrc
CHANGELOG.md
CLAUDE.md
CONTRIBUTING.md
Dockerfile
Dockerfile.docs
docs/
coolify-openapi.yaml
openapi-chunks/
applications-api.yaml
cloud-providers-api.yaml
databases-api.yaml
deployments-api.yaml
destinations-api.yaml
private-keys-api.yaml
projects-api.yaml
resources-api.yaml
schemas.yaml
servers-api.yaml
services-api.yaml
tags-api.yaml
teams-api.yaml
untagged-api.yaml
eslint.config.js
evals/
.gitignore
.prettierignore
eslint.config.js
FINDINGS.md
package-lock.json
package.json
README.md
redteam.ts
redteam.yaml
src/
contract/
__toolsnaps__/
_roster.json
application_logs.json
application.json
bulk_env_update.json
cloud_tokens.json
control.json
database_backups.json
database.json
deploy.json
deployment.json
diagnose_app.json
diagnose_server.json
env_vars.json
environments.json
find_issues.json
get_application.json
get_database.json
get_infrastructure_overview.json
get_mcp_version.json
get_server.json
get_service.json
get_version.json
github_apps.json
hetzner.json
list_applications.json
list_databases.json
list_deployments.json
list_servers.json
list_services.json
logs.json
private_keys.json
projects.json
redeploy_project.json
restart_project_apps.json
scheduled_tasks.json
search_docs.json
server_domains.json
server_resources.json
service.json
stop_all_apps.json
storages.json
system.json
tags.json
teams.json
validate_server.json
toolsnaps.test.ts
fixture/
data.ts
server.ts
harness/
agent.ts
mcp.ts
injection/
prompt-injection.eval.ts
selection/
tool-selection.eval.ts
tsconfig.json
vitest.config.ts
jest.config.js
LICENSE
manifest.json
package-lock.json
package.json
README.md
scripts/
__tests__/
check-client-spec-drift.test.ts
split-openapi-chunks.test.ts
check-client-spec-drift.mjs
split-openapi-chunks.mjs
sync-manifests.mjs
server.json
site/
.gitignore
.prettierignore
.prettierrc.json
astro.config.mjs
og-card.html
package-lock.json
package.json
public/
favicon.svg
og.png
robots.txt
src/
data/
tools.ts
layouts/
Base.astro
pages/
api/
contact.ts
index.astro
test/
contact.test.ts
tsconfig.json
skills/
coolify/
SKILL.md
src/
__tests__/
coolify-client.test.ts
docs-search.test.ts
elicitation.test.ts
integration/
diagnostics.integration.test.ts
docs-search.integration.test.ts
helpers.ts
logs.integration.test.ts
smoke.integration.test.ts
tags.integration.test.ts
v42-compat.integration.test.ts
manifests.test.ts
mcp-server.test.ts
parse-headers.test.ts
index.ts
lib/
coolify-client.ts
docs-search.ts
elicit.ts
mcp-server.ts
parse-headers.ts
types/
coolify.ts
tsconfig.jsonFAQ
coolify-mcp is a Claude Code plugin with 1 hand-picked skill for deployment work, indexed on Flowy. Install it with the command on its page. It includes coolify. Its skills do not fire on their own yet. Request auto-invocation to have Flowy route them as you prompt. Free and open source.