@mks2508/coolify-mks-cli-mcp 0.3.2 → 0.4.1

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.
@@ -17173,7 +17173,7 @@ class CoolifyService {
17173
17173
  const parsed = data;
17174
17174
  let errorMessage = parsed?.message || `HTTP ${response.status}`;
17175
17175
  if (parsed?.errors) {
17176
- const details = Object.entries(parsed.errors).map(([field, reasons]) => `${field}: ${reasons.join(", ")}`).join("; ");
17176
+ const details = Object.entries(parsed.errors).map(([field, reasons]) => `${field}: ${Array.isArray(reasons) ? reasons.join(", ") : String(reasons)}`).join("; ");
17177
17177
  errorMessage += ` — ${details}`;
17178
17178
  }
17179
17179
  return { error: errorMessage, status: response.status, durationMs };
@@ -17247,7 +17247,10 @@ class CoolifyService {
17247
17247
  };
17248
17248
  if (appType === "public" || appType === "private-github-app" || appType === "private-deploy-key") {
17249
17249
  if (options.githubRepoUrl) {
17250
- body.git_repository = options.githubRepoUrl;
17250
+ body.git_repository = options.githubRepoUrl.replace(/^https?:\/\/github\.com\//, "").replace(/\.git$/, "");
17251
+ }
17252
+ if (options.githubAppUuid) {
17253
+ body.github_app_uuid = options.githubAppUuid;
17251
17254
  }
17252
17255
  body.git_branch = options.branch || "main";
17253
17256
  body.build_pack = options.buildPack || "dockerfile";
@@ -17286,21 +17289,22 @@ class CoolifyService {
17286
17289
  });
17287
17290
  }
17288
17291
  async setEnvironmentVariables(appUuid, envVars) {
17289
- log.info(`Setting environment variables for ${appUuid}`);
17290
- const envArray = Object.entries(envVars).map(([key, value]) => ({
17291
- key,
17292
- value,
17293
- is_build_time: false
17294
- }));
17295
- const result = await this.request(`/applications/${appUuid}/envs`, {
17296
- method: "POST",
17297
- body: JSON.stringify({ data: envArray })
17298
- });
17299
- if (result.error) {
17300
- log.error(`Failed to set env vars: ${result.error}`);
17301
- return err(new Error(result.error));
17292
+ log.info(`Setting ${Object.keys(envVars).length} environment variables for ${appUuid}`);
17293
+ for (const [key, value] of Object.entries(envVars)) {
17294
+ const result = await this.request(`/applications/${appUuid}/envs`, {
17295
+ method: "POST",
17296
+ body: JSON.stringify({
17297
+ key,
17298
+ value,
17299
+ is_preview: false
17300
+ })
17301
+ });
17302
+ if (result.error) {
17303
+ log.error(`Failed to set env var ${key}: ${result.error}`);
17304
+ return err(new Error(`Failed to set ${key}: ${result.error}`));
17305
+ }
17302
17306
  }
17303
- log.success("Environment variables set");
17307
+ log.success(`${Object.keys(envVars).length} environment variables set`);
17304
17308
  return ok(undefined);
17305
17309
  }
17306
17310
  async getEnvironmentVariables(appUuid) {
@@ -17389,6 +17393,12 @@ class CoolifyService {
17389
17393
  log.success(`Server details retrieved: ${serverUuid}`);
17390
17394
  return ok(result.data);
17391
17395
  }
17396
+ async listGithubApps() {
17397
+ const result = await this.request("/github-apps");
17398
+ if (result.error)
17399
+ return err(new Error(result.error));
17400
+ return ok(result.data || []);
17401
+ }
17392
17402
  async listProjects() {
17393
17403
  const result = await this.request("/projects");
17394
17404
  if (result.error) {
@@ -17489,6 +17499,8 @@ class CoolifyService {
17489
17499
  body.base_directory = options.baseDirectory;
17490
17500
  if (options.domains)
17491
17501
  body.domains = options.domains;
17502
+ if (options.dockerComposeDomains)
17503
+ body.docker_compose_domains = options.dockerComposeDomains;
17492
17504
  if (options.isForceHttpsEnabled !== undefined)
17493
17505
  body.is_force_https_enabled = options.isForceHttpsEnabled;
17494
17506
  if (options.isAutoDeployEnabled !== undefined)
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@mks2508/coolify-mks-cli-mcp",
3
- "version": "0.3.2",
3
+ "version": "0.4.1",
4
4
  "description": "MCP server and CLI for Coolify deployment management",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",
@@ -169,7 +169,7 @@ export class CoolifyService {
169
169
  // Include validation errors if present (Coolify returns { message, errors: { field: [reasons] } })
170
170
  if (parsed?.errors) {
171
171
  const details = Object.entries(parsed.errors)
172
- .map(([field, reasons]) => `${field}: ${reasons.join(', ')}`)
172
+ .map(([field, reasons]) => `${field}: ${Array.isArray(reasons) ? reasons.join(', ') : String(reasons)}`)
173
173
  .join('; ')
174
174
  errorMessage += ` — ${details}`
175
175
  }
@@ -300,7 +300,13 @@ export class CoolifyService {
300
300
  // Type-specific fields
301
301
  if (appType === 'public' || appType === 'private-github-app' || appType === 'private-deploy-key') {
302
302
  if (options.githubRepoUrl) {
303
+ // Coolify expects 'user/repo' format, not full URL
303
304
  body.git_repository = options.githubRepoUrl
305
+ .replace(/^https?:\/\/github\.com\//, '')
306
+ .replace(/\.git$/, '')
307
+ }
308
+ if (options.githubAppUuid) {
309
+ body.github_app_uuid = options.githubAppUuid
304
310
  }
305
311
  body.git_branch = options.branch || 'main'
306
312
  body.build_pack = options.buildPack || 'dockerfile'
@@ -356,25 +362,26 @@ export class CoolifyService {
356
362
  appUuid: string,
357
363
  envVars: Record<string, string>
358
364
  ): Promise<Result<void, Error>> {
359
- log.info(`Setting environment variables for ${appUuid}`)
360
-
361
- const envArray = Object.entries(envVars).map(([key, value]) => ({
362
- key,
363
- value,
364
- is_build_time: false,
365
- }))
365
+ log.info(`Setting ${Object.keys(envVars).length} environment variables for ${appUuid}`)
366
366
 
367
- const result = await this.request(`/applications/${appUuid}/envs`, {
368
- method: 'POST',
369
- body: JSON.stringify({ data: envArray }),
370
- })
367
+ // Coolify API accepts one env var per POST request
368
+ for (const [key, value] of Object.entries(envVars)) {
369
+ const result = await this.request(`/applications/${appUuid}/envs`, {
370
+ method: 'POST',
371
+ body: JSON.stringify({
372
+ key,
373
+ value,
374
+ is_preview: false,
375
+ }),
376
+ })
371
377
 
372
- if (result.error) {
373
- log.error(`Failed to set env vars: ${result.error}`)
374
- return err(new Error(result.error))
378
+ if (result.error) {
379
+ log.error(`Failed to set env var ${key}: ${result.error}`)
380
+ return err(new Error(`Failed to set ${key}: ${result.error}`))
381
+ }
375
382
  }
376
383
 
377
- log.success('Environment variables set')
384
+ log.success(`${Object.keys(envVars).length} environment variables set`)
378
385
  return ok(undefined)
379
386
  }
380
387
 
@@ -553,6 +560,17 @@ export class CoolifyService {
553
560
  return ok(result.data as ICoolifyServer)
554
561
  }
555
562
 
563
+ /**
564
+ * Lists all GitHub Apps configured in Coolify.
565
+ *
566
+ * @returns Result with GitHub Apps list or error
567
+ */
568
+ async listGithubApps(): Promise<Result<Array<{ id: number; uuid: string; name: string; is_public: boolean }>, Error>> {
569
+ const result = await this.request<Array<{ id: number; uuid: string; name: string; is_public: boolean }>>('/github-apps')
570
+ if (result.error) return err(new Error(result.error))
571
+ return ok(result.data || [])
572
+ }
573
+
556
574
  /**
557
575
  * Lists all projects.
558
576
  *
@@ -735,6 +753,7 @@ export class CoolifyService {
735
753
  if (options.dockerfileLocation) body.dockerfile_location = options.dockerfileLocation
736
754
  if (options.baseDirectory) body.base_directory = options.baseDirectory
737
755
  if (options.domains) body.domains = options.domains
756
+ if (options.dockerComposeDomains) body.docker_compose_domains = options.dockerComposeDomains
738
757
  if (options.isForceHttpsEnabled !== undefined) body.is_force_https_enabled = options.isForceHttpsEnabled
739
758
  if (options.isAutoDeployEnabled !== undefined) body.is_auto_deploy_enabled = options.isAutoDeployEnabled
740
759
 
@@ -50,6 +50,8 @@ export interface ICoolifyAppOptions {
50
50
  destinationUuid?: string
51
51
  /** Application type */
52
52
  type?: TCoolifyApplicationType
53
+ /** GitHub App UUID (required for private-github-app type — get from listGithubApps) */
54
+ githubAppUuid?: string
53
55
  /** GitHub repository URL (for git-based apps) */
54
56
  githubRepoUrl?: string
55
57
  /** Git branch */
@@ -96,8 +98,10 @@ export interface ICoolifyUpdateOptions {
96
98
  dockerfileLocation?: string
97
99
  /** Base directory for build context (default: "/") */
98
100
  baseDirectory?: string
99
- /** Domains/FQDN - comma separated list of domains with protocol (e.g., "https://app.example.com,https://www.example.com") */
101
+ /** Domains/FQDN - comma separated list of domains with protocol (e.g., "https://app.example.com") — NOT for dockercompose apps */
100
102
  domains?: string
103
+ /** Docker Compose domains - JSON object: { "service-name": { "domain": "https://..." } } — for dockercompose apps */
104
+ dockerComposeDomains?: string
101
105
  /** Force HTTPS redirect */
102
106
  isForceHttpsEnabled?: boolean
103
107
  /** Enable auto deploy on git push */