Skip to main content
Glama
coolify-mcp
by amintt2

coolify-mcp

Let your AI agent run your self-hosted Coolify: create apps from git, manage env vars safely, deploy, restart and read logs.

CI License: MIT

An MCP server for the Coolify v4 REST API. Works with Claude Code, Claude Desktop, Cursor, VS Code, Windsurf and any other stdio MCP client. No install step: your client runs it with npx -y github:amintt2/coolify-mcp.

Website and config generator: https://amintt2.github.io/coolify-mcp/ (type your Coolify URL, pick your client, copy the snippet or click Add to Cursor / Add to VS Code).

Why this one

  • Secrets are masked by default. list_envs shows post*** (41 chars), not your database password. Plaintext needs reveal: true in the call and COOLIFY_ALLOW_REVEAL=1 on the server, so an agent can't decide on its own to read them.

  • Dry runs. set_envs, delete_env, create_application and update_application take dry_run: true and report what would change (per key, per field, or the exact create request) without touching anything. Env values are never echoed back.

  • Create, but never delete apps. create_application sets up an app from a public repo, a GitHub App or a deploy key; update_application changes a short allow-list of settings. There is deliberately no tool that deletes an application.

  • Read-only mode. COOLIFY_READ_ONLY=1 refuses every mutating tool. Good for "look but don't touch" sessions.

  • Coolify quirks handled. Coolify's bulk env endpoint silently resets is_literal, is_multiline and is_shown_once when they are omitted, so set_envs resends the current flags for each key it updates. It also sends both the current is_buildtime flag and the older beta name is_build_time.

  • Human references. Point at an app by uuid, name or part of its domain ("api", "shop.example.com"). Ambiguous references fail and list the candidates instead of guessing.

  • Token hygiene. The token is never logged and is redacted from every error message.

Related MCP server: Coolify MCP Server

Quick start

You need Node.js 20+ and git (npx fetches the server from GitHub on first run), plus a Coolify v4 instance.

1. Enable the API

Coolify → Settings → Advanced → turn on API Access. If Allowed IPs is set there, add the IP of the machine that will run the MCP server (your laptop, usually).

2. Create a token

Coolify → Keys & Tokens → API tokens → Create. The token is scoped to the team you are in. Recommended permissions:

Permission

Needed for

read

Listing, env keys and flags, deployments, app logs. The minimum.

read:sensitive

Env values (to mask them and to tell unchanged from updated) and deployment logs. Values reach this server and are masked before they reach the agent.

write

set_envs, delete_env, create_application, update_application

deploy

deploy, start_application, stop_application, restart_application, restart_service, create_application with instant_deploy: true

Don't use root. For an inspection-only setup, give read (+ read:sensitive) and run with COOLIFY_READ_ONLY=1. Only team admins and owners can create tokens with write, deploy or read:sensitive.

3. Add it to your client

Replace https://coolify.example.com with your instance and <YOUR_COOLIFY_TOKEN> with the token.

claude mcp add coolify --scope user \
  -e COOLIFY_URL="https://coolify.example.com" \
  -e COOLIFY_TOKEN="<YOUR_COOLIFY_TOKEN>" \
  -- npx -y github:amintt2/coolify-mcp

Add -e COOLIFY_READ_ONLY=1 or -e COOLIFY_ALLOW_REVEAL=1 to turn those on. Check with claude mcp list.

Edit claude_desktop_config.json (Settings → Developer → Edit Config), at ~/Library/Application Support/Claude/claude_desktop_config.json on macOS or %APPDATA%\Claude\claude_desktop_config.json on Windows:

{
  "mcpServers": {
    "coolify": {
      "command": "npx",
      "args": ["-y", "github:amintt2/coolify-mcp"],
      "env": {
        "COOLIFY_URL": "https://coolify.example.com",
        "COOLIFY_TOKEN": "<YOUR_COOLIFY_TOKEN>"
      }
    }
  }
}

Restart Claude Desktop. If it can't find npx (common with nvm), use the absolute path from which npx.

One click: use the Add to Cursor button on the website, or open this deeplink (it installs with placeholder values; edit the token afterwards in Settings → MCP):

cursor://anysphere.cursor-deeplink/mcp/install?name=coolify&config=eyJjb21tYW5kIjoibnB4IiwiYXJncyI6WyIteSIsImdpdGh1YjphbWludHQyL2Nvb2xpZnktbWNwIl0sImVudiI6eyJDT09MSUZZX1VSTCI6Imh0dHBzOi8vY29vbGlmeS5leGFtcGxlLmNvbSIsIkNPT0xJRllfVE9LRU4iOiI8WU9VUl9DT09MSUZZX1RPS0VOPiJ9fQ%3D%3D

