@jurislm/coolify-plugin 4.0.3 → 4.0.5

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "coolify-plugin",
3
- "version": "4.0.3",
3
+ "version": "4.0.5",
4
4
  "description": "Fallback Codex metadata for local stdio Coolify tools.",
5
5
  "author": {
6
6
  "name": "JurisLM",
package/.mcp.json CHANGED
@@ -3,7 +3,8 @@
3
3
  "coolify": {
4
4
  "type": "stdio",
5
5
  "command": "bunx",
6
- "args": ["-y", "@jurislm/coolify-plugin@latest"]
6
+ "args": ["-y", "@jurislm/coolify-plugin@latest"],
7
+ "env_vars": ["COOLIFY_BASE_URL", "COOLIFY_ACCESS_TOKEN"]
7
8
  }
8
9
  }
9
10
  }
package/README.md CHANGED
@@ -22,6 +22,7 @@ bun dist/index.js
22
22
  `mcp.json` and `.mcp.json` use the same published-package `bunx` stdio registration as the Woodpecker CI plugin. `.mcp.json.example` contains placeholder environment values only. NPM package release is allowed. Remote MCP transport, OAuth, vault, hosting, and OpenAI Plugin Directory submission are out of scope.
23
23
 
24
24
  For Codex repository marketplace installation, use the repository root and leave the sparse path empty. The supported marketplace manifest is `.agents/plugins/marketplace.json`; do not enter `plugins/codex`.
25
+ The Codex MCP registration forwards `COOLIFY_BASE_URL` and `COOLIFY_ACCESS_TOKEN` from the Codex session environment. A desktop session may not inherit values exported in a terminal; start a new task after configuring the app environment, then verify a read-only Coolify tool before making changes.
25
26
 
26
27
  ```sh
27
28
  codex plugin marketplace add https://github.com/jurislm/coolify-plugin
package/api/manifest.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "sourceUrl": "https://raw.githubusercontent.com/coollabsio/coolify/v4.3.23/openapi.json",
3
- "fetchedAt": "2026-09-23T12:23:33.000Z",
4
- "sha256": "e80f5efe8df44d0887285a8b923bca84bfc3af6a62b1e63405164e71939d6595",
3
+ "fetchedAt": "2026-09-25T02:22:36.551Z",
4
+ "sha256": "cdada83c8199f7b517bb19049ce7cb18773acee51f2fbadfb5a8370bd9d5f892",
5
5
  "upstreamSha256": "964360ffb3d4c026252aa4657d6561190f59ac4256395bf0645bf6a4f171ec88",
6
6
  "openapiVersion": "3.1.0",
7
7
  "infoVersion": "0.1",
@@ -15,6 +15,12 @@
15
15
  "Unsupported server validation operation removed",
16
16
  "Database PATCH omits unspecified health-check defaults",
17
17
  "Server reachability and service status are response fields",
18
- "Server metadata, deployment git type, and environment descriptions can be null"
18
+ "Server metadata, deployment git type, and environment descriptions can be null",
19
+ "Database responses and nullable service hash match live Coolify payloads",
20
+ "Application settings, destination lists, shared environment variables, and log drain nulls match live responses",
21
+ "Shared environment variable writes accept bodies and return live response shapes",
22
+ "Plain Dockerfile input is encoded for the API",
23
+ "Cloud-init, notifications, GitHub apps, private keys, and team metadata match live response shapes",
24
+ "Resource creation accepts either environment name or UUID as documented"
19
25
  ]
20
26
  }
package/dist/client.js CHANGED
@@ -1,5 +1,5 @@
1
1
  import { CoolifyApiError } from "./errors.js";
2
- const sensitiveKey = /(^value$|real_?value|private_?key|token|secret|password|authorization|cookie)/iu;
2
+ const sensitiveKey = /(^value$|real_?value|private_?key|api_?key|user_?key|webhook_?url|token|secret|password|authorization|cookie)/iu;
3
3
  export function redactSensitive(value) {
4
4
  if (Array.isArray(value))
5
5
  return value.map(redactSensitive);
@@ -59,7 +59,10 @@ export class CoolifyClient {
59
59
  const init = { method: operation.method, headers, signal: AbortSignal.timeout(this.config.timeoutMs) };
60
60
  if (input.body !== undefined && !["GET", "HEAD"].includes(operation.method)) {
61
61
  headers.set("content-type", "application/json");
62
- init.body = JSON.stringify(input.body);
62
+ const body = input.body;
63
+ init.body = JSON.stringify(operation.path === "/applications/dockerfile" && typeof body.dockerfile === "string"
64
+ ? { ...body, dockerfile: Buffer.from(body.dockerfile, "utf8").toString("base64") }
65
+ : body);
63
66
  }
64
67
  let response;
65
68
  try {
@@ -68,8 +71,20 @@ export class CoolifyClient {
68
71
  catch (error) {
69
72
  throw new CoolifyApiError(0, operation.method, path, `Coolify request failed for ${operation.method} ${path}: ${error instanceof Error ? error.message.replaceAll(token, "[REDACTED]") : "request error"}`);
70
73
  }
71
- if (!response.ok)
72
- throw new CoolifyApiError(response.status, operation.method, path, `Coolify API returned ${response.status} for ${operation.method} ${path}`);
74
+ if (!response.ok) {
75
+ let fields = "";
76
+ if (response.status === 422) {
77
+ try {
78
+ const body = await response.json();
79
+ const errors = body?.errors;
80
+ if (errors && typeof errors === "object" && !Array.isArray(errors)) {
81
+ fields = Object.keys(errors).filter((key) => /^[a-z][a-z0-9_.-]{0,63}$/iu.test(key)).slice(0, 8).map((key) => key.replaceAll(token, "[REDACTED]")).join(", ");
82
+ }
83
+ }
84
+ catch { }
85
+ }
86
+ throw new CoolifyApiError(response.status, operation.method, path, `Coolify API returned ${response.status} for ${operation.method} ${path}${fields ? `; fields: ${fields}` : ""}`);
87
+ }
73
88
  let data = null;
74
89
  if (response.status !== 204) {
75
90
  const contentType = response.headers.get("content-type")?.toLowerCase() ?? "";