applications.ts•12 kB
/**
* Coolify Application Management Tools
* MCP tools for managing Coolify applications
*/
import { Tool } from '@modelcontextprotocol/sdk/types.js';
import { CoolifyApiClient } from '../utils/coolify-client';
import {
DeployApplicationSchema,
GetApplicationSchema,
ListApplicationsSchema,
GetApplicationStatusSchema,
StopApplicationSchema,
StartApplicationSchema,
RestartApplicationSchema,
DeployApplicationInput,
GetApplicationInput,
ListApplicationsInput,
GetApplicationStatusInput,
StopApplicationInput,
StartApplicationInput,
RestartApplicationInput,
} from '../types/mcp';
/**
* Tool: Deploy Application
* Triggers a deployment of an existing application
*/
export const deployApplicationTool: Tool = {
name: 'coolify_deploy_application',
description: 'Deploy an application in Coolify. This triggers a new deployment of the specified application.',
inputSchema: {
type: 'object',
properties: {
applicationId: {
type: 'string',
description: 'The ID of the application to deploy',
},
force: {
type: 'boolean',
description: 'Force deployment even if another deployment is in progress',
default: false,
},
branch: {
type: 'string',
description: 'Git branch to deploy (if different from configured branch)',
},
},
required: ['applicationId'],
},
};
export async function handleDeployApplication(
client: CoolifyApiClient,
args: DeployApplicationInput
): Promise<any> {
const validatedArgs = DeployApplicationSchema.parse(args);
try {
const deployOptions: { force?: boolean; branch?: string } = {};
if (validatedArgs.force !== undefined) {
deployOptions.force = validatedArgs.force;
}
if (validatedArgs.branch !== undefined) {
deployOptions.branch = validatedArgs.branch;
}
const deployment = await client.deployApplication(
validatedArgs.applicationId,
deployOptions
);
return {
content: [
{
type: 'text',
text: `✅ Deployment initiated for application ${validatedArgs.applicationId}\n\n` +
`Deployment ID: ${deployment.id}\n` +
`Status: ${deployment.status}\n` +
`Started at: ${deployment.started_at || 'Not started yet'}`,
},
],
};
} catch (error) {
return {
content: [
{
type: 'text',
text: `❌ Failed to deploy application ${validatedArgs.applicationId}: ${error instanceof Error ? error.message : 'Unknown error'}`,
},
],
};
}
}
/**
* Tool: Get Application Details
* Retrieves detailed information about a specific application
*/
export const getApplicationTool: Tool = {
name: 'coolify_get_application',
description: 'Get detailed information about a specific application including status, configuration, and metadata.',
inputSchema: {
type: 'object',
properties: {
applicationId: {
type: 'string',
description: 'The ID of the application to retrieve',
},
},
required: ['applicationId'],
},
};
export async function handleGetApplication(
client: CoolifyApiClient,
args: GetApplicationInput
): Promise<any> {
const validatedArgs = GetApplicationSchema.parse(args);
try {
const application = await client.getApplication(validatedArgs.applicationId);
return {
content: [
{
type: 'text',
text: `📱 Application Details: ${application.name}\n\n` +
`ID: ${application.id}\n` +
`Status: ${application.status}\n` +
`Description: ${application.description || 'No description'}\n` +
`Git Repository: ${application.git_repository || 'Not configured'}\n` +
`Git Branch: ${application.git_branch || 'main'}\n` +
`Build Pack: ${application.build_pack || 'Auto-detected'}\n` +
`FQDN: ${application.fqdn || 'Not configured'}\n` +
`Created: ${application.created_at}\n` +
`Updated: ${application.updated_at}`,
},
],
};
} catch (error) {
return {
content: [
{
type: 'text',
text: `❌ Failed to get application ${validatedArgs.applicationId}: ${error instanceof Error ? error.message : 'Unknown error'}`,
},
],
};
}
}
/**
* Tool: List Applications
* Lists all applications or filters them by criteria
*/
export const listApplicationsTool: Tool = {
name: 'coolify_list_applications',
description: 'List all applications in Coolify with optional filtering by server or status.',
inputSchema: {
type: 'object',
properties: {
serverId: {
type: 'string',
description: 'Filter applications by server ID',
},
status: {
type: 'string',
enum: ['running', 'stopped', 'building', 'error'],
description: 'Filter applications by status',
},
},
required: [],
},
};
export async function handleListApplications(
client: CoolifyApiClient,
args: ListApplicationsInput
): Promise<any> {
const validatedArgs = ListApplicationsSchema.parse(args);
try {
let applications = await client.getApplications();
// Apply filters if provided
if (validatedArgs.status) {
applications = applications.filter(app => app.status === validatedArgs.status);
}
if (applications.length === 0) {
return {
content: [
{
type: 'text',
text: '📋 No applications found matching the criteria.',
},
],
};
}
const appList = applications
.map(app =>
`• ${app.name} (${app.id})\n` +
` Status: ${app.status}\n` +
` FQDN: ${app.fqdn || 'Not configured'}\n` +
` Repository: ${app.git_repository || 'Not configured'}`
)
.join('\n\n');
return {
content: [
{
type: 'text',
text: `📋 Applications (${applications.length} found):\n\n${appList}`,
},
],
};
} catch (error) {
return {
content: [
{
type: 'text',
text: `❌ Failed to list applications: ${error instanceof Error ? error.message : 'Unknown error'}`,
},
],
};
}
}
/**
* Tool: Get Application Status
* Gets the current deployment status of an application
*/
export const getApplicationStatusTool: Tool = {
name: 'coolify_get_application_status',
description: 'Get the current deployment status and health of an application.',
inputSchema: {
type: 'object',
properties: {
applicationId: {
type: 'string',
description: 'The ID of the application',
},
},
required: ['applicationId'],
},
};
export async function handleGetApplicationStatus(
client: CoolifyApiClient,
args: GetApplicationStatusInput
): Promise<any> {
const validatedArgs = GetApplicationStatusSchema.parse(args);
try {
const status = await client.getApplicationStatus(validatedArgs.applicationId);
return {
content: [
{
type: 'text',
text: `📊 Application Status: ${validatedArgs.applicationId}\n\n` +
`Status: ${status.status}\n` +
`Started: ${status.started_at || 'Not started'}\n` +
`Finished: ${status.finished_at || 'In progress'}\n` +
`Deployment ID: ${status.id}`,
},
],
};
} catch (error) {
return {
content: [
{
type: 'text',
text: `❌ Failed to get application status: ${error instanceof Error ? error.message : 'Unknown error'}`,
},
],
};
}
}
/**
* Tool: Stop Application
* Stops a running application
*/
export const stopApplicationTool: Tool = {
name: 'coolify_stop_application',
description: 'Stop a running application. This will make the application unavailable.',
inputSchema: {
type: 'object',
properties: {
applicationId: {
type: 'string',
description: 'The ID of the application to stop',
},
},
required: ['applicationId'],
},
};
export async function handleStopApplication(
client: CoolifyApiClient,
args: StopApplicationInput
): Promise<any> {
const validatedArgs = StopApplicationSchema.parse(args);
try {
const success = await client.stopApplication(validatedArgs.applicationId);
if (success) {
return {
content: [
{
type: 'text',
text: `⏹️ Application ${validatedArgs.applicationId} has been stopped successfully.`,
},
],
};
} else {
return {
content: [
{
type: 'text',
text: `❌ Failed to stop application ${validatedArgs.applicationId}.`,
},
],
};
}
} catch (error) {
return {
content: [
{
type: 'text',
text: `❌ Failed to stop application: ${error instanceof Error ? error.message : 'Unknown error'}`,
},
],
};
}
}
/**
* Tool: Start Application
* Starts a stopped application
*/
export const startApplicationTool: Tool = {
name: 'coolify_start_application',
description: 'Start a stopped application. This will make the application available again.',
inputSchema: {
type: 'object',
properties: {
applicationId: {
type: 'string',
description: 'The ID of the application to start',
},
},
required: ['applicationId'],
},
};
export async function handleStartApplication(
client: CoolifyApiClient,
args: StartApplicationInput
): Promise<any> {
const validatedArgs = StartApplicationSchema.parse(args);
try {
const success = await client.startApplication(validatedArgs.applicationId);
if (success) {
return {
content: [
{
type: 'text',
text: `▶️ Application ${validatedArgs.applicationId} has been started successfully.`,
},
],
};
} else {
return {
content: [
{
type: 'text',
text: `❌ Failed to start application ${validatedArgs.applicationId}.`,
},
],
};
}
} catch (error) {
return {
content: [
{
type: 'text',
text: `❌ Failed to start application: ${error instanceof Error ? error.message : 'Unknown error'}`,
},
],
};
}
}
/**
* Tool: Restart Application
* Restarts an application (stop + start)
*/
export const restartApplicationTool: Tool = {
name: 'coolify_restart_application',
description: 'Restart an application. This will stop and then start the application.',
inputSchema: {
type: 'object',
properties: {
applicationId: {
type: 'string',
description: 'The ID of the application to restart',
},
},
required: ['applicationId'],
},
};
export async function handleRestartApplication(
client: CoolifyApiClient,
args: RestartApplicationInput
): Promise<any> {
const validatedArgs = RestartApplicationSchema.parse(args);
try {
const success = await client.restartApplication(validatedArgs.applicationId);
if (success) {
return {
content: [
{
type: 'text',
text: `🔄 Application ${validatedArgs.applicationId} has been restarted successfully.`,
},
],
};
} else {
return {
content: [
{
type: 'text',
text: `❌ Failed to restart application ${validatedArgs.applicationId}.`,
},
],
};
}
} catch (error) {
return {
content: [
{
type: 'text',
text: `❌ Failed to restart application: ${error instanceof Error ? error.message : 'Unknown error'}`,
},
],
};
}
}