mlgym-deploy 2.3.0 → 2.3.2

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 +147 -82
  2. package/package.json +1 -1
package/index.js CHANGED
@@ -17,7 +17,7 @@ import crypto from 'crypto';
17
17
  const execAsync = promisify(exec);
18
18
 
19
19
  // Current version of this MCP server
20
- const CURRENT_VERSION = '2.3.0';
20
+ const CURRENT_VERSION = '2.3.2';
21
21
  const PACKAGE_NAME = 'mlgym-deploy';
22
22
 
23
23
  // Version check state
@@ -25,6 +25,34 @@ let versionCheckResult = null;
25
25
  let lastVersionCheck = 0;
26
26
  const VERSION_CHECK_INTERVAL = 3600000; // Check once per hour
27
27
 
28
+ // Helper to wrap tool response with update message if needed
29
+ function wrapResponseWithUpdateMessage(response) {
30
+ if (versionCheckResult && versionCheckResult.updateAvailable) {
31
+ const updateMessage = `\n╔════════════════════════════════════════════════════════════════════╗
32
+ ║ 🔄 UPDATE AVAILABLE 🔄 ║
33
+ ║ ║
34
+ ║ A newer version of MLGym MCP Server is available! ║
35
+ ║ ║
36
+ ║ Current version: ${CURRENT_VERSION.padEnd(52)} ║
37
+ ║ Latest version: ${versionCheckResult.latest.padEnd(52)} ║
38
+ ║ ║
39
+ ║ To update in Cursor: ║
40
+ ║ 1. Close this terminal/tab ║
41
+ ║ 2. Run: npm install -g ${PACKAGE_NAME}@latest ║
42
+ ║ 3. Restart Cursor to use the updated MCP server ║
43
+ ║ ║
44
+ ║ ⚠️ Using outdated version may cause issues! ║
45
+ ╚════════════════════════════════════════════════════════════════════╝\n`;
46
+
47
+ // Prepend update message to the response
48
+ if (response.content && response.content[0] && response.content[0].type === 'text') {
49
+ const originalText = response.content[0].text;
50
+ response.content[0].text = updateMessage + "\n" + originalText;
51
+ }
52
+ }
53
+ return response;
54
+ }
55
+
28
56
  // Helper to check for updates
