@fndchagas/coolify-mcp 0.1.2 → 0.1.4
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/README.md +33 -62
- package/dist/config.js +2 -1
- package/dist/coolify/client.js +12 -49
- package/dist/coolify/constants.js +3 -0
- package/dist/generated/client/client.gen.js +229 -0
- package/dist/generated/client/index.js +6 -0
- package/dist/generated/client/types.gen.js +2 -0
- package/dist/generated/client/utils.gen.js +231 -0
- package/dist/generated/client.gen.js +3 -0
- package/dist/generated/core/auth.gen.js +14 -0
- package/dist/generated/core/bodySerializer.gen.js +57 -0
- package/dist/generated/core/params.gen.js +100 -0
- package/dist/generated/core/pathSerializer.gen.js +114 -0
- package/dist/generated/core/queryKeySerializer.gen.js +99 -0
- package/dist/generated/core/serverSentEvents.gen.js +137 -0
- package/dist/generated/core/types.gen.js +2 -0
- package/dist/generated/core/utils.gen.js +87 -0
- package/dist/generated/index.js +2 -0
- package/dist/generated/sdk.gen.js +176 -0
- package/dist/generated/types.gen.js +2 -0
- package/dist/generated/zod.gen.js +340 -0
- package/dist/server.js +21 -3
- package/dist/tools/coolify.js +120 -117
- package/package.json +17 -5
- package/dist/generated/coolify-api.js +0 -5
- package/openapi/coolify/v4.0.0-beta.460.json +0 -11151
|
@@ -0,0 +1,340 @@
|
|
|
1
|
+
// This file is auto-generated by @hey-api/openapi-ts
|
|
2
|
+
import { z } from 'zod';
|
|
3
|
+
/**
|
|
4
|
+
* Environment Variable model
|
|
5
|
+
*/
|
|
6
|
+
export const zEnvironmentVariable = z.object({
|
|
7
|
+
id: z.optional(z.int()),
|
|
8
|
+
uuid: z.optional(z.string()),
|
|
9
|
+
resourceable_type: z.optional(z.string()),
|
|
10
|
+
resourceable_id: z.optional(z.int()),
|
|
11
|
+
is_literal: z.optional(z.boolean()),
|
|
12
|
+
is_multiline: z.optional(z.boolean()),
|
|
13
|
+
is_preview: z.optional(z.boolean()),
|
|
14
|
+
is_runtime: z.optional(z.boolean()),
|
|
15
|
+
is_buildtime: z.optional(z.boolean()),
|
|
16
|
+
is_shared: z.optional(z.boolean()),
|
|
17
|
+
is_shown_once: z.optional(z.boolean()),
|
|
18
|
+
key: z.optional(z.string()),
|
|
19
|
+
value: z.optional(z.string()),
|
|
20
|
+
real_value: z.optional(z.string()),
|
|
21
|
+
version: z.optional(z.string()),
|
|
22
|
+
created_at: z.optional(z.string()),
|
|
23
|
+
updated_at: z.optional(z.string())
|
|
24
|
+
});
|
|
25
|
+
/**
|
|
26
|
+
* Project model
|
|
27
|
+
*/
|
|
28
|
+
export const zApplicationDeploymentQueue = z.object({
|
|
29
|
+
id: z.optional(z.int()),
|
|
30
|
+
application_id: z.optional(z.string()),
|
|
31
|
+
deployment_uuid: z.optional(z.string()),
|
|
32
|
+
pull_request_id: z.optional(z.int()),
|
|
33
|
+
force_rebuild: z.optional(z.boolean()),
|
|
34
|
+
commit: z.optional(z.string()),
|
|
35
|
+
status: z.optional(z.string()),
|
|
36
|
+
is_webhook: z.optional(z.boolean()),
|
|
37
|
+
is_api: z.optional(z.boolean()),
|
|
38
|
+
created_at: z.optional(z.string()),
|
|
39
|
+
updated_at: z.optional(z.string()),
|
|
40
|
+
logs: z.optional(z.string()),
|
|
41
|
+
current_process_id: z.optional(z.string()),
|
|
42
|
+
restart_only: z.optional(z.boolean()),
|
|
43
|
+
git_type: z.optional(z.string()),
|
|
44
|
+
server_id: z.optional(z.int()),
|
|
45
|
+
application_name: z.optional(z.string()),
|
|
46
|
+
server_name: z.optional(z.string()),
|
|
47
|
+
deployment_url: z.optional(z.string()),
|
|
48
|
+
destination_id: z.optional(z.string()),
|
|
49
|
+
only_this_server: z.optional(z.boolean()),
|
|
50
|
+
rollback: z.optional(z.boolean()),
|
|
51
|
+
commit_message: z.optional(z.string())
|
|
52
|
+
});
|
|
53
|
+
/**
|
|
54
|
+
* Application model
|
|
55
|
+
*/
|
|
56
|
+
export const zApplication = z.object({
|
|
57
|
+
id: z.optional(z.int()),
|
|
58
|
+
description: z.optional(z.string()),
|
|
59
|
+
repository_project_id: z.optional(z.int()),
|
|
60
|
+
uuid: z.optional(z.string()),
|
|
61
|
+
name: z.optional(z.string()),
|
|
62
|
+
fqdn: z.optional(z.string()),
|
|
63
|
+
config_hash: z.optional(z.string()),
|
|
64
|
+
git_repository: z.optional(z.string()),
|
|
65
|
+
git_branch: z.optional(z.string()),
|
|
66
|
+
git_commit_sha: z.optional(z.string()),
|
|
67
|
+
git_full_url: z.optional(z.string()),
|
|
68
|
+
docker_registry_image_name: z.optional(z.string()),
|
|
69
|
+
docker_registry_image_tag: z.optional(z.string()),
|
|
70
|
+
build_pack: z.optional(z.enum([
|
|
71
|
+
'nixpacks',
|
|
72
|
+
'static',
|
|
73
|
+
'dockerfile',
|
|
74
|
+
'dockercompose'
|
|
75
|
+
])),
|
|
76
|
+
static_image: z.optional(z.string()),
|
|
77
|
+
install_command: z.optional(z.string()),
|
|
78
|
+
build_command: z.optional(z.string()),
|
|
79
|
+
start_command: z.optional(z.string()),
|
|
80
|
+
ports_exposes: z.optional(z.string()),
|
|
81
|
+
ports_mappings: z.optional(z.string()),
|
|
82
|
+
custom_network_aliases: z.optional(z.string()),
|
|
83
|
+
base_directory: z.optional(z.string()),
|
|
84
|
+
publish_directory: z.optional(z.string()),
|
|
85
|
+
health_check_enabled: z.optional(z.boolean()),
|
|
86
|
+
health_check_path: z.optional(z.string()),
|
|
87
|
+
health_check_port: z.optional(z.string()),
|
|
88
|
+
health_check_host: z.optional(z.string()),
|
|
89
|
+
health_check_method: z.optional(z.string()),
|
|
90
|
+
health_check_return_code: z.optional(z.int()),
|
|
91
|
+
health_check_scheme: z.optional(z.string()),
|
|
92
|
+
health_check_response_text: z.optional(z.string()),
|
|
93
|
+
health_check_interval: z.optional(z.int()),
|
|
94
|
+
health_check_timeout: z.optional(z.int()),
|
|
95
|
+
health_check_retries: z.optional(z.int()),
|
|
96
|
+
health_check_start_period: z.optional(z.int()),
|
|
97
|
+
limits_memory: z.optional(z.string()),
|
|
98
|
+
limits_memory_swap: z.optional(z.string()),
|
|
99
|
+
limits_memory_swappiness: z.optional(z.int()),
|
|
100
|
+
limits_memory_reservation: z.optional(z.string()),
|
|
101
|
+
limits_cpus: z.optional(z.string()),
|
|
102
|
+
limits_cpuset: z.optional(z.string()),
|
|
103
|
+
limits_cpu_shares: z.optional(z.int()),
|
|
104
|
+
status: z.optional(z.string()),
|
|
105
|
+
preview_url_template: z.optional(z.string()),
|
|
106
|
+
destination_type: z.optional(z.string()),
|
|
107
|
+
destination_id: z.optional(z.int()),
|
|
108
|
+
source_id: z.optional(z.int()),
|
|
109
|
+
private_key_id: z.optional(z.int()),
|
|
110
|
+
environment_id: z.optional(z.int()),
|
|
111
|
+
dockerfile: z.optional(z.string()),
|
|
112
|
+
dockerfile_location: z.optional(z.string()),
|
|
113
|
+
custom_labels: z.optional(z.string()),
|
|
114
|
+
dockerfile_target_build: z.optional(z.string()),
|
|
115
|
+
manual_webhook_secret_github: z.optional(z.string()),
|
|
116
|
+
manual_webhook_secret_gitlab: z.optional(z.string()),
|
|
117
|
+
manual_webhook_secret_bitbucket: z.optional(z.string()),
|
|
118
|
+
manual_webhook_secret_gitea: z.optional(z.string()),
|
|
119
|
+
docker_compose_location: z.optional(z.string()),
|
|
120
|
+
docker_compose: z.optional(z.string()),
|
|
121
|
+
docker_compose_raw: z.optional(z.string()),
|
|
122
|
+
docker_compose_domains: z.optional(z.string()),
|
|
123
|
+
docker_compose_custom_start_command: z.optional(z.string()),
|
|
124
|
+
docker_compose_custom_build_command: z.optional(z.string()),
|
|
125
|
+
swarm_replicas: z.optional(z.int()),
|
|
126
|
+
swarm_placement_constraints: z.optional(z.string()),
|
|
127
|
+
custom_docker_run_options: z.optional(z.string()),
|
|
128
|
+
post_deployment_command: z.optional(z.string()),
|
|
129
|
+
post_deployment_command_container: z.optional(z.string()),
|
|
130
|
+
pre_deployment_command: z.optional(z.string()),
|
|
131
|
+
pre_deployment_command_container: z.optional(z.string()),
|
|
132
|
+
watch_paths: z.optional(z.string()),
|
|
133
|
+
custom_healthcheck_found: z.optional(z.boolean()),
|
|
134
|
+
redirect: z.optional(z.enum([
|
|
135
|
+
'www',
|
|
136
|
+
'non-www',
|
|
137
|
+
'both'
|
|
138
|
+
])),
|
|
139
|
+
created_at: z.optional(z.iso.datetime()),
|
|
140
|
+
updated_at: z.optional(z.iso.datetime()),
|
|
141
|
+
deleted_at: z.optional(z.iso.datetime()),
|
|
142
|
+
compose_parsing_version: z.optional(z.string()),
|
|
143
|
+
custom_nginx_configuration: z.optional(z.string()),
|
|
144
|
+
is_http_basic_auth_enabled: z.optional(z.boolean()),
|
|
145
|
+
http_basic_auth_username: z.optional(z.string()),
|
|
146
|
+
http_basic_auth_password: z.optional(z.string())
|
|
147
|
+
});
|
|
148
|
+
export const zListApplicationsData = z.object({
|
|
149
|
+
body: z.optional(z.never()),
|
|
150
|
+
path: z.optional(z.never()),
|
|
151
|
+
query: z.optional(z.never())
|
|
152
|
+
});
|
|
153
|
+
/**
|
|
154
|
+
* Get all applications.
|
|
155
|
+
*/
|
|
156
|
+
export const zListApplicationsResponse = z.array(zApplication);
|
|
157
|
+
export const zGetApplicationByUuidData = z.object({
|
|
158
|
+
body: z.optional(z.never()),
|
|
159
|
+
path: z.object({
|
|
160
|
+
uuid: z.string()
|
|
161
|
+
}),
|
|
162
|
+
query: z.optional(z.never())
|
|
163
|
+
});
|
|
164
|
+
/**
|
|
165
|
+
* Get application by UUID.
|
|
166
|
+
*/
|
|
167
|
+
export const zGetApplicationByUuidResponse = zApplication;
|
|
168
|
+
export const zGetApplicationLogsByUuidData = z.object({
|
|
169
|
+
body: z.optional(z.never()),
|
|
170
|
+
path: z.object({
|
|
171
|
+
uuid: z.string()
|
|
172
|
+
}),
|
|
173
|
+
query: z.optional(z.object({
|
|
174
|
+
lines: z.optional(z.int().min(-2147483648, { error: 'Invalid value: Expected int32 to be >= -2147483648' }).max(2147483647, { error: 'Invalid value: Expected int32 to be <= 2147483647' })).default(100)
|
|
175
|
+
}))
|
|
176
|
+
});
|
|
177
|
+
/**
|
|
178
|
+
* Get application logs by UUID.
|
|
179
|
+
*/
|
|
180
|
+
export const zGetApplicationLogsByUuidResponse = z.object({
|
|
181
|
+
logs: z.optional(z.string())
|
|
182
|
+
});
|
|
183
|
+
export const zListEnvsByApplicationUuidData = z.object({
|
|
184
|
+
body: z.optional(z.never()),
|
|
185
|
+
path: z.object({
|
|
186
|
+
uuid: z.string()
|
|
187
|
+
}),
|
|
188
|
+
query: z.optional(z.never())
|
|
189
|
+
});
|
|
190
|
+
/**
|
|
191
|
+
* All environment variables by application UUID.
|
|
192
|
+
*/
|
|
193
|
+
export const zListEnvsByApplicationUuidResponse = z.array(zEnvironmentVariable);
|
|
194
|
+
export const zUpdateEnvByApplicationUuidData = z.object({
|
|
195
|
+
body: z.object({
|
|
196
|
+
key: z.string(),
|
|
197
|
+
value: z.string(),
|
|
198
|
+
is_preview: z.optional(z.boolean()),
|
|
199
|
+
is_literal: z.optional(z.boolean()),
|
|
200
|
+
is_multiline: z.optional(z.boolean()),
|
|
201
|
+
is_shown_once: z.optional(z.boolean())
|
|
202
|
+
}),
|
|
203
|
+
path: z.object({
|
|
204
|
+
uuid: z.string()
|
|
205
|
+
}),
|
|
206
|
+
query: z.optional(z.never())
|
|
207
|
+
});
|
|
208
|
+
/**
|
|
209
|
+
* Environment variable updated.
|
|
210
|
+
*/
|
|
211
|
+
export const zUpdateEnvByApplicationUuidResponse = z.object({
|
|
212
|
+
message: z.optional(z.string())
|
|
213
|
+
});
|
|
214
|
+
export const zCreateEnvByApplicationUuidData = z.object({
|
|
215
|
+
body: z.object({
|
|
216
|
+
key: z.optional(z.string()),
|
|
217
|
+
value: z.optional(z.string()),
|
|
218
|
+
is_preview: z.optional(z.boolean()),
|
|
219
|
+
is_literal: z.optional(z.boolean()),
|
|
220
|
+
is_multiline: z.optional(z.boolean()),
|
|
221
|
+
is_shown_once: z.optional(z.boolean())
|
|
222
|
+
}),
|
|
223
|
+
path: z.object({
|
|
224
|
+
uuid: z.string()
|
|
225
|
+
}),
|
|
226
|
+
query: z.optional(z.never())
|
|
227
|
+
});
|
|
228
|
+
/**
|
|
229
|
+
* Environment variable created.
|
|
230
|
+
*/
|
|
231
|
+
export const zCreateEnvByApplicationUuidResponse = z.object({
|
|
232
|
+
uuid: z.optional(z.string())
|
|
233
|
+
});
|
|
234
|
+
export const zListDatabasesData = z.object({
|
|
235
|
+
body: z.optional(z.never()),
|
|
236
|
+
path: z.optional(z.never()),
|
|
237
|
+
query: z.optional(z.never())
|
|
238
|
+
});
|
|
239
|
+
/**
|
|
240
|
+
* Get all databases
|
|
241
|
+
*/
|
|
242
|
+
export const zListDatabasesResponse = z.string();
|
|
243
|
+
export const zGetDatabaseByUuidData = z.object({
|
|
244
|
+
body: z.optional(z.never()),
|
|
245
|
+
path: z.object({
|
|
246
|
+
uuid: z.string()
|
|
247
|
+
}),
|
|
248
|
+
query: z.optional(z.never())
|
|
249
|
+
});
|
|
250
|
+
/**
|
|
251
|
+
* Get all databases
|
|
252
|
+
*/
|
|
253
|
+
export const zGetDatabaseByUuidResponse = z.string();
|
|
254
|
+
export const zListDeploymentsData = z.object({
|
|
255
|
+
body: z.optional(z.never()),
|
|
256
|
+
path: z.optional(z.never()),
|
|
257
|
+
query: z.optional(z.never())
|
|
258
|
+
});
|
|
259
|
+
/**
|
|
260
|
+
* Get all currently running deployments.
|
|
261
|
+
*/
|
|
262
|
+
export const zListDeploymentsResponse = z.array(zApplicationDeploymentQueue);
|
|
263
|
+
export const zGetDeploymentByUuidData = z.object({
|
|
264
|
+
body: z.optional(z.never()),
|
|
265
|
+
path: z.object({
|
|
266
|
+
uuid: z.string()
|
|
267
|
+
}),
|
|
268
|
+
query: z.optional(z.never())
|
|
269
|
+
});
|
|
270
|
+
/**
|
|
271
|
+
* Get deployment by UUID.
|
|
272
|
+
*/
|
|
273
|
+
export const zGetDeploymentByUuidResponse = zApplicationDeploymentQueue;
|
|
274
|
+
export const zCancelDeploymentByUuidData = z.object({
|
|
275
|
+
body: z.optional(z.never()),
|
|
276
|
+
path: z.object({
|
|
277
|
+
uuid: z.string()
|
|
278
|
+
}),
|
|
279
|
+
query: z.optional(z.never())
|
|
280
|
+
});
|
|
281
|
+
/**
|
|
282
|
+
* Deployment cancelled successfully.
|
|
283
|
+
*/
|
|
284
|
+
export const zCancelDeploymentByUuidResponse = z.object({
|
|
285
|
+
message: z.optional(z.string()),
|
|
286
|
+
deployment_uuid: z.optional(z.string()),
|
|
287
|
+
status: z.optional(z.string())
|
|
288
|
+
});
|
|
289
|
+
export const zDeployByTagOrUuidData = z.object({
|
|
290
|
+
body: z.optional(z.never()),
|
|
291
|
+
path: z.optional(z.never()),
|
|
292
|
+
query: z.optional(z.object({
|
|
293
|
+
tag: z.optional(z.string()),
|
|
294
|
+
uuid: z.optional(z.string()),
|
|
295
|
+
force: z.optional(z.boolean()),
|
|
296
|
+
pr: z.optional(z.int())
|
|
297
|
+
}))
|
|
298
|
+
});
|
|
299
|
+
/**
|
|
300
|
+
* Get deployment(s) UUID's
|
|
301
|
+
*/
|
|
302
|
+
export const zDeployByTagOrUuidResponse = z.object({
|
|
303
|
+
deployments: z.optional(z.array(z.object({
|
|
304
|
+
message: z.optional(z.string()),
|
|
305
|
+
resource_uuid: z.optional(z.string()),
|
|
306
|
+
deployment_uuid: z.optional(z.string())
|
|
307
|
+
})))
|
|
308
|
+
});
|
|
309
|
+
export const zListDeploymentsByAppUuidData = z.object({
|
|
310
|
+
body: z.optional(z.never()),
|
|
311
|
+
path: z.object({
|
|
312
|
+
uuid: z.string()
|
|
313
|
+
}),
|
|
314
|
+
query: z.optional(z.object({
|
|
315
|
+
skip: z.optional(z.int().gte(0)).default(0),
|
|
316
|
+
take: z.optional(z.int().gte(1)).default(10)
|
|
317
|
+
}))
|
|
318
|
+
});
|
|
319
|
+
/**
|
|
320
|
+
* List application deployments by using the app uuid.
|
|
321
|
+
*/
|
|
322
|
+
export const zListDeploymentsByAppUuidResponse = z.array(zApplication);
|
|
323
|
+
export const zVersionData = z.object({
|
|
324
|
+
body: z.optional(z.never()),
|
|
325
|
+
path: z.optional(z.never()),
|
|
326
|
+
query: z.optional(z.never())
|
|
327
|
+
});
|
|
328
|
+
/**
|
|
329
|
+
* Returns the version of the application
|
|
330
|
+
*/
|
|
331
|
+
export const zVersionResponse = z.string();
|
|
332
|
+
export const zListResourcesData = z.object({
|
|
333
|
+
body: z.optional(z.never()),
|
|
334
|
+
path: z.optional(z.never()),
|
|
335
|
+
query: z.optional(z.never())
|
|
336
|
+
});
|
|
337
|
+
/**
|
|
338
|
+
* Get all resources
|
|
339
|
+
*/
|
|
340
|
+
export const zListResourcesResponse = z.string();
|
package/dist/server.js
CHANGED
|
@@ -1,22 +1,40 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
+
import { createRequire } from 'node:module';
|
|
2
3
|
import { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';
|
|
3
4
|
import { StdioServerTransport } from '@modelcontextprotocol/sdk/server/stdio.js';
|
|
4
5
|
import { StreamableHTTPServerTransport } from '@modelcontextprotocol/sdk/server/streamableHttp.js';
|
|
5
6
|
import express from 'express';
|
|
6
7
|
import { registerCoolifyTools } from './tools/coolify.js';
|
|
7
8
|
import { COOLIFY_OPENAPI_REF, COOLIFY_STRICT_VERSION, MCP_HTTP_PORT, MCP_TRANSPORT, } from './config.js';
|
|
8
|
-
import {
|
|
9
|
+
import { initializeClient } from './coolify/client.js';
|
|
10
|
+
import { version } from './generated/sdk.gen.js';
|
|
11
|
+
const require = createRequire(import.meta.url);
|
|
12
|
+
const { version: MCP_VERSION } = require('../package.json');
|
|
9
13
|
const server = new McpServer({
|
|
10
14
|
name: 'coolify-mcp',
|
|
11
|
-
version:
|
|
15
|
+
version: MCP_VERSION,
|
|
12
16
|
});
|
|
17
|
+
initializeClient();
|
|
13
18
|
registerCoolifyTools(server);
|
|
14
19
|
function normalizeVersion(value) {
|
|
15
20
|
return value.replace(/^v/i, '');
|
|
16
21
|
}
|
|
22
|
+
function extractVersion(data) {
|
|
23
|
+
if (typeof data === 'string')
|
|
24
|
+
return data;
|
|
25
|
+
if (data && typeof data === 'object' && 'version' in data) {
|
|
26
|
+
return String(data.version);
|
|
27
|
+
}
|
|
28
|
+
return 'unknown';
|
|
29
|
+
}
|
|
17
30
|
async function checkVersion() {
|
|
18
31
|
try {
|
|
19
|
-
const
|
|
32
|
+
const result = await version();
|
|
33
|
+
if ('error' in result && result.error) {
|
|
34
|
+
throw new Error('Failed to fetch version');
|
|
35
|
+
}
|
|
36
|
+
const data = 'data' in result ? result.data : undefined;
|
|
37
|
+
const current = extractVersion(data);
|
|
20
38
|
if (normalizeVersion(current) !== normalizeVersion(COOLIFY_OPENAPI_REF)) {
|
|
21
39
|
const message = `Coolify version mismatch. Server=${current}, OpenAPI=${COOLIFY_OPENAPI_REF}.`;
|
|
22
40
|
if (COOLIFY_STRICT_VERSION) {
|
package/dist/tools/coolify.js
CHANGED
|
@@ -1,130 +1,133 @@
|
|
|
1
|
-
import
|
|
2
|
-
import
|
|
3
|
-
import
|
|
4
|
-
function
|
|
1
|
+
import { COOLIFY_ALLOW_WRITE } from "../config.js";
|
|
2
|
+
import * as sdk from "../generated/sdk.gen.js";
|
|
3
|
+
import * as z from "../generated/zod.gen.js";
|
|
4
|
+
async function unwrap(promise) {
|
|
5
|
+
const result = await promise;
|
|
6
|
+
if (result.error) {
|
|
7
|
+
const msg = typeof result.error === "object" &&
|
|
8
|
+
result.error !== null &&
|
|
9
|
+
"message" in result.error
|
|
10
|
+
? String(result.error.message)
|
|
11
|
+
: "API request failed";
|
|
12
|
+
throw new Error(msg);
|
|
13
|
+
}
|
|
14
|
+
return result.data;
|
|
15
|
+
}
|
|
16
|
+
// Convert any data to Record for structuredContent (single conversion point)
|
|
17
|
+
function toRecord(data) {
|
|
18
|
+
if (data === null || data === undefined)
|
|
19
|
+
return {};
|
|
20
|
+
if (typeof data === "object" && !Array.isArray(data)) {
|
|
21
|
+
return data;
|
|
22
|
+
}
|
|
23
|
+
// Wrap primitives and arrays in a data property
|
|
24
|
+
return { data };
|
|
25
|
+
}
|
|
26
|
+
const ok = (text, data) => ({
|
|
27
|
+
content: [{ type: "text", text }],
|
|
28
|
+
structuredContent: toRecord(data),
|
|
29
|
+
});
|
|
30
|
+
const list = (text, items) => ok(text, { items });
|
|
31
|
+
function requireWrite() {
|
|
5
32
|
if (!COOLIFY_ALLOW_WRITE) {
|
|
6
|
-
throw new Error(
|
|
33
|
+
throw new Error("Write operations are disabled (COOLIFY_ALLOW_WRITE=false).");
|
|
7
34
|
}
|
|
8
35
|
}
|
|
9
36
|
export function registerCoolifyTools(server) {
|
|
10
|
-
server.registerTool(
|
|
11
|
-
title:
|
|
12
|
-
description:
|
|
37
|
+
server.registerTool("coolify.listResources", {
|
|
38
|
+
title: "List resources",
|
|
39
|
+
description: "List all Coolify resources.",
|
|
13
40
|
inputSchema: {},
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
outputSchema: { envs: z.array(z.unknown()) },
|
|
39
|
-
}, async ({ appUuid }) => {
|
|
40
|
-
const data = await request('GET', `/api/v1/applications/${appUuid}/envs`);
|
|
41
|
-
return {
|
|
42
|
-
content: [{ type: 'text', text: `Env vars for ${appUuid} fetched.` }],
|
|
43
|
-
structuredContent: { envs: data },
|
|
44
|
-
};
|
|
45
|
-
});
|
|
46
|
-
server.registerTool('coolify.upsertEnv', {
|
|
47
|
-
title: 'Upsert environment variable',
|
|
48
|
-
description: 'Upsert an environment variable for an application.',
|
|
41
|
+
}, async () => list("Resources fetched.", await unwrap(sdk.listResources())));
|
|
42
|
+
server.registerTool("coolify.listApplications", {
|
|
43
|
+
title: "List applications",
|
|
44
|
+
description: "List all Coolify applications.",
|
|
45
|
+
inputSchema: {},
|
|
46
|
+
}, async () => list("Applications fetched.", await unwrap(sdk.listApplications())));
|
|
47
|
+
server.registerTool("coolify.listDatabases", {
|
|
48
|
+
title: "List databases",
|
|
49
|
+
description: "List all Coolify databases.",
|
|
50
|
+
inputSchema: {},
|
|
51
|
+
}, async () => list("Databases fetched.", await unwrap(sdk.listDatabases())));
|
|
52
|
+
server.registerTool("coolify.listDeployments", {
|
|
53
|
+
title: "List deployments",
|
|
54
|
+
description: "List currently running deployments.",
|
|
55
|
+
inputSchema: {},
|
|
56
|
+
}, async () => list("Running deployments fetched.", await unwrap(sdk.listDeployments())));
|
|
57
|
+
server.registerTool("coolify.listEnvs", {
|
|
58
|
+
title: "List env vars",
|
|
59
|
+
description: "List environment variables for an application.",
|
|
60
|
+
inputSchema: z.zListEnvsByApplicationUuidData.shape.path.shape,
|
|
61
|
+
}, async ({ uuid }) => list(`Env vars for ${uuid} fetched.`, await unwrap(sdk.listEnvsByApplicationUuid({ path: { uuid } }))));
|
|
62
|
+
server.registerTool("coolify.listAppDeployments", {
|
|
63
|
+
title: "List app deployments",
|
|
64
|
+
description: "List deployments for an application with pagination (skip/take).",
|
|
49
65
|
inputSchema: {
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
value: z.string(),
|
|
53
|
-
is_buildtime: z.boolean().optional(),
|
|
54
|
-
is_runtime: z.boolean().optional(),
|
|
66
|
+
...z.zListDeploymentsByAppUuidData.shape.path.shape,
|
|
67
|
+
...z.zListDeploymentsByAppUuidData.shape.query.unwrap().shape,
|
|
55
68
|
},
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
});
|
|
67
|
-
server.registerTool(
|
|
68
|
-
title:
|
|
69
|
-
description:
|
|
70
|
-
inputSchema:
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
}, async ({
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
structuredContent: { deployment: data },
|
|
92
|
-
};
|
|
69
|
+
}, async ({ uuid, ...query }) => list(`Deployments for ${uuid} fetched.`, await unwrap(sdk.listDeploymentsByAppUuid({ path: { uuid }, query }))));
|
|
70
|
+
server.registerTool("coolify.getApplication", {
|
|
71
|
+
title: "Get application",
|
|
72
|
+
description: "Get application details by UUID.",
|
|
73
|
+
inputSchema: z.zGetApplicationByUuidData.shape.path.shape,
|
|
74
|
+
}, async ({ uuid }) => ok(`Application ${uuid} fetched.`, await unwrap(sdk.getApplicationByUuid({ path: { uuid } }))));
|
|
75
|
+
server.registerTool("coolify.getDatabase", {
|
|
76
|
+
title: "Get database",
|
|
77
|
+
description: "Get database details by UUID.",
|
|
78
|
+
inputSchema: z.zGetDatabaseByUuidData.shape.path.shape,
|
|
79
|
+
}, async ({ uuid }) => ok(`Database ${uuid} fetched.`, await unwrap(sdk.getDatabaseByUuid({ path: { uuid } }))));
|
|
80
|
+
server.registerTool("coolify.getDeployment", {
|
|
81
|
+
title: "Get deployment",
|
|
82
|
+
description: "Get deployment status and logs by UUID.",
|
|
83
|
+
inputSchema: z.zGetDeploymentByUuidData.shape.path.shape,
|
|
84
|
+
}, async ({ uuid }) => ok(`Deployment ${uuid} fetched.`, await unwrap(sdk.getDeploymentByUuid({ path: { uuid } }))));
|
|
85
|
+
server.registerTool("coolify.getLogs", {
|
|
86
|
+
title: "Get logs",
|
|
87
|
+
description: "Fetch runtime logs for an application.",
|
|
88
|
+
inputSchema: {
|
|
89
|
+
...z.zGetApplicationLogsByUuidData.shape.path.shape,
|
|
90
|
+
...z.zGetApplicationLogsByUuidData.shape.query.unwrap().shape,
|
|
91
|
+
},
|
|
92
|
+
}, async ({ uuid, ...query }) => ok("Logs fetched.", await unwrap(sdk.getApplicationLogsByUuid({ path: { uuid }, query }))));
|
|
93
|
+
server.registerTool("coolify.createEnv", {
|
|
94
|
+
title: "Create env var",
|
|
95
|
+
description: "Create a new environment variable for an application.",
|
|
96
|
+
inputSchema: {
|
|
97
|
+
...z.zCreateEnvByApplicationUuidData.shape.path.shape,
|
|
98
|
+
...z.zCreateEnvByApplicationUuidData.shape.body.shape,
|
|
99
|
+
},
|
|
100
|
+
}, async ({ uuid, ...body }) => {
|
|
101
|
+
requireWrite();
|
|
102
|
+
const data = await unwrap(sdk.createEnvByApplicationUuid({ path: { uuid }, body }));
|
|
103
|
+
return ok(`Env var ${body.key} created.`, data);
|
|
93
104
|
});
|
|
94
|
-
server.registerTool(
|
|
95
|
-
title:
|
|
96
|
-
description:
|
|
97
|
-
inputSchema: {
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
};
|
|
105
|
+
server.registerTool("coolify.updateEnv", {
|
|
106
|
+
title: "Update env var",
|
|
107
|
+
description: "Update an existing environment variable for an application.",
|
|
108
|
+
inputSchema: {
|
|
109
|
+
...z.zUpdateEnvByApplicationUuidData.shape.path.shape,
|
|
110
|
+
...z.zUpdateEnvByApplicationUuidData.shape.body.shape,
|
|
111
|
+
},
|
|
112
|
+
}, async ({ uuid, ...body }) => {
|
|
113
|
+
requireWrite();
|
|
114
|
+
const data = await unwrap(sdk.updateEnvByApplicationUuid({ path: { uuid }, body }));
|
|
115
|
+
return ok(`Env var ${body.key} updated.`, data);
|
|
105
116
|
});
|
|
106
|
-
server.registerTool(
|
|
107
|
-
title:
|
|
108
|
-
description:
|
|
109
|
-
inputSchema:
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
return {
|
|
114
|
-
content: [{ type: 'text', text: 'Databases fetched.' }],
|
|
115
|
-
structuredContent: { databases: data },
|
|
116
|
-
};
|
|
117
|
+
server.registerTool("coolify.deploy", {
|
|
118
|
+
title: "Trigger deploy",
|
|
119
|
+
description: "Trigger a deployment for an application by UUID or tag.",
|
|
120
|
+
inputSchema: z.zDeployByTagOrUuidData.shape.query.unwrap().shape,
|
|
121
|
+
}, async (query) => {
|
|
122
|
+
requireWrite();
|
|
123
|
+
return ok("Deployment triggered.", await unwrap(sdk.deployByTagOrUuid({ query })));
|
|
117
124
|
});
|
|
118
|
-
server.registerTool(
|
|
119
|
-
title:
|
|
120
|
-
description:
|
|
121
|
-
inputSchema:
|
|
122
|
-
outputSchema: { database: z.unknown() },
|
|
125
|
+
server.registerTool("coolify.cancelDeployment", {
|
|
126
|
+
title: "Cancel deployment",
|
|
127
|
+
description: "Cancel a running deployment by UUID.",
|
|
128
|
+
inputSchema: z.zCancelDeploymentByUuidData.shape.path.shape,
|
|
123
129
|
}, async ({ uuid }) => {
|
|
124
|
-
|
|
125
|
-
return {
|
|
126
|
-
content: [{ type: 'text', text: `Database ${uuid} fetched.` }],
|
|
127
|
-
structuredContent: { database: data },
|
|
128
|
-
};
|
|
130
|
+
requireWrite();
|
|
131
|
+
return ok(`Deployment ${uuid} cancelled.`, await unwrap(sdk.cancelDeploymentByUuid({ path: { uuid } })));
|
|
129
132
|
});
|
|
130
133
|
}
|