@masonator/coolify-mcp 2.1.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
@@ -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');
@@ -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
  }
@@ -1,5 +1,5 @@
1
1
  /**
2
- * Coolify MCP Server v2.1.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.1.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.1.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' }] };
@@ -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':
@@ -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;
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@masonator/coolify-mcp",
3
3
  "scope": "@masonator",
4
- "version": "2.1.0",
4
+ "version": "2.2.0",
5
5
  "description": "MCP server implementation for Coolify",
6
6
  "type": "module",
7
7
  "main": "./dist/index.js",