import { Tool } from '@modelcontextprotocol/sdk/types.js';
import { CoolifyApiClient } from '../client/coolify-api';
import {
ListAppsSchema,
GetAppSchema,
CreateAppSchema,
UpdateAppSchema,
DeleteAppSchema,
} from '../schemas';
import { logger, logToolInvocation } from '../utils/logger';
export const listAppsTool: Tool = {
name: 'coolify.list_apps',
description: 'List all applications in a project',
inputSchema: {
type: 'object',
properties: {
projectId: {
type: 'string',
description: 'Project ID to list applications from',
},
},
required: ['projectId'],
},
};
export const getAppTool: Tool = {
name: 'coolify.get_app',
description: 'Get details of a specific application',
inputSchema: {
type: 'object',
properties: {
id: {
type: 'string',
description: 'Application ID',
},
},
required: ['id'],
},
};
export const createAppTool: Tool = {
name: 'coolify.create_app',
description: 'Create a new application in a project',
inputSchema: {
type: 'object',
properties: {
projectId: {
type: 'string',
description: 'Project ID to create the application in',
},
name: {
type: 'string',
description: 'Application name (1-255 characters)',
},
description: {
type: 'string',
description: 'Optional application description',
},
type: {
type: 'string',
enum: ['dockerfile', 'image', 'compose'],
description: 'Application build type',
},
gitRepository: {
type: 'object',
properties: {
url: {
type: 'string',
description: 'Git repository URL',
},
branch: {
type: 'string',
description: 'Git branch to use',
},
},
required: ['url'],
},
dockerImage: {
type: 'string',
description: 'Docker image name (for image type)',
},
dockerCompose: {
type: 'string',
description: 'Docker Compose content (for compose type)',
},
environment: {
type: 'object',
description: 'Environment variables for the application',
additionalProperties: {
type: 'string',
},
},
ports: {
type: 'array',
items: {
type: 'integer',
},
description: 'Ports to expose',
},
},
required: ['projectId', 'name', 'type'],
},
};
export const updateAppTool: Tool = {
name: 'coolify.update_app',
description: 'Update an existing application',
inputSchema: {
type: 'object',
properties: {
id: {
type: 'string',
description: 'Application ID to update',
},
name: {
type: 'string',
description: 'New application name (1-255 characters)',
},
description: {
type: 'string',
description: 'New application description',
},
environment: {
type: 'object',
description: 'Updated environment variables',
additionalProperties: {
type: 'string',
},
},
ports: {
type: 'array',
items: {
type: 'integer',
},
description: 'Updated ports to expose',
},
},
required: ['id'],
},
};
export const deleteAppTool: Tool = {
name: 'coolify.delete_app',
description: 'Delete an application',
inputSchema: {
type: 'object',
properties: {
id: {
type: 'string',
description: 'Application ID to delete',
},
},
required: ['id'],
},
};
export async function handleListApps(args: any, apiClient: CoolifyApiClient) {
logToolInvocation('coolify.list_apps', args);
try {
const validated = ListAppsSchema.parse(args);
const apps = await apiClient.listApplications(validated.projectId);
logger.info(`Retrieved ${apps.length} applications for project ${validated.projectId}`);
return {
success: true,
apps,
count: apps.length,
projectId: validated.projectId,
};
} catch (error: any) {
logger.error('Failed to list applications', { error: error.message });
return {
success: false,
error: {
code: error.code || 'UNKNOWN_ERROR',
message: error.message,
},
};
}
}
export async function handleGetApp(args: any, apiClient: CoolifyApiClient) {
logToolInvocation('coolify.get_app', args);
try {
const validated = GetAppSchema.parse(args);
const app = await apiClient.getApplication(validated.id);
logger.info(`Retrieved application: ${app.name} (${app.id})`);
return {
success: true,
app,
};
} catch (error: any) {
logger.error('Failed to get application', { error: error.message });
return {
success: false,
error: {
code: error.code || 'UNKNOWN_ERROR',
message: error.message,
},
};
}
}
export async function handleCreateApp(args: any, apiClient: CoolifyApiClient) {
logToolInvocation('coolify.create_app', args);
try {
const validated = CreateAppSchema.parse(args);
const app = await apiClient.createApplication(validated.projectId, validated);
logger.info(`Created application: ${app.name} (${app.id}) in project ${validated.projectId}`);
return {
success: true,
app,
};
} catch (error: any) {
logger.error('Failed to create application', { error: error.message });
return {
success: false,
error: {
code: error.code || 'UNKNOWN_ERROR',
message: error.message,
},
};
}
}
export async function handleUpdateApp(args: any, apiClient: CoolifyApiClient) {
logToolInvocation('coolify.update_app', args);
try {
const validated = UpdateAppSchema.parse(args);
const app = await apiClient.updateApplication(validated.id, validated);
logger.info(`Updated application: ${app.name} (${app.id})`);
return {
success: true,
app,
};
} catch (error: any) {
logger.error('Failed to update application', { error: error.message });
return {
success: false,
error: {
code: error.code || 'UNKNOWN_ERROR',
message: error.message,
},
};
}
}
export async function handleDeleteApp(args: any, apiClient: CoolifyApiClient) {
logToolInvocation('coolify.delete_app', args);
try {
const validated = DeleteAppSchema.parse(args);
await apiClient.deleteApplication(validated.id);
logger.info(`Deleted application: ${validated.id}`);
return {
success: true,
id: validated.id,
message: 'Application deleted successfully',
};
} catch (error: any) {
logger.error('Failed to delete application', { error: error.message });
return {
success: false,
error: {
code: error.code || 'UNKNOWN_ERROR',
message: error.message,
},
};
}
}