@masonator/coolify-mcp 2.0.0 → 2.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/README.md CHANGED
@@ -17,25 +17,25 @@ A Model Context Protocol (MCP) server for [Coolify](https://coolify.io/), enabli
17
17
 
18
18
  This MCP server provides **34 token-optimized tools** for **debugging, management, and deployment**:
19
19
 
20
- | Category | Tools |
21
- | -------------------- | ----------------------------------------------------------------------------------------- |
22
- | **Infrastructure** | `get_infrastructure_overview`, `get_mcp_version`, `get_version` |
23
- | **Diagnostics** | `diagnose_app`, `diagnose_server`, `find_issues` |
24
- | **Batch Operations** | `restart_project_apps`, `bulk_env_update`, `stop_all_apps`, `redeploy_project` |
25
- | **Servers** | `list_servers`, `get_server`, `validate_server`, `server_resources`, `server_domains` |
26
- | **Projects** | `projects` (list, get, create, update, delete via action param) |
27
- | **Environments** | `environments` (list, get, create, delete via action param) |
28
- | **Applications** | `list_applications`, `get_application`, `application` (CRUD), `application_logs` |
29
- | **Databases** | `list_databases`, `get_database`, `database` (create 8 types, delete), `database_backups` |
30
- | **Services** | `list_services`, `get_service`, `service` (create, update, delete) |
31
- | **Control** | `control` (start/stop/restart for apps, databases, services) |
32
- | **Env Vars** | `env_vars` (CRUD for application and service env vars) |
33
- | **Deployments** | `list_deployments`, `deploy`, `deployment` (get, cancel, list_for_app) |
34
- | **Private Keys** | `private_keys` (list, get, create, update, delete via action param) |
35
-
36
- ### v2.0.0 Token Diet
37
-
38
- v2.0.0 reduced token usage by **85%** (from ~43,000 to ~6,600 tokens) by consolidating related operations into single tools with action parameters. This prevents context window exhaustion in AI assistants.
20
+ | Category | Tools |
21
+ | -------------------- | --------------------------------------------------------------------------------------------------------------------------- |
22
+ | **Infrastructure** | `get_infrastructure_overview`, `get_mcp_version`, `get_version` |
23
+ | **Diagnostics** | `diagnose_app`, `diagnose_server`, `find_issues` |
24
+ | **Batch Operations** | `restart_project_apps`, `bulk_env_update`, `stop_all_apps`, `redeploy_project` |
25
+ | **Servers** | `list_servers`, `get_server`, `validate_server`, `server_resources`, `server_domains` |
26
+ | **Projects** | `projects` (list, get, create, update, delete via action param) |
27
+ | **Environments** | `environments` (list, get, create, delete via action param) |
28
+ | **Applications** | `list_applications`, `get_application`, `application` (CRUD), `application_logs` |
29
+ | **Databases** | `list_databases`, `get_database`, `database` (create 8 types, delete), `database_backups` (CRUD schedules, view executions) |
30
+ | **Services** | `list_services`, `get_service`, `service` (create, update, delete) |
31
+ | **Control** | `control` (start/stop/restart for apps, databases, services) |
32
+ | **Env Vars** | `env_vars` (CRUD for application and service env vars) |
33
+ | **Deployments** | `list_deployments`, `deploy`, `deployment` (get, cancel, list_for_app) |
34
+ | **Private Keys** | `private_keys` (list, get, create, update, delete via action param) |
35
+
36
+ ### Token-Optimized Design
37
+
38
+ The server uses **85% fewer tokens** than a naive implementation (6,600 vs 43,000) by consolidating related operations into single tools with action parameters. This prevents context window exhaustion in AI assistants.
39
39
 
40
40
  ## Installation
41
41
 
@@ -216,78 +216,49 @@ These tools accept human-friendly identifiers instead of just UUIDs:
216
216
 
217
217
  ### Projects
218
218
 
219
- - `list_projects` - List all projects (returns summary)
220
- - `get_project` - Get project details
221
- - `create_project` - Create a new project
222
- - `update_project` - Update a project
223
- - `delete_project` - Delete a project
219
+ - `projects` - Manage projects with `action: list|get|create|update|delete`
224
220
 
225
221
  ### Environments
226
222
 
227
- - `list_environments` - List environments in a project
228
- - `get_environment` - Get environment details
229
- - `create_environment` - Create environment in a project
230
- - `delete_environment` - Delete an environment
223
+ - `environments` - Manage environments with `action: list|get|create|delete`
231
224
 
232
225
  ### Applications
233
226
 
234
227
  - `list_applications` - List all applications (returns summary)
235
228
  - `get_application` - Get application details
236
- - `create_application_private_gh` - Create app from private GitHub repo (GitHub App)
237
- - `create_application_private_key` - Create app from private repo using deploy key
238
- - `update_application` - Update an application
239
- - `delete_application` - Delete an application
240
- - `start_application` - Start an application
241
- - `stop_application` - Stop an application
242
- - `restart_application` - Restart an application
243
- - `get_application_logs` - Get application logs
244
- - `list_application_envs` - List application environment variables
245
- - `create_application_env` - Create application environment variable
246
- - `update_application_env` - Update application environment variable
247
- - `delete_application_env` - Delete application environment variable
229
+ - `application_logs` - Get application logs
230
+ - `application` - Create, update, or delete apps with `action: create_github|create_key|update|delete`
231
+ - `env_vars` - Manage env vars with `resource: application, action: list|create|update|delete`
232
+ - `control` - Start/stop/restart with `resource: application, action: start|stop|restart`
248
233
 
249
234
  ### Databases
250
235
 
251
236
  - `list_databases` - List all databases (returns summary)
252
237
  - `get_database` - Get database details
253
- - `start_database` - Start a database
254
- - `stop_database` - Stop a database
255
- - `restart_database` - Restart a database
256
- - `delete_database` - Delete a database (with optional volume cleanup)
257
- - `list_database_backups` - List scheduled backups for a database
258
- - `get_database_backup` - Get details of a scheduled backup
259
- - `list_backup_executions` - List execution history for a scheduled backup
260
- - `get_backup_execution` - Get details of a specific backup execution
238
+ - `database` - Create or delete databases with `action: create|delete, type: postgresql|mysql|mariadb|mongodb|redis|keydb|clickhouse|dragonfly`
239
+ - `database_backups` - Manage backup schedules with `action: list_schedules|get_schedule|create|update|delete|list_executions|get_execution`
240
+ - Configure frequency, retention policies, S3 storage
241
+ - Enable/disable schedules without deletion
242
+ - View backup execution history
243
+ - `control` - Start/stop/restart with `resource: database, action: start|stop|restart`
261
244
 
262
245
  ### Services
263
246
 
264
247
  - `list_services` - List all services (returns summary)
265
248
  - `get_service` - Get service details
266
- - `create_service` - Create a one-click service (e.g., pocketbase, mysql, redis, wordpress)
267
- - `update_service` - Update a service
268
- - `delete_service` - Delete a service
269
- - `start_service` - Start a service
270
- - `stop_service` - Stop a service
271
- - `restart_service` - Restart a service
272
- - `list_service_envs` - List service environment variables
273
- - `create_service_env` - Create service environment variable
274
- - `delete_service_env` - Delete service environment variable
249
+ - `service` - Create, update, or delete services with `action: create|update|delete`
250
+ - `env_vars` - Manage env vars with `resource: service, action: list|create|delete`
251
+ - `control` - Start/stop/restart with `resource: service, action: start|stop|restart`
275
252
 
276
253
  ### Deployments
277
254
 
278
255
  - `list_deployments` - List running deployments (returns summary)
279
- - `get_deployment` - Get deployment details
280
256
  - `deploy` - Deploy by tag or UUID
281
- - `cancel_deployment` - Cancel a running deployment
282
- - `list_application_deployments` - List deployments for an application
257
+ - `deployment` - Manage deployments with `action: get|cancel|list_for_app`
283
258
 
284
259
  ### Private Keys
285
260
 
286
- - `list_private_keys` - List all private keys (SSH keys for deployments)
287
- - `get_private_key` - Get private key details
288
- - `create_private_key` - Create a new private key for deployments
289
- - `update_private_key` - Update a private key
290
- - `delete_private_key` - Delete a private key
261
+ - `private_keys` - Manage SSH keys with `action: list|get|create|update|delete`
291
262
 
292
263
  ### Batch Operations
293
264
 
@@ -303,9 +274,8 @@ Power user tools for operating on multiple resources at once:
303
274
  - **Context-Optimized**: Responses are 90-99% smaller than raw API, preventing context window exhaustion
304
275
  - **Smart Lookup**: Find apps by domain (`stuartmason.co.uk`), servers by IP, not just UUIDs
305
276
  - **Batch Operations**: Restart entire projects, bulk update env vars, emergency stop all apps
306
- - **Workflow Prompts**: Pre-built guided workflows for common tasks
307
277
  - **Production Ready**: 98%+ test coverage, TypeScript strict mode, comprehensive error handling
308
- - **Always Current**: Weekly OpenAPI drift detection ensures we stay in sync with Coolify
278
+ - **Always Current**: Weekly OpenAPI drift detection ensures the server stays in sync with Coolify
309
279
 
310
280
  ## Related Links
311
281
 
@@ -377,6 +377,16 @@ describe('CoolifyClient', () => {
377
377
  mockFetch.mockResolvedValueOnce(mockResponse({}, false, 500));
378
378
  await expect(client.listServers()).rejects.toThrow('HTTP 500: Error');
379
379
  });
380
+ it('should include validation errors in error message', async () => {
381
+ mockFetch.mockResolvedValueOnce(mockResponse({
382
+ message: 'Validation failed.',
383
+ errors: {
384
+ name: ['The name field is required.'],
385
+ email: ['The email must be valid.', 'The email is already taken.'],
386
+ },
387
+ }, false, 422));
388
+ await expect(client.listServers()).rejects.toThrow('Validation failed. - name: The name field is required.; email: The email must be valid., The email is already taken.');
389
+ });
380
390
  });