The config parameter is the base64 of the server JSON ({"command": ..., "args": ..., "env": ...}).

Or by hand, in ~/.cursor/mcp.json (global) or .cursor/mcp.json (project):

{
  "mcpServers": {
    "coolify": {
      "command": "npx",
      "args": ["-y", "github:amintt2/coolify-mcp"],
      "env": {
        "COOLIFY_URL": "https://coolify.example.com",
        "COOLIFY_TOKEN": "<YOUR_COOLIFY_TOKEN>"
      }
    }
  }
}

From a terminal:

code --add-mcp '{"name":"coolify","type":"stdio","command":"npx","args":["-y","github:amintt2/coolify-mcp"],"env":{"COOLIFY_URL":"https://coolify.example.com","COOLIFY_TOKEN":"<YOUR_COOLIFY_TOKEN>"}}'

Or per workspace in .vscode/mcp.json, where VS Code prompts for the token once and stores it securely:

{
  "inputs": [
    { "type": "promptString", "id": "coolify-token", "description": "Coolify API token", "password": true }
  ],
  "servers": {
    "coolify": {
      "type": "stdio",
      "command": "npx",
      "args": ["-y", "github:amintt2/coolify-mcp"],
      "env": {
        "COOLIFY_URL": "https://coolify.example.com",
        "COOLIFY_TOKEN": "${input:coolify-token}"
      }
    }
  }
}

The website also has an Add to VS Code button (vscode:mcp/install?...).

Edit ~/.codeium/windsurf/mcp_config.json (Windsurf Settings → Cascade → MCP servers → View raw config):

{
  "mcpServers": {
    "coolify": {
      "command": "npx",
      "args": ["-y", "github:amintt2/coolify-mcp"],
      "env": {
        "COOLIFY_URL": "https://coolify.example.com",
        "COOLIFY_TOKEN": "<YOUR_COOLIFY_TOKEN>"
      }
    }
  }
}

Command npx, arguments -y github:amintt2/coolify-mcp, environment COOLIFY_URL and COOLIFY_TOKEN:

{
  "command": "npx",
  "args": ["-y", "github:amintt2/coolify-mcp"],
  "env": {
    "COOLIFY_URL": "https://coolify.example.com",
    "COOLIFY_TOKEN": "<YOUR_COOLIFY_TOKEN>"
  }
}

To run from a local clone instead: npm install (builds dist/ via prepare), then use node /path/to/coolify-mcp/dist/index.js as the command.

Then ask your agent something like "Which Coolify apps are unhealthy?", "Set LOG_LEVEL=debug on the api app, dry run first", "Create an app for acme/landing on the Marketing project, static, served at https://acme.com" or "Redeploy the web app and show me the build log".

The first launch takes a little longer: npx clones the repo and compiles it once, then caches it.

Tools

20 tools. Every tool that takes an application or service accepts a uuid, the exact name, or a unique part of the name or domain. Projects and servers are resolved the same way (uuid or name).

Area

Tool

What it does

Discovery

get_version

Coolify version, health, API base in use, read-only / reveal flags. Call first when something fails.

list_projects

Projects and their environments

list_servers

Servers, IPs, reachability, proxy type

list_applications

Name, uuid, fqdn, status, git repo/branch, project/environment (filter optional)

get_application

One application's details, secrets stripped

list_services

One-click / compose services (filter optional)

list_databases

Standalone databases, no credentials

Apps

create_application

Create an app from a git repo: public, private via GitHub App (github_app) or deploy key (private_key_uuid); dry_run, instant_deploy

update_application

Change name, description, domains, branch, build pack, ports, base/publish directory, install/build/start commands, health check path; only changed fields are sent; dry_run

Env vars

list_envs

Keys, uuids and flags of an app or service, values masked (key_filter, reveal)

set_envs

Upsert up to 200 {key, value, is_build_time?, is_runtime?, is_preview?, is_literal?, is_multiline?} in one call; dry_run

delete_env

Delete a key (is_preview selects the preview copy); dry_run

Lifecycle

deploy

Deploy by resource (uuid/name, comma-separated) or Coolify tag; force rebuilds without cache

restart_application

Restart containers without rebuilding (picks up runtime env changes)

start_application

Start a stopped app (force, instant_deploy)

stop_application

Stop an app (docker_cleanup)

restart_service

Restart a service, optionally pulling latest images

Observability

list_deployments

Recent deployments of an app, or everything queued / in progress

get_deployment

Status plus the last N build/deploy log lines (default 100)

get_application_logs

