@masonator/coolify-mcp 2.0.0 → 2.1.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.
@@ -780,6 +780,37 @@ describe('CoolifyClient', () => {
780
780
  expect(result).toEqual(mockBackup);
781
781
  expect(mockFetch).toHaveBeenCalledWith('http://localhost:3000/api/v1/databases/db-uuid/backups/backup-uuid', expect.any(Object));
782
782
  });
783
+ it('should create a database backup', async () => {
784
+ const mockBackup = { uuid: 'backup-uuid', frequency: '0 0 * * *', enabled: true };
785
+ mockFetch.mockResolvedValueOnce(mockResponse(mockBackup));
786
+ const result = await client.createDatabaseBackup('db-uuid', {
787
+ frequency: '0 0 * * *',
788
+ enabled: true,
789
+ save_s3: true,
790
+ s3_storage_uuid: 'storage-uuid',
791
+ database_backup_retention_days_locally: 7,
792
+ database_backup_retention_days_s3: 7,
793
+ });
794
+ expect(result).toEqual(mockBackup);
795
+ expect(mockFetch).toHaveBeenCalledWith('http://localhost:3000/api/v1/databases/db-uuid/backups', expect.objectContaining({ method: 'POST' }));
796
+ });
797
+ it('should update a database backup', async () => {
798
+ const mockData = { message: 'Backup updated' };
799
+ mockFetch.mockResolvedValueOnce(mockResponse(mockData));
800
+ const result = await client.updateDatabaseBackup('db-uuid', 'backup-uuid', {
801
+ enabled: false,
802
+ frequency: '0 2 * * *',
803
+ });
804
+ expect(result).toEqual(mockData);
805
+ expect(mockFetch).toHaveBeenCalledWith('http://localhost:3000/api/v1/databases/db-uuid/backups/backup-uuid', expect.objectContaining({ method: 'PATCH' }));
806
+ });
807
+ it('should delete a database backup', async () => {
808
+ const mockData = { message: 'Backup deleted' };
809
+ mockFetch.mockResolvedValueOnce(mockResponse(mockData));
810
+ const result = await client.deleteDatabaseBackup('db-uuid', 'backup-uuid');
811
+ expect(result).toEqual(mockData);
812
+ expect(mockFetch).toHaveBeenCalledWith('http://localhost:3000/api/v1/databases/db-uuid/backups/backup-uuid', expect.objectContaining({ method: 'DELETE' }));
813
+ });
783
814
  it('should list backup executions', async () => {
784
815
  const mockExecutions = [{ uuid: 'exec-uuid', status: 'success' }];
785
816
  mockFetch.mockResolvedValueOnce(mockResponse(mockExecutions));
@@ -108,6 +108,9 @@ describe('CoolifyMcpServer v2', () => {
108
108
  // Backup operations
109
109
  expect(typeof client.listDatabaseBackups).toBe('function');
110
110
  expect(typeof client.getDatabaseBackup).toBe('function');
111
+ expect(typeof client.createDatabaseBackup).toBe('function');
112
+ expect(typeof client.updateDatabaseBackup).toBe('function');
113
+ expect(typeof client.deleteDatabaseBackup).toBe('function');
111
114
  expect(typeof client.listBackupExecutions).toBe('function');
112
115
  expect(typeof client.getBackupExecution).toBe('function');
113
116
  // 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).
@@ -648,6 +648,23 @@ export class CoolifyClient {
648
648
  async getBackupExecution(databaseUuid, backupUuid, executionUuid) {
649
649
  return this.request(`/databases/${databaseUuid}/backups/${backupUuid}/executions/${executionUuid}`);
650
650
  }
651
+ async createDatabaseBackup(databaseUuid, data) {
652
+ return this.request(`/databases/${databaseUuid}/backups`, {
653
+ method: 'POST',
654
+ body: JSON.stringify(data),
655
+ });
656
+ }
657
+ async updateDatabaseBackup(databaseUuid, backupUuid, data) {
658
+ return this.request(`/databases/${databaseUuid}/backups/${backupUuid}`, {
659
+ method: 'PATCH',
660
+ body: JSON.stringify(data),
661
+ });
662
+ }
663
+ async deleteDatabaseBackup(databaseUuid, backupUuid) {
664
+ return this.request(`/databases/${databaseUuid}/backups/${backupUuid}`, {
665
+ method: 'DELETE',
666
+ });
667
+ }
651
668
  // ===========================================================================
652
669
  // Deployment Control endpoints
653
670
  // ===========================================================================
@@ -1,5 +1,5 @@
1
1
  /**
2
- * Coolify MCP Server v2.0.0
2
+ * Coolify MCP Server v2.1.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.1.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.1.0';
10
10
  /** Wrap handler with error handling */
11
11
  function wrap(fn) {
12
12
  return fn()
@@ -277,11 +277,11 @@ export class CoolifyMcpServer extends McpServer {
277
277
  clickhouse_admin_password: z.string().optional(),
278
278
  dragonfly_password: z.string().optional(),
279
279
  }, async (args) => {
280
- const { action, type, uuid } = args;
280
+ const { action, type, uuid, delete_volumes, ...dbData } = args;
281
281
  if (action === 'delete') {
282
282
  if (!uuid)
283
283
  return { content: [{ type: 'text', text: 'Error: uuid required' }] };
284
- return wrap(() => this.client.deleteDatabase(uuid, { deleteVolumes: args.delete_volumes }));
284
+ return wrap(() => this.client.deleteDatabase(uuid, { deleteVolumes: delete_volumes }));
285
285
  }
286
286
  // create
287
287
  if (!type || !args.server_uuid || !args.project_uuid) {
@@ -301,7 +301,7 @@ export class CoolifyMcpServer extends McpServer {
301
301
  clickhouse: (d) => this.client.createClickhouse(d),
302
302
  dragonfly: (d) => this.client.createDragonfly(d),
303
303
  };
304
- return wrap(() => dbMethods[type](args));
304
+ return wrap(() => dbMethods[type](dbData));
305
305
  });
306
306
  // =========================================================================
307
307
  // Services (3 tools)
@@ -476,12 +476,32 @@ export class CoolifyMcpServer extends McpServer {
476
476
  // =========================================================================
477
477
  // Database Backups (1 tool - consolidated)
478
478
  // =========================================================================
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']),
479
+ this.tool('database_backups', 'Manage backups: list_schedules/get_schedule/list_executions/get_execution/create/update/delete', {
480
+ action: z.enum([
481
+ 'list_schedules',
482
+ 'get_schedule',
483
+ 'list_executions',
484
+ 'get_execution',
485
+ 'create',
486
+ 'update',
487
+ 'delete',
488
+ ]),
481
489
  database_uuid: z.string(),
482
490
  backup_uuid: z.string().optional(),
483
491
  execution_uuid: z.string().optional(),
484
- }, async ({ action, database_uuid, backup_uuid, execution_uuid }) => {
492
+ // Backup configuration parameters
493
+ frequency: z.string().optional(),
494
+ enabled: z.boolean().optional(),
495
+ save_s3: z.boolean().optional(),
496
+ s3_storage_uuid: z.string().optional(),
497
+ databases_to_backup: z.string().optional(),
498
+ dump_all: z.boolean().optional(),
499
+ database_backup_retention_days_locally: z.number().optional(),
500
+ database_backup_retention_days_s3: z.number().optional(),
501
+ database_backup_retention_amount_locally: z.number().optional(),
502
+ database_backup_retention_amount_s3: z.number().optional(),
503
+ }, async (args) => {
504
+ const { action, database_uuid, backup_uuid, execution_uuid, ...backupData } = args;
485
505
  switch (action) {
486
506
  case 'list_schedules':
487
507
  return wrap(() => this.client.listDatabaseBackups(database_uuid));
@@ -501,6 +521,21 @@ export class CoolifyMcpServer extends McpServer {
501
521
  ],
502
522
  };
503
523
  return wrap(() => this.client.getBackupExecution(database_uuid, backup_uuid, execution_uuid));
524
+ case 'create':
525
+ if (!args.frequency)
526
+ return { content: [{ type: 'text', text: 'Error: frequency required' }] };
527
+ return wrap(() => this.client.createDatabaseBackup(database_uuid, {
528
+ ...backupData,
529
+ frequency: args.frequency,
530
+ }));
531
+ case 'update':
532
+ if (!backup_uuid)
533
+ return { content: [{ type: 'text', text: 'Error: backup_uuid required' }] };
534
+ return wrap(() => this.client.updateDatabaseBackup(database_uuid, backup_uuid, backupData));
535
+ case 'delete':
536
+ if (!backup_uuid)
537
+ return { content: [{ type: 'text', text: 'Error: backup_uuid required' }] };
538
+ return wrap(() => this.client.deleteDatabaseBackup(database_uuid, backup_uuid));
504
539
  }
505
540
  });
506
541
  // =========================================================================
@@ -541,9 +541,22 @@ export interface CreateDatabaseBackupRequest {
541
541
  s3_storage_uuid?: string;
542
542
  databases_to_backup?: string;
543
543
  dump_all?: boolean;
544
- backup_now?: boolean;
545
- backup_retention?: number;
546
- backup_retention_days?: number;
544
+ database_backup_retention_days_locally?: number;
545
+ database_backup_retention_days_s3?: number;
546
+ database_backup_retention_amount_locally?: number;
547
+ database_backup_retention_amount_s3?: number;
548
+ }
549
+ export interface UpdateDatabaseBackupRequest {
550
+ frequency?: string;
551
+ enabled?: boolean;
552
+ save_s3?: boolean;
553
+ s3_storage_uuid?: string;
554
+ databases_to_backup?: string;
555
+ dump_all?: boolean;
556
+ database_backup_retention_days_locally?: number;
557
+ database_backup_retention_days_s3?: number;
558
+ database_backup_retention_amount_locally?: number;
559
+ database_backup_retention_amount_s3?: number;
547
560
  }
548
561
  export interface BackupExecution {
549
562
  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.1.0",
5
5
  "description": "MCP server implementation for Coolify",
6
6
  "type": "module",
7
7
  "main": "./dist/index.js",