Skip to main content
Glama

Enhanced Coolify MCP Server

coolify-client.ts.backupโ€ข14 kB
import { CoolifyConfig, ErrorResponse, ServerInfo, ServerResources, ServerDomain, ValidationResponse, Project, CreateProjectRequest, UpdateProjectRequest, Environment, Deployment, Database, DatabaseUpdateRequest, Service, CreateServiceRequest, DeleteServiceOptions, Application, CreateApplicationRequest, EnvironmentVariable, EnvironmentVariableUpdate, CreateDockerComposeServiceRequest, UpdateDockerComposeServiceRequest, ApplicationResources, LogOptions, LogEntry, CreateFullStackProjectRequest, FullStackProjectResponse, InfrastructureDeploymentConfig, InfrastructureDeploymentResponse, } from '../types/coolify.js'; import { ErrorHandler, EnhancedError } from './error-handler.js'; import { RetryManager } from './retry-manager.js'; import debug from 'debug'; const log = debug('coolify:client'); export class CoolifyClient { private baseUrl: string; private accessToken: string; constructor(config: CoolifyConfig) { if (!config.baseUrl) { throw new Error('Coolify base URL is required'); } if (!config.accessToken) { throw new Error('Coolify access token is required'); } this.baseUrl = config.baseUrl.replace(/\/$/, ''); this.accessToken = config.accessToken; } private async request<T>(path: string, options: RequestInit = {}): Promise<T> { return RetryManager.executeWithRetry( async () => { try { const url = `${this.baseUrl}/api/v1${path}`; log(`Making request to: ${url}`); const response = await fetch(url, { headers: { 'Content-Type': 'application/json', Authorization: `Bearer ${this.accessToken}`, }, ...options, }); let data: any; try { data = await response.json(); } catch (jsonError) { // Handle non-JSON responses const text = await response.text(); if (!response.ok) { throw new Error(`HTTP ${response.status}: ${text || response.statusText}`); } return text as T; } if (!response.ok) { const error = data as ErrorResponse; const errorMessage = error.message || `HTTP ${response.status}: ${response.statusText}`; log(`API error: ${response.status} - ${errorMessage}`); throw new Error(errorMessage); } log(`Request successful: ${path}`); return data as T; } catch (error) { log(`Request failed: ${path} - ${error}`); throw error; } }, RetryManager.createRetryOptions('api') ); } async listServers(): Promise<ServerInfo[]> { return this.request<ServerInfo[]>('/servers'); } async getServer(uuid: string): Promise<ServerInfo> { return this.request<ServerInfo>(`/servers/${uuid}`); } async getServerResources(uuid: string): Promise<ServerResources> { return this.request<ServerResources>(`/servers/${uuid}/resources`); } async getServerDomains(uuid: string): Promise<ServerDomain[]> { return this.request<ServerDomain[]>(`/servers/${uuid}/domains`); } async validateServer(uuid: string): Promise<ValidationResponse> { return this.request<ValidationResponse>(`/servers/${uuid}/validate`); } async validateConnection(): Promise<void> { try { await this.listServers(); } catch (error) { throw new Error( `Failed to connect to Coolify server: ${error instanceof Error ? error.message : 'Unknown error'}`, ); } } async listProjects(): Promise<Project[]> { return this.request<Project[]>('/projects'); } async getProject(uuid: string): Promise<Project> { return this.request<Project>(`/projects/${uuid}`); } async createProject(project: CreateProjectRequest): Promise<{ uuid: string }> { return this.request<{ uuid: string }>('/projects', { method: 'POST', body: JSON.stringify(project), }); } async updateProject(uuid: string, project: UpdateProjectRequest): Promise<Project> { return this.request<Project>(`/projects/${uuid}`, { method: 'PATCH', body: JSON.stringify(project), }); } async deleteProject(uuid: string): Promise<{ message: string }> { return this.request<{ message: string }>(`/projects/${uuid}`, { method: 'DELETE', }); } async getProjectEnvironment( projectUuid: string, environmentNameOrUuid: string, ): Promise<Environment> { return this.request<Environment>(`/projects/${projectUuid}/${environmentNameOrUuid}`); } async deployApplication(uuid: string): Promise<Deployment> { const response = await this.request<Deployment>(`/applications/${uuid}/deploy`, { method: 'POST', }); return response; } async listDatabases(): Promise<Database[]> { return this.request<Database[]>('/databases'); } async getDatabase(uuid: string): Promise<Database> { return this.request<Database>(`/databases/${uuid}`); } async updateDatabase(uuid: string, data: DatabaseUpdateRequest): Promise<Database> { return this.request<Database>(`/databases/${uuid}`, { method: 'PATCH', body: JSON.stringify(data), }); } async deleteDatabase( uuid: string, options?: { deleteConfigurations?: boolean; deleteVolumes?: boolean; dockerCleanup?: boolean; deleteConnectedNetworks?: boolean; }, ): Promise<{ message: string }> { const queryParams = new URLSearchParams(); if (options) { if (options.deleteConfigurations !== undefined) { queryParams.set('delete_configurations', options.deleteConfigurations.toString()); } if (options.deleteVolumes !== undefined) { queryParams.set('delete_volumes', options.deleteVolumes.toString()); } if (options.dockerCleanup !== undefined) { queryParams.set('docker_cleanup', options.dockerCleanup.toString()); } if (options.deleteConnectedNetworks !== undefined) { queryParams.set('delete_connected_networks', options.deleteConnectedNetworks.toString()); } } const queryString = queryParams.toString(); const url = queryString ? `/databases/${uuid}?${queryString}` : `/databases/${uuid}`; return this.request<{ message: string }>(url, { method: 'DELETE', }); } async listServices(): Promise<Service[]> { return this.request<Service[]>('/services'); } async getService(uuid: string): Promise<Service> { return this.request<Service>(`/services/${uuid}`); } async createService(data: CreateServiceRequest): Promise<{ uuid: string; domains: string[] }> { return this.request<{ uuid: string; domains: string[] }>('/services', { method: 'POST', body: JSON.stringify(data), }); } async deleteService(uuid: string, options?: DeleteServiceOptions): Promise<{ message: string }> { const queryParams = new URLSearchParams(); if (options) { if (options.deleteConfigurations !== undefined) { queryParams.set('delete_configurations', options.deleteConfigurations.toString()); } if (options.deleteVolumes !== undefined) { queryParams.set('delete_volumes', options.deleteVolumes.toString()); } if (options.dockerCleanup !== undefined) { queryParams.set('docker_cleanup', options.dockerCleanup.toString()); } if (options.deleteConnectedNetworks !== undefined) { queryParams.set('delete_connected_networks', options.deleteConnectedNetworks.toString()); } } const queryString = queryParams.toString(); const url = queryString ? `/services/${uuid}?${queryString}` : `/services/${uuid}`; return this.request<{ message: string }>(url, { method: 'DELETE', }); } // Application Management Methods async listApplications(): Promise<Application[]> { return this.request<Application[]>('/applications'); } async getApplication(uuid: string): Promise<Application> { return this.request<Application>(`/applications/${uuid}`); } async createApplication(data: CreateApplicationRequest): Promise<{ uuid: string }> { return this.request<{ uuid: string }>('/applications', { method: 'POST', body: JSON.stringify(data), }); } async updateApplication(uuid: string, data: Partial<Application>): Promise<Application> { return this.request<Application>(`/applications/${uuid}`, { method: 'PATCH', body: JSON.stringify(data), }); } async deleteApplication(uuid: string, options?: DeleteServiceOptions): Promise<{ message: string }> { const queryParams = new URLSearchParams(); if (options) { if (options.deleteConfigurations !== undefined) { queryParams.set('delete_configurations', options.deleteConfigurations.toString()); } if (options.deleteVolumes !== undefined) { queryParams.set('delete_volumes', options.deleteVolumes.toString()); } if (options.dockerCleanup !== undefined) { queryParams.set('docker_cleanup', options.dockerCleanup.toString()); } if (options.deleteConnectedNetworks !== undefined) { queryParams.set('delete_connected_networks', options.deleteConnectedNetworks.toString()); } } const queryString = queryParams.toString(); const url = queryString ? `/applications/${uuid}?${queryString}` : `/applications/${uuid}`; return this.request<{ message: string }>(url, { method: 'DELETE', }); } // Environment Variable Management async getApplicationEnvironmentVariables(uuid: string): Promise<EnvironmentVariable[]> { return this.request<EnvironmentVariable[]>(`/applications/${uuid}/envs`); } async updateApplicationEnvironmentVariables( uuid: string, variables: EnvironmentVariableUpdate[] ): Promise<{ message: string }> { return this.request<{ message: string }>(`/applications/${uuid}/envs`, { method: 'POST', body: JSON.stringify(variables), }); } // Docker Compose Service Management async createDockerComposeService(data: CreateDockerComposeServiceRequest): Promise<{ uuid: string }> { return this.request<{ uuid: string }>('/services/docker-compose', { method: 'POST', body: JSON.stringify(data), }); } async updateDockerComposeService( uuid: string, data: UpdateDockerComposeServiceRequest ): Promise<Service> { return this.request<Service>(`/services/${uuid}/docker-compose`, { method: 'PATCH', body: JSON.stringify(data), }); } // Deployment Management async getDeployments(applicationUuid: string): Promise<Deployment[]> { return this.request<Deployment[]>(`/applications/${applicationUuid}/deployments`); } async getDeployment(uuid: string): Promise<Deployment> { return this.request<Deployment>(`/deployments/${uuid}`); } async cancelDeployment(uuid: string): Promise<{ message: string }> { return this.request<{ message: string }>(`/deployments/${uuid}/cancel`, { method: 'POST', }); } // Resource Management async getApplicationResources(uuid: string): Promise<ApplicationResources> { return this.request<ApplicationResources>(`/applications/${uuid}/resources`); } async getApplicationLogs(uuid: string, options?: LogOptions): Promise<LogEntry[]> { const queryParams = new URLSearchParams(); if (options?.since) queryParams.set('since', options.since); if (options?.until) queryParams.set('until', options.until); if (options?.lines) queryParams.set('lines', options.lines.toString()); const queryString = queryParams.toString(); const url = queryString ? `/applications/${uuid}/logs?${queryString}` : `/applications/${uuid}/logs`; return this.request<LogEntry[]>(url); } // Full-Stack Project Methods async createFullStackProject(data: CreateFullStackProjectRequest): Promise<FullStackProjectResponse> { // Create project first const project = await this.createProject({ name: data.name, description: data.description || 'Full-Stack Application Deployment' }); return { project_uuid: project.uuid, name: data.name, description: data.description, services: [], status: 'created' }; } async deployInfrastructureStack( projectUuid: string, serverUuid: string, config: InfrastructureDeploymentConfig ): Promise<InfrastructureDeploymentResponse> { const services: string[] = []; try { // Deploy PostgreSQL if (config.includePostgres) { const postgres = await this.createService({ type: 'postgresql', project_uuid: projectUuid, server_uuid: serverUuid, name: 'app-postgres', description: 'PostgreSQL Database' }); services.push(postgres.uuid); } // Deploy Redis if (config.includeRedis) { const redis = await this.createService({ type: 'redis', project_uuid: projectUuid, server_uuid: serverUuid, name: 'app-redis', description: 'Redis Cache' }); services.push(redis.uuid); } // Deploy MinIO if (config.includeMinIO) { const minio = await this.createService({ type: 'minio', project_uuid: projectUuid, server_uuid: serverUuid, name: 'app-minio', description: 'Object Storage' }); services.push(minio.uuid); } return { project_uuid: projectUuid, services, status: 'deployed', message: 'Infrastructure stack deployed successfully' }; } catch (error) { return { project_uuid: projectUuid, services, status: 'failed', message: `Deployment failed: ${error instanceof Error ? error.message : 'Unknown error'}` }; } } }

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/dazeb/coolify-mcp-enhanced'

If you have feedback or need assistance with the MCP directory API, please join our Discord server