PR #174 opened: fix(env-vars): match Coolify API field names (is_buildtime/is_runtime), expose runtime-only flag
Summary
Fixes #135. Coolify v4 API uses is_buildtime and is_runtime (one word each), not is_build_time (with underscore). The MCP was using the wrong field name throughout, which produced two distinct silent-failure modes against a real Coolify server.
Live-API verification (Coolify v4.0.0-beta.473)
# POST /applications/{uuid}/envs with is_build_time -> 422
{"message":"Validation failed.","errors":{"is_build_time":["This field is not allowed."]}}
# PATCH /applications/{uuid}/envs with is_build_time -> 422 (same)
# PATCH /applications/{uuid}/envs/bulk with is_build_time -> 201
# but the flag is silently dropped (response: "is_buildtime": true unchanged)
# All three endpoints with is_buildtime/is_runtime -> 201 + flag persists.
What changes
| Surface | Before | After |
|---|---|---|
EnvironmentVariable, CreateEnvVarRequest, UpdateEnvVarRequest, EnvVarSummary, diagnostics env-var view | is_build_time (always undefined against real Coolify) | is_buildtime + is_runtime |
env_vars tool — app create/update, service create | flags not exposed; tool dropped them with a TODO comment | accepts is_buildtime + is_runtime, threads to client |
bulk_env_update tool / bulkEnvUpdate(...) | is_build_time was sent on the wire and silently ignored | is_buildtime + new is_runtime |
toEnvVarSummary and diagnostics projection | read envVar.is_build_time (always undefined) | read the correct fields |
Why this matters (the #135 use case)
Setting is_buildtime: false, is_runtime: true is the only way to add multiline secrets (PEM keys, certificates, etc.) to a Coolify app via API/MCP. Without it, Coolify injects the value as a Dockerfile ARG and breaks the build with a parser error on the second line of the PEM. We've hit this same trap multiple times in production (NODE_ENV, Auth.js AUTH_URL, PASSPORT_PRIVATE_KEY-style secrets) and worked around it via the Coolify web UI.
Breaking change (typed-only)
EnvironmentVariable.is_build_time->is_buildtime+ newis_runtimeCreate/UpdateEnvVarRequest.is_build_time?->is_buildtime?+ newis_runtime?EnvVarSummary.is_build_time->is_buildtime+ newis_runtimebulkEnvUpdate(uuids, key, value, isBuildTime)->bulkEnvUpdate(uuids, key, value, isBuildtime?, isRuntime?)
Programmatic TypeScript consumers of @masonator/coolify-mcp will need to update field references. Note: under the old field name the value was always undefined against a real Coolify server, so any caller that worked end-to-end was already not relying on it.
Notes
- Supersedes the
claude/issue-135-20260303-0903branch (which used the wrong field nameis_build_timeand would have produced HTTP 422 on every create/update call). The deleted comment// is_build_time is not passed - Coolify API rejects it for create actionwas correct in spirit — the workaround was just hiding the underlying field-name bug. - Service
updateaction remains hard-erroring (Error: service env update not supported); preserved as-is, separate from this fix.
Test plan
-
npm run buildclean. -
npm test— 282/282 passing (was 280/280, +2 new tests covering the runtime-only create + update case from #135). -
npm run lint— 0 errors (4 pre-existing warnings unchanged). - Live-API probe against Coolify v4.0.0-beta.473 — POST/PATCH/bulk all accept
is_buildtime+is_runtimeand persist the flags; old field nameis_build_timeeither 422s (single endpoints) or silently no-ops (bulk).