mlgym-deploy 3.3.29 → 3.3.32

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (2) hide show
  1. package/index.js +37 -6
  2. package/package.json +1 -1
package/index.js CHANGED
@@ -18,7 +18,7 @@ import crypto from 'crypto';
18
18
  const execAsync = promisify(exec);
19
19
 
20
20
  // Current version of this MCP server - INCREMENT FOR WORKFLOW FIXES
21
- const CURRENT_VERSION = '3.3.29'; // Fix SSH key per-user when using MLGYM_TOKEN env var
21
+ const CURRENT_VERSION = '3.3.32'; // Fix misleading hostname description - URL is always {app_id}.eu{1,2,3}.ezb.net
22
22
  const PACKAGE_NAME = 'mlgym-deploy';
23
23
 
24
24
  // Debug logging configuration - ENABLED BY DEFAULT
@@ -1225,10 +1225,17 @@ async function detectDeploymentStrategy(projectPath) {
1225
1225
  log.info('MCP >>> [detectDeploymentStrategy] Both files found, analyzing compose...');
1226
1226
 
1227
1227
  try {
1228
- const { webServiceCount, usesLocalDockerfile, totalServiceCount } = await analyzeComposeFile(composePath);
1228
+ const { webServiceCount, usesLocalDockerfile, totalServiceCount, slowStartServices } = await analyzeComposeFile(composePath);
1229
1229
 
1230
1230
  log.info(`MCP >>> [analyzeCompose] Total services: ${totalServiceCount}, Web services: ${webServiceCount}, Uses local Dockerfile: ${usesLocalDockerfile}`);
1231
1231
 
1232
+ // Warn about slow-starting services
1233
+ if (slowStartServices && slowStartServices.length > 0) {
1234
+ log.warning(`⚠ WARNING: Detected services with slow startup: ${slowStartServices.join(', ')}`);
1235
+ log.warning(`⏱ These services (Cassandra, MongoDB, Elasticsearch, etc.) may take 2-5 minutes to become healthy.`);
1236
+ log.warning(` Your application will not be accessible until ALL services are running.`);
1237
+ }
1238
+
1232
1239
  // SIMPLE: Only 1 web service, no other services, uses local Dockerfile
1233
1240
  // → docker-compose is just convenience wrapper
1234
1241
  if (totalServiceCount === 1 && webServiceCount === 1 && usesLocalDockerfile) {
@@ -1240,7 +1247,7 @@ async function detectDeploymentStrategy(projectPath) {
1240
1247
  // COMPLEX: Multiple services (web + database, etc.)
1241
1248
  // → MUST use docker-compose for orchestration
1242
1249
  log.info('MCP >>> [detectDeploymentStrategy] Strategy: dockercompose (multi-service)');
1243
- return { type: 'dockercompose', reason: 'Application requires multiple services (web + database/cache/etc)' };
1250
+ return { type: 'dockercompose', reason: 'Application requires multiple services (web + database/cache/etc)', slowStartServices };
1244
1251
  } catch (err) {
1245
1252
  log.error('MCP >>> [detectDeploymentStrategy] Analysis failed, defaulting to dockercompose:', err.message);
1246
1253
  return { type: 'dockercompose', reason: 'Multiple deployment files found' };
@@ -1531,6 +1538,7 @@ async function analyzeComposeFile(composePath) {
1531
1538
  let inServicesSection = false;
1532
1539
  let currentService = '';
1533
1540
  let currentServiceIsWeb = false;
1541
+ let slowStartServices = []; // Track services with known slow startup
1534
1542
 
1535
1543
  for (const line of lines) {
1536
1544
  const trimmed = line.trim();
@@ -1567,6 +1575,15 @@ async function analyzeComposeFile(composePath) {
1567
1575
 
1568
1576
  currentService = trimmed.split(':')[0].trim();
1569
1577
  currentServiceIsWeb = false;
1578
+
1579
+ // Check for services with known slow startup times
1580
+ const serviceLower = currentService.toLowerCase();
1581
+ if (serviceLower.includes('cassandra') || serviceLower.includes('elasticsearch') ||
1582
+ serviceLower.includes('mongodb') || serviceLower.includes('kafka') ||
1583
+ serviceLower.includes('zookeeper') || serviceLower.includes('spark')) {
1584
+ slowStartServices.push(currentService);
1585
+ }
1586
+
1570
1587
  continue;
1571
1588
  }
1572
1589
 
@@ -1579,6 +1596,18 @@ async function analyzeComposeFile(composePath) {
1579
1596
  if (trimmed === 'build: .' || trimmed === 'build: ./') {
1580
1597
  usesLocalDockerfile = true;
1581
1598
  }
1599
+
1600
+ // Also detect slow-start services by image name
1601
+ if (trimmed.startsWith('image:')) {
1602
+ const imageName = trimmed.substring(6).trim().toLowerCase();
1603
+ if (imageName.includes('cassandra') || imageName.includes('elasticsearch') ||
1604
+ imageName.includes('mongodb') || imageName.includes('kafka') ||
1605
+ imageName.includes('zookeeper') || imageName.includes('spark')) {
1606
+ if (!slowStartServices.includes(currentService)) {
1607
+ slowStartServices.push(currentService);
1608
+ }
1609
+ }
1610
+ }
1582
1611
  }
1583
1612
 
1584
1613
  // Count last service
@@ -1589,7 +1618,7 @@ async function analyzeComposeFile(composePath) {
1589
1618
  }
1590
1619
  }
1591
1620
 
1592
- return { webServiceCount, usesLocalDockerfile, totalServiceCount };
1621
+ return { webServiceCount, usesLocalDockerfile, totalServiceCount, slowStartServices };
1593
1622
  }
1594
1623
 
1595
1624
  // Helper to check if file exists
@@ -1934,7 +1963,9 @@ async function initProject(args) {
1934
1963
  if (status === 'deployed' || status === 'running') {
1935
1964
  deploymentStatus = {
1936
1965
  status: 'deployed',
1937
- url: statusResult.data.url || `https://${hostname}.ezb.net`,
1966
+ // Use deployment_url from backend response, NOT a fallback hostname pattern
1967
+ // The correct format is: https://{coolify_app_id}.{eu1|eu2|eu3}.ezb.net
1968
+ url: statusResult.data.url || project.deployment_url || null,
1938
1969
  message: 'Application successfully deployed'
1939
1970
  };
1940
1971
  break;
@@ -3668,7 +3699,7 @@ server.setRequestHandler(ListToolsRequestSchema, async () => {
3668
3699
  },
3669
3700
  hostname: {
3670
3701
  type: 'string',
3671
- description: 'Deployment hostname/subdomain (optional, defaults to project_name). Will be accessible at https://<hostname>.ezb.net',
3702
+ description: 'Custom hostname (optional). The actual deployment URL will be https://{app_id}.eu{1,2,3}.ezb.net based on the assigned server.',
3672
3703
  pattern: '^[a-z][a-z0-9-]*[a-z0-9]$',
3673
3704
  minLength: 3,
3674
3705
  maxLength: 63
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "mlgym-deploy",
3
- "version": "3.3.29",
3
+ "version": "3.3.32",
4
4
  "description": "MCP server for MLGym - Complete deployment management: deploy, configure, monitor, and rollback applications",
5
5
  "main": "index.js",
6
6
  "type": "module",