Coolify MCP Server
by StuMason
Verified
import { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';
import { Transport } from '@modelcontextprotocol/sdk/shared/transport.js';
import { CoolifyClient } from './coolify-client.js';
import debug from 'debug';
import { z } from 'zod';
import type {
ServerInfo,
ServerResources,
ServerDomain,
ValidationResponse,
Project,
CreateProjectRequest,
UpdateProjectRequest,
Environment,
Deployment,
Database,
DatabaseUpdateRequest,
Service,
CreateServiceRequest,
DeleteServiceOptions,
} from '../types/coolify.js';
const log = debug('coolify:mcp');
// Define valid service types
const serviceTypes = [
'activepieces',
'appsmith',
'appwrite',
'authentik',
'babybuddy',
'budge',
'changedetection',
'chatwoot',
'classicpress-with-mariadb',
'classicpress-with-mysql',
'classicpress-without-database',
'cloudflared',
'code-server',
'dashboard',
'directus',
'directus-with-postgresql',
'docker-registry',
'docuseal',
'docuseal-with-postgres',
'dokuwiki',
'duplicati',
'emby',
'embystat',
'fider',
'filebrowser',
'firefly',
'formbricks',
'ghost',
'gitea',
'gitea-with-mariadb',
'gitea-with-mysql',
'gitea-with-postgresql',
'glance',
'glances',
'glitchtip',
'grafana',
'grafana-with-postgresql',
'grocy',
'heimdall',
'homepage',
'jellyfin',
'kuzzle',
'listmonk',
'logto',
'mediawiki',
'meilisearch',
'metabase',
'metube',
'minio',
'moodle',
'n8n',
'n8n-with-postgresql',
'next-image-transformation',
'nextcloud',
'nocodb',
'odoo',
'openblocks',
'pairdrop',
'penpot',
'phpmyadmin',
'pocketbase',
'posthog',
'reactive-resume',
'rocketchat',
'shlink',
'slash',
'snapdrop',
'statusnook',
'stirling-pdf',
'supabase',
'syncthing',
'tolgee',
'trigger',
'trigger-with-external-database',
'twenty',
'umami',
'unleash-with-postgresql',
'unleash-without-database',
'uptime-kuma',
'vaultwarden',
'vikunja',
'weblate',
'whoogle',
'wordpress-with-mariadb',
'wordpress-with-mysql',
'wordpress-without-database'
] as const;
export class CoolifyMcpServer extends McpServer {
private client: CoolifyClient;
constructor(config: { baseUrl: string; accessToken: string }) {
super({
name: 'coolify',
version: '0.1.18'
});
log('Initializing server with config: %o', config);
this.client = new CoolifyClient(config);
}
async initialize(): Promise<void> {
// Register capabilities first
await this.server.registerCapabilities({
tools: {}
});
// Then register all tools
this.tool('list_servers', 'List all Coolify servers', {}, async () => {
const servers = await this.client.listServers();
return {
content: [{ type: 'text', text: JSON.stringify(servers, null, 2) }]
};
});
this.tool('get_server', 'Get details about a specific Coolify server', {
uuid: z.string().describe('UUID of the server to get details for')
}, async (args) => {
const server = await this.client.getServer(args.uuid);
return {
content: [{ type: 'text', text: JSON.stringify(server, null, 2) }]
};
});
this.tool('get_server_resources', 'Get the current resources running on a specific Coolify server', {
uuid: z.string()
}, async (args, _extra) => {
const resources = await this.client.getServerResources(args.uuid);
return {
content: [{ type: 'text', text: JSON.stringify(resources, null, 2) }]
};
});
this.tool('get_server_domains', 'Get domains for a specific Coolify server', {
uuid: z.string()
}, async (args, _extra) => {
const domains = await this.client.getServerDomains(args.uuid);
return {
content: [{ type: 'text', text: JSON.stringify(domains, null, 2) }]
};
});
this.tool('validate_server', 'Validate a specific Coolify server', {
uuid: z.string()
}, async (args, _extra) => {
const validation = await this.client.validateServer(args.uuid);
return {
content: [{ type: 'text', text: JSON.stringify(validation, null, 2) }]
};
});
this.tool('list_projects', 'List all Coolify projects', {}, async (_args, _extra) => {
const projects = await this.client.listProjects();
return {
content: [{ type: 'text', text: JSON.stringify(projects, null, 2) }]
};
});
this.tool('get_project', 'Get details about a specific Coolify project', {
uuid: z.string()
}, async (args, _extra) => {
const project = await this.client.getProject(args.uuid);
return {
content: [{ type: 'text', text: JSON.stringify(project, null, 2) }]
};
});
this.tool('create_project', 'Create a new Coolify project', {
name: z.string(),
description: z.string().optional()
}, async (args, _extra) => {
const result = await this.client.createProject({
name: args.name,
description: args.description
});
return {
content: [{ type: 'text', text: JSON.stringify(result, null, 2) }]
};
});
this.tool('update_project', 'Update an existing Coolify project', {
uuid: z.string(),
name: z.string(),
description: z.string().optional()
}, async (args, _extra) => {
const { uuid, ...updateData } = args;
const result = await this.client.updateProject(uuid, updateData);
return {
content: [{ type: 'text', text: JSON.stringify(result, null, 2) }]
};
});
this.tool('delete_project', 'Delete a Coolify project', {
uuid: z.string()
}, async (args, _extra) => {
const result = await this.client.deleteProject(args.uuid);
return {
content: [{ type: 'text', text: JSON.stringify(result, null, 2) }]
};
});
this.tool('get_project_environment', 'Get environment details for a Coolify project', {
project_uuid: z.string(),
environment_name_or_uuid: z.string()
}, async (args, _extra) => {
const environment = await this.client.getProjectEnvironment(args.project_uuid, args.environment_name_or_uuid);
return {
content: [{ type: 'text', text: JSON.stringify(environment, null, 2) }]
};
});
this.tool('list_databases', 'List all Coolify databases', {}, async (_args, _extra) => {
const databases = await this.client.listDatabases();
return {
content: [{ type: 'text', text: JSON.stringify(databases, null, 2) }]
};
});
this.tool('get_database', 'Get details about a specific Coolify database', {
uuid: z.string()
}, async (args, _extra) => {
const database = await this.client.getDatabase(args.uuid);
return {
content: [{ type: 'text', text: JSON.stringify(database, null, 2) }]
};
});
this.tool('update_database', 'Update a Coolify database', {
uuid: z.string(),
data: z.record(z.unknown())
}, async (args, _extra) => {
const result = await this.client.updateDatabase(args.uuid, args.data);
return {
content: [{ type: 'text', text: JSON.stringify(result, null, 2) }]
};
});
const deleteOptionsSchema = {
deleteConfigurations: z.boolean().optional(),
deleteVolumes: z.boolean().optional(),
dockerCleanup: z.boolean().optional(),
deleteConnectedNetworks: z.boolean().optional()
};
this.tool('delete_database', 'Delete a Coolify database', {
uuid: z.string(),
options: z.object(deleteOptionsSchema).optional()
}, async (args, _extra) => {
const result = await this.client.deleteDatabase(args.uuid, args.options);
return {
content: [{ type: 'text', text: JSON.stringify(result, null, 2) }]
};
});
this.tool('deploy_application', 'Deploy a Coolify application', {
uuid: z.string()
}, async (args, _extra) => {
const result = await this.client.deployApplication(args.uuid);
return {
content: [{ type: 'text', text: JSON.stringify(result, null, 2) }]
};
});
this.tool('list_services', 'List all Coolify services', {}, async (_args, _extra) => {
const services = await this.client.listServices();
return {
content: [{ type: 'text', text: JSON.stringify(services, null, 2) }]
};
});
this.tool('get_service', 'Get details about a specific Coolify service', {
uuid: z.string()
}, async (args, _extra) => {
const service = await this.client.getService(args.uuid);
return {
content: [{ type: 'text', text: JSON.stringify(service, null, 2) }]
};
});
this.tool('create_service', 'Create a new Coolify service', {
type: z.enum(serviceTypes),
project_uuid: z.string(),
server_uuid: z.string(),
name: z.string().optional(),
description: z.string().optional(),
environment_name: z.string().optional(),
environment_uuid: z.string().optional(),
destination_uuid: z.string().optional(),
instant_deploy: z.boolean().optional()
}, async (args, _extra) => {
const result = await this.client.createService(args);
return {
content: [{ type: 'text', text: JSON.stringify(result, null, 2) }]
};
});
this.tool('delete_service', 'Delete a Coolify service', {
uuid: z.string(),
options: z.object(deleteOptionsSchema).optional()
}, async (args, _extra) => {
const result = await this.client.deleteService(args.uuid, args.options);
return {
content: [{ type: 'text', text: JSON.stringify(result, null, 2) }]
};
});
}
async connect(transport: Transport): Promise<void> {
log('Starting server...');
log('Validating connection...');
await this.client.validateConnection();
await this.initialize();
await super.connect(transport);
log('Server started successfully');
}
async list_servers(): Promise<ServerInfo[]> {
return this.client.listServers();
}
async get_server(uuid: string): Promise<ServerInfo> {
return this.client.getServer(uuid);
}
async get_server_resources(uuid: string): Promise<ServerResources> {
return this.client.getServerResources(uuid);
}
async get_server_domains(uuid: string): Promise<ServerDomain[]> {
return this.client.getServerDomains(uuid);
}
async validate_server(uuid: string): Promise<ValidationResponse> {
return this.client.validateServer(uuid);
}
async list_projects(): Promise<Project[]> {
return this.client.listProjects();
}
async get_project(uuid: string): Promise<Project> {
return this.client.getProject(uuid);
}
async create_project(project: CreateProjectRequest): Promise<{ uuid: string }> {
return this.client.createProject(project);
}
async update_project(uuid: string, project: UpdateProjectRequest): Promise<Project> {
return this.client.updateProject(uuid, project);
}
async delete_project(uuid: string): Promise<{ message: string }> {
return this.client.deleteProject(uuid);
}
async get_project_environment(
projectUuid: string,
environmentNameOrUuid: string,
): Promise<Environment> {
return this.client.getProjectEnvironment(projectUuid, environmentNameOrUuid);
}
async deploy_application(params: { uuid: string }): Promise<Deployment> {
return this.client.deployApplication(params.uuid);
}
async list_databases(): Promise<Database[]> {
return this.client.listDatabases();
}
async get_database(uuid: string): Promise<Database> {
return this.client.getDatabase(uuid);
}
async update_database(uuid: string, data: DatabaseUpdateRequest): Promise<Database> {
return this.client.updateDatabase(uuid, data);
}
async delete_database(
uuid: string,
options?: {
deleteConfigurations?: boolean;
deleteVolumes?: boolean;
dockerCleanup?: boolean;
deleteConnectedNetworks?: boolean;
},
): Promise<{ message: string }> {
return this.client.deleteDatabase(uuid, options);
}
async list_services(): Promise<Service[]> {
return this.client.listServices();
}
async get_service(uuid: string): Promise<Service> {
return this.client.getService(uuid);
}
async create_service(data: CreateServiceRequest): Promise<{ uuid: string; domains: string[] }> {
return this.client.createService(data);
}
async delete_service(uuid: string, options?: DeleteServiceOptions): Promise<{ message: string }> {
return this.client.deleteService(uuid, options);
}
}