381
391
  // =========================================================================
382
392
  // Server endpoints - additional coverage
@@ -780,6 +790,37 @@ describe('CoolifyClient', () => {
780
790
  expect(result).toEqual(mockBackup);
781
791
  expect(mockFetch).toHaveBeenCalledWith('http://localhost:3000/api/v1/databases/db-uuid/backups/backup-uuid', expect.any(Object));
782
792
  });
793
+ it('should create a database backup', async () => {
794
+ const mockBackup = { uuid: 'backup-uuid', frequency: '0 0 * * *', enabled: true };
795
+ mockFetch.mockResolvedValueOnce(mockResponse(mockBackup));
796
+ const result = await client.createDatabaseBackup('db-uuid', {
797
+ frequency: '0 0 * * *',
798
+ enabled: true,
799
+ save_s3: true,
800
+ s3_storage_uuid: 'storage-uuid',
801
+ database_backup_retention_days_locally: 7,
802
+ database_backup_retention_days_s3: 7,
803
+ });
804
+ expect(result).toEqual(mockBackup);
805
+ expect(mockFetch).toHaveBeenCalledWith('http://localhost:3000/api/v1/databases/db-uuid/backups', expect.objectContaining({ method: 'POST' }));
806
+ });
807
+ it('should update a database backup', async () => {
808
+ const mockData = { message: 'Backup updated' };
809
+ mockFetch.mockResolvedValueOnce(mockResponse(mockData));
810
+ const result = await client.updateDatabaseBackup('db-uuid', 'backup-uuid', {
811
+ enabled: false,
812
+ frequency: '0 2 * * *',
813
+ });
814
+ expect(result).toEqual(mockData);
815
+ expect(mockFetch).toHaveBeenCalledWith('http://localhost:3000/api/v1/databases/db-uuid/backups/backup-uuid', expect.objectContaining({ method: 'PATCH' }));
816
+ });
817
+ it('should delete a database backup', async () => {
818
+ const mockData = { message: 'Backup deleted' };
819
+ mockFetch.mockResolvedValueOnce(mockResponse(mockData));
820
+ const result = await client.deleteDatabaseBackup('db-uuid', 'backup-uuid');
821
+ expect(result).toEqual(mockData);
822
+ expect(mockFetch).toHaveBeenCalledWith('http://localhost:3000/api/v1/databases/db-uuid/backups/backup-uuid', expect.objectContaining({ method: 'DELETE' }));
823
+ });
783
824
  it('should list backup executions', async () => {
784
825
  const mockExecutions = [{ uuid: 'exec-uuid', status: 'success' }];
785
826
  mockFetch.mockResolvedValueOnce(mockResponse(mockExecutions));
@@ -54,6 +54,7 @@ describe('CoolifyMcpServer v2', () => {
54
54
  expect(typeof client.getApplication).toBe('function');
55
55
  expect(typeof client.createApplicationPrivateGH).toBe('function');
56
56
  expect(typeof client.createApplicationPrivateKey).toBe('function');
57
+ expect(typeof client.createApplicationDockerImage).toBe('function');
57
58
  expect(typeof client.updateApplication).toBe('function');
58
59
  expect(typeof client.deleteApplication).toBe('function');
59
60
  expect(typeof client.getApplicationLogs).toBe('function');
@@ -108,6 +109,9 @@ describe('CoolifyMcpServer v2', () => {
108
109
  // Backup operations
109
110
  expect(typeof client.listDatabaseBackups).toBe('function');
110
111
  expect(typeof client.getDatabaseBackup).toBe('function');
112
+ expect(typeof client.createDatabaseBackup).toBe('function');
113
+ expect(typeof client.updateDatabaseBackup).toBe('function');
114
+ expect(typeof client.deleteDatabaseBackup).toBe('function');
111
115
  expect(typeof client.listBackupExecutions).toBe('function');
112
116
  expect(typeof client.getBackupExecution).toBe('function');
113
117
  // Diagnostic operations
@@ -2,7 +2,7 @@
2
2
  * Coolify API Client
3
3
  * Complete HTTP client for the Coolify API v1
4
4
  */
5
- import type { CoolifyConfig, DeleteOptions, MessageResponse, UuidResponse, Server, ServerResource, ServerDomain, ServerValidation, CreateServerRequest, UpdateServerRequest, Project, CreateProjectRequest, UpdateProjectRequest, Environment, CreateEnvironmentRequest, Application, CreateApplicationPublicRequest, CreateApplicationPrivateGHRequest, CreateApplicationPrivateKeyRequest, CreateApplicationDockerfileRequest, CreateApplicationDockerImageRequest, CreateApplicationDockerComposeRequest, UpdateApplicationRequest, ApplicationActionResponse, EnvironmentVariable, EnvVarSummary, CreateEnvVarRequest, UpdateEnvVarRequest, BulkUpdateEnvVarsRequest, Database, UpdateDatabaseRequest, CreatePostgresqlRequest, CreateMysqlRequest, CreateMariadbRequest, CreateMongodbRequest, CreateRedisRequest, CreateKeydbRequest, CreateClickhouseRequest, CreateDragonflyRequest, CreateDatabaseResponse, DatabaseBackup, BackupExecution, Service, CreateServiceRequest, UpdateServiceRequest, ServiceCreateResponse, Deployment, Team, TeamMember, PrivateKey, CreatePrivateKeyRequest, UpdatePrivateKeyRequest, CloudToken, CreateCloudTokenRequest, UpdateCloudTokenRequest, CloudTokenValidation, Version, ApplicationDiagnostic, ServerDiagnostic, InfrastructureIssuesReport, BatchOperationResult } from '../types/coolify.js';
5
+ import type { CoolifyConfig, DeleteOptions, MessageResponse, UuidResponse, Server, ServerResource, ServerDomain, ServerValidation, CreateServerRequest, UpdateServerRequest, Project, CreateProjectRequest, UpdateProjectRequest, Environment, CreateEnvironmentRequest, Application, CreateApplicationPublicRequest, CreateApplicationPrivateGHRequest, CreateApplicationPrivateKeyRequest, CreateApplicationDockerfileRequest, CreateApplicationDockerImageRequest, CreateApplicationDockerComposeRequest, UpdateApplicationRequest, ApplicationActionResponse, EnvironmentVariable, EnvVarSummary, CreateEnvVarRequest, UpdateEnvVarRequest, BulkUpdateEnvVarsRequest, Database, UpdateDatabaseRequest, CreatePostgresqlRequest, CreateMysqlRequest, CreateMariadbRequest, CreateMongodbRequest, CreateRedisRequest, CreateKeydbRequest, CreateClickhouseRequest, CreateDragonflyRequest, CreateDatabaseResponse, DatabaseBackup, BackupExecution, CreateDatabaseBackupRequest, UpdateDatabaseBackupRequest, Service, CreateServiceRequest, UpdateServiceRequest, ServiceCreateResponse, Deployment, Team, TeamMember, PrivateKey, CreatePrivateKeyRequest, UpdatePrivateKeyRequest, CloudToken, CreateCloudTokenRequest, UpdateCloudTokenRequest, CloudTokenValidation, Version, ApplicationDiagnostic, ServerDiagnostic, InfrastructureIssuesReport, BatchOperationResult } from '../types/coolify.js';
6
6
  export interface ListOptions {
7
7
  page?: number;
8
8
  per_page?: number;
@@ -158,6 +158,9 @@ export declare class CoolifyClient {
158
158
  getDatabaseBackup(databaseUuid: string, backupUuid: string): Promise<DatabaseBackup>;
159
159
  listBackupExecutions(databaseUuid: string, backupUuid: string): Promise<BackupExecution[]>;
160
160
  getBackupExecution(databaseUuid: string, backupUuid: string, executionUuid: string): Promise<BackupExecution>;
161
+ createDatabaseBackup(databaseUuid: string, data: CreateDatabaseBackupRequest): Promise<DatabaseBackup>;
162
+ updateDatabaseBackup(databaseUuid: string, backupUuid: string, data: UpdateDatabaseBackupRequest): Promise<MessageResponse>;
163
+ deleteDatabaseBackup(databaseUuid: string, backupUuid: string): Promise<MessageResponse>;
161
164
  cancelDeployment(uuid: string): Promise<MessageResponse>;
162
165
  /**
163
166
  * Check if a string looks like a UUID (Coolify format or standard format).
@@ -112,7 +112,15 @@ export class CoolifyClient {
112
112
  const data = text ? JSON.parse(text) : {};
113
113
  if (!response.ok) {
114
114
  const error = data;
115
- throw new Error(error.message || `HTTP ${response.status}: ${response.statusText}`);
115
+ // Include validation errors if present
116
+ let errorMessage = error.message || `HTTP ${response.status}: ${response.statusText}`;
117
+ if (error.errors && Object.keys(error.errors).length > 0) {
118
+ const validationDetails = Object.entries(error.errors)
119
+ .map(([field, messages]) => `${field}: ${messages.join(', ')}`)
120
+ .join('; ');
121
+ errorMessage = `${errorMessage} - ${validationDetails}`;
122
+ }
123
+ throw new Error(errorMessage);
116
124
  }
117
125
  return data;
118
126
  }
@@ -648,6 +656,23 @@ export class CoolifyClient {
648
656
  async getBackupExecution(databaseUuid, backupUuid, executionUuid) {
649
657
  return this.request(`/databases/${databaseUuid}/backups/${backupUuid}/executions/${executionUuid}`);
650
658
  }
659
+ async createDatabaseBackup(databaseUuid, data) {
660
+ return this.request(`/databases/${databaseUuid}/backups`, {
661
+ method: 'POST',
662
+ body: JSON.stringify(data),
663
+ });
664
+ }
665
+ async updateDatabaseBackup(databaseUuid, backupUuid, data) {
666
+ return this.request(`/databases/${databaseUuid}/backups/${backupUuid}`, {
667
+ method: 'PATCH',
668
+ body: JSON.stringify(data),
669
+ });
670
+ }
671
+ async deleteDatabaseBackup(databaseUuid, backupUuid) {
672
+ return this.request(`/databases/${databaseUuid}/backups/${backupUuid}`, {
673
+ method: 'DELETE',
674
+ });
675
+ }
651
676
  // ===========================================================================
652
677
  // Deployment Control endpoints
653
678
  // ===========================================================================
@@ -1,5 +1,5 @@
1
1
  /**
2
- * Coolify MCP Server v2.0.0
2
+ * Coolify MCP Server v2.2.0
3
3
  * Consolidated tools for efficient token usage
4
4
  */
5
5
  import { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';
@@ -1,12 +1,12 @@
1
1
  /**
2
- * Coolify MCP Server v2.0.0
2
+ * Coolify MCP Server v2.2.0
3
3
  * Consolidated tools for efficient token usage
4
4
  */
5
5
  /* eslint-disable @typescript-eslint/no-explicit-any */
6
6
  import { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';
7
7
  import { z } from 'zod';
8
8
  import { CoolifyClient, } from './coolify-client.js';
9
- const VERSION = '2.0.0';
9
+ const VERSION = '2.2.0';
10
10
  /** Wrap handler with error handling */
11
11
  function wrap(fn) {
12
12
  return fn()
@@ -162,7 +162,7 @@ export class CoolifyMcpServer extends McpServer {
162
162
  this.tool('list_applications', 'List apps (summary)', { page: z.number().optional(), per_page: z.number().optional() }, async ({ page, per_page }) => wrap(() => this.client.listApplications({ page, per_page, summary: true })));
163
163
  this.tool('get_application', 'App details', { uuid: z.string() }, async ({ uuid }) => wrap(() => this.client.getApplication(uuid)));
164
164
  this.tool('application', 'Manage app: create/update/delete', {
165
- action: z.enum(['create_github', 'create_key', 'update', 'delete']),
165
+ action: z.enum(['create_github', 'create_key', 'create_dockerimage', 'update', 'delete']),
166
166
  uuid: z.string().optional(),
167
167
  // Create fields
168
168
  project_uuid: z.string().optional(),
@@ -174,10 +174,26 @@ export class CoolifyMcpServer extends McpServer {
174
174
  environment_name: z.string().optional(),
175
175
  build_pack: z.string().optional(),
176
176
  ports_exposes: z.string().optional(),
177
+ // Docker image fields
178
+ docker_registry_image_name: z.string().optional(),
179
+ docker_registry_image_tag: z.string().optional(),
177
180
  // Update fields
178
181
  name: z.string().optional(),
179
182
  description: z.string().optional(),
180
183
  fqdn: z.string().optional(),
184
+ // Health check fields
185
+ health_check_enabled: z.boolean().optional(),
186
+ health_check_path: z.string().optional(),
187
+ health_check_port: z.number().optional(),
188
+ health_check_host: z.string().optional(),
189
+ health_check_method: z.string().optional(),
190
+ health_check_return_code: z.number().optional(),
191
+ health_check_scheme: z.string().optional(),
192
+ health_check_response_text: z.string().optional(),
193
+ health_check_interval: z.number().optional(),
194
+ health_check_timeout: z.number().optional(),
195
+ health_check_retries: z.number().optional(),
196
+ health_check_start_period: z.number().optional(),
181
197
  // Delete fields
182
198
  delete_volumes: z.boolean().optional(),
183
199
  }, async (args) => {
@@ -215,6 +231,21 @@ export class CoolifyMcpServer extends McpServer {
215
231
  };
216
232
  }
217
233
  return wrap(() => this.client.createApplicationPrivateKey(args));
234
+ case 'create_dockerimage':
235
+ if (!args.project_uuid ||
236
+ !args.server_uuid ||
237
+ !args.docker_registry_image_name ||
238
+ !args.ports_exposes) {
239
+ return {
240
+ content: [
241
+ {
242
+ type: 'text',
243
+ text: 'Error: project_uuid, server_uuid, docker_registry_image_name, ports_exposes required',
244
+ },
245
+ ],
246
+ };
247
+ }
248
+ return wrap(() => this.client.createApplicationDockerImage(args));
218
249
  case 'update':
219
250
  if (!uuid)
220
251
  return { content: [{ type: 'text', text: 'Error: uuid required' }] };
@@ -277,11 +308,11 @@ export class CoolifyMcpServer extends McpServer {
277
308
  clickhouse_admin_password: z.string().optional(),
278
309
  dragonfly_password: z.string().optional(),
279
310
  }, async (args) => {
280
- const { action, type, uuid } = args;
311
+ const { action, type, uuid, delete_volumes, ...dbData } = args;
281
312
  if (action === 'delete') {
282
313
  if (!uuid)
283
314
  return { content: [{ type: 'text', text: 'Error: uuid required' }] };
284
- return wrap(() => this.client.deleteDatabase(uuid, { deleteVolumes: args.delete_volumes }));
315
+ return wrap(() => this.client.deleteDatabase(uuid, { deleteVolumes: delete_volumes }));
285
316
  }
286
317
  // create
287
318
  if (!type || !args.server_uuid || !args.project_uuid) {
@@ -301,7 +332,7 @@ export class CoolifyMcpServer extends McpServer {
301
332
  clickhouse: (d) => this.client.createClickhouse(d),
302
333
  dragonfly: (d) => this.client.createDragonfly(d),
303
334
  };
304
- return wrap(() => dbMethods[type](args));
335
+ return wrap(() => dbMethods[type](dbData));
305
336
  });
306
337
  // =========================================================================
307
338
  // Services (3 tools)
@@ -428,10 +459,21 @@ export class CoolifyMcpServer extends McpServer {
428
459
  this.tool('deployment', 'Manage deployment: get/cancel/list_for_app', {
429
460
  action: z.enum(['get', 'cancel', 'list_for_app']),
430
461
  uuid: z.string(),
431
- }, async ({ action, uuid }) => {
462
+ lines: z.number().optional(), // Limit log output to last N lines (for 'get' action)
463
+ }, async ({ action, uuid, lines }) => {
432
464
  switch (action) {
433
465
  case 'get':
434
- return wrap(() => this.client.getDeployment(uuid));
466
+ return wrap(async () => {
467
+ const deployment = await this.client.getDeployment(uuid);
468
+ // Truncate logs to last N lines if specified
469
+ if (lines && deployment.logs) {
470
+ const logLines = deployment.logs.split('\n');
471
+ if (logLines.length > lines) {
472
+ deployment.logs = logLines.slice(-lines).join('\n');
473
+ }
474
+ }
475
+ return deployment;
476
+ });
435
477
  case 'cancel':
436
478
  return wrap(() => this.client.cancelDeployment(uuid));
437
479
  case 'list_for_app':
@@ -476,12 +518,32 @@ export class CoolifyMcpServer extends McpServer {
476
518
  // =========================================================================
477
519
  // Database Backups (1 tool - consolidated)
478
520
  // =========================================================================
479
- this.tool('database_backups', 'Manage backups: list_schedules/get_schedule/list_executions/get_execution', {
480
- action: z.enum(['list_schedules', 'get_schedule', 'list_executions', 'get_execution']),
521
+ this.tool('database_backups', 'Manage backups: list_schedules/get_schedule/list_executions/get_execution/create/update/delete', {
522
+ action: z.enum([
523
+ 'list_schedules',
524
+ 'get_schedule',
525
+ 'list_executions',
526
+ 'get_execution',
527
+ 'create',
528
+ 'update',
529
+ 'delete',
530
+ ]),
481
531
  database_uuid: z.string(),
482
532
  backup_uuid: z.string().optional(),
483
533
  execution_uuid: z.string().optional(),
484
- }, async ({ action, database_uuid, backup_uuid, execution_uuid }) => {
534
+ // Backup configuration parameters
535
+ frequency: z.string().optional(),
536
+ enabled: z.boolean().optional(),
537
+ save_s3: z.boolean().optional(),
538
+ s3_storage_uuid: z.string().optional(),
539
+ databases_to_backup: z.string().optional(),
540
+ dump_all: z.boolean().optional(),
541
+ database_backup_retention_days_locally: z.number().optional(),
542
+ database_backup_retention_days_s3: z.number().optional(),
543
+ database_backup_retention_amount_locally: z.number().optional(),
544
+ database_backup_retention_amount_s3: z.number().optional(),
545
+ }, async (args) => {
546
+ const { action, database_uuid, backup_uuid, execution_uuid, ...backupData } = args;
485
547
  switch (action) {
486
548
  case 'list_schedules':
487
549
  return wrap(() => this.client.listDatabaseBackups(database_uuid));
@@ -501,6 +563,21 @@ export class CoolifyMcpServer extends McpServer {
501
563
  ],
502
564
  };
503
565
  return wrap(() => this.client.getBackupExecution(database_uuid, backup_uuid, execution_uuid));
566
+ case 'create':
567
+ if (!args.frequency)
568
+ return { content: [{ type: 'text', text: 'Error: frequency required' }] };
569
+ return wrap(() => this.client.createDatabaseBackup(database_uuid, {
570
+ ...backupData,
571
+ frequency: args.frequency,
572
+ }));
573
+ case 'update':
574
+ if (!backup_uuid)
575
+ return { content: [{ type: 'text', text: 'Error: backup_uuid required' }] };
576
+ return wrap(() => this.client.updateDatabaseBackup(database_uuid, backup_uuid, backupData));
577
+ case 'delete':
578
+ if (!backup_uuid)
579
+ return { content: [{ type: 'text', text: 'Error: backup_uuid required' }] };
580
+ return wrap(() => this.client.deleteDatabaseBackup(database_uuid, backup_uuid));
504
581
  }
505
582
  });
506
583
  // =========================================================================
@@ -10,6 +10,7 @@ export interface ErrorResponse {
10
10
  error?: string;
11
11
  message: string;
12
12
  status?: number;
13
+ errors?: Record<string, string[]>;
13
14
  }
14
15
  export interface DeleteOptions {
15
16
  deleteConfigurations?: boolean;
@@ -297,6 +298,15 @@ export interface UpdateApplicationRequest {
297
298
  health_check_enabled?: boolean;
298
299
  health_check_path?: string;
299
300
  health_check_port?: number;
301
+ health_check_host?: string;
302
+ health_check_method?: string;
303
+ health_check_return_code?: number;
304
+ health_check_scheme?: string;
305
+ health_check_response_text?: string;
306
+ health_check_interval?: number;
307
+ health_check_timeout?: number;
308
+ health_check_retries?: number;
309
+ health_check_start_period?: number;
300
310
  limits_memory?: string;
301
311
  limits_memory_swap?: string;
302
312
  limits_cpus?: string;
@@ -541,9 +551,22 @@ export interface CreateDatabaseBackupRequest {
541
551
  s3_storage_uuid?: string;
542
552
  databases_to_backup?: string;
543
553
  dump_all?: boolean;
544
- backup_now?: boolean;
545
- backup_retention?: number;
546
- backup_retention_days?: number;
554
+ database_backup_retention_days_locally?: number;
555
+ database_backup_retention_days_s3?: number;
556
+ database_backup_retention_amount_locally?: number;
557
+ database_backup_retention_amount_s3?: number;
558
+ }
559
+ export interface UpdateDatabaseBackupRequest {
560
+ frequency?: string;
561
+ enabled?: boolean;
562
+ save_s3?: boolean;
563
+ s3_storage_uuid?: string;
564
+ databases_to_backup?: string;
565
+ dump_all?: boolean;
566
+ database_backup_retention_days_locally?: number;
567
+ database_backup_retention_days_s3?: number;
568
+ database_backup_retention_amount_locally?: number;
569
+ database_backup_retention_amount_s3?: number;
547
570
  }
548
571
  export interface BackupExecution {
549
572
  id: number;
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@masonator/coolify-mcp",
3
3
  "scope": "@masonator",
4
- "version": "2.0.0",
4
+ "version": "2.2.0",
5
5
  "description": "MCP server implementation for Coolify",
6
6
  "type": "module",
7
7
  "main": "./dist/index.js",