@mks2508/coolify-mks-cli-mcp 0.1.0 → 0.2.0

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.
@@ -0,0 +1,74 @@
1
+ /**
2
+ * Show command for CLI.
3
+ *
4
+ * Shows detailed information about an application.
5
+ *
6
+ * @module
7
+ */
8
+
9
+ import { isErr } from '@mks2508/no-throw'
10
+ import chalk from 'chalk'
11
+ import { getCoolifyService } from '../../coolify/index.js'
12
+ import type { ICoolifyApplication } from '../../coolify/types.js'
13
+
14
+ /**
15
+ * Show command handler.
16
+ *
17
+ * @param uuid - Application UUID
18
+ */
19
+ export async function showCommand(uuid: string) {
20
+ const coolify = getCoolifyService()
21
+ const initResult = await coolify.init()
22
+
23
+ if (isErr(initResult)) {
24
+ console.error(chalk.red(`Error: ${initResult.error.message}`))
25
+ return
26
+ }
27
+
28
+ // We need to add getApplication method to CoolifyService
29
+ // For now, use listApplications and filter
30
+ const result = await coolify.listApplications()
31
+
32
+ if (isErr(result)) {
33
+ console.error(chalk.red(`Error: ${result.error.message}`))
34
+ return
35
+ }
36
+
37
+ const apps = result.value
38
+ const app = apps.find(a => a.uuid === uuid || a.uuid.startsWith(uuid))
39
+
40
+ if (!app) {
41
+ console.error(chalk.red(`Application not found: ${uuid}`))
42
+ return
43
+ }
44
+
45
+ console.log(chalk.cyan('Application Details:'))
46
+ console.log('')
47
+ console.log(chalk.gray('UUID: ') + chalk.white(app.uuid))
48
+ console.log(chalk.gray('Name: ') + chalk.white(app.name))
49
+ console.log(chalk.gray('Status: ') + chalk.white(app.status))
50
+ console.log(chalk.gray('Description:') + chalk.white(app.description || 'N/A'))
51
+ console.log(chalk.gray('Repository: ') + chalk.white(app.git_repository || 'N/A'))
52
+ console.log(chalk.gray('Branch: ') + chalk.white(app.git_branch || 'N/A'))
53
+ console.log(chalk.gray('Build Pack: ') + chalk.white(app.build_pack || 'N/A'))
54
+ console.log(chalk.gray('Ports: ') + chalk.white(app.ports_exposes || 'N/A'))
55
+ console.log(chalk.gray('FQDN: ') + chalk.white(app.fqdn || 'N/A'))
56
+ console.log(chalk.gray('Dockerfile: ') + chalk.white(app.dockerfile_location || 'N/A'))
57
+ console.log(chalk.gray('Base Dir: ') + chalk.white(app.base_directory || 'N/A'))
58
+ console.log('')
59
+ console.log(chalk.cyan('Destination:'))
60
+ if (app.destination) {
61
+ console.log(chalk.gray(' UUID: ') + chalk.white(app.destination.uuid))
62
+ console.log(chalk.gray(' Name: ') + chalk.white(app.destination.name))
63
+ if (app.destination.server) {
64
+ console.log(chalk.gray(' Server:') + chalk.white(` ${app.destination.server.name} (${app.destination.server.ip})`))
65
+ }
66
+ } else {
67
+ console.log(chalk.yellow(' No destination configured'))
68
+ }
69
+ console.log('')
70
+ console.log(chalk.cyan('Commands:'))
71
+ if (app.install_command) console.log(chalk.gray(' Install: ') + chalk.white(app.install_command))
72
+ if (app.build_command) console.log(chalk.gray(' Build: ') + chalk.white(app.build_command))
73
+ if (app.start_command) console.log(chalk.gray(' Start: ') + chalk.white(app.start_command))
74
+ }
@@ -0,0 +1,81 @@
1
+ /**
2
+ * Update application command.
3
+ *
4
+ * Updates an existing Coolify application configuration.
5
+ *
6
+ * @module
7
+ */
8
+
9
+ import { isErr } from '@mks2508/no-throw'
10
+ import chalk from 'chalk'
11
+ import { getCoolifyService } from '../../coolify/index.js'
12
+ import type { ICoolifyUpdateOptions } from '../../coolify/types.js'
13
+
14
+ /**
15
+ * Options for the update command.
16
+ */
17
+ interface IUpdateCommandOptions {
18
+ uuid: string
19
+ name?: string
20
+ description?: string
21
+ buildPack?: string
22
+ gitBranch?: string
23
+ ports?: string
24
+ installCommand?: string
25
+ buildCommand?: string
26
+ startCommand?: string
27
+ dockerfileLocation?: string
28
+ baseDirectory?: string
29
+ }
30
+
31
+ /**
32
+ * Executes the update command.
33
+ *
34
+ * @param options - Command options
35
+ */
36
+ export async function updateCommand(options: IUpdateCommandOptions): Promise<void> {
37
+ console.log(chalk.cyan(`Updating application ${chalk.bold(options.uuid)}...`))
38
+
39
+ const service = getCoolifyService()
40
+ const initResult = await service.init()
41
+
42
+ if (isErr(initResult)) {
43
+ console.error(chalk.red('Failed to initialize Coolify service'))
44
+ console.error(chalk.gray(initResult.error.message))
45
+ process.exit(1)
46
+ }
47
+
48
+ const updateOptions: ICoolifyUpdateOptions = {}
49
+
50
+ if (options.name) updateOptions.name = options.name
51
+ if (options.description) updateOptions.description = options.description
52
+ if (options.buildPack) updateOptions.buildPack = options.buildPack as 'dockerfile' | 'nixpacks' | 'static'
53
+ if (options.gitBranch) updateOptions.gitBranch = options.gitBranch
54
+ if (options.ports) updateOptions.portsExposes = options.ports
55
+ if (options.installCommand) updateOptions.installCommand = options.installCommand
56
+ if (options.buildCommand) updateOptions.buildCommand = options.buildCommand
57
+ if (options.startCommand) updateOptions.startCommand = options.startCommand
58
+ if (options.dockerfileLocation) updateOptions.dockerfileLocation = options.dockerfileLocation
59
+ if (options.baseDirectory) updateOptions.baseDirectory = options.baseDirectory
60
+
61
+ if (Object.keys(updateOptions).length === 0) {
62
+ console.warn(chalk.yellow('No update options provided. Use --help to see available options.'))
63
+ process.exit(0)
64
+ }
65
+
66
+ const result = await service.updateApplication(options.uuid, updateOptions)
67
+
68
+ if (isErr(result)) {
69
+ console.error(chalk.red('Failed to update application'))
70
+ console.error(chalk.gray(result.error.message))
71
+ process.exit(1)
72
+ }
73
+
74
+ console.log(chalk.green('Application updated successfully'))
75
+ console.log(chalk.gray(`UUID: ${result.value.uuid}`))
76
+ console.log(chalk.gray(`Name: ${result.value.name}`))
77
+
78
+ if (result.value.description) {
79
+ console.log(chalk.gray(`Description: ${result.value.description}`))
80
+ }
81
+ }
package/src/cli/index.ts CHANGED
@@ -9,12 +9,20 @@
9
9
 