Last N container log lines of a running app

Env changes apply after a restart (runtime variables) or a redeploy (build-time variables). set_envs says which in its result. Mutating tools carry MCP destructiveHint / readOnlyHint annotations so clients can ask before running them.

Creating and updating applications

create_application needs a project and a repository; everything else has a default.

// Public GitHub repo, static site, custom domain. Dry run first to see the exact request.
{
  "project": "Marketing",               // uuid or name (list_projects)
  "environment": "production",          // default; must already exist in the project
  "server": "localhost",                // optional when only one server can host apps
  "git_repository": "acme/landing",     // owner/repo, https://host/owner/repo or git@host:owner/repo.git
  "git_branch": "main",                 // default
  "build_pack": "static",               // nixpacks (default) | static | dockerfile | dockercompose | railpack
  "publish_directory": "/dist",
  "domains": "https://acme.com,https://www.acme.com",
  "dry_run": true
}

The result carries the new uuid and next steps: set_envs on that uuid, then deploy (or pass instant_deploy: true, which needs the token's deploy permission). ports_exposes defaults to 80 for static / dockercompose and 3000 otherwise. Without domains, Coolify 4.0.0+ generates one (server wildcard domain or sslip.io).

Private repositories:

  • GitHub App: "github_app": "my-org-app" (uuid or name of a GitHub App registered in Coolify). The repo is sent as owner/repo.

  • Deploy key: "private_key_uuid": "<uuid>" (Coolify: Keys & Tokens → Private Keys; add the public key to the repo as a deploy key). The repo is sent as git@host:owner/repo.git. Keys are referenced by uuid only: listing them would pull private key material through this server.

update_application takes an application reference plus any of name, description, domains, git_branch, build_pack, ports_exposes, publish_directory, base_directory, install_command, build_command, start_command, health_check_path (null clears description and commands). It compares with the current values, PATCHes only what differs and returns each change as from → to:

{ "application": "landing", "domains": "https://acme.com", "start_command": "node server.js", "dry_run": true }

Changes apply on the next deploy. Domain conflicts with another resource come back as an error naming that resource; this server does not expose Coolify's force_domain_override.

Configuration

Variable

Required

Meaning

COOLIFY_URL

yes

Instance URL, e.g. https://coolify.example.com. A trailing slash or /api/v1 is stripped; /api/v1 is added.

COOLIFY_TOKEN

yes

API token (sent as Authorization: Bearer).

COOLIFY_READ_ONLY

no

1 refuses every mutating tool. Dry runs are still allowed.

COOLIFY_ALLOW_REVEAL

no

1 lets list_envs return plaintext when called with reveal: true. Off by default.

COOLIFY_TIMEOUT_MS

no

Per-request timeout in ms. Default 30000.

npx -y github:amintt2/coolify-mcp --help prints the same list.

Security notes

  • The server runs locally over stdio. It talks only to your COOLIFY_URL; there is no telemetry and no other network access.

  • Your token lives in your MCP client's config. Prefer a client that stores secrets securely (VS Code inputs), keep config files out of git, and scope the token to the permissions you actually want the agent to have.

  • With read:sensitive, env values are fetched from Coolify so they can be compared and masked, but they are not returned to the agent unless you enabled COOLIFY_ALLOW_REVEAL=1 and the agent asked for reveal: true.

  • Service and database listings strip credentials; application details strip webhook secrets and basic-auth passwords.

  • stop_application and delete_env are marked destructive. Use COOLIFY_READ_ONLY=1 when you only want answers.

  • There is no tool to delete applications, services or databases, on purpose. update_application can only touch the fields listed above (no secrets, limits, labels or compose files).

  • Anything the agent reads (app names, logs) is still shown to your model provider. Don't reveal secrets you wouldn't paste into a chat.

Found a vulnerability? Please open a private security advisory rather than a public issue.

Coolify API notes

  • PATCH /{applications|services}/{uuid}/envs/bulk with {"data": [...]} is an upsert. On applications it resets is_literal, is_multiline and is_shown_once when they are omitted, so set_envs sends the current flags for every key it updates.

  • The build-time flag is is_buildtime (with is_runtime) on current Coolify and is_build_time on older betas. set_envs sends both; the endpoint ignores the one it doesn't know.

  • Service env vars have no preview or build-time flags. Coolify trims values and stores an empty value as null.

  • Applications are created with POST /applications/public, /applications/private-github-app or /applications/private-deploy-key and updated with PATCH /applications/{uuid}. Coolify answers 422 "This field is not allowed." for any unknown key, so the server sends only fields that every v4 version accepts: environment_name rather than environment_uuid (4.0.0-beta.400+), no autogenerate_domain / is_spa (4.0.0+). The railpack build pack needs Coolify 4.1.0+. GET /github-apps (to resolve a GitHub App by name) needs 4.0.0+; on older versions pass its uuid.

  • Coolify rejects domains on dockercompose applications (domains are set per compose service), so both tools refuse it up front. Domain conflicts come back as 409 (Coolify 4.0.0-beta.434+) and are reported with the resource that owns the domain.

  • Application env listings include preview copies: the same key can exist once as a main copy and once as a preview copy (is_preview).

Contributing

Issues and pull requests are welcome.

git clone https://github.com/amintt2/coolify-mcp && cd coolify-mcp
npm install     # also builds dist/ through the prepare script
npm test        # build, then node:test unit tests + an MCP stdio smoke test against an in-process mock Coolify
npm run dev     # tsc --watch

Tests never talk to a real Coolify. When you add a tool, add it to the mock in test/mock-coolify.ts, cover it in test/tools.test.ts and update the tool list in test/smoke.test.ts, this README and docs/index.html.

To try a local build in Claude Code: claude mcp add coolify-dev -e COOLIFY_URL=... -e COOLIFY_TOKEN=... -- node "$PWD/dist/index.js".

License

MIT © Tahar Amin. Not affiliated with Coolify.

Available Tools

20 tools
create_applicationCreate application from a git repositoryA

Create a Coolify application from a git repository. Public repos by default; a private repo needs either github_app (a GitHub App registered in Coolify) or private_key_uuid (a deploy key stored in Coolify: Keys & Tokens -> Private Keys). project and server accept a uuid or name (see list_projects / list_servers); server may be omitted when only one server can host apps. Nothing is built unless instant_deploy: true (needs the token's deploy permission). Use dry_run: true to see the exact request first. Returns the new application's uuid and next steps (set_envs, then deploy).

Inputs: project (required), git_repository (required), name, server, +18 more.

delete_envDelete an environment variableA
Destructive

Delete one environment variable from an application or service, by key. For applications, is_preview selects the preview copy (default: the main one). Use dry_run to check first. Takes effect after a restart/redeploy.

Inputs: key (required), resource (required), dry_run, is_preview, +1 more.

deployDeployA

Queue a (re)deployment — rebuilds and restarts. Target either resource (application/service uuid or name; comma-separate several) or tag (every resource with that Coolify tag). force: true rebuilds without cache. Returns deployment uuids; follow progress with get_deployment. Needs the token's deploy permission.

Inputs: tag, force, resource.

get_applicationGet applicationA
Read-only

Get one application's details (domains, status, git, build/start commands, ports, health check, limits, project/environment). Accepts a uuid, exact name, or a unique name/domain substring; errors with the candidates when ambiguous. Secrets (webhook secrets, basic-auth password, compose files) are never returned.

Inputs: application (required).

get_application_logsGet application logsA
Read-only

Last lines lines (default 100) of a running application's container logs. Fails with a clear message if the app is not running.

Inputs: application (required), lines, show_timestamps.

get_deploymentGet deploymentA
Read-only

Status of one deployment plus the last lines lines of its build/deploy log (default 100). Log output requires the token's read:sensitive permission.

Inputs: deployment_uuid (required), lines.

get_versionCoolify version and healthA
Read-only

Check connectivity: returns the Coolify version, the health endpoint result, the API base URL in use and whether this MCP server is read-only / allows revealing secrets. Call this first when other tools fail.

Inputs: no named parameters.

list_applicationsList applicationsA
Read-only

List applications with name, uuid, domain(s) (fqdn), status (e.g. running:healthy, exited), git repo/branch, build pack, project and environment. Use filter to narrow by name/domain substring.

Inputs: filter.

list_databasesList databasesA
Read-only

List standalone databases (name, uuid, type, status, public exposure, project/environment). Connection URLs and passwords are never returned.

Inputs: no named parameters.

list_deploymentsList deploymentsA
Read-only

With application: that app's most recent deployments (newest first, status/commit/timestamps). Without it: deployments currently queued or in progress across all servers.

Inputs: limit, application.

list_envsList environment variablesA
Read-only

List the environment variables of an application or service: key, uuid and flags (is_build_time, is_runtime, is_preview, is_literal, is_multiline, is_shown_once). Values are MASKED (short prefix + length, or "(empty)") so secrets stay out of the conversation. reveal: true returns plaintext only if the server was started with COOLIFY_ALLOW_REVEAL=1 — avoid it unless the user explicitly needs a value.

Inputs: resource (required), reveal, key_filter, resource_type.

list_projectsList projectsA
Read-only

List Coolify projects with their environments (e.g. production, staging).

Inputs: no named parameters.

list_serversList serversA
Read-only

List servers attached to Coolify with IP, reachability and proxy type.

Inputs: no named parameters.

list_servicesList servicesA
Read-only

List one-click / docker-compose services (name, uuid, type, status, project/environment).

Inputs: filter.

restart_applicationRestart applicationA

Restart an application's containers without rebuilding (picks up runtime env var changes; build-time changes need deploy). Returns a deployment uuid to follow with get_deployment.

Inputs: application (required).

restart_serviceRestart serviceA

Restart a service (all its containers), e.g. after changing its env vars. latest: true pulls the latest images first.

Inputs: service (required), latest.

set_envsCreate or update environment variablesA
Idempotent

Upsert one or many environment variables on an application or service in a single call: existing keys are updated, missing keys created, identical ones left alone. Returns per key created / updated / unchanged plus which fields changed — values are never echoed. Flags you omit keep their current value on update. For applications, the main and preview copies of a key are separate (use is_preview). Use dry_run to preview. Changes only take effect after restart_application / restart_service, or deploy for build-time variables.

Inputs: envs (required), resource (required), dry_run, resource_type.

start_applicationStart applicationB

Start (deploy) a stopped application. force rebuilds without cache; instant_deploy skips the queue.

Inputs: application (required), force, instant_deploy.

stop_applicationStop applicationA
Destructive

Stop an application's containers (the site goes down until start_application or deploy). docker_cleanup (Coolify default true) prunes networks/volumes afterwards.

Inputs: application (required), docker_cleanup.

update_applicationUpdate application settingsA
Idempotent

Change a safe subset of an application's settings: name, description, domains, git_branch, build_pack, ports_exposes, publish_directory, base_directory, install/build/start commands, health_check_path. Only fields that actually differ are sent; returns each change as from -> to. Nothing else (secrets, limits, compose files) can be touched. Use dry_run: true to preview. Changes apply on the next deploy (domains need a redeploy or restart for the proxy labels).

Inputs: application (required), name, domains, dry_run, +10 more.

Tool Schema Changelog

Recent tool additions, removals, and schema changes observed during successful MCP inspections.

Loading tool schema changelog…

    TDQS

    A3.8/5.0

    Scored across 20 tools

    Disambiguation4/5

    Tools are largely distinct by resource and action, with clear boundaries for get/list/create/update/restart/start/stop. Minor overlap exists between deploy and start_application (both trigger deployment) and between restart_application and deploy for applying changes, but descriptions clarify the intended use.

    Naming Consistency4/5

    Nearly all tools follow a snake_case verb_noun pattern (get_, list_, create_, update_, set_, delete_, restart_, start_, stop_). Minor deviations: env vs envs across list_envs/set_envs/delete_env, and deploy is a verb without a noun.

    Tool Count4/5

    20 tools is appropriate for a Coolify management server spanning applications, deployments, envs, services, databases, projects, and servers. It is slightly on the high side but each tool maps to a distinct operation rather than being redundant.

    Completeness3/5

    Core application lifecycle (create/update/start/stop/restart/logs), env management, and deployment tracking are covered. However delete_application is missing, and services/databases/projects/servers have only read or restart operations—no create/update/delete/get for services or databases, creating significant dead ends for full platform management.

    Maintenance

    ActivitySlowing
    ResponsivenessOutdated data

    Related MCP Connectors

    Related MCP Servers

    • A
      license
      A
      quality
      D
      maintenance
      Enables AI assistants to interact with Coolify self-hosted instances for application deployment, management, and monitoring. Features 4 unified tools optimized for VS Code's limits, covering app management, environment configuration, system administration, and built-in documentation.
      4
      416 npm
      1
      MIT
    • A
      license
      Not graded
      quality
      D
      maintenance
      Enables AI agents to deploy and manage applications on Coolify through structured tools, supporting project management, app lifecycle control, pre-configured templates, and deployment monitoring with built-in safety guardrails.
      416 npm
      3
      MIT
    • A
      license
      B
      quality
      C
      maintenance
      Enables control and management of Coolify self-hosted PaaS instances, allowing you to deploy applications, manage databases, monitor servers, and execute operations directly from AI assistants.
      89
      11 npm
      28
      MIT
    • A
      license
      B
      quality
      D
      maintenance
      Enables management of Coolify instances to control applications, databases, and servers through the Model Context Protocol. It provides a comprehensive set of tools for deploying services and monitoring self-hosted infrastructure using natural language.
      18
      15 npm
      3
      MIT