Coolify ships a built-in MCP server with its self-hosted PaaS. Enable it in Settings, point your agent at /mcp, and it can inspect your infrastructure in plain English. One of the most popular community alternatives describes that built-in server, flatly, as "a raw pass-through" — and then spends its entire architecture fixing the gap: operation modes, scoped tokens, allowlists, production safeguards.
That sentence is the whole story. A platform vendor shipped the protocol — tools over MCP, working transport, working auth — and the community had to ship the policy: everything that decides what an agent is allowed to do, when a human must approve, and what gets recorded. The result is a two-layer outcome no one planned, and it is the clearest field evidence we have for what a governed agent interface on a self-hosted PaaS must contain. Here it is in one table.
The two-layer outcome, in one table
| Control | Coolify built-in /mcp | StuMason/coolify-mcp | hecateq/mcp-coolify |
|---|---|---|---|
| Tool scope | 10 read-only tools, one instance, one team | 42+ tools (now 46), reads + writes, fleet mode | 42 tools, reads + writes |
| Operation modes | None (read-only by design) | Read-only mode hides unregistered tools' prompts | read-only (default), deploy-only, safe-write |
| Token scoping | One team-scoped API token | Token stays server-side in remote mode; clients use OAuth 2.1 | 5 scoped tokens: read, sensitive-read, write, deploy, fallback |
| Before a destructive call | Not applicable (no writes) | Asks the human in-client via elicitation, naming the blast radius; fails closed over HTTP | Mode + allowlists gate the call before it reaches the API |
| Secret handling | Coolify-native RBAC only | Secrets masked at the API boundary; logs wrapped as untrusted data | Host paths redacted; token-management endpoints deliberately unimplemented |
| Audit trail | Whatever Coolify logs | One JSON line per tool call and per refusal, with OAuth client id | Policy denials enforced at the boundary |
| Remote auth | Streamable HTTP + Sanctum token | Streamable HTTP + OAuth 2.1, runs as a container inside Coolify | Local stdio server |
Every row in that table is a design decision the vendor left out and the ecosystem put back. The rest of this post walks the three columns, then turns them into a checklist any PaaS building deploy-from-chat from scratch can use on day one.
What the vendor shipped: 10 read-only tools and a token
Coolify's built-in MCP server arrived with v4.1 (PR #9862), implemented on Laravel MCP and served at the instance's own /mcp endpoint behind auth:sanctum middleware. There is an instance-level toggle plus a per-team switch, and the tool list is exactly ten read-only calls: get_infrastructure_overview, list_servers, get_server, list_projects, list_applications, get_application, list_databases, get_database, list_services, get_service.
That is a reasonable v1. It is also, structurally, a pass-through: one team-scoped token in, raw API-shaped answers out. There are no writes (Coolify documents the server as read-only with writes planned, and PR #11000 would expand coverage considerably), no modes, no per-operation scoping, no approval step. For a single instance, a single team, and read-only questions, even the community authors say to use it — Stu Mason's README recommends the built-in outright for that shape, calling it "the shortest path" with the real advantage that no third-party code ever holds your token.
The limitation is not quality, it is scope. The moment an agent needs to do something — deploy, restart, rotate an env var — read-only stops being a safety property and starts being a missing feature. And the moment it can do something, "one token with the team's full power" stops being simplicity and starts being a blast radius. Both community servers exist because of that second moment.
What the community added, control by control
The two governed servers took different routes up the same mountain, which is precisely what makes the pair instructive. Their overlap is the consensus; their differences are the design space.
StuMason/coolify-mcp: writes with a human gate. The project exposes 42 token-optimized tools at v2 (mid-40s by v3, with 46 in the current README) covering deploy, rollback, env vars, databases across 8 engines, and estate-wide operations like redeploy_project and stop_all_apps. Three governance choices stand out.
First, destructive operations stop and ask the human in their own client using MCP elicitation, stating the blast radius — and in remote HTTP mode, where there may be no human to ask, the guard fails closed. Second, secrets are masked at the API boundary (plaintext only for one exact key on request), log output is wrapped as untrusted data so a poisoned log line cannot inject instructions, and an eval suite red-teams both claims on every change. Third, v3.0.0 (shipped August 22, 2026) added a remote mode: the server runs as a container inside the Coolify it manages, serves Streamable HTTP behind OAuth 2.1, and the Coolify token never leaves the server. On top of all that, every tool call and every refusal is audit-logged as one JSON line with tool, action, resource UUIDs, outcome, duration, and — in HTTP mode — the OAuth client id.
hecateq/mcp-coolify: policy before the API. Where StuMason governs at the moment of action, hecateq governs at the boundary. The server defaults to read-only mode, with deploy-only and safe-write as explicit escalations. Instead of one master token it takes five scoped tokens — COOLIFY_READ_TOKEN, COOLIFY_SENSITIVE_TOKEN (env vars, logs), COOLIFY_WRITE_TOKEN, COOLIFY_DEPLOY_TOKEN, and a fallback full-access token — and selects the least-privilege token per operation.
Access is further constrained by allowlists on project, environment, and resource UUIDs, plus field-level allowlists on config updates (only known-safe fields like replicas or memory_limit pass; anything else is dropped or rejected). Sensitive surfaces are redacted, and the capability matrix shows API-token management endpoints deliberately unimplemented: the agent can never mint, read, or rotate the credentials that authorize it. That last choice is the purest expression of the policy mindset — a capability removed is a control that cannot fail.
Note what neither project re-invented: transport. Both ride the spec — stdio locally, Streamable HTTP remotely (standardized March 2025), OAuth 2.1 for remote authorization (the spec's auth basis since June 2025, recommended for remote servers since November 2025). The community's energy went entirely into policy, because the protocol was already fine.
Why this keeps happening: the protocol/policy split
This is not a two-project anecdote. Scan the rest of the Coolify agent-tooling ecosystem and every entry re-invents governance, not transport. NohchiyBors/coolify-mcp-server wraps the v4 HTTP API as 72 typed tools. devrim-1283/coolify-mcp goes fleet-level — multiple instances and teams from one connection — precisely because the built-in is "bound to a single team" and the established servers wrap one instance per process. coriou/coolify-harness-api sidesteps MCP entirely with a safe CLI and typed library that defaults to dry-run and audits env access keys-only.
The pattern is consistent enough to state as a rule: a vendor's agent interface ships the protocol, and the blast radius ships later, built by whoever got burned first. Each fork adds the control its author needed — modes, gates, redaction, dry-run — and none of them interoperate, because policy invented downstream has no shared vocabulary. That is the real cost of the two-layer outcome: not that governance exists in two places, but that it exists in five, each with its own configuration dialect, each maintained by whoever needed it that month.
There is a second, quieter lesson in StuMason's README. It contains a comparison table against the built-in server and the official CLI, and it tells a defined segment of readers not to use it. That honesty is load-bearing for trust: an agent interface that admits where it does not belong is one an operator can reason about. Vendors writing their own MCP docs should steal the move.
The launch-governed checklist: 7 controls to ship on day one
If you are designing deploy-from-chat for a self-hosted PaaS from scratch, the Coolify ecosystem has already run the experiment. Ship these seven controls with the first version, not the third:
- Least-privilege token scopes. Separate read, sensitive-read, write, and deploy credentials (hecateq's five-token model), so a diagnostics agent never holds deploy power.
- Operation modes.
read-onlyby default, with named escalations likedeploy-onlyandsafe-write— a coarse switch an operator can set without reading tool docs. - Human approval gates that fail closed. Destructive calls ask in-client with the blast radius stated (elicitation), and headless/remote paths default to refusal, not to silent execution.
- Secret masking plus untrusted-output wrapping. Mask at the API boundary, and treat tool output (logs especially) as data, never as instructions.
- Audit every call and every refusal. One structured line per action with actor identity — including the OAuth client id for remote calls — so incidents are reconstructible.
- Resource allowlists. Scope the server to named projects, environments, or resources, so one agent connection cannot wander the whole estate.
- OAuth 2.1 remote with server-side tokens. Remote clients authenticate as OAuth clients; the platform token never leaves the server boundary.
Each item maps to something the Coolify community built after the fact. That is the argument for building them before: the demand is proven, the designs are public, and the only thing repeating the two-layer outcome buys is a year of fragmented policy dialects.
What this means for the next PaaS MCP server
The uncomfortable reading is that Coolify did everything right at the protocol layer — spec transport, token auth, sensible read-only v1 — and still ended up with governance fragmented across third-party servers, because policy was nobody's launch requirement. The comfortable reading is that the fix is now a checklist, not a research project.
For a platform designing its agent interface today, the takeaway is blunt: least-privilege scopes, approval gates, and audit logging are the product, not the wrapper. Launch governed, and the community builds workflows on top of you instead of guardrails around you.
Bex.co is the open-source, AI-native Render alternative — push a git repo, get a running HTTPS service on machines you own. AI agents are first-class operators here, which means the agent interface gets scopes, gates, and audit from day one. Star the repo on GitHub or deploy your first app today.