10
10
  import { Command } from 'commander'
11
11
  import chalk from 'chalk'
12
+ import { createCommand } from './commands/create.js'
12
13
  import { deployCommand } from './commands/deploy.js'
13
14
  import { listCommand } from './commands/list.js'
14
15
  import { logsCommand } from './commands/logs.js'
15
16
  import { serversCommand } from './commands/servers.js'
17
+ import { projectsCommand } from './commands/projects.js'
18
+ import { environmentsCommand } from './commands/environments.js'
16
19
  import { configCommand } from './commands/config.js'
17
20
  import { envCommand } from './commands/env.js'
21
+ import { updateCommand } from './commands/update.js'
22
+ import { deleteCommand } from './commands/delete.js'
23
+ import { destinationsCommand } from './commands/destinations.js'
24
+ import { showCommand } from './commands/show.js'
25
+ import { deploymentsCommand } from './commands/deployments.js'
18
26
 
19
27
  const program = new Command()
20
28
 
@@ -23,6 +31,26 @@ program
23
31
  .description('CLI for Coolify deployment management')
24
32
  .version('0.1.0')
25
33
 
34
+ // Create application
35
+ program
36
+ .command('create')
37
+ .description('Create a new application')
38
+ .option('--name <name>', 'Application name')
39
+ .option('--description <desc>', 'Application description')
40
+ .option('--server <uuid>', 'Server UUID')
41
+ .option('--project <uuid>', 'Project UUID')
42
+ .option('--environment <uuid>', 'Environment UUID (auto-fetched if not provided)')
43
+ .option('--repo <url>', 'Git repository URL')
44
+ .option('--branch <branch>', 'Git branch', 'main')
45
+ .option('--type <type>', 'Application type (public, private-github-app, private-deploy-key, dockerfile, docker-image, docker-compose)', 'public')
46
+ .option('--build-pack <pack>', 'Build pack (dockerfile, nixpacks, static)', 'dockerfile')
47
+ .option('--ports <ports>', 'Ports to expose (default: 3000)', '3000')
48
+ .option('--docker-image <image>', 'Docker image (for docker-image type)')
49
+ .option('--docker-compose <content>', 'Docker Compose content (for docker-compose type)')
50
+ .option('--dockerfile-location <path>', 'Dockerfile location (e.g., "apps/haidodocs/Dockerfile")')
51
+ .option('--base-directory <dir>', 'Base directory for build context (default: "/")', '/')
52
+ .action(createCommand)
53
+
26
54
  // Config command
