@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.
- package/dist/cli/index.js +471 -34
- package/dist/coolify/index.d.ts +16 -1
- package/dist/coolify/index.d.ts.map +1 -1
- package/dist/coolify/types.d.ts +32 -4
- package/dist/coolify/types.d.ts.map +1 -1
- package/dist/index.cjs +79 -31
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +79 -31
- package/dist/index.js.map +1 -1
- package/dist/server/stdio.js +79 -28
- package/package.json +1 -1
- package/src/cli/commands/create.ts +116 -0
- package/src/cli/commands/delete.ts +69 -0
- package/src/cli/commands/deployments.ts +77 -0
- package/src/cli/commands/destinations.ts +60 -0
- package/src/cli/commands/environments.ts +72 -0
- package/src/cli/commands/list.ts +3 -3
- package/src/cli/commands/projects.ts +69 -0
- package/src/cli/commands/servers.ts +3 -3
- package/src/cli/commands/show.ts +74 -0
- package/src/cli/commands/update.ts +81 -0
- package/src/cli/index.ts +92 -1
- package/src/coolify/index.ts +115 -29
- package/src/coolify/types.ts +39 -4
- package/src/index.ts +6 -3
- package/src/tools/handlers.ts +5 -2
|
@@ -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
|
-
.
|
|
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'))
|
package/src/coolify/index.ts
CHANGED
|
@@ -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
|
|
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
|
-
|
|
202
|
-
|
|
203
|
-
|
|
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: ${
|
|
238
|
+
log.success(`Deployment started: ${deployment.deployment_uuid}`)
|
|
221
239
|
return ok({
|
|
222
240
|
success: true,
|
|
223
|
-
deploymentUuid:
|
|
224
|
-
resourceUuid:
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
/**
|
package/src/coolify/types.ts
CHANGED
|
@@ -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
|
-
/**
|
|
35
|
-
|
|
36
|
-
/** GitHub repository URL */
|
|
37
|
-
githubRepoUrl
|
|
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
|
|
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
|
-
|
|
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
|
-
|
|
714
|
+
type: 'public',
|
|
712
715
|
githubRepoUrl: args.githubRepoUrl,
|
|
713
716
|
branch: args.branch,
|
|
714
717
|
buildPack: args.buildPack,
|
package/src/tools/handlers.ts
CHANGED
|
@@ -155,7 +155,8 @@ interface GetServerDestinationsArgs {
|
|
|
155
155
|
interface CreateApplicationArgs {
|
|
156
156
|
name: string
|
|
157
157
|
serverUuid: string
|
|
158
|
-
|
|
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
|
-
|
|
523
|
+
type: 'public',
|
|
521
524
|
githubRepoUrl: args.githubRepoUrl,
|
|
522
525
|
branch: args.branch,
|
|
523
526
|
buildPack: args.buildPack
|