@masonator/coolify-mcp 0.2.8 → 0.2.12

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