27
55
  program
28
56
  .command('config')
@@ -38,6 +66,7 @@ program
38
66
  .description('List all applications')
39
67
  .option('-t, --team <id>', 'Filter by team ID')
40
68
  .option('-p, --project <id>', 'Filter by project ID')
69
+ .option('--full', 'Show full UUIDs instead of truncated')
41
70
  .action(listCommand)
42
71
 
43
72
  // Deploy application
@@ -63,7 +92,22 @@ program
63
92
  program
64
93
  .command('servers')
65
94
  .description('List available servers')
66
- .action(serversCommand)
95
+ .option('--full', 'Show full UUIDs instead of truncated')
96
+ .action((options) => serversCommand(options))
97
+
98
+ // Projects command
99
+ program
100
+ .command('projects')
101
+ .description('List available projects')
102
+ .option('--full', 'Show full UUIDs instead of truncated')
103
+ .action((options) => projectsCommand(options))
104
+
105
+ // Environments command
106
+ program
107
+ .command('environments <projectUuid>')
108
+ .description('List environments for a project')
109
+ .option('--full', 'Show full UUIDs instead of truncated')
110
+ .action((projectUuid, options) => environmentsCommand(projectUuid, options))
67
111
 
68
112
  // Env vars command
69
113
  program
@@ -71,6 +115,53 @@ program
71
115
  .description('Get environment variables for an application')
72
116
  .action(envCommand)
73
117
 
118
+ // Update application
119
+ program
120
+ .command('update <uuid>')
121
+ .description('Update an application configuration')
122
+ .option('--name <name>', 'Application name')
123
+ .option('--description <desc>', 'Application description')
124
+ .option('--build-pack <pack>', 'Build pack (dockerfile, nixpacks, static)')
125
+ .option('--git-branch <branch>', 'Git branch')
126
+ .option('--ports <ports>', 'Ports to expose (e.g., 3000)')
127
+ .option('--install-command <cmd>', 'Install command (nixpacks)')
128
+ .option('--build-command <cmd>', 'Build command')
129
+ .option('--start-command <cmd>', 'Start command')
130
+ .option('--dockerfile-location <path>', 'Dockerfile location (e.g., "apps/haidodocs/Dockerfile")')
131
+ .option('--base-directory <dir>', 'Base directory for build context (e.g., "/")')
132
+ .action((uuid, options) => updateCommand({ uuid, ...options }))
133
+
134
+ // Delete application
135
+ program
136
+ .command('delete <uuid>')
137
+ .description('Delete an application')
138
+ .option('-f, --force', 'Skip confirmation prompt')
139
+ .option('-y, --yes', 'Skip confirmation prompt (alias for --force)')
140
+ .action((uuid, options) => deleteCommand(uuid, options))
141
+
142
+ // Destinations command
143
+ program
144
+ .command('destinations <serverUuid>')
145
+ .description('List available destinations for a server')
146
+ .action(destinationsCommand)
147
+
148
+ // Show application details
149
+ program
150
+ .command('show <uuid>')
151
+ .description('Show detailed information about an application')
152
+ .action(showCommand)
153
+
154
+ // Deployments history
155
+ program
156
+ .command('deployments <uuid>')
157
+ .description('Show deployment history for an application')
158
+ .option('--full', 'Show full UUIDs')
159
+ .option('-n, --limit <number>', 'Limit number of deployments shown', '10')
160
+ .action((uuid, options) => {
161
+ const limit = parseInt(options.limit, 10)
162
+ deploymentsCommand(uuid, { full: options.full, limit })
163
+ })
164
+
74
165
  // Show help by default
