@masonator/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/dist/__tests__/coolify-client.test.js +137 -398
- package/dist/__tests__/mcp-server.test.js +24 -26
- package/dist/__tests__/resources/application-resources.test.js +6 -9
- package/dist/__tests__/resources/database-resources.test.js +30 -34
- package/dist/__tests__/resources/deployment-resources.test.js +19 -20
- package/dist/__tests__/resources/service-resources.test.js +36 -41
- package/dist/index.js +4 -6
- package/dist/lib/coolify-client.js +1 -5
- package/dist/lib/mcp-server.d.ts +2 -2
- package/dist/lib/mcp-server.js +542 -509
- package/dist/lib/resource.js +3 -7
- package/dist/resources/application-resources.js +6 -10
- package/dist/resources/database-resources.js +6 -10
- package/dist/resources/deployment-resources.js +5 -9
- package/dist/resources/index.js +4 -20
- package/dist/resources/service-resources.js +6 -10
- package/dist/types/coolify.js +1 -2
- package/package.json +17 -11
package/dist/lib/mcp-server.js
CHANGED
|
@@ -1,522 +1,556 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
const index_js_1 = require("../resources/index.js");
|
|
8
|
-
class CoolifyMcpServer {
|
|
1
|
+
import { Server } from '@modelcontextprotocol/sdk/server/index.js';
|
|
2
|
+
import { CallToolRequestSchema, ListToolsRequestSchema } from '@modelcontextprotocol/sdk/types.js';
|
|
3
|
+
import { CoolifyClient } from './coolify-client.js';
|
|
4
|
+
import { z } from 'zod';
|
|
5
|
+
import { DatabaseResources, DeploymentResources, ApplicationResources, ServiceResources, } from '../resources/index.js';
|
|
6
|
+
export class CoolifyMcpServer {
|
|
9
7
|
constructor(config) {
|
|
10
|
-
this.
|
|
8
|
+
this.client = new CoolifyClient(config);
|
|
9
|
+
this.server = new Server({
|
|
11
10
|
name: 'coolify',
|
|
12
11
|
version: '0.1.0',
|
|
12
|
+
}, {
|
|
13
|
+
capabilities: {
|
|
14
|
+
tools: {},
|
|
15
|
+
},
|
|
13
16
|
});
|
|
14
|
-
this.
|
|
15
|
-
this.
|
|
16
|
-
this.
|
|
17
|
-
this.
|
|
18
|
-
this.
|
|
19
|
-
this.setupTools();
|
|
17
|
+
this.databaseResources = new DatabaseResources(this.client);
|
|
18
|
+
this.deploymentResources = new DeploymentResources(this.client);
|
|
19
|
+
this.applicationResources = new ApplicationResources(this.client);
|
|
20
|
+
this.serviceResources = new ServiceResources(this.client);
|
|
21
|
+
this.setupHandlers();
|
|
20
22
|
}
|
|
21
|
-
|
|
22
|
-
this.server.
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
limits_cpus: zod_1.z.string().optional().describe('CPU limit (e.g., "0.5", "1")'),
|
|
253
|
-
limits_cpuset: zod_1.z.string().optional().describe('CPU set (e.g., "0", "0,1")'),
|
|
254
|
-
limits_cpu_shares: zod_1.z.number().optional().describe('CPU shares (relative weight)'),
|
|
255
|
-
// Database-specific configuration
|
|
256
|
-
postgres_user: zod_1.z.string().optional().describe('PostgreSQL user'),
|
|
257
|
-
postgres_password: zod_1.z.string().optional().describe('PostgreSQL password'),
|
|
258
|
-
postgres_db: zod_1.z.string().optional().describe('PostgreSQL database name'),
|
|
259
|
-
postgres_initdb_args: zod_1.z.string().optional().describe('PostgreSQL initdb arguments'),
|
|
260
|
-
postgres_host_auth_method: zod_1.z.string().optional().describe('PostgreSQL host auth method'),
|
|
261
|
-
postgres_conf: zod_1.z.string().optional().describe('PostgreSQL configuration'),
|
|
262
|
-
clickhouse_admin_user: zod_1.z.string().optional().describe('Clickhouse admin user'),
|
|
263
|
-
clickhouse_admin_password: zod_1.z.string().optional().describe('Clickhouse admin password'),
|
|
264
|
-
dragonfly_password: zod_1.z.string().optional().describe('Dragonfly password'),
|
|
265
|
-
redis_password: zod_1.z.string().optional().describe('Redis password'),
|
|
266
|
-
redis_conf: zod_1.z.string().optional().describe('Redis configuration'),
|
|
267
|
-
keydb_password: zod_1.z.string().optional().describe('KeyDB password'),
|
|
268
|
-
keydb_conf: zod_1.z.string().optional().describe('KeyDB configuration'),
|
|
269
|
-
mariadb_conf: zod_1.z.string().optional().describe('MariaDB configuration'),
|
|
270
|
-
mariadb_root_password: zod_1.z.string().optional().describe('MariaDB root password'),
|
|
271
|
-
mariadb_user: zod_1.z.string().optional().describe('MariaDB user'),
|
|
272
|
-
mariadb_password: zod_1.z.string().optional().describe('MariaDB password'),
|
|
273
|
-
mariadb_database: zod_1.z.string().optional().describe('MariaDB database name'),
|
|
274
|
-
mongo_conf: zod_1.z.string().optional().describe('MongoDB configuration'),
|
|
275
|
-
mongo_initdb_root_username: zod_1.z.string().optional().describe('MongoDB root username'),
|
|
276
|
-
mongo_initdb_root_password: zod_1.z.string().optional().describe('MongoDB root password'),
|
|
277
|
-
mongo_initdb_database: zod_1.z.string().optional().describe('MongoDB initial database'),
|
|
278
|
-
mysql_root_password: zod_1.z.string().optional().describe('MySQL root password'),
|
|
279
|
-
mysql_password: zod_1.z.string().optional().describe('MySQL password'),
|
|
280
|
-
mysql_user: zod_1.z.string().optional().describe('MySQL user'),
|
|
281
|
-
mysql_database: zod_1.z.string().optional().describe('MySQL database name'),
|
|
282
|
-
}, async (params) => {
|
|
283
|
-
try {
|
|
284
|
-
const { uuid, ...updateData } = params;
|
|
285
|
-
const result = await this.client.updateDatabase(uuid, updateData);
|
|
286
|
-
return {
|
|
287
|
-
content: [{ type: 'text', text: JSON.stringify(result) }],
|
|
288
|
-
isError: false,
|
|
289
|
-
};
|
|
290
|
-
}
|
|
291
|
-
catch (error) {
|
|
292
|
-
const errorMessage = error instanceof Error ? error.message : 'Unknown error';
|
|
293
|
-
return {
|
|
294
|
-
content: [{ type: 'text', text: errorMessage }],
|
|
295
|
-
isError: true,
|
|
296
|
-
};
|
|
297
|
-
}
|
|
298
|
-
});
|
|
299
|
-
this.server.tool('delete_database', 'Delete a database', {
|
|
300
|
-
uuid: zod_1.z.string().describe('UUID of the database to delete'),
|
|
301
|
-
deleteConfigurations: zod_1.z.boolean().optional().describe('Whether to delete configurations'),
|
|
302
|
-
deleteVolumes: zod_1.z.boolean().optional().describe('Whether to delete volumes'),
|
|
303
|
-
dockerCleanup: zod_1.z.boolean().optional().describe('Whether to run docker cleanup'),
|
|
304
|
-
deleteConnectedNetworks: zod_1.z
|
|
305
|
-
.boolean()
|
|
306
|
-
.optional()
|
|
307
|
-
.describe('Whether to delete connected networks'),
|
|
308
|
-
}, async (params) => {
|
|
309
|
-
try {
|
|
310
|
-
const { uuid, ...options } = params;
|
|
311
|
-
const result = await this.client.deleteDatabase(uuid, options);
|
|
312
|
-
return {
|
|
313
|
-
content: [{ type: 'text', text: JSON.stringify(result) }],
|
|
314
|
-
isError: false,
|
|
315
|
-
};
|
|
316
|
-
}
|
|
317
|
-
catch (error) {
|
|
318
|
-
const errorMessage = error instanceof Error ? error.message : 'Unknown error';
|
|
319
|
-
return {
|
|
320
|
-
content: [{ type: 'text', text: errorMessage }],
|
|
321
|
-
isError: true,
|
|
322
|
-
};
|
|
323
|
-
}
|
|
324
|
-
});
|
|
325
|
-
this.server.tool('deploy_application', 'Deploy an application using its UUID', {
|
|
326
|
-
uuid: zod_1.z.string().describe('UUID of the application to deploy'),
|
|
327
|
-
}, async (params) => {
|
|
328
|
-
try {
|
|
329
|
-
const deployment = await this.client.deployApplication(params.uuid);
|
|
330
|
-
return {
|
|
331
|
-
content: [{ type: 'text', text: JSON.stringify(deployment) }],
|
|
332
|
-
isError: false,
|
|
333
|
-
};
|
|
334
|
-
}
|
|
335
|
-
catch (error) {
|
|
336
|
-
const errorMessage = error instanceof Error ? error.message : 'Unknown error';
|
|
337
|
-
return {
|
|
338
|
-
content: [{ type: 'text', text: errorMessage }],
|
|
339
|
-
isError: true,
|
|
340
|
-
};
|
|
341
|
-
}
|
|
342
|
-
});
|
|
343
|
-
this.server.tool('list_services', 'List all services', {}, async () => {
|
|
344
|
-
try {
|
|
345
|
-
const services = await this.client.listServices();
|
|
346
|
-
return {
|
|
347
|
-
content: [{ type: 'text', text: JSON.stringify(services) }],
|
|
348
|
-
isError: false,
|
|
349
|
-
};
|
|
350
|
-
}
|
|
351
|
-
catch (error) {
|
|
352
|
-
const errorMessage = error instanceof Error ? error.message : 'Unknown error';
|
|
353
|
-
return {
|
|
354
|
-
content: [{ type: 'text', text: errorMessage }],
|
|
355
|
-
isError: true,
|
|
356
|
-
};
|
|
357
|
-
}
|
|
358
|
-
});
|
|
359
|
-
this.server.tool('get_service', 'Get details about a specific service', { uuid: zod_1.z.string().describe('UUID of the service to get details for') }, async (params) => {
|
|
360
|
-
try {
|
|
361
|
-
const service = await this.client.getService(params.uuid);
|
|
362
|
-
return {
|
|
363
|
-
content: [{ type: 'text', text: JSON.stringify(service) }],
|
|
364
|
-
isError: false,
|
|
365
|
-
};
|
|
366
|
-
}
|
|
367
|
-
catch (error) {
|
|
368
|
-
const errorMessage = error instanceof Error ? error.message : 'Unknown error';
|
|
369
|
-
return {
|
|
370
|
-
content: [{ type: 'text', text: errorMessage }],
|
|
371
|
-
isError: true,
|
|
372
|
-
};
|
|
373
|
-
}
|
|
374
|
-
});
|
|
375
|
-
this.server.tool('create_service', 'Create a new service', {
|
|
376
|
-
type: zod_1.z
|
|
377
|
-
.enum([
|
|
378
|
-
'activepieces',
|
|
379
|
-
'appsmith',
|
|
380
|
-
'appwrite',
|
|
381
|
-
'authentik',
|
|
382
|
-
'babybuddy',
|
|
383
|
-
'budge',
|
|
384
|
-
'changedetection',
|
|
385
|
-
'chatwoot',
|
|
386
|
-
'classicpress-with-mariadb',
|
|
387
|
-
'classicpress-with-mysql',
|
|
388
|
-
'classicpress-without-database',
|
|
389
|
-
'cloudflared',
|
|
390
|
-
'code-server',
|
|
391
|
-
'dashboard',
|
|
392
|
-
'directus',
|
|
393
|
-
'directus-with-postgresql',
|
|
394
|
-
'docker-registry',
|
|
395
|
-
'docuseal',
|
|
396
|
-
'docuseal-with-postgres',
|
|
397
|
-
'dokuwiki',
|
|
398
|
-
'duplicati',
|
|
399
|
-
'emby',
|
|
400
|
-
'embystat',
|
|
401
|
-
'fider',
|
|
402
|
-
'filebrowser',
|
|
403
|
-
'firefly',
|
|
404
|
-
'formbricks',
|
|
405
|
-
'ghost',
|
|
406
|
-
'gitea',
|
|
407
|
-
'gitea-with-mariadb',
|
|
408
|
-
'gitea-with-mysql',
|
|
409
|
-
'gitea-with-postgresql',
|
|
410
|
-
'glance',
|
|
411
|
-
'glances',
|
|
412
|
-
'glitchtip',
|
|
413
|
-
'grafana',
|
|
414
|
-
'grafana-with-postgresql',
|
|
415
|
-
'grocy',
|
|
416
|
-
'heimdall',
|
|
417
|
-
'homepage',
|
|
418
|
-
'jellyfin',
|
|
419
|
-
'kuzzle',
|
|
420
|
-
'listmonk',
|
|
421
|
-
'logto',
|
|
422
|
-
'mediawiki',
|
|
423
|
-
'meilisearch',
|
|
424
|
-
'metabase',
|
|
425
|
-
'metube',
|
|
426
|
-
'minio',
|
|
427
|
-
'moodle',
|
|
428
|
-
'n8n',
|
|
429
|
-
'n8n-with-postgresql',
|
|
430
|
-
'next-image-transformation',
|
|
431
|
-
'nextcloud',
|
|
432
|
-
'nocodb',
|
|
433
|
-
'odoo',
|
|
434
|
-
'openblocks',
|
|
435
|
-
'pairdrop',
|
|
436
|
-
'penpot',
|
|
437
|
-
'phpmyadmin',
|
|
438
|
-
'pocketbase',
|
|
439
|
-
'posthog',
|
|
440
|
-
'reactive-resume',
|
|
441
|
-
'rocketchat',
|
|
442
|
-
'shlink',
|
|
443
|
-
'slash',
|
|
444
|
-
'snapdrop',
|
|
445
|
-
'statusnook',
|
|
446
|
-
'stirling-pdf',
|
|
447
|
-
'supabase',
|
|
448
|
-
'syncthing',
|
|
449
|
-
'tolgee',
|
|
450
|
-
'trigger',
|
|
451
|
-
'trigger-with-external-database',
|
|
452
|
-
'twenty',
|
|
453
|
-
'umami',
|
|
454
|
-
'unleash-with-postgresql',
|
|
455
|
-
'unleash-without-database',
|
|
456
|
-
'uptime-kuma',
|
|
457
|
-
'vaultwarden',
|
|
458
|
-
'vikunja',
|
|
459
|
-
'weblate',
|
|
460
|
-
'whoogle',
|
|
461
|
-
'wordpress-with-mariadb',
|
|
462
|
-
'wordpress-with-mysql',
|
|
463
|
-
'wordpress-without-database',
|
|
464
|
-
])
|
|
465
|
-
.describe('Type of service to create'),
|
|
466
|
-
name: zod_1.z.string().optional().describe('Name for the service'),
|
|
467
|
-
description: zod_1.z.string().optional().describe('Description of the service'),
|
|
468
|
-
project_uuid: zod_1.z.string().describe('UUID of the project to create the service in'),
|
|
469
|
-
environment_name: zod_1.z.string().optional().describe('Name of the environment'),
|
|
470
|
-
environment_uuid: zod_1.z.string().optional().describe('UUID of the environment'),
|
|
471
|
-
server_uuid: zod_1.z.string().describe('UUID of the server to deploy the service on'),
|
|
472
|
-
destination_uuid: zod_1.z.string().optional().describe('UUID of the destination'),
|
|
473
|
-
instant_deploy: zod_1.z
|
|
474
|
-
.boolean()
|
|
475
|
-
.optional()
|
|
476
|
-
.describe('Whether to deploy the service immediately'),
|
|
477
|
-
}, async (params) => {
|
|
478
|
-
try {
|
|
479
|
-
const result = await this.client.createService(params);
|
|
480
|
-
return {
|
|
481
|
-
content: [{ type: 'text', text: JSON.stringify(result) }],
|
|
482
|
-
isError: false,
|
|
483
|
-
};
|
|
484
|
-
}
|
|
485
|
-
catch (error) {
|
|
486
|
-
const errorMessage = error instanceof Error ? error.message : 'Unknown error';
|
|
487
|
-
return {
|
|
488
|
-
content: [{ type: 'text', text: errorMessage }],
|
|
489
|
-
isError: true,
|
|
490
|
-
};
|
|
491
|
-
}
|
|
23
|
+
setupHandlers() {
|
|
24
|
+
this.server.setRequestHandler(ListToolsRequestSchema, async () => {
|
|
25
|
+
return {
|
|
26
|
+
tools: [
|
|
27
|
+
{
|
|
28
|
+
name: 'list_servers',
|
|
29
|
+
description: 'List all Coolify servers',
|
|
30
|
+
inputSchema: {},
|
|
31
|
+
},
|
|
32
|
+
{
|
|
33
|
+
name: 'get_server',
|
|
34
|
+
description: 'Get details about a specific Coolify server',
|
|
35
|
+
inputSchema: {
|
|
36
|
+
type: 'object',
|
|
37
|
+
properties: {
|
|
38
|
+
uuid: { type: 'string', description: 'UUID of the server to get details for' },
|
|
39
|
+
},
|
|
40
|
+
required: ['uuid'],
|
|
41
|
+
},
|
|
42
|
+
},
|
|
43
|
+
{
|
|
44
|
+
name: 'get_server_resources',
|
|
45
|
+
description: 'Get the current resources running on a specific Coolify server',
|
|
46
|
+
inputSchema: {
|
|
47
|
+
type: 'object',
|
|
48
|
+
properties: {
|
|
49
|
+
uuid: { type: 'string', description: 'UUID of the server to get resources for' },
|
|
50
|
+
},
|
|
51
|
+
required: ['uuid'],
|
|
52
|
+
},
|
|
53
|
+
},
|
|
54
|
+
{
|
|
55
|
+
name: 'get_server_domains',
|
|
56
|
+
description: 'Get the domains associated with a specific Coolify server',
|
|
57
|
+
inputSchema: {
|
|
58
|
+
type: 'object',
|
|
59
|
+
properties: {
|
|
60
|
+
uuid: { type: 'string', description: 'UUID of the server to get domains for' },
|
|
61
|
+
},
|
|
62
|
+
required: ['uuid'],
|
|
63
|
+
},
|
|
64
|
+
},
|
|
65
|
+
{
|
|
66
|
+
name: 'validate_server',
|
|
67
|
+
description: 'Validate the connection to a specific Coolify server',
|
|
68
|
+
inputSchema: {
|
|
69
|
+
type: 'object',
|
|
70
|
+
properties: {
|
|
71
|
+
uuid: { type: 'string', description: 'UUID of the server to validate' },
|
|
72
|
+
},
|
|
73
|
+
required: ['uuid'],
|
|
74
|
+
},
|
|
75
|
+
},
|
|
76
|
+
{
|
|
77
|
+
name: 'list_projects',
|
|
78
|
+
description: 'List all Coolify projects',
|
|
79
|
+
inputSchema: {},
|
|
80
|
+
},
|
|
81
|
+
{
|
|
82
|
+
name: 'get_project',
|
|
83
|
+
description: 'Get details about a specific Coolify project',
|
|
84
|
+
inputSchema: {
|
|
85
|
+
type: 'object',
|
|
86
|
+
properties: {
|
|
87
|
+
uuid: { type: 'string', description: 'UUID of the project to get details for' },
|
|
88
|
+
},
|
|
89
|
+
required: ['uuid'],
|
|
90
|
+
},
|
|
91
|
+
},
|
|
92
|
+
{
|
|
93
|
+
name: 'create_project',
|
|
94
|
+
description: 'Create a new Coolify project',
|
|
95
|
+
inputSchema: {
|
|
96
|
+
type: 'object',
|
|
97
|
+
properties: {
|
|
98
|
+
name: { type: 'string', description: 'Name of the project' },
|
|
99
|
+
description: { type: 'string', description: 'Optional description of the project' },
|
|
100
|
+
},
|
|
101
|
+
required: ['name'],
|
|
102
|
+
},
|
|
103
|
+
},
|
|
104
|
+
{
|
|
105
|
+
name: 'update_project',
|
|
106
|
+
description: 'Update an existing Coolify project',
|
|
107
|
+
inputSchema: {
|
|
108
|
+
type: 'object',
|
|
109
|
+
properties: {
|
|
110
|
+
uuid: { type: 'string', description: 'UUID of the project to update' },
|
|
111
|
+
name: { type: 'string', description: 'New name for the project' },
|
|
112
|
+
description: { type: 'string', description: 'New description for the project' },
|
|
113
|
+
},
|
|
114
|
+
required: ['uuid'],
|
|
115
|
+
},
|
|
116
|
+
},
|
|
117
|
+
{
|
|
118
|
+
name: 'delete_project',
|
|
119
|
+
description: 'Delete a Coolify project',
|
|
120
|
+
inputSchema: {
|
|
121
|
+
type: 'object',
|
|
122
|
+
properties: {
|
|
123
|
+
uuid: { type: 'string', description: 'UUID of the project to delete' },
|
|
124
|
+
},
|
|
125
|
+
required: ['uuid'],
|
|
126
|
+
},
|
|
127
|
+
},
|
|
128
|
+
{
|
|
129
|
+
name: 'get_project_environment',
|
|
130
|
+
description: 'Get details about a specific environment in a project',
|
|
131
|
+
inputSchema: {
|
|
132
|
+
type: 'object',
|
|
133
|
+
properties: {
|
|
134
|
+
project_uuid: { type: 'string', description: 'UUID of the project' },
|
|
135
|
+
environment_name_or_uuid: {
|
|
136
|
+
type: 'string',
|
|
137
|
+
description: 'Name or UUID of the environment',
|
|
138
|
+
},
|
|
139
|
+
},
|
|
140
|
+
required: ['project_uuid', 'environment_name_or_uuid'],
|
|
141
|
+
},
|
|
142
|
+
},
|
|
143
|
+
{
|
|
144
|
+
name: 'list_databases',
|
|
145
|
+
description: 'List all databases',
|
|
146
|
+
inputSchema: {},
|
|
147
|
+
},
|
|
148
|
+
{
|
|
149
|
+
name: 'get_database',
|
|
150
|
+
description: 'Get details about a specific Coolify database',
|
|
151
|
+
inputSchema: {
|
|
152
|
+
type: 'object',
|
|
153
|
+
properties: {
|
|
154
|
+
uuid: { type: 'string', description: 'UUID of the database to get details for' },
|
|
155
|
+
},
|
|
156
|
+
required: ['uuid'],
|
|
157
|
+
},
|
|
158
|
+
},
|
|
159
|
+
{
|
|
160
|
+
name: 'update_database',
|
|
161
|
+
description: 'Update a Coolify database',
|
|
162
|
+
inputSchema: {
|
|
163
|
+
type: 'object',
|
|
164
|
+
properties: {
|
|
165
|
+
uuid: { type: 'string', description: 'UUID of the database to update' },
|
|
166
|
+
data: { type: 'object', description: 'Update data for the database' },
|
|
167
|
+
},
|
|
168
|
+
required: ['uuid', 'data'],
|
|
169
|
+
},
|
|
170
|
+
},
|
|
171
|
+
{
|
|
172
|
+
name: 'delete_database',
|
|
173
|
+
description: 'Delete a Coolify database',
|
|
174
|
+
inputSchema: {
|
|
175
|
+
type: 'object',
|
|
176
|
+
properties: {
|
|
177
|
+
uuid: { type: 'string', description: 'UUID of the database to delete' },
|
|
178
|
+
options: {
|
|
179
|
+
type: 'object',
|
|
180
|
+
properties: {
|
|
181
|
+
deleteConfigurations: { type: 'boolean' },
|
|
182
|
+
deleteVolumes: { type: 'boolean' },
|
|
183
|
+
dockerCleanup: { type: 'boolean' },
|
|
184
|
+
deleteConnectedNetworks: { type: 'boolean' },
|
|
185
|
+
},
|
|
186
|
+
},
|
|
187
|
+
},
|
|
188
|
+
required: ['uuid'],
|
|
189
|
+
},
|
|
190
|
+
},
|
|
191
|
+
{
|
|
192
|
+
name: 'deploy_application',
|
|
193
|
+
description: 'Deploy a Coolify application',
|
|
194
|
+
inputSchema: {
|
|
195
|
+
type: 'object',
|
|
196
|
+
properties: {
|
|
197
|
+
uuid: { type: 'string', description: 'UUID of the application to deploy' },
|
|
198
|
+
},
|
|
199
|
+
required: ['uuid'],
|
|
200
|
+
},
|
|
201
|
+
},
|
|
202
|
+
{
|
|
203
|
+
name: 'list_services',
|
|
204
|
+
description: 'List all services',
|
|
205
|
+
inputSchema: {},
|
|
206
|
+
},
|
|
207
|
+
{
|
|
208
|
+
name: 'get_service',
|
|
209
|
+
description: 'Get details about a specific Coolify service',
|
|
210
|
+
inputSchema: {
|
|
211
|
+
type: 'object',
|
|
212
|
+
properties: {
|
|
213
|
+
uuid: { type: 'string', description: 'UUID of the service to get details for' },
|
|
214
|
+
},
|
|
215
|
+
required: ['uuid'],
|
|
216
|
+
},
|
|
217
|
+
},
|
|
218
|
+
{
|
|
219
|
+
name: 'create_service',
|
|
220
|
+
description: 'Create a new Coolify service',
|
|
221
|
+
inputSchema: {
|
|
222
|
+
type: 'object',
|
|
223
|
+
properties: {
|
|
224
|
+
type: { type: 'string', description: 'Type of service to create' },
|
|
225
|
+
project_uuid: { type: 'string', description: 'UUID of the project' },
|
|
226
|
+
server_uuid: { type: 'string', description: 'UUID of the server' },
|
|
227
|
+
data: { type: 'object', description: 'Additional service configuration' },
|
|
228
|
+
},
|
|
229
|
+
required: ['type', 'project_uuid', 'server_uuid'],
|
|
230
|
+
},
|
|
231
|
+
},
|
|
232
|
+
{
|
|
233
|
+
name: 'delete_service',
|
|
234
|
+
description: 'Delete a Coolify service',
|
|
235
|
+
inputSchema: {
|
|
236
|
+
type: 'object',
|
|
237
|
+
properties: {
|
|
238
|
+
uuid: { type: 'string', description: 'UUID of the service to delete' },
|
|
239
|
+
options: {
|
|
240
|
+
type: 'object',
|
|
241
|
+
properties: {
|
|
242
|
+
deleteConfigurations: { type: 'boolean' },
|
|
243
|
+
deleteVolumes: { type: 'boolean' },
|
|
244
|
+
dockerCleanup: { type: 'boolean' },
|
|
245
|
+
deleteConnectedNetworks: { type: 'boolean' },
|
|
246
|
+
},
|
|
247
|
+
},
|
|
248
|
+
},
|
|
249
|
+
required: ['uuid'],
|
|
250
|
+
},
|
|
251
|
+
},
|
|
252
|
+
],
|
|
253
|
+
};
|
|
492
254
|
});
|
|
493
|
-
this.server.
|
|
494
|
-
uuid: zod_1.z.string().describe('UUID of the service to delete'),
|
|
495
|
-
deleteConfigurations: zod_1.z.boolean().optional().describe('Whether to delete configurations'),
|
|
496
|
-
deleteVolumes: zod_1.z.boolean().optional().describe('Whether to delete volumes'),
|
|
497
|
-
dockerCleanup: zod_1.z.boolean().optional().describe('Whether to run docker cleanup'),
|
|
498
|
-
deleteConnectedNetworks: zod_1.z
|
|
499
|
-
.boolean()
|
|
500
|
-
.optional()
|
|
501
|
-
.describe('Whether to delete connected networks'),
|
|
502
|
-
}, async (params) => {
|
|
255
|
+
this.server.setRequestHandler(CallToolRequestSchema, async (request) => {
|
|
503
256
|
try {
|
|
504
|
-
|
|
505
|
-
|
|
506
|
-
|
|
507
|
-
|
|
508
|
-
|
|
509
|
-
|
|
257
|
+
if (!request.params.arguments) {
|
|
258
|
+
throw new Error('Arguments are required');
|
|
259
|
+
}
|
|
260
|
+
switch (request.params.name) {
|
|
261
|
+
case 'list_servers': {
|
|
262
|
+
const servers = await this.client.listServers();
|
|
263
|
+
return {
|
|
264
|
+
content: [{ type: 'text', text: JSON.stringify(servers, null, 2) }],
|
|
265
|
+
};
|
|
266
|
+
}
|
|
267
|
+
case 'get_server': {
|
|
268
|
+
const args = z.object({ uuid: z.string() }).parse(request.params.arguments);
|
|
269
|
+
const server = await this.client.getServer(args.uuid);
|
|
270
|
+
return {
|
|
271
|
+
content: [{ type: 'text', text: JSON.stringify(server, null, 2) }],
|
|
272
|
+
};
|
|
273
|
+
}
|
|
274
|
+
case 'get_server_resources': {
|
|
275
|
+
const args = z.object({ uuid: z.string() }).parse(request.params.arguments);
|
|
276
|
+
const resources = await this.client.getServerResources(args.uuid);
|
|
277
|
+
return {
|
|
278
|
+
content: [{ type: 'text', text: JSON.stringify(resources, null, 2) }],
|
|
279
|
+
};
|
|
280
|
+
}
|
|
281
|
+
case 'get_server_domains': {
|
|
282
|
+
const args = z.object({ uuid: z.string() }).parse(request.params.arguments);
|
|
283
|
+
const domains = await this.client.getServerDomains(args.uuid);
|
|
284
|
+
return {
|
|
285
|
+
content: [{ type: 'text', text: JSON.stringify(domains, null, 2) }],
|
|
286
|
+
};
|
|
287
|
+
}
|
|
288
|
+
case 'validate_server': {
|
|
289
|
+
const args = z.object({ uuid: z.string() }).parse(request.params.arguments);
|
|
290
|
+
const result = await this.client.validateServer(args.uuid);
|
|
291
|
+
return {
|
|
292
|
+
content: [{ type: 'text', text: JSON.stringify(result, null, 2) }],
|
|
293
|
+
};
|
|
294
|
+
}
|
|
295
|
+
case 'list_projects': {
|
|
296
|
+
const projects = await this.client.listProjects();
|
|
297
|
+
return {
|
|
298
|
+
content: [{ type: 'text', text: JSON.stringify(projects, null, 2) }],
|
|
299
|
+
};
|
|
300
|
+
}
|
|
301
|
+
case 'get_project': {
|
|
302
|
+
const args = z.object({ uuid: z.string() }).parse(request.params.arguments);
|
|
303
|
+
const project = await this.client.getProject(args.uuid);
|
|
304
|
+
return {
|
|
305
|
+
content: [{ type: 'text', text: JSON.stringify(project, null, 2) }],
|
|
306
|
+
};
|
|
307
|
+
}
|
|
308
|
+
case 'create_project': {
|
|
309
|
+
const args = z
|
|
310
|
+
.object({
|
|
311
|
+
name: z.string(),
|
|
312
|
+
description: z.string().optional(),
|
|
313
|
+
})
|
|
314
|
+
.parse(request.params.arguments);
|
|
315
|
+
const result = await this.client.createProject(args);
|
|
316
|
+
return {
|
|
317
|
+
content: [{ type: 'text', text: JSON.stringify(result, null, 2) }],
|
|
318
|
+
};
|
|
319
|
+
}
|
|
320
|
+
case 'update_project': {
|
|
321
|
+
const args = z
|
|
322
|
+
.object({
|
|
323
|
+
uuid: z.string(),
|
|
324
|
+
name: z.string().optional(),
|
|
325
|
+
description: z.string().optional(),
|
|
326
|
+
})
|
|
327
|
+
.parse(request.params.arguments);
|
|
328
|
+
const { uuid, ...updateData } = args;
|
|
329
|
+
const result = await this.client.updateProject(uuid, updateData);
|
|
330
|
+
return {
|
|
331
|
+
content: [{ type: 'text', text: JSON.stringify(result, null, 2) }],
|
|
332
|
+
};
|
|
333
|
+
}
|
|
334
|
+
case 'delete_project': {
|
|
335
|
+
const args = z.object({ uuid: z.string() }).parse(request.params.arguments);
|
|
336
|
+
const result = await this.client.deleteProject(args.uuid);
|
|
337
|
+
return {
|
|
338
|
+
content: [{ type: 'text', text: JSON.stringify(result, null, 2) }],
|
|
339
|
+
};
|
|
340
|
+
}
|
|
341
|
+
case 'get_project_environment': {
|
|
342
|
+
const args = z
|
|
343
|
+
.object({
|
|
344
|
+
project_uuid: z.string(),
|
|
345
|
+
environment_name_or_uuid: z.string(),
|
|
346
|
+
})
|
|
347
|
+
.parse(request.params.arguments);
|
|
348
|
+
const environment = await this.client.getProjectEnvironment(args.project_uuid, args.environment_name_or_uuid);
|
|
349
|
+
return {
|
|
350
|
+
content: [{ type: 'text', text: JSON.stringify(environment, null, 2) }],
|
|
351
|
+
};
|
|
352
|
+
}
|
|
353
|
+
case 'list_databases': {
|
|
354
|
+
const databases = await this.client.listDatabases();
|
|
355
|
+
return {
|
|
356
|
+
content: [{ type: 'text', text: JSON.stringify(databases, null, 2) }],
|
|
357
|
+
};
|
|
358
|
+
}
|
|
359
|
+
case 'get_database': {
|
|
360
|
+
const args = z.object({ uuid: z.string() }).parse(request.params.arguments);
|
|
361
|
+
const database = await this.client.getDatabase(args.uuid);
|
|
362
|
+
return {
|
|
363
|
+
content: [{ type: 'text', text: JSON.stringify(database, null, 2) }],
|
|
364
|
+
};
|
|
365
|
+
}
|
|
366
|
+
case 'update_database': {
|
|
367
|
+
const args = z
|
|
368
|
+
.object({
|
|
369
|
+
uuid: z.string(),
|
|
370
|
+
data: z.object({}).passthrough(),
|
|
371
|
+
})
|
|
372
|
+
.parse(request.params.arguments);
|
|
373
|
+
const database = await this.client.updateDatabase(args.uuid, args.data);
|
|
374
|
+
return {
|
|
375
|
+
content: [{ type: 'text', text: JSON.stringify(database, null, 2) }],
|
|
376
|
+
};
|
|
377
|
+
}
|
|
378
|
+
case 'delete_database': {
|
|
379
|
+
const args = z
|
|
380
|
+
.object({
|
|
381
|
+
uuid: z.string(),
|
|
382
|
+
options: z
|
|
383
|
+
.object({
|
|
384
|
+
deleteConfigurations: z.boolean().optional(),
|
|
385
|
+
deleteVolumes: z.boolean().optional(),
|
|
386
|
+
dockerCleanup: z.boolean().optional(),
|
|
387
|
+
deleteConnectedNetworks: z.boolean().optional(),
|
|
388
|
+
})
|
|
389
|
+
.optional(),
|
|
390
|
+
})
|
|
391
|
+
.parse(request.params.arguments);
|
|
392
|
+
const result = await this.client.deleteDatabase(args.uuid, args.options);
|
|
393
|
+
return {
|
|
394
|
+
content: [{ type: 'text', text: JSON.stringify(result, null, 2) }],
|
|
395
|
+
};
|
|
396
|
+
}
|
|
397
|
+
case 'deploy_application': {
|
|
398
|
+
const args = z.object({ uuid: z.string() }).parse(request.params.arguments);
|
|
399
|
+
const deployment = await this.client.deployApplication(args.uuid);
|
|
400
|
+
return {
|
|
401
|
+
content: [{ type: 'text', text: JSON.stringify(deployment, null, 2) }],
|
|
402
|
+
};
|
|
403
|
+
}
|
|
404
|
+
case 'list_services': {
|
|
405
|
+
const services = await this.client.listServices();
|
|
406
|
+
return {
|
|
407
|
+
content: [{ type: 'text', text: JSON.stringify(services, null, 2) }],
|
|
408
|
+
};
|
|
409
|
+
}
|
|
410
|
+
case 'get_service': {
|
|
411
|
+
const args = z.object({ uuid: z.string() }).parse(request.params.arguments);
|
|
412
|
+
const service = await this.client.getService(args.uuid);
|
|
413
|
+
return {
|
|
414
|
+
content: [{ type: 'text', text: JSON.stringify(service, null, 2) }],
|
|
415
|
+
};
|
|
416
|
+
}
|
|
417
|
+
case 'create_service': {
|
|
418
|
+
const args = z
|
|
419
|
+
.object({
|
|
420
|
+
type: z.enum([
|
|
421
|
+
'activepieces',
|
|
422
|
+
'appsmith',
|
|
423
|
+
'appwrite',
|
|
424
|
+
'authentik',
|
|
425
|
+
'babybuddy',
|
|
426
|
+
'budge',
|
|
427
|
+
'changedetection',
|
|
428
|
+
'chatwoot',
|
|
429
|
+
'classicpress-with-mariadb',
|
|
430
|
+
'classicpress-with-mysql',
|
|
431
|
+
'classicpress-without-database',
|
|
432
|
+
'cloudflared',
|
|
433
|
+
'code-server',
|
|
434
|
+
'dashboard',
|
|
435
|
+
'directus',
|
|
436
|
+
'directus-with-postgresql',
|
|
437
|
+
'docker-registry',
|
|
438
|
+
'docuseal',
|
|
439
|
+
'docuseal-with-postgres',
|
|
440
|
+
'dokuwiki',
|
|
441
|
+
'duplicati',
|
|
442
|
+
'emby',
|
|
443
|
+
'embystat',
|
|
444
|
+
'fider',
|
|
445
|
+
'filebrowser',
|
|
446
|
+
'firefly',
|
|
447
|
+
'formbricks',
|
|
448
|
+
'ghost',
|
|
449
|
+
'gitea',
|
|
450
|
+
'gitea-with-mariadb',
|
|
451
|
+
'gitea-with-mysql',
|
|
452
|
+
'gitea-with-postgresql',
|
|
453
|
+
'glance',
|
|
454
|
+
'glances',
|
|
455
|
+
'glitchtip',
|
|
456
|
+
'grafana',
|
|
457
|
+
'grafana-with-postgresql',
|
|
458
|
+
'grocy',
|
|
459
|
+
'heimdall',
|
|
460
|
+
'homepage',
|
|
461
|
+
'jellyfin',
|
|
462
|
+
'kuzzle',
|
|
463
|
+
'listmonk',
|
|
464
|
+
'logto',
|
|
465
|
+
'mediawiki',
|
|
466
|
+
'meilisearch',
|
|
467
|
+
'metabase',
|
|
468
|
+
'metube',
|
|
469
|
+
'minio',
|
|
470
|
+
'moodle',
|
|
471
|
+
'n8n',
|
|
472
|
+
'n8n-with-postgresql',
|
|
473
|
+
'next-image-transformation',
|
|
474
|
+
'nextcloud',
|
|
475
|
+
'nocodb',
|
|
476
|
+
'odoo',
|
|
477
|
+
'openblocks',
|
|
478
|
+
'pairdrop',
|
|
479
|
+
'penpot',
|
|
480
|
+
'phpmyadmin',
|
|
481
|
+
'pocketbase',
|
|
482
|
+
'posthog',
|
|
483
|
+
'reactive-resume',
|
|
484
|
+
'rocketchat',
|
|
485
|
+
'shlink',
|
|
486
|
+
'slash',
|
|
487
|
+
'snapdrop',
|
|
488
|
+
'statusnook',
|
|
489
|
+
'stirling-pdf',
|
|
490
|
+
'supabase',
|
|
491
|
+
'syncthing',
|
|
492
|
+
'tolgee',
|
|
493
|
+
'trigger',
|
|
494
|
+
'trigger-with-external-database',
|
|
495
|
+
'twenty',
|
|
496
|
+
'umami',
|
|
497
|
+
'unleash-with-postgresql',
|
|
498
|
+
'unleash-without-database',
|
|
499
|
+
'uptime-kuma',
|
|
500
|
+
'vaultwarden',
|
|
501
|
+
'vikunja',
|
|
502
|
+
'weblate',
|
|
503
|
+
'whoogle',
|
|
504
|
+
'wordpress-with-mariadb',
|
|
505
|
+
'wordpress-with-mysql',
|
|
506
|
+
'wordpress-without-database',
|
|
507
|
+
]),
|
|
508
|
+
project_uuid: z.string(),
|
|
509
|
+
server_uuid: z.string(),
|
|
510
|
+
name: z.string().optional(),
|
|
511
|
+
description: z.string().optional(),
|
|
512
|
+
environment_name: z.string().optional(),
|
|
513
|
+
environment_uuid: z.string().optional(),
|
|
514
|
+
destination_uuid: z.string().optional(),
|
|
515
|
+
instant_deploy: z.boolean().optional(),
|
|
516
|
+
data: z.object({}).passthrough().optional(),
|
|
517
|
+
})
|
|
518
|
+
.parse(request.params.arguments);
|
|
519
|
+
const result = await this.client.createService(args);
|
|
520
|
+
return {
|
|
521
|
+
content: [{ type: 'text', text: JSON.stringify(result, null, 2) }],
|
|
522
|
+
};
|
|
523
|
+
}
|
|
524
|
+
case 'delete_service': {
|
|
525
|
+
const args = z
|
|
526
|
+
.object({
|
|
527
|
+
uuid: z.string(),
|
|
528
|
+
options: z
|
|
529
|
+
.object({
|
|
530
|
+
deleteConfigurations: z.boolean().optional(),
|
|
531
|
+
deleteVolumes: z.boolean().optional(),
|
|
532
|
+
dockerCleanup: z.boolean().optional(),
|
|
533
|
+
deleteConnectedNetworks: z.boolean().optional(),
|
|
534
|
+
})
|
|
535
|
+
.optional(),
|
|
536
|
+
})
|
|
537
|
+
.parse(request.params.arguments);
|
|
538
|
+
const result = await this.client.deleteService(args.uuid, args.options);
|
|
539
|
+
return {
|
|
540
|
+
content: [{ type: 'text', text: JSON.stringify(result, null, 2) }],
|
|
541
|
+
};
|
|
542
|
+
}
|
|
543
|
+
default:
|
|
544
|
+
throw new Error(`Unknown tool: ${request.params.name}`);
|
|
545
|
+
}
|
|
510
546
|
}
|
|
511
547
|
catch (error) {
|
|
512
|
-
|
|
513
|
-
|
|
514
|
-
|
|
515
|
-
|
|
516
|
-
};
|
|
548
|
+
if (error instanceof z.ZodError) {
|
|
549
|
+
throw new Error(`Invalid input: ${JSON.stringify(error.errors)}`);
|
|
550
|
+
}
|
|
551
|
+
throw error;
|
|
517
552
|
}
|
|
518
553
|
});
|
|
519
|
-
// End of tool definitions
|
|
520
554
|
}
|
|
521
555
|
async start(transport) {
|
|
522
556
|
await this.client.validateConnection();
|
|
@@ -583,4 +617,3 @@ class CoolifyMcpServer {
|
|
|
583
617
|
return this.client.deleteService(uuid, options);
|
|
584
618
|
}
|
|
585
619
|
}
|
|
586
|
-
exports.CoolifyMcpServer = CoolifyMcpServer;
|