@masonator/coolify-mcp 1.1.1 → 1.6.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
@@ -1,26 +1,35 @@
1
1
  # Coolify MCP Server
2
2
 
3
+ [![npm version](https://img.shields.io/npm/v/@masonator/coolify-mcp.svg)](https://www.npmjs.com/package/@masonator/coolify-mcp)
4
+ [![npm downloads](https://img.shields.io/npm/dm/@masonator/coolify-mcp.svg)](https://www.npmjs.com/package/@masonator/coolify-mcp)
5
+ [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)
6
+ [![Node.js Version](https://img.shields.io/node/v/@masonator/coolify-mcp.svg)](https://nodejs.org)
7
+ [![TypeScript](https://img.shields.io/badge/TypeScript-5.8-blue.svg)](https://www.typescriptlang.org/)
8
+ [![CI](https://github.com/StuMason/coolify-mcp/actions/workflows/ci.yml/badge.svg)](https://github.com/StuMason/coolify-mcp/actions/workflows/ci.yml)
9
+ [![codecov](https://codecov.io/gh/StuMason/coolify-mcp/branch/main/graph/badge.svg)](https://codecov.io/gh/StuMason/coolify-mcp)
3
10
  [![MseeP.ai Security Assessment Badge](https://mseep.net/pr/stumason-coolify-mcp-badge.png)](https://mseep.ai/app/stumason-coolify-mcp)
4
11
 
12
+ > **The most comprehensive MCP server for Coolify** - 75 tools, 7 workflow prompts, smart diagnostics, and batch operations for managing your self-hosted PaaS through AI assistants.
13
+
5
14
  A Model Context Protocol (MCP) server for [Coolify](https://coolify.io/), enabling AI assistants to manage and debug your Coolify instances through natural language.
6
15
 
7
16
  ## Features
8
17
 
9
- This MCP server provides **67 tools** and **7 workflow prompts** for **debugging, management, and deployment**:
10
-
11
- | Category | Tools |
12
- | -------------------- | -------------------------------------------------------------------------------------------------------- |
13
- | **Infrastructure** | overview, mcp_version (all resources at once) |
14
- | **Diagnostics** | diagnose_app, diagnose_server, find_issues (smart lookup by name/domain/IP) |
15
- | **Batch Operations** | restart_project_apps, bulk_env_update, stop_all_apps, redeploy_project |
16
- | **Servers** | list, get, validate, resources, domains |
17
- | **Projects** | list, get, create, update, delete |
18
- | **Environments** | list, get, create, delete |
19
- | **Applications** | list, get, update, delete, start, stop, restart, logs, env vars (CRUD), create (private-gh, private-key) |
20
- | **Databases** | list, get, delete, start, stop, restart, backups (list, get), backup executions (list, get) |
21
- | **Services** | list, get, create, update, delete, start, stop, restart, env vars (list, create, delete) |
22
- | **Deployments** | list, get, deploy, cancel, list by application |
23
- | **Private Keys** | list, get, create, update, delete |
18
+ This MCP server provides **75 tools** and **7 workflow prompts** for **debugging, management, and deployment**:
19
+
20
+ | Category | Tools |
21
+ | -------------------- | ------------------------------------------------------------------------------------------------------------- |
22
+ | **Infrastructure** | overview, mcp_version (all resources at once) |
23
+ | **Diagnostics** | diagnose_app, diagnose_server, find_issues (smart lookup by name/domain/IP) |
24
+ | **Batch Operations** | restart_project_apps, bulk_env_update, stop_all_apps, redeploy_project |
25
+ | **Servers** | list, get, validate, resources, domains |
26
+ | **Projects** | list, get, create, update, delete |
27
+ | **Environments** | list, get, create, delete |
28
+ | **Applications** | list, get, update, delete, start, stop, restart, logs, env vars (CRUD), create (private-gh, private-key) |
29
+ | **Databases** | list, get, create (8 types), delete, start, stop, restart, backups (list, get), backup executions (list, get) |
30
+ | **Services** | list, get, create, update, delete, start, stop, restart, env vars (list, create, delete) |
31
+ | **Deployments** | list, get, deploy, cancel, list by application |
32
+ | **Private Keys** | list, get, create, update, delete |
24
33
 
25
34
  ### Workflow Prompts
26
35
 
@@ -297,15 +306,36 @@ Power user tools for operating on multiple resources at once:
297
306
  - `stop_all_apps` - Emergency stop all running applications (requires confirmation)
298
307
  - `redeploy_project` - Redeploy all applications in a project with force rebuild
299
308
 
309
+ ## Why Coolify MCP?
310
+
311
+ - **Context-Optimized**: Responses are 90-99% smaller than raw API, preventing context window exhaustion
312
+ - **Smart Lookup**: Find apps by domain (`stuartmason.co.uk`), servers by IP, not just UUIDs
313
+ - **Batch Operations**: Restart entire projects, bulk update env vars, emergency stop all apps
314
+ - **Workflow Prompts**: Pre-built guided workflows for common tasks
315
+ - **Production Ready**: 98%+ test coverage, TypeScript strict mode, comprehensive error handling
316
+ - **Always Current**: Weekly OpenAPI drift detection ensures we stay in sync with Coolify
317
+
318
+ ## Related Links
319
+
320
+ - [Coolify](https://coolify.io/) - The open-source & self-hostable Heroku/Netlify/Vercel alternative
321
+ - [Model Context Protocol](https://modelcontextprotocol.io/) - The protocol powering AI tool integrations
322
+ - [MCP Server Registry](https://github.com/modelcontextprotocol/servers) - Official MCP server directory
323
+
300
324
  ## Contributing
301
325
 
302
- Contributions welcome! Please open an issue first to discuss major changes.
326
+ Contributions welcome! Please see [CONTRIBUTING.md](CONTRIBUTING.md) for guidelines.
303
327
 
304
328
  ## License
305
329
 
306
- MIT
330
+ MIT - see [LICENSE](LICENSE) for details.
307
331
 
308
332
  ## Support
309
333
 
310
- - [GitHub Issues](https://github.com/stumason/coolify-mcp/issues)
334
+ - [GitHub Issues](https://github.com/StuMason/coolify-mcp/issues)
311
335
  - [Coolify Community](https://coolify.io/docs/contact)
336
+
337
+ ---
338
+
339
+ <p align="center">
340
+ <strong>If you find this useful, please ⭐ star the repo!</strong>
341
+ </p>
@@ -495,9 +495,9 @@ describe('CoolifyClient', () => {
495
495
  });
496
496
  it('should delete a project environment', async () => {
497
497
  mockFetch.mockResolvedValueOnce(mockResponse({ message: 'Deleted' }));
498
- const result = await client.deleteProjectEnvironment('env-uuid');
498
+ const result = await client.deleteProjectEnvironment('project-uuid', 'env-uuid');
499
499
  expect(result).toEqual({ message: 'Deleted' });
500
- expect(mockFetch).toHaveBeenCalledWith('http://localhost:3000/api/v1/projects/environments/env-uuid', expect.objectContaining({ method: 'DELETE' }));
500
+ expect(mockFetch).toHaveBeenCalledWith('http://localhost:3000/api/v1/projects/project-uuid/environments/env-uuid', expect.objectContaining({ method: 'DELETE' }));
501
501
  });
502
502
  });
503
503
  // =========================================================================
@@ -794,6 +794,87 @@ describe('CoolifyClient', () => {
794
794
  expect(result).toEqual(mockExecution);
795
795
  expect(mockFetch).toHaveBeenCalledWith('http://localhost:3000/api/v1/databases/db-uuid/backups/backup-uuid/executions/exec-uuid', expect.any(Object));
796
796
  });
797
+ it('should create a PostgreSQL database', async () => {
798
+ mockFetch.mockResolvedValueOnce(mockResponse({ uuid: 'pg-uuid' }));
799
+ const result = await client.createPostgresql({
800
+ server_uuid: 'server-uuid',
801
+ project_uuid: 'project-uuid',
802
+ environment_name: 'production',
803
+ postgres_user: 'myuser',
804
+ postgres_db: 'mydb',
805
+ });
806
+ expect(result).toEqual({ uuid: 'pg-uuid' });
807
+ expect(mockFetch).toHaveBeenCalledWith('http://localhost:3000/api/v1/databases/postgresql', expect.objectContaining({ method: 'POST' }));
808
+ });
809
+ it('should create a MySQL database', async () => {
810
+ mockFetch.mockResolvedValueOnce(mockResponse({ uuid: 'mysql-uuid' }));
811
+ const result = await client.createMysql({
812
+ server_uuid: 'server-uuid',
813
+ project_uuid: 'project-uuid',
814
+ mysql_user: 'myuser',
815
+ mysql_database: 'mydb',
816
+ });
817
+ expect(result).toEqual({ uuid: 'mysql-uuid' });
818
+ expect(mockFetch).toHaveBeenCalledWith('http://localhost:3000/api/v1/databases/mysql', expect.objectContaining({ method: 'POST' }));
819
+ });
820
+ it('should create a MariaDB database', async () => {
821
+ mockFetch.mockResolvedValueOnce(mockResponse({ uuid: 'mariadb-uuid' }));
822
+ const result = await client.createMariadb({
823
+ server_uuid: 'server-uuid',
824
+ project_uuid: 'project-uuid',
825
+ });
826
+ expect(result).toEqual({ uuid: 'mariadb-uuid' });
827
+ expect(mockFetch).toHaveBeenCalledWith('http://localhost:3000/api/v1/databases/mariadb', expect.objectContaining({ method: 'POST' }));
828
+ });
829
+ it('should create a MongoDB database', async () => {
830
+ mockFetch.mockResolvedValueOnce(mockResponse({ uuid: 'mongo-uuid' }));
831
+ const result = await client.createMongodb({
832
+ server_uuid: 'server-uuid',
833
+ project_uuid: 'project-uuid',
834
+ mongo_initdb_root_username: 'admin',
835
+ });
836
+ expect(result).toEqual({ uuid: 'mongo-uuid' });
837
+ expect(mockFetch).toHaveBeenCalledWith('http://localhost:3000/api/v1/databases/mongodb', expect.objectContaining({ method: 'POST' }));
838
+ });
839
+ it('should create a Redis database', async () => {
840
+ mockFetch.mockResolvedValueOnce(mockResponse({ uuid: 'redis-uuid' }));
841
+ const result = await client.createRedis({
842
+ server_uuid: 'server-uuid',
843
+ project_uuid: 'project-uuid',
844
+ redis_password: 'secret',
845
+ });
846
+ expect(result).toEqual({ uuid: 'redis-uuid' });
847
+ expect(mockFetch).toHaveBeenCalledWith('http://localhost:3000/api/v1/databases/redis', expect.objectContaining({ method: 'POST' }));
848
+ });
849
+ it('should create a KeyDB database', async () => {
850
+ mockFetch.mockResolvedValueOnce(mockResponse({ uuid: 'keydb-uuid' }));
851
+ const result = await client.createKeydb({
852
+ server_uuid: 'server-uuid',
853
+ project_uuid: 'project-uuid',
854
+ });
855
+ expect(result).toEqual({ uuid: 'keydb-uuid' });
856
+ expect(mockFetch).toHaveBeenCalledWith('http://localhost:3000/api/v1/databases/keydb', expect.objectContaining({ method: 'POST' }));
857
+ });
858
+ it('should create a ClickHouse database', async () => {
859
+ mockFetch.mockResolvedValueOnce(mockResponse({ uuid: 'clickhouse-uuid' }));
860
+ const result = await client.createClickhouse({
861
+ server_uuid: 'server-uuid',
862
+ project_uuid: 'project-uuid',
863
+ clickhouse_admin_user: 'admin',
864
+ });
865
+ expect(result).toEqual({ uuid: 'clickhouse-uuid' });
866
+ expect(mockFetch).toHaveBeenCalledWith('http://localhost:3000/api/v1/databases/clickhouse', expect.objectContaining({ method: 'POST' }));
867
+ });
868
+ it('should create a Dragonfly database', async () => {
869
+ mockFetch.mockResolvedValueOnce(mockResponse({ uuid: 'dragonfly-uuid' }));
870
+ const result = await client.createDragonfly({
871
+ server_uuid: 'server-uuid',
872
+ project_uuid: 'project-uuid',
873
+ dragonfly_password: 'secret',
874
+ });
875
+ expect(result).toEqual({ uuid: 'dragonfly-uuid' });
876
+ expect(mockFetch).toHaveBeenCalledWith('http://localhost:3000/api/v1/databases/dragonfly', expect.objectContaining({ method: 'POST' }));
877
+ });
797
878
  });
798
879
  // =========================================================================
799
880
  // Service endpoints - extended coverage
@@ -16,6 +16,14 @@ const mockDiagnoseApplication = jest.fn();
16
16
  const mockDiagnoseServer = jest.fn();
17
17
  const mockFindInfrastructureIssues = jest.fn();
18
18
  const mockDeleteDatabase = jest.fn();
19
+ const mockCreatePostgresql = jest.fn();
20
+ const mockCreateMysql = jest.fn();
21
+ const mockCreateMariadb = jest.fn();
22
+ const mockCreateMongodb = jest.fn();
23
+ const mockCreateRedis = jest.fn();
24
+ const mockCreateKeydb = jest.fn();
25
+ const mockCreateClickhouse = jest.fn();
26
+ const mockCreateDragonfly = jest.fn();
19
27
  // Mock the CoolifyClient module
20
28
  jest.mock('../lib/coolify-client.js', () => ({
21
29
  CoolifyClient: jest.fn().mockImplementation(() => ({
@@ -28,6 +36,14 @@ jest.mock('../lib/coolify-client.js', () => ({
28
36
  diagnoseServer: mockDiagnoseServer,
29
37
  findInfrastructureIssues: mockFindInfrastructureIssues,
30
38
  deleteDatabase: mockDeleteDatabase,
39
+ createPostgresql: mockCreatePostgresql,
40
+ createMysql: mockCreateMysql,
41
+ createMariadb: mockCreateMariadb,
42
+ createMongodb: mockCreateMongodb,
43
+ createRedis: mockCreateRedis,
44
+ createKeydb: mockCreateKeydb,
45
+ createClickhouse: mockCreateClickhouse,
46
+ createDragonfly: mockCreateDragonfly,
31
47
  getVersion: jest.fn(),
32
48
  })),
33
49
  }));
@@ -317,6 +333,71 @@ describe('CoolifyMcpServer', () => {
317
333
  expect(mockDeleteDatabase).toHaveBeenCalledWith('db-uuid-123', { deleteVolumes: true });
318
334
  });
319
335
  });
336
+ describe('database creation tools', () => {
337
+ const baseParams = {
338
+ server_uuid: 'server-uuid',
339
+ project_uuid: 'project-uuid',
340
+ environment_name: 'production',
341
+ };
342
+ it('should call createPostgresql with correct params', async () => {
343
+ mockCreatePostgresql.mockResolvedValue({ uuid: 'pg-uuid' });
344
+ await mockCreatePostgresql({ ...baseParams, postgres_user: 'myuser' });
345
+ expect(mockCreatePostgresql).toHaveBeenCalledWith({
346
+ ...baseParams,
347
+ postgres_user: 'myuser',
348
+ });
349
+ });
350
+ it('should call createMysql with correct params', async () => {
351
+ mockCreateMysql.mockResolvedValue({ uuid: 'mysql-uuid' });
352
+ await mockCreateMysql({ ...baseParams, mysql_user: 'myuser' });
353
+ expect(mockCreateMysql).toHaveBeenCalledWith({
354
+ ...baseParams,
355
+ mysql_user: 'myuser',
356
+ });
357
+ });
358
+ it('should call createMariadb with correct params', async () => {
359
+ mockCreateMariadb.mockResolvedValue({ uuid: 'mariadb-uuid' });
360
+ await mockCreateMariadb(baseParams);
361
+ expect(mockCreateMariadb).toHaveBeenCalledWith(baseParams);
362
+ });
363
+ it('should call createMongodb with correct params', async () => {
364
+ mockCreateMongodb.mockResolvedValue({ uuid: 'mongo-uuid' });
365
+ await mockCreateMongodb({ ...baseParams, mongo_initdb_root_username: 'admin' });
366
+ expect(mockCreateMongodb).toHaveBeenCalledWith({
367
+ ...baseParams,
368
+ mongo_initdb_root_username: 'admin',
369
+ });
370
+ });
371
+ it('should call createRedis with correct params', async () => {
372
+ mockCreateRedis.mockResolvedValue({ uuid: 'redis-uuid' });
373
+ await mockCreateRedis({ ...baseParams, redis_password: 'secret' });
374
+ expect(mockCreateRedis).toHaveBeenCalledWith({
375
+ ...baseParams,
376
+ redis_password: 'secret',
377
+ });
378
+ });
379
+ it('should call createKeydb with correct params', async () => {
380
+ mockCreateKeydb.mockResolvedValue({ uuid: 'keydb-uuid' });
381
+ await mockCreateKeydb(baseParams);
382
+ expect(mockCreateKeydb).toHaveBeenCalledWith(baseParams);
383
+ });
384
+ it('should call createClickhouse with correct params', async () => {
385
+ mockCreateClickhouse.mockResolvedValue({ uuid: 'clickhouse-uuid' });
386
+ await mockCreateClickhouse({ ...baseParams, clickhouse_admin_user: 'admin' });
387
+ expect(mockCreateClickhouse).toHaveBeenCalledWith({
388
+ ...baseParams,
389
+ clickhouse_admin_user: 'admin',
390
+ });
391
+ });
392
+ it('should call createDragonfly with correct params', async () => {
393
+ mockCreateDragonfly.mockResolvedValue({ uuid: 'dragonfly-uuid' });
394
+ await mockCreateDragonfly({ ...baseParams, dragonfly_password: 'secret' });
395
+ expect(mockCreateDragonfly).toHaveBeenCalledWith({
396
+ ...baseParams,
397
+ dragonfly_password: 'secret',
398
+ });
399
+ });
400
+ });
320
401
  });
321
402
  describe('version tools', () => {
322
403
  it('get_mcp_version should return correct version format', () => {
@@ -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, 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, 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;
@@ -82,7 +82,7 @@ export declare class CoolifyClient {
82
82
  listProjectEnvironments(projectUuid: string): Promise<Environment[]>;
83
83
  getProjectEnvironment(projectUuid: string, environmentNameOrUuid: string): Promise<Environment>;
84
84
  createProjectEnvironment(projectUuid: string, data: CreateEnvironmentRequest): Promise<UuidResponse>;
85
- deleteProjectEnvironment(environmentUuid: string): Promise<MessageResponse>;
85
+ deleteProjectEnvironment(projectUuid: string, environmentNameOrUuid: string): Promise<MessageResponse>;
86
86
  listApplications(options?: ListOptions): Promise<Application[] | ApplicationSummary[]>;
87
87
  getApplication(uuid: string): Promise<Application>;
88
88
  createApplicationPublic(data: CreateApplicationPublicRequest): Promise<UuidResponse>;
@@ -114,6 +114,14 @@ export declare class CoolifyClient {
114
114
  startDatabase(uuid: string): Promise<MessageResponse>;
115
115
  stopDatabase(uuid: string): Promise<MessageResponse>;
116
116
  restartDatabase(uuid: string): Promise<MessageResponse>;
117
+ createPostgresql(data: CreatePostgresqlRequest): Promise<CreateDatabaseResponse>;
118
+ createMysql(data: CreateMysqlRequest): Promise<CreateDatabaseResponse>;
119
+ createMariadb(data: CreateMariadbRequest): Promise<CreateDatabaseResponse>;
120
+ createMongodb(data: CreateMongodbRequest): Promise<CreateDatabaseResponse>;
121
+ createRedis(data: CreateRedisRequest): Promise<CreateDatabaseResponse>;
122
+ createKeydb(data: CreateKeydbRequest): Promise<CreateDatabaseResponse>;
123
+ createClickhouse(data: CreateClickhouseRequest): Promise<CreateDatabaseResponse>;
124
+ createDragonfly(data: CreateDragonflyRequest): Promise<CreateDatabaseResponse>;
117
125
  listServices(options?: ListOptions): Promise<Service[] | ServiceSummary[]>;
118
126
  getService(uuid: string): Promise<Service>;
119
127
  createService(data: CreateServiceRequest): Promise<ServiceCreateResponse>;
@@ -244,8 +244,8 @@ export class CoolifyClient {
244
244
  body: JSON.stringify(data),
245
245
  });
246
246
  }
247
- async deleteProjectEnvironment(environmentUuid) {
248
- return this.request(`/projects/environments/${environmentUuid}`, {
247
+ async deleteProjectEnvironment(projectUuid, environmentNameOrUuid) {
248
+ return this.request(`/projects/${projectUuid}/environments/${environmentNameOrUuid}`, {
249
249
  method: 'DELETE',
250
250
  });
251
251
  }
@@ -414,6 +414,55 @@ export class CoolifyClient {
414
414
  method: 'POST',
415
415
  });
416
416
  }
417
+ // Database creation methods
418
+ async createPostgresql(data) {
419
+ return this.request('/databases/postgresql', {
420
+ method: 'POST',
421
+ body: JSON.stringify(data),
422
+ });
423
+ }
424
+ async createMysql(data) {
425
+ return this.request('/databases/mysql', {
426
+ method: 'POST',
427
+ body: JSON.stringify(data),
428
+ });
429
+ }
430
+ async createMariadb(data) {
431
+ return this.request('/databases/mariadb', {
432
+ method: 'POST',
433
+ body: JSON.stringify(data),
434
+ });
435
+ }
436
+ async createMongodb(data) {
437
+ return this.request('/databases/mongodb', {
438
+ method: 'POST',
439
+ body: JSON.stringify(data),
440
+ });
441
+ }
442
+ async createRedis(data) {
443
+ return this.request('/databases/redis', {
444
+ method: 'POST',
445
+ body: JSON.stringify(data),
446
+ });
447
+ }
448
+ async createKeydb(data) {
449
+ return this.request('/databases/keydb', {
450
+ method: 'POST',
451
+ body: JSON.stringify(data),
452
+ });
453
+ }
454
+ async createClickhouse(data) {
455
+ return this.request('/databases/clickhouse', {
456
+ method: 'POST',
457
+ body: JSON.stringify(data),
458
+ });
459
+ }
460
+ async createDragonfly(data) {
461
+ return this.request('/databases/dragonfly', {
462
+ method: 'POST',
463
+ body: JSON.stringify(data),
464
+ });
465
+ }
417
466
  // ===========================================================================
418
467
  // Service endpoints
419
468
  // ===========================================================================
@@ -20,7 +20,7 @@
20
20
  import { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';
21
21
  import { z } from 'zod';
22
22
  import { CoolifyClient, } from './coolify-client.js';
23
- const VERSION = '1.1.1';
23
+ const VERSION = '1.6.0';
24
24
  /** Wrap tool handler with consistent error handling */
25
25
  function wrapHandler(fn) {
26
26
  return fn()
@@ -146,7 +146,10 @@ export class CoolifyMcpServer extends McpServer {
146
146
  name: z.string().describe('Environment name'),
147
147
  description: z.string().optional().describe('Description'),
148
148
  }, async ({ project_uuid, ...data }) => wrapHandler(() => this.client.createProjectEnvironment(project_uuid, data)));
149
- this.tool('delete_environment', 'Delete an environment', { environment_uuid: z.string().describe('Environment UUID') }, async ({ environment_uuid }) => wrapHandler(() => this.client.deleteProjectEnvironment(environment_uuid)));
149
+ this.tool('delete_environment', 'Delete an environment. Environment must be empty (no resources).', {
150
+ project_uuid: z.string().describe('Project UUID'),
151
+ environment_name_or_uuid: z.string().describe('Environment name or UUID'),
152
+ }, async ({ project_uuid, environment_name_or_uuid }) => wrapHandler(() => this.client.deleteProjectEnvironment(project_uuid, environment_name_or_uuid)));
150
153
  // =========================================================================
151
154
  // Applications (15 tools)
152
155
  // =========================================================================
@@ -219,7 +222,7 @@ export class CoolifyMcpServer extends McpServer {
219
222
  env_uuid: z.string().describe('Env variable UUID'),
220
223
  }, async ({ uuid, env_uuid }) => wrapHandler(() => this.client.deleteApplicationEnvVar(uuid, env_uuid)));
221
224
  // =========================================================================
222
- // Databases (6 tools)
225
+ // Databases (14 tools)
223
226
  // =========================================================================
224
227
  this.tool('list_databases', 'List all databases (returns summary: uuid, name, type, status). Use get_database for full details.', {
225
228
  page: z.number().optional().describe('Page number for pagination'),
@@ -233,6 +236,78 @@ export class CoolifyMcpServer extends McpServer {
233
236
  uuid: z.string().describe('Database UUID'),
234
237
  delete_volumes: z.boolean().optional().describe('Delete volumes (default: false)'),
235
238
  }, async ({ uuid, delete_volumes }) => wrapHandler(() => this.client.deleteDatabase(uuid, { deleteVolumes: delete_volumes })));
239
+ // Database creation tools - shared schema for base fields
240
+ const databaseBaseSchema = {
241
+ server_uuid: z.string().describe('Server UUID'),
242
+ project_uuid: z.string().describe('Project UUID'),
243
+ environment_name: z.string().optional().describe('Environment name'),
244
+ environment_uuid: z.string().optional().describe('Environment UUID'),
245
+ destination_uuid: z.string().optional().describe('Destination UUID'),
246
+ name: z.string().optional().describe('Database name'),
247
+ description: z.string().optional().describe('Database description'),
248
+ image: z.string().optional().describe('Docker image'),
249
+ is_public: z.boolean().optional().describe('Make database publicly accessible'),
250
+ public_port: z.number().optional().describe('Public port'),
251
+ limits_memory: z.string().optional().describe('Memory limit'),
252
+ limits_memory_swap: z.string().optional().describe('Memory swap limit'),
253
+ limits_memory_swappiness: z.number().optional().describe('Memory swappiness'),
254
+ limits_memory_reservation: z.string().optional().describe('Memory reservation'),
255
+ limits_cpus: z.string().optional().describe('CPU limit'),
256
+ limits_cpuset: z.string().optional().describe('CPU set'),
257
+ limits_cpu_shares: z.number().optional().describe('CPU shares'),
258
+ instant_deploy: z.boolean().optional().describe('Deploy immediately after creation'),
259
+ };
260
+ this.tool('create_postgresql', 'Create a new PostgreSQL database', {
261
+ ...databaseBaseSchema,
262
+ postgres_user: z.string().optional().describe('PostgreSQL user'),
263
+ postgres_password: z.string().optional().describe('PostgreSQL password'),
264
+ postgres_db: z.string().optional().describe('PostgreSQL database name'),
265
+ postgres_initdb_args: z.string().optional().describe('PostgreSQL initdb args'),
266
+ postgres_host_auth_method: z.string().optional().describe('PostgreSQL host auth method'),
267
+ postgres_conf: z.string().optional().describe('PostgreSQL configuration'),
268
+ }, async (args) => wrapHandler(() => this.client.createPostgresql(args)));
269
+ this.tool('create_mysql', 'Create a new MySQL database', {
270
+ ...databaseBaseSchema,
271
+ mysql_root_password: z.string().optional().describe('MySQL root password'),
272
+ mysql_user: z.string().optional().describe('MySQL user'),
273
+ mysql_password: z.string().optional().describe('MySQL password'),
274
+ mysql_database: z.string().optional().describe('MySQL database name'),
275
+ mysql_conf: z.string().optional().describe('MySQL configuration'),
276
+ }, async (args) => wrapHandler(() => this.client.createMysql(args)));
277
+ this.tool('create_mariadb', 'Create a new MariaDB database', {
278
+ ...databaseBaseSchema,
279
+ mariadb_root_password: z.string().optional().describe('MariaDB root password'),
280
+ mariadb_user: z.string().optional().describe('MariaDB user'),
281
+ mariadb_password: z.string().optional().describe('MariaDB password'),
282
+ mariadb_database: z.string().optional().describe('MariaDB database name'),
283
+ mariadb_conf: z.string().optional().describe('MariaDB configuration'),
284
+ }, async (args) => wrapHandler(() => this.client.createMariadb(args)));
285
+ this.tool('create_mongodb', 'Create a new MongoDB database', {
286
+ ...databaseBaseSchema,
287
+ mongo_initdb_root_username: z.string().optional().describe('MongoDB root username'),
288
+ mongo_initdb_root_password: z.string().optional().describe('MongoDB root password'),
289
+ mongo_initdb_database: z.string().optional().describe('MongoDB database name'),
290
+ mongo_conf: z.string().optional().describe('MongoDB configuration'),
291
+ }, async (args) => wrapHandler(() => this.client.createMongodb(args)));
292
+ this.tool('create_redis', 'Create a new Redis database', {
293
+ ...databaseBaseSchema,
294
+ redis_password: z.string().optional().describe('Redis password'),
295
+ redis_conf: z.string().optional().describe('Redis configuration'),
296
+ }, async (args) => wrapHandler(() => this.client.createRedis(args)));
297
+ this.tool('create_keydb', 'Create a new KeyDB database', {
298
+ ...databaseBaseSchema,
299
+ keydb_password: z.string().optional().describe('KeyDB password'),
300
+ keydb_conf: z.string().optional().describe('KeyDB configuration'),
301
+ }, async (args) => wrapHandler(() => this.client.createKeydb(args)));
302
+ this.tool('create_clickhouse', 'Create a new ClickHouse database', {
303
+ ...databaseBaseSchema,
304
+ clickhouse_admin_user: z.string().optional().describe('ClickHouse admin user'),
305
+ clickhouse_admin_password: z.string().optional().describe('ClickHouse admin password'),
306
+ }, async (args) => wrapHandler(() => this.client.createClickhouse(args)));
307
+ this.tool('create_dragonfly', 'Create a new Dragonfly database (Redis-compatible)', {
308
+ ...databaseBaseSchema,
309
+ dragonfly_password: z.string().optional().describe('Dragonfly password'),
310
+ }, async (args) => wrapHandler(() => this.client.createDragonfly(args)));
236
311
  // =========================================================================
237
312
  // Services (11 tools)
238
313
  // =========================================================================
@@ -451,6 +451,72 @@ export interface UpdateDatabaseRequest {
451
451
  clickhouse_admin_password?: string;
452
452
  dragonfly_password?: string;
453
453
  }
454
+ export interface CreateDatabaseBaseRequest {
455
+ server_uuid: string;
456
+ project_uuid: string;
457
+ environment_name?: string;
458
+ environment_uuid?: string;
459
+ destination_uuid?: string;
460
+ name?: string;
461
+ description?: string;
462
+ image?: string;
463
+ is_public?: boolean;
464
+ public_port?: number;
465
+ limits_memory?: string;
466
+ limits_memory_swap?: string;
467
+ limits_memory_swappiness?: number;
468
+ limits_memory_reservation?: string;
469
+ limits_cpus?: string;
470
+ limits_cpuset?: string;
471
+ limits_cpu_shares?: number;
472
+ instant_deploy?: boolean;
473
+ }
474
+ export interface CreatePostgresqlRequest extends CreateDatabaseBaseRequest {
475
+ postgres_user?: string;
476
+ postgres_password?: string;
477
+ postgres_db?: string;
478
+ postgres_initdb_args?: string;
479
+ postgres_host_auth_method?: string;
480
+ postgres_conf?: string;
481
+ }
482
+ export interface CreateMysqlRequest extends CreateDatabaseBaseRequest {
483
+ mysql_root_password?: string;
484
+ mysql_user?: string;
485
+ mysql_password?: string;
486
+ mysql_database?: string;
487
+ mysql_conf?: string;
488
+ }
489
+ export interface CreateMariadbRequest extends CreateDatabaseBaseRequest {
490
+ mariadb_root_password?: string;
491
+ mariadb_user?: string;
492
+ mariadb_password?: string;
493
+ mariadb_database?: string;
494
+ mariadb_conf?: string;
495
+ }
496
+ export interface CreateMongodbRequest extends CreateDatabaseBaseRequest {
497
+ mongo_initdb_root_username?: string;
498
+ mongo_initdb_root_password?: string;
499
+ mongo_initdb_database?: string;
500
+ mongo_conf?: string;
501
+ }
502
+ export interface CreateRedisRequest extends CreateDatabaseBaseRequest {
503
+ redis_password?: string;
504
+ redis_conf?: string;
505
+ }
506
+ export interface CreateKeydbRequest extends CreateDatabaseBaseRequest {
507
+ keydb_password?: string;
508
+ keydb_conf?: string;
509
+ }
510
+ export interface CreateClickhouseRequest extends CreateDatabaseBaseRequest {
511
+ clickhouse_admin_user?: string;
512
+ clickhouse_admin_password?: string;
513
+ }
514
+ export interface CreateDragonflyRequest extends CreateDatabaseBaseRequest {
515
+ dragonfly_password?: string;
516
+ }
517
+ export interface CreateDatabaseResponse {
518
+ uuid: string;
519
+ }
454
520
  export interface DatabaseBackup {
455
521
  id: number;
456
522
  uuid: string;
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@masonator/coolify-mcp",
3
3
  "scope": "@masonator",
4
- "version": "1.1.1",
4
+ "version": "1.6.0",
5
5
  "description": "MCP server implementation for Coolify",
6
6
  "type": "module",
7
7
  "main": "./dist/index.js",