environment.ts•8.68 kB
/**
* Coolify Environment and Domain Management Tools
* MCP tools for managing application environment variables and domains
*/
import { Tool } from '@modelcontextprotocol/sdk/types.js';
import { CoolifyApiClient } from '../utils/coolify-client';
import {
UpdateEnvironmentVariablesSchema,
SetDomainSchema,
GetLogsSchema,
UpdateEnvironmentVariablesInput,
SetDomainInput,
GetLogsInput,
} from '../types/mcp';
/**
* Tool: Update Environment Variables
* Updates environment variables for an application
*/
export const updateEnvironmentVariablesTool: Tool = {
name: 'coolify_update_environment_variables',
description: 'Update environment variables for an application. This will set or update the specified environment variables.',
inputSchema: {
type: 'object',
properties: {
applicationId: {
type: 'string',
description: 'The ID of the application',
},
variables: {
type: 'array',
description: 'Array of environment variables to set',
items: {
type: 'object',
properties: {
key: {
type: 'string',
description: 'Environment variable key/name',
},
value: {
type: 'string',
description: 'Environment variable value',
},
is_sensitive: {
type: 'boolean',
description: 'Whether this is a sensitive variable (will be hidden in UI)',
default: false,
},
is_build_time: {
type: 'boolean',
description: 'Whether this variable is available at build time',
default: false,
},
},
required: ['key', 'value'],
},
},
},
required: ['applicationId', 'variables'],
},
};
export async function handleUpdateEnvironmentVariables(
client: CoolifyApiClient,
args: UpdateEnvironmentVariablesInput
): Promise<any> {
const validatedArgs = UpdateEnvironmentVariablesSchema.parse(args);
try {
// Convert the validated variables to match EnvironmentVariable interface
const envVars = validatedArgs.variables.map(v => ({
key: v.key,
value: v.value,
is_sensitive: v.is_sensitive ?? false,
is_build_time: v.is_build_time ?? false,
}));
const success = await client.updateEnvironmentVariables(
validatedArgs.applicationId,
envVars
);
if (success) {
const varList = validatedArgs.variables
.map(v => `• ${v.key}=${v.is_sensitive ? '[SENSITIVE]' : v.value}`)
.join('\n');
return {
content: [
{
type: 'text',
text: `✅ Environment variables updated for application ${validatedArgs.applicationId}\n\n` +
`Updated variables:\n${varList}`,
},
],
};
} else {
return {
content: [
{
type: 'text',
text: `❌ Failed to update environment variables for application ${validatedArgs.applicationId}.`,
},
],
};
}
} catch (error) {
return {
content: [
{
type: 'text',
text: `❌ Failed to update environment variables: ${error instanceof Error ? error.message : 'Unknown error'}`,
},
],
};
}
}
/**
* Tool: Get Environment Variables
* Retrieves current environment variables for an application
*/
export const getEnvironmentVariablesTool: Tool = {
name: 'coolify_get_environment_variables',
description: 'Get current environment variables for an application.',
inputSchema: {
type: 'object',
properties: {
applicationId: {
type: 'string',
description: 'The ID of the application',
},
},
required: ['applicationId'],
},
};
export async function handleGetEnvironmentVariables(
client: CoolifyApiClient,
args: { applicationId: string }
): Promise<any> {
try {
const variables = await client.getEnvironmentVariables(args.applicationId);
if (variables.length === 0) {
return {
content: [
{
type: 'text',
text: `📋 No environment variables found for application ${args.applicationId}.`,
},
],
};
}
const varList = variables
.map(v =>
`• ${v.key}=${v.is_sensitive ? '[SENSITIVE]' : v.value}\n` +
` Build-time: ${v.is_build_time ? 'Yes' : 'No'}\n` +
` Sensitive: ${v.is_sensitive ? 'Yes' : 'No'}`
)
.join('\n\n');
return {
content: [
{
type: 'text',
text: `📋 Environment Variables for ${args.applicationId} (${variables.length} found):\n\n${varList}`,
},
],
};
} catch (error) {
return {
content: [
{
type: 'text',
text: `❌ Failed to get environment variables: ${error instanceof Error ? error.message : 'Unknown error'}`,
},
],
};
}
}
/**
* Tool: Set Domain
* Sets or updates the domain for an application
*/
export const setDomainTool: Tool = {
name: 'coolify_set_domain',
description: 'Set or update the domain for an application. This configures the FQDN and optionally enables HTTPS/SSL.',
inputSchema: {
type: 'object',
properties: {
applicationId: {
type: 'string',
description: 'The ID of the application',
},
domain: {
type: 'string',
description: 'The domain name to set (e.g., example.com or app.example.com)',
},
enableHttps: {
type: 'boolean',
description: 'Whether to enable HTTPS/SSL (recommended: true)',
default: true,
},
},
required: ['applicationId', 'domain'],
},
};
export async function handleSetDomain(
client: CoolifyApiClient,
args: SetDomainInput
): Promise<any> {
const validatedArgs = SetDomainSchema.parse(args);
try {
const domain = await client.setDomain(
validatedArgs.applicationId,
validatedArgs.domain,
validatedArgs.enableHttps ?? true
);
return {
content: [
{
type: 'text',
text: `🌐 Domain configured for application ${validatedArgs.applicationId}\n\n` +
`Domain: ${domain.domain}\n` +
`HTTPS: ${domain.is_https ? 'Enabled' : 'Disabled'}\n` +
`Certificate Status: ${domain.certificate?.status || 'Not configured'}`,
},
],
};
} catch (error) {
return {
content: [
{
type: 'text',
text: `❌ Failed to set domain: ${error instanceof Error ? error.message : 'Unknown error'}`,
},
],
};
}
}
/**
* Tool: Get Application Logs
* Retrieves recent logs from an application
*/
export const getApplicationLogsTool: Tool = {
name: 'coolify_get_application_logs',
description: 'Get recent logs from an application. Useful for debugging and monitoring.',
inputSchema: {
type: 'object',
properties: {
applicationId: {
type: 'string',
description: 'The ID of the application',
},
lines: {
type: 'number',
description: 'Number of log lines to retrieve (default: 100, max: 1000)',
default: 100,
minimum: 1,
maximum: 1000,
},
since: {
type: 'string',
description: 'Retrieve logs since this timestamp (ISO format, e.g., 2024-01-01T00:00:00Z)',
},
},
required: ['applicationId'],
},
};
export async function handleGetApplicationLogs(
client: CoolifyApiClient,
args: GetLogsInput
): Promise<any> {
const validatedArgs = GetLogsSchema.parse(args);
try {
const logs = await client.getApplicationLogs(
validatedArgs.applicationId,
validatedArgs.lines ?? 100,
validatedArgs.since
);
if (logs.length === 0) {
return {
content: [
{
type: 'text',
text: `📋 No logs found for application ${validatedArgs.applicationId}.`,
},
],
};
}
const logText = logs
.map(log => `[${log.timestamp}] ${log.level.toUpperCase()}: ${log.message}`)
.join('\n');
return {
content: [
{
type: 'text',
text: `📋 Application Logs for ${validatedArgs.applicationId} (${logs.length} entries):\n\n${logText}`,
},
],
};
} catch (error) {
return {
content: [
{
type: 'text',
text: `❌ Failed to get application logs: ${error instanceof Error ? error.message : 'Unknown error'}`,
},
],
};
}
}