UNPKG

@crazyrabbitltc/railway-mcp

Version:

Railway MCP Server - 146+ tools with 100% Railway API coverage, comprehensive MCP testing framework, and real infrastructure management through AI assistants. Enhanced version with enterprise features, based on original work by Jason Tan.

111 lines (110 loc) 5.09 kB
import { BaseService } from '../services/base.service.js'; import { createSuccessResponse, createErrorResponse, formatError } from '../utils/responses.js'; import { getStatusEmoji } from '../utils/helpers.js'; export class DeploymentService extends BaseService { constructor() { super(); } async listDeployments(projectId, serviceId, environmentId, limit = 5) { try { const deployments = await this.client.deployments.listDeployments({ projectId, serviceId, environmentId, limit }); if (deployments.length === 0) { return createSuccessResponse({ text: "No deployments found for this service.", data: [] }); } const deploymentDetails = deployments.map(deployment => { const status = deployment.status.toLowerCase(); const emoji = status === 'success' ? '✅' : status === 'failed' ? '❌' : '🔄'; return `${emoji} Deployment ${deployment.id} Status: ${deployment.status} Created: ${new Date(deployment.createdAt).toLocaleString()} Service: ${deployment.serviceId} ${deployment.url ? `URL: ${deployment.url}` : ''}`; }); return createSuccessResponse({ text: `Recent deployments:\n\n${deploymentDetails.join('\n\n')}`, data: deployments }); } catch (error) { return createErrorResponse(`Error listing deployments: ${formatError(error)}`); } } async triggerDeployment(projectId, serviceId, environmentId, commitSha) { try { // Wait for 5 seconds before triggering deployment // Seems like the LLMs like to call this function multiple times in combination // with the health check function and the list deployments function // so we need to wait a bit to avoid rate limiting await new Promise(resolve => setTimeout(resolve, 5000)); const deploymentId = await this.client.deployments.triggerDeployment({ serviceId, environmentId, commitSha }); return createSuccessResponse({ text: `Triggered new deployment (ID: ${deploymentId})`, data: { deploymentId } }); } catch (error) { return createErrorResponse(`Error triggering deployment: ${formatError(error)}`); } } async getDeploymentLogs(deploymentId, limit = 100) { try { // Wait for 5 seconds before fetching logs // Seems like the LLMs like to call this function multiple times in combination // with the health check function, so we need to wait a bit to avoid rate limiting await new Promise(resolve => setTimeout(resolve, 5000)); const buildLogs = await this.client.deployments.getBuildLogs(deploymentId, limit); const deploymentLogs = await this.client.deployments.getDeploymentLogs(deploymentId, limit); const logs = [...buildLogs.map(log => ({ ...log, type: 'build' })), ...deploymentLogs.map(log => ({ ...log, type: 'deployment' }))]; if (logs.length === 0) { return createSuccessResponse({ text: `No logs found for deployment ${deploymentId}`, data: [] }); } const formattedLogs = logs.map(log => { const timestamp = new Date(log.timestamp).toLocaleString(); const severity = log.severity.toLowerCase(); const emoji = severity === 'error' ? '❌' : severity === 'warn' ? '⚠️' : '📝'; return `[${log.type}] [${timestamp}] ${emoji} ${log.message}`; }).join('\n'); return createSuccessResponse({ text: formattedLogs, data: logs }); } catch (error) { return createErrorResponse(`Error fetching logs: ${formatError(error)}`); } } async healthCheckDeployment(deploymentId) { try { // Wait for 5 seconds before checking status // Seems like the LLMs like to call this function multiple times in combination // with the health check function, so we need to wait a bit await new Promise(resolve => setTimeout(resolve, 5000)); const status = await this.client.deployments.healthCheckDeployment(deploymentId); const emoji = getStatusEmoji(status); return createSuccessResponse({ text: `Deployment Status: ${emoji} ${status}`, data: { status } }); } catch (error) { return createErrorResponse(`Error checking deployment health: ${formatError(error)}`); } } } // Initialize and export the singleton instance export const deploymentService = new DeploymentService();