75
166
  program.action(() => {
76
167
  console.log(chalk.cyan('Coolify MCP CLI'))
@@ -18,6 +18,7 @@ import {
18
18
  type ICoolifyDeployOptions,
19
19
  type ICoolifyDeployResult,
20
20
  type ICoolifyDestination,
21
+ type ICoolifyEnvironment,
21
22
  type ICoolifyLogs,
22
23
  type ICoolifyLogsOptions,
23
24
  type ICoolifyProject,
@@ -137,7 +138,9 @@ export class CoolifyService {
137
138
  }
138
139
 
139
140
  try {
140
- const url = `${this.baseUrl}/api/v1${endpoint}`
141
+ const baseUrl = this.baseUrl.replace(/\/+$/, '')
142
+ const url = `${baseUrl}/api/v1${endpoint}`
143
+
141
144
  const response = await fetch(url, {
142
145
  ...options,
143
146
  headers: {
@@ -197,16 +200,22 @@ export class CoolifyService {
197
200
  onProgress?.(25, 'Validating deployment configuration')
198
201
  onProgress?.(50, 'Triggering build pipeline...')
199
202
 
203
+ // Build query parameters for deploy endpoint
204
+ const params = new URLSearchParams()
205
+ if (options.uuid) params.set('uuid', options.uuid)
206
+ if (options.tag) params.set('tag', options.tag)
207
+ if (options.force) params.set('force', 'true')
208
+
209
+ const endpoint = `/deploy${params.toString() ? `?${params.toString()}` : ''}`
210
+
200
211
  const result = await this.request<{
201
- resource_uuid: string
202
- deployment_uuid: string
203
- }>('/deploy', {
212
+ deployments: Array<{
213
+ message: string
214
+ resource_uuid: string
215
+ deployment_uuid: string
216
+ }>
217
+ }>(endpoint, {
204
218
  method: 'POST',
205
- body: JSON.stringify({
206
- uuid: options.uuid,
207
- tag: options.tag,
208
- force: options.force ?? false,
209
- }),
210
219
  })
211
220
 
212
221
  if (result.error) {
@@ -214,20 +223,37 @@ export class CoolifyService {
214
223
  return err(new Error(result.error))
215
224
  }
216
225
 
226
+ // Response is { deployments: [{ message, resource_uuid, deployment_uuid }] }
227
+ const deployments = result.data?.deployments || []
228
+ if (deployments.length === 0) {
229
+ log.error('No deployments started')
230
+ return err(new Error('No deployments started - check application configuration'))
231
+ }
232
+
233
+ const deployment = deployments[0]
234
+
217
235
  onProgress?.(90, 'Build started on Coolify server')
218
236
  onProgress?.(100, 'Deployment triggered')
219
237
 
220
- log.success(`Deployment started: ${result.data?.deployment_uuid}`)
238
+ log.success(`Deployment started: ${deployment.deployment_uuid}`)
221
239
  return ok({
222
240
  success: true,
223
- deploymentUuid: result.data?.deployment_uuid,
224
- resourceUuid: result.data?.resource_uuid,
241
+ deploymentUuid: deployment.deployment_uuid,
242
+ resourceUuid: deployment.resource_uuid,
225
243
  })
226
244
  }
227
245
 
228
246
  /**
229
247
  * Creates a new application in Coolify.
230
248
  *
249
+ * Uses type-specific endpoints for different application types:
250
+ * - /applications/public - Public Git repository
251
+ * - /applications/private-github-app - Private repo with GitHub App
252
+ * - /applications/private-deploy-key - Private repo with deploy key
253
+ * - /applications/dockerfile - Dockerfile-based application
254
+ * - /applications/docker-image - Docker image
255
+ * - /applications/docker-compose - Docker Compose application
256
+ *
231
257
  * @param options - Application options
232
258
  * @param onProgress - Optional progress callback (0-100, message, step)
233
259
  * @returns Result with application UUID or error
@@ -238,26 +264,59 @@ export class CoolifyService {
238
264
  ): Promise<Result<ICoolifyAppResult, Error>> {
239
265
  onProgress?.(5, `Preparing app "${options.name}"`)
240
266
 
241
- log.info(`Creating application ${options.name}`)
267
+ const appType = options.type || 'public'
268
+ log.info(`Creating application ${options.name} (type: ${appType})`)
242
269
 
243
270
  onProgress?.(25, `Validating server ${options.serverUuid.slice(0, 8)}...`)
244
271
  onProgress?.(50, 'Sending creation request to Coolify API...')
245
272
 
246
- const result = await this.request<{ uuid: string }>('/applications', {
273
+ // Determine endpoint based on application type
274
+ const endpointMap: Record<string, string> = {
275
+ 'public': '/applications/public',
276
+ 'private-github-app': '/applications/private-github-app',
277
+ 'private-deploy-key': '/applications/private-deploy-key',
278
+ 'dockerfile': '/applications/dockerfile',
279
+ 'docker-image': '/applications/docker-image',
280
+ 'docker-compose': '/applications/docker-compose',
281
+ }
282
+
283
+ const endpoint = endpointMap[appType] || '/applications/public'
284
+
285
+ // Build request body based on application type
286
+ const body: Record<string, unknown> = {
287
+ name: options.name,
288
+ description: options.description,
289
+ project_uuid: options.projectUuid,
290
+ environment_uuid: options.environmentUuid,
291
+ server_uuid: options.serverUuid,
292
+ }
293
+
294
+ // Type-specific fields
295
+ if (appType === 'public' || appType === 'private-github-app' || appType === 'private-deploy-key') {
296
+ if (options.githubRepoUrl) {
297
+ body.git_repository = options.githubRepoUrl
298
+ }
299
+ body.git_branch = options.branch || 'main'
300
+ body.build_pack = options.buildPack || 'dockerfile'
301
+ if (options.portsExposes) {
302
+ body.ports_exposes = options.portsExposes
303
+ }
304
+ // Dockerfile configuration
305
+ if (options.dockerfileLocation) {
306
+ body.dockerfile_location = options.dockerfileLocation
307
+ }
308
+ if (options.baseDirectory) {
309
+ body.base_directory = options.baseDirectory
310
+ }
311
+ } else if (appType === 'docker-image' && options.dockerImage) {
312
+ body.docker_image = options.dockerImage
313
+ } else if (appType === 'docker-compose' && options.dockerCompose) {
314
+ body.docker_compose = options.dockerCompose
315
+ }
316
+
317
+ const result = await this.request<{ uuid: string }>(endpoint, {
247
318
  method: 'POST',
248
- body: JSON.stringify({
249
- name: options.name,
250
- description: options.description,
251
- server_uuid: options.serverUuid,
252
- destination_uuid: options.destinationUuid,
253
- project_uuid: options.serverUuid,
254
- environment_name: 'production',
255
- git_repository: options.githubRepoUrl,
256
- git_branch: options.branch || 'main',
257
- build_pack: options.buildPack || 'nixpacks',
258
- ports_exposes: '3000',
259
- instant_deploy: false,
260
- }),
319
+ body: JSON.stringify(body),
261
320
  })
262
321
 
263
322
  if (result.error) {
@@ -403,6 +462,30 @@ export class CoolifyService {
403
462
  return ok(result.data || [])
404
463
  }
405
464
 
465
+ /**
466
+ * Gets environments for a project.
467
+ *
468
+ * @param projectUuid - Project UUID
469
+ * @returns Result with environments list or error
470
+ */
471
+ async getProjectEnvironments(
472
+ projectUuid: string
473
+ ): Promise<Result<ICoolifyEnvironment[], Error>> {
474
+ log.info(`Getting environments for project ${projectUuid}`)
475
+
476
+ const result = await this.request<{ environments: ICoolifyEnvironment[] }>(
477
+ `/projects/${projectUuid}`
478
+ )
479
+
480
+ if (result.error) {
481
+ log.error(`Failed to get environments: ${result.error}`)
482
+ return err(new Error(result.error))
483
+ }
484
+
485
+ log.success(`Environments retrieved for project ${projectUuid}`)
486
+ return ok(result.data?.environments || [])
487
+ }
488
+
406
489
  /**
407
490
  * Lists all teams.
408
491
  *
@@ -516,6 +599,8 @@ export class CoolifyService {
516
599
  if (options.installCommand) body.install_command = options.installCommand
517
600
  if (options.buildCommand) body.build_command = options.buildCommand
518
601
  if (options.startCommand) body.start_command = options.startCommand
602
+ if (options.dockerfileLocation) body.dockerfile_location = options.dockerfileLocation
603
+ if (options.baseDirectory) body.base_directory = options.baseDirectory
519
604
 
520
605
  const result = await this.request<ICoolifyApplication>(`/applications/${appUuid}`, {
521
606
  method: 'PATCH',
@@ -575,7 +660,8 @@ export class CoolifyService {
575
660
  ): Promise<Result<ICoolifyDeployment[], Error>> {
576
661
  log.info(`Getting deployment history for ${appUuid}`)
577
662
 
578
- const result = await this.request<ICoolifyDeployment[]>(`/applications/${appUuid}/deployments`)
663
+ // According to Coolify API docs, endpoint is /applications/{app_uuid}/deployments
664
+ const result = await this.request<{ deployments: ICoolifyDeployment[] }>(`/applications/${appUuid}/deployments`)
579
665
 
580
666
  if (result.error) {
581
667
  log.error(`Failed to get deployment history: ${result.error}`)
@@ -583,7 +669,7 @@ export class CoolifyService {
583
669
  }
584
670
 
585
671
  log.success(`Deployment history retrieved for ${appUuid}`)
586
- return ok(result.data || [])
672
+ return ok(result.data?.deployments || [])
587
673
  }
588
674
 
589
675
  /**
@@ -21,6 +21,17 @@ export interface ICoolifyDeployOptions {
21
21
  onProgress?: IProgressCallback
22
22
  }
23
23
 
24
+ /**
25
+ * Application types supported by Coolify.
26
+ */
27
+ export type TCoolifyApplicationType =
28
+ | 'public'
29
+ | 'private-github-app'
30
+ | 'private-deploy-key'
31
+ | 'dockerfile'
32
+ | 'docker-image'
33
+ | 'docker-compose'
34
+
24
35
  /**
25
36
  * Options for creating a Coolify application.
26
37
  */
@@ -29,18 +40,32 @@ export interface ICoolifyAppOptions {
29
40
  name: string
30
41
  /** Application description */
31
42
  description?: string
43
+ /** Project UUID */
44
+ projectUuid: string
45
+ /** Environment UUID */
46
+ environmentUuid: string
32
47
  /** Server UUID */
33
48
  serverUuid: string
34
- /** Destination UUID */
35
- destinationUuid: string
36
- /** GitHub repository URL */
37
- githubRepoUrl: string
49
+ /** Application type */
50
+ type?: TCoolifyApplicationType
51
+ /** GitHub repository URL (for git-based apps) */
52
+ githubRepoUrl?: string
38
53
  /** Git branch */
39
54
  branch?: string
40
55
  /** Build pack type */
41
56
  buildPack?: 'dockerfile' | 'nixpacks' | 'static'
57
+ /** Ports to expose */
58
+ portsExposes?: string
59
+ /** Docker image (for docker-image type) */
60
+ dockerImage?: string
61
+ /** Docker Compose content (for docker-compose type) */
62
+ dockerCompose?: string
42
63
  /** Environment variables */
43
64
  envVars?: Record<string, string>
65
+ /** Dockerfile location (path relative to repo root, e.g., "apps/haidodocs/Dockerfile") */
66
+ dockerfileLocation?: string
67
+ /** Base directory for build context (default: "/") */
68
+ baseDirectory?: string
44
69
  }
45
70
 
46
71
  /**
@@ -63,6 +88,10 @@ export interface ICoolifyUpdateOptions {
63
88
  buildCommand?: string
64
89
  /** Start command */
65
90
  startCommand?: string
91
+ /** Dockerfile location (path relative to repo root, e.g., "apps/haidodocs/Dockerfile") */
92
+ dockerfileLocation?: string
93
+ /** Base directory for build context (default: "/") */
94
+ baseDirectory?: string
66
95
  }
67
96
 
68
97
  /**
@@ -173,6 +202,10 @@ export interface ICoolifyApplication {
173
202
  build_pack?: string | null
174
203
  /** Ports exposed */
175
204
  ports_exposes?: string | null
205
+ /** Dockerfile location */
206
+ dockerfile_location?: string | null
207
+ /** Base directory */
208
+ base_directory?: string | null
176
209
  /** Server status (boolean) */
177
210
  server_status?: boolean
178
211
  /** Environment ID */
@@ -259,6 +292,8 @@ export interface ICoolifyProject {
259
292
  * Environment within a project from API (snake_case).
260
293
  */
261
294
  export interface ICoolifyEnvironment {
295
+ /** Environment UUID (needed for API calls) */
296
+ uuid: string
262
297
  /** Environment ID */
263
298
  id: number
264
299
  /** Environment name */
package/src/index.ts CHANGED
@@ -684,12 +684,13 @@ Each destination represents a Docker network/environment on the server.`,
684
684
  'create_application',
685
685
  `Create a new application in Coolify from a GitHub repository.
686
686
 
687
- Requires server UUID and destination UUID (get them from list_servers and get_server_destinations).
687
+ Requires server UUID, project UUID, and environment UUID.
688
688
  The GitHub repository must be accessible via the configured GitHub App.`,
689
689
  {
690
690
  name: z.string().describe('Application name'),
691
691
  serverUuid: z.string().uuid().describe('Server UUID to deploy to'),
692
- destinationUuid: z.string().uuid().describe('Destination UUID (Docker network)'),
692
+ projectUuid: z.string().uuid().describe('Project UUID'),
693
+ environmentUuid: z.string().uuid().describe('Environment UUID'),
693
694
  githubRepoUrl: z.string().describe('GitHub repository URL (e.g., https://github.com/user/repo)'),
694
695
  description: z.string().optional().describe('Application description'),
695
696
  branch: z.string().default('main').describe('Git branch to deploy'),
@@ -707,8 +708,10 @@ The GitHub repository must be accessible via the configured GitHub App.`,
707
708
  const result = await coolify.createApplication({
708
709
  name: args.name,
709
710
  description: args.description,
711
+ projectUuid: args.projectUuid,
712
+ environmentUuid: args.environmentUuid,
710
713
  serverUuid: args.serverUuid,
711
- destinationUuid: args.destinationUuid,
714
+ type: 'public',
712
715
  githubRepoUrl: args.githubRepoUrl,
713
716
  branch: args.branch,
714
717
  buildPack: args.buildPack,
@@ -155,7 +155,8 @@ interface GetServerDestinationsArgs {
155
155
  interface CreateApplicationArgs {
156
156
  name: string
157
157
  serverUuid: string
158
- destinationUuid: string
158
+ projectUuid: string
159
+ environmentUuid: string
159
160
  githubRepoUrl: string
160
161
  description?: string
161
162
  branch?: string
@@ -516,8 +517,10 @@ async function handleCreateApplication(coolify: CoolifyService, args: CreateAppl
516
517
  const result = await coolify.createApplication({
517
518
  name: args.name,
518
519
  description: args.description,
520
+ projectUuid: args.projectUuid,
521
+ environmentUuid: args.environmentUuid,
519
522
  serverUuid: args.serverUuid,
520
- destinationUuid: args.destinationUuid,
523
+ type: 'public',
521
524
  githubRepoUrl: args.githubRepoUrl,
522
525
  branch: args.branch,
523
526
  buildPack: args.buildPack