StuMason/coolify-mcp
TypeScript
Pull Request Merged
PR #182 merged: fix(env_vars): mask value and real_value by default, opt-in reveal
Summary
Closes #159.
env_vars list responses previously included plaintext value (and real_value on the full projection), exposing secrets to any MCP client / LLM that called the tool. Now masked with '***' by default; callers opt in with reveal: true on the list action when they explicitly need the value (e.g. "what is FOO set to right now?").
Per @daniel-rudaev's option 1 in #159 and @StuMason's scope notes (masking at the boundary, both EnvVarSummary and EnvironmentVariable shapes, opt-in reveal on list, metadata untouched).
Changes
- Added
MASKED_VALUEsentinel +maskEnvVar()/maskEnvVarSummary()helpers incoolify-client.ts. Applied at the boundary on the list endpoints — masking doesn't run inside the projection step, so both summary and full projections share one default policy. listApplicationEnvVars(uuid, { summary?, reveal? })andlistServiceEnvVars(uuid, { reveal? })—revealdefaultsfalse.env_varsMCP tool: addedreveal: z.boolean().optional()to the schema and plumbed through to bothlistbranches. Updated tool description.bulkEnvUpdatewas already safe — returnsBatchOperationResultwith{ uuid, name, error? }only, never echoed env var values. No code change there, noted in CHANGELOG for completeness.diagnoseApplicationcallslistApplicationEnvVarswithout options, so its env-var aggregator now consumes masked data — but the diagnostic only projectskey/is_buildtime/is_runtime(nevervalue), so user-visible output is identical.- Tests:
- 5 new tests covering masked default + reveal=true paths for both list methods, on both summary and full projections, plus
real_valuemasking. - 2 existing tests rewritten — they asserted the leaked plaintext
value. Those assertions were the bug surface.
- 5 new tests covering masked default + reveal=true paths for both list methods, on both summary and full projections, plus
Breaking (behavioural)
Callers that relied on value being present in env_vars list responses must now pass reveal: true. This is documented as a Security entry in CHANGELOG.
Test plan
-
npm test— 297/297 passing -
npm run lint— clean -
npm run build— clean - Client coverage: 98.79% lines, 86.74% branches
- Both
reveal: trueandreveal: falsepaths exercised for codecov patch coverage
+233
additions
-14
deletions
4
files changed