29
57
  async function checkForUpdates() {
30
58
  try {
@@ -402,18 +430,18 @@ const TOOLS = [
402
430
  },
403
431
  {
404
432
  name: 'mlgym_auth_check',
405
- description: 'Check if a user account exists and whether SSH keys are configured. Use this BEFORE creating a new account to avoid duplicates.',
433
+ description: '🚨 ALWAYS USE THIS FIRST when deploying! Check if user account exists BEFORE asking for other details. Start by ONLY asking for email.',
406
434
  inputSchema: {
407
435
  type: 'object',
408
436
  properties: {
409
437
  email: {
410
438
  type: 'string',
411
- description: 'Email address to check',
439
+ description: 'Email address to check (ask for this FIRST)',
412
440
  pattern: '^[^@]+@[^@]+\\.[^@]+$'
413
441
  },
414
442
  password: {
415
443
  type: 'string',
416
- description: 'Password (optional - only needed if account exists)',
444
+ description: 'Password (ONLY ask if account exists)',
417
445
  minLength: 8
418
446
  }
419
447
  },
@@ -422,7 +450,7 @@ const TOOLS = [
422
450
  },
423
451
  {
424
452
  name: 'mlgym_user_create',
425
- description: 'Create a new user OR setup SSH keys for existing user. First use mlgym_auth_check to verify if account exists.',
453
+ description: 'Create new user or setup SSH. ⚠️ NEVER use this first! Always check with mlgym_auth_check before asking for full details.',
426
454
  inputSchema: {
427
455
  type: 'object',
428
456
  properties: {
@@ -456,7 +484,7 @@ const TOOLS = [
456
484
  },
457
485
  {
458
486
  name: 'mlgym_project_init',
459
- description: 'Initialize and deploy a project with GitLab repository and Coolify deployment. IMPORTANT: You must explicitly ask the user for project name, description, and deployment URL if deployment is enabled.',
487
+ description: 'Initialize project deployment. ⚠️ ONLY use AFTER authentication! Ask for project details AFTER user is logged in, not before.',
460
488
  inputSchema: {
461
489
  type: 'object',
462
490
  properties: {
@@ -1176,166 +1204,222 @@ server.setRequestHandler(ListToolsRequestSchema, async () => {
1176
1204
  server.setRequestHandler(CallToolRequestSchema, async (request) => {
1177
1205
  const { name, arguments: args } = request.params;
1178
1206
 
1207
+ let response;
1179
1208
  switch (name) {
1180
1209
  case 'mlgym_git_configure':
1181
- return await configureGit(args);
1210
+ response = await configureGit(args);
1211
+ break;
1182
1212
 
1183
1213
  case 'mlgym_debug_last_error':
1184
- return await debugLastError(args);
1214
+ response = await debugLastError(args);
1215
+ break;
1185
1216
 
1186
1217
  case 'mlgym_debug_status':
1187
- return await debugStatus(args);
1218
+ response = await debugStatus(args);
1219
+ break;
1188
1220
 
1189
1221
  case 'mlgym_debug_logs':
1190
- return await debugLogs(args);
1222
+ response = await debugLogs(args);
1223
+ break;
1191
1224
 
1192
1225
  case 'mlgym_debug_deployment':
1193
- return await debugDeployment(args);
1226
+ response = await debugDeployment(args);
1227
+ break;
1194
1228
 
1195
1229
  case 'mlgym_version_check':
1196
- return await versionCheck(args);
1230
+ response = await versionCheck(args);
1231
+ break;
1197
1232
 
1198
1233
  case 'mlgym_auth_check':
1199
- return await checkUserExists(args);
1234
+ response = await checkUserExists(args);
1235
+ break;
1200
1236
 
1201
1237
  case 'mlgym_user_create':
1202
- return await createUser(args);
1238
+ response = await createUser(args);
1239
+ break;
1203
1240
 
1204
1241
  case 'mlgym_project_init':
1205
- return await initProject(args);
1242
+ response = await initProject(args);
1243
+ break;
1206
1244
 
1207
1245
  case 'mlgym_user_recover':
1208
- return await recoverUser(args);
1246
+ response = await recoverUser(args);
1247
+ break;
1209
1248
 
1210
1249
  case 'mlgym_auth_login':
1211
- return await loginUser(args);
1250
+ response = await loginUser(args);
1251
+ break;
1212
1252
 
1213
1253
  case 'mlgym_projects_list':
1214
- return await listProjects(args);
1254
+ response = await listProjects(args);
1255
+ break;
1215
1256
 
1216
1257
  case 'mlgym_deployments_trigger':
1217
- return await triggerDeployment(args);
1258
+ response = await triggerDeployment(args);
1259
+ break;
1218
1260
 
1219
1261
  case 'mlgym_deployments_get_status':
1220
- return await getDeploymentStatus(args);
1262
+ response = await getDeploymentStatus(args);
1263
+ break;
1221
1264
 
1222
1265
  case 'mlgym_auth_get_current_user':
1223
- return await getCurrentUser(args);
1266
+ response = await getCurrentUser(args);
1267
+ break;
1224
1268
 
1225
1269
  case 'mlgym_projects_get':
1226
- return await getProject(args);
1270
+ response = await getProject(args);
1271
+ break;
1227
1272
 
1228
1273
  case 'mlgym_projects_delete':
1229
- return await deleteProject(args);
1274
+ response = await deleteProject(args);
1275
+ break;
1230
1276
 
1231
1277
  case 'mlgym_keys_list':
1232
- return await listKeys(args);
1278
+ response = await listKeys(args);
1279
+ break;
1233
1280
 
1234
1281
  case 'mlgym_projects_update':
1235
- return await updateProject(args);
1282
+ response = await updateProject(args);
1283
+ break;
1236
1284
 
1237
1285
  case 'mlgym_deployments_list':
1238
- return await listDeployments(args);
1286
+ response = await listDeployments(args);
1287
+ break;
1239
1288
 
1240
1289
  case 'mlgym_deployments_get_logs':
1241
- return await getDeploymentLogs(args);
1290
+ response = await getDeploymentLogs(args);
1291
+ break;
1242
1292
 
1243
1293
  case 'mlgym_keys_add':
1244
- return await addKey(args);
1294
+ response = await addKey(args);
1295
+ break;
1245
1296
 
1246
1297
  case 'mlgym_keys_delete':
1247
- return await deleteKey(args);
1298
+ response = await deleteKey(args);
1299
+ break;
1248
1300
 
1249
1301
  case 'mlgym_regions_list':
1250
- return await listRegions(args);
1302
+ response = await listRegions(args);
1303
+ break;
1251
1304
 
1252
1305
  case 'mlgym_regions_get_status':
1253
- return await getRegionStatus(args);
1306
+ response = await getRegionStatus(args);
1307
+ break;
1254
1308
 
1255
1309
  case 'mlgym_pools_list':
1256
- return await listPools(args);
1310
+ response = await listPools(args);
1311
+ break;
1257
1312
 
1258
1313
  case 'mlgym_pools_get_stats':
1259
- return await getPoolStats(args);
1314
+ response = await getPoolStats(args);
1315
+ break;
1260
1316
 
1261
1317
  case 'mlgym_pools_select_optimal':
1262
- return await selectOptimalPool(args);
1318
+ response = await selectOptimalPool(args);
1319
+ break;
1263
1320
 
1264
1321
  case 'mlgym_regions_select_isp':
1265
- return await selectISP(args);
1322
+ response = await selectISP(args);
1323
+ break;
1266
1324
 
1267
1325
  case 'mlgym_health_get_report':
1268
- return await getHealthReport(args);
1326
+ response = await getHealthReport(args);
1327
+ break;
1269
1328
 
1270
1329
  case 'mlgym_health_check_pool':
1271
- return await checkPoolHealth(args);
1330
+ response = await checkPoolHealth(args);
1331
+ break;
1272
1332
 
1273
1333
  case 'mlgym_health_check_node':
1274
- return await checkNodeHealth(args);
1334
+ response = await checkNodeHealth(args);
1335
+ break;
1275
1336
 
1276
1337
  case 'mlgym_metrics_get_deployment_metrics':
1277
- return await getDeploymentMetrics(args);
1338
+ response = await getDeploymentMetrics(args);
1339
+ break;
1278
1340
 
1279
1341
  case 'mlgym_metrics_get_pool_utilization':
1280
- return await getPoolUtilization(args);
1342
+ response = await getPoolUtilization(args);
1343
+ break;
1281
1344
 
1282
1345
  case 'mlgym_git_get_remote_url':
1283
- return await getGitRemoteUrl(args);
1346
+ response = await getGitRemoteUrl(args);
1347
+ break;
1284
1348
 
1285
1349
  case 'mlgym_git_setup_push':
1286
- return await setupGitPush(args);
1350
+ response = await setupGitPush(args);
1351
+ break;
1287
1352
 
1288
1353
  case 'mlgym_git_get_clone_command':
1289
- return await getGitCloneCommand(args);
1354
+ response = await getGitCloneCommand(args);
1355
+ break;
1290
1356
 
1291
1357
  case 'mlgym_deployments_rollback':
1292
- return await rollbackDeployment(args);
1358
+ response = await rollbackDeployment(args);
1359
+ break;
1293
1360
 
1294
1361
  case 'mlgym_deployments_scale':
1295
- return await scaleDeployment(args);
1362
+ response = await scaleDeployment(args);
1363
+ break;
1296
1364
 
1297
1365
  case 'mlgym_auth_logout':
1298
- return await logoutUser(args);
1366
+ response = await logoutUser(args);
1367
+ break;
1299
1368
 
1300
1369
  case 'mlgym_auth_refresh_token':
1301
- return await refreshToken(args);
1370
+ response = await refreshToken(args);
1371
+ break;
1302
1372
 
1303
1373
  case 'mlgym_auth_login_to_isp':
1304
- return await loginToISP(args);
1374
+ response = await loginToISP(args);
1375
+ break;
1305
1376
 
1306
1377
  case 'mlgym_keys_generate_pair':
1307
- return await generateKeyPair(args);
1378
+ response = await generateKeyPair(args);
1379
+ break;
1308
1380
 
1309
1381
  case 'mlgym_config_set_environment':
1310
- return await setEnvironment(args);
1382
+ response = await setEnvironment(args);
1383
+ break;
1311
1384
 
1312
1385
  case 'mlgym_config_get_endpoints':
1313
- return await getEndpoints(args);
1386
+ response = await getEndpoints(args);
1387
+ break;
1314
1388
 
1315
1389
  case 'mlgym_config_set_default_pool':
1316
- return await setDefaultPool(args);
1390
+ response = await setDefaultPool(args);
1391
+ break;
1317
1392
 
1318
1393
  case 'mlgym_webhooks_setup':
1319
- return await setupWebhook(args);
1394
+ response = await setupWebhook(args);
1395
+ break;
1320
1396
 
1321
1397
  case 'mlgym_webhooks_test':
1322
- return await testWebhook(args);
1398
+ response = await testWebhook(args);
1399
+ break;
1323
1400
 
1324
1401
  case 'mlgym_webhooks_get_logs':
1325
- return await getWebhookLogs(args);
1402
+ response = await getWebhookLogs(args);
1403
+ break;
1326
1404
 
1327
1405
  case 'mlgym_federation_get_status':
1328
- return await getFederationStatus(args);
1406
+ response = await getFederationStatus(args);
1407
+ break;
1329
1408
 
1330
1409
  case 'mlgym_federation_list_peers':
1331
- return await listFederationPeers(args);
1410
+ response = await listFederationPeers(args);
1411
+ break;
1332
1412
 
1333
1413
  case 'mlgym_federation_replicate_project':
1334
- return await replicateProject(args);
1414
+ response = await replicateProject(args);
1415
+ break;
1335
1416
 
1336
1417
  default:
1337
1418
  throw new Error(`Unknown tool: ${name}`);
1338
1419
  }
1420
+
1421
+ // Wrap response with update message if an update is available
1422
+ return wrapResponseWithUpdateMessage(response);
1339
1423
  });
1340
1424
 
1341
1425
  // Helper to generate SSH key pair
@@ -6327,33 +6411,14 @@ async function replicateProject(args) {
6327
6411
 
6328
6412
  // Start the server
6329
6413
  async function main() {
6330
- // Check for updates BEFORE starting the server
6331
- const updateCheck = await checkForUpdates();
6332
-
6333
- if (updateCheck.updateAvailable) {
6334
- // Block execution and show update required message
6335
- console.error(`\n╔════════════════════════════════════════════════════════════════════╗`);
6336
- console.error(`║ 🚫 UPDATE REQUIRED 🚫 ║`);
6337
- console.error(`║ ║`);
6338
- console.error(`║ The MLGym MCP Server is out of date and cannot run. ║`);
6339
- console.error(`║ ║`);
6340
- console.error(`║ Current version: ${CURRENT_VERSION.padEnd(52)} ║`);
6341
- console.error(`║ Required version: ${updateCheck.latest.padEnd(51)} ║`);
6342
- console.error(`║ ║`);
6343
- console.error(`║ Please update before continuing: ║`);
6344
- console.error(`║ ║`);
6345
- console.error(`║ npm install -g ${PACKAGE_NAME}@latest ║`);
6346
- console.error(`║ ║`);
6347
- console.error(`║ Then restart your IDE or MCP client. ║`);
6348
- console.error(`╚════════════════════════════════════════════════════════════════════════╝\n`);
6349
-
6350
- // Exit with error code to prevent MCP from starting
6351
- process.exit(1);
6352
- }
6353
-
6354
6414
  const transport = new StdioServerTransport();
6355
6415
  await server.connect(transport);
6356
6416
  console.error(`GitLab Backend MCP Server v${CURRENT_VERSION} started`);
6417
+
6418
+ // Check for updates in the background
6419
+ setTimeout(async () => {
6420
+ await checkForUpdates();
6421
+ }, 1000);
6357
6422
  }
6358
6423
 
6359
6424
  main().catch((error) => {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "mlgym-deploy",
3
- "version": "2.3.0",
3
+ "version": "2.3.2",
4
4
  "description": "MCP server for GitLab Backend - User creation and project deployment",
5
5
  "main": "index.js",
6
6
  "type": "module",