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.
- package/index.js +147 -82
- 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.
|
|
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
|
|
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 (
|
|
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
|
|
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
|
|
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
|
-
|
|
1210
|
+
response = await configureGit(args);
|
|
1211
|
+
break;
|
|
1182
1212
|
|
|
1183
1213
|
case 'mlgym_debug_last_error':
|
|
1184
|
-
|
|
1214
|
+
response = await debugLastError(args);
|
|
1215
|
+
break;
|
|
1185
1216
|
|
|
1186
1217
|
case 'mlgym_debug_status':
|
|
1187
|
-
|
|
1218
|
+
response = await debugStatus(args);
|
|
1219
|
+
break;
|
|
1188
1220
|
|
|
1189
1221
|
case 'mlgym_debug_logs':
|
|
1190
|
-
|
|
1222
|
+
response = await debugLogs(args);
|
|
1223
|
+
break;
|
|
1191
1224
|
|
|
1192
1225
|
case 'mlgym_debug_deployment':
|
|
1193
|
-
|
|
1226
|
+
response = await debugDeployment(args);
|
|
1227
|
+
break;
|
|
1194
1228
|
|
|
1195
1229
|
case 'mlgym_version_check':
|
|
1196
|
-
|
|
1230
|
+
response = await versionCheck(args);
|
|
1231
|
+
break;
|
|
1197
1232
|
|
|
1198
1233
|
case 'mlgym_auth_check':
|
|
1199
|
-
|
|
1234
|
+
response = await checkUserExists(args);
|
|
1235
|
+
break;
|
|
1200
1236
|
|
|
1201
1237
|
case 'mlgym_user_create':
|
|
1202
|
-
|
|
1238
|
+
response = await createUser(args);
|
|
1239
|
+
break;
|
|
1203
1240
|
|
|
1204
1241
|
case 'mlgym_project_init':
|
|
1205
|
-
|
|
1242
|
+
response = await initProject(args);
|
|
1243
|
+
break;
|
|
1206
1244
|
|
|
1207
1245
|
case 'mlgym_user_recover':
|
|
1208
|
-
|
|
1246
|
+
response = await recoverUser(args);
|
|
1247
|
+
break;
|
|
1209
1248
|
|
|
1210
1249
|
case 'mlgym_auth_login':
|
|
1211
|
-
|
|
1250
|
+
response = await loginUser(args);
|
|
1251
|
+
break;
|
|
1212
1252
|
|
|
1213
1253
|
case 'mlgym_projects_list':
|
|
1214
|
-
|
|
1254
|
+
response = await listProjects(args);
|
|
1255
|
+
break;
|
|
1215
1256
|
|
|
1216
1257
|
case 'mlgym_deployments_trigger':
|
|
1217
|
-
|
|
1258
|
+
response = await triggerDeployment(args);
|
|
1259
|
+
break;
|
|
1218
1260
|
|
|
1219
1261
|
case 'mlgym_deployments_get_status':
|
|
1220
|
-
|
|
1262
|
+
response = await getDeploymentStatus(args);
|
|
1263
|
+
break;
|
|
1221
1264
|
|
|
1222
1265
|
case 'mlgym_auth_get_current_user':
|
|
1223
|
-
|
|
1266
|
+
response = await getCurrentUser(args);
|
|
1267
|
+
break;
|
|
1224
1268
|
|
|
1225
1269
|
case 'mlgym_projects_get':
|
|
1226
|
-
|
|
1270
|
+
response = await getProject(args);
|
|
1271
|
+
break;
|
|
1227
1272
|
|
|
1228
1273
|
case 'mlgym_projects_delete':
|
|
1229
|
-
|
|
1274
|
+
response = await deleteProject(args);
|
|
1275
|
+
break;
|
|
1230
1276
|
|
|
1231
1277
|
case 'mlgym_keys_list':
|
|
1232
|
-
|
|
1278
|
+
response = await listKeys(args);
|
|
1279
|
+
break;
|
|
1233
1280
|
|
|
1234
1281
|
case 'mlgym_projects_update':
|
|
1235
|
-
|
|
1282
|
+
response = await updateProject(args);
|
|
1283
|
+
break;
|
|
1236
1284
|
|
|
1237
1285
|
case 'mlgym_deployments_list':
|
|
1238
|
-
|
|
1286
|
+
response = await listDeployments(args);
|
|
1287
|
+
break;
|
|
1239
1288
|
|
|
1240
1289
|
case 'mlgym_deployments_get_logs':
|
|
1241
|
-
|
|
1290
|
+
response = await getDeploymentLogs(args);
|
|
1291
|
+
break;
|
|
1242
1292
|
|
|
1243
1293
|
case 'mlgym_keys_add':
|
|
1244
|
-
|
|
1294
|
+
response = await addKey(args);
|
|
1295
|
+
break;
|
|
1245
1296
|
|
|
1246
1297
|
case 'mlgym_keys_delete':
|
|
1247
|
-
|
|
1298
|
+
response = await deleteKey(args);
|
|
1299
|
+
break;
|
|
1248
1300
|
|
|
1249
1301
|
case 'mlgym_regions_list':
|
|
1250
|
-
|
|
1302
|
+
response = await listRegions(args);
|
|
1303
|
+
break;
|
|
1251
1304
|
|
|
1252
1305
|
case 'mlgym_regions_get_status':
|
|
1253
|
-
|
|
1306
|
+
response = await getRegionStatus(args);
|
|
1307
|
+
break;
|
|
1254
1308
|
|
|
1255
1309
|
case 'mlgym_pools_list':
|
|
1256
|
-
|
|
1310
|
+
response = await listPools(args);
|
|
1311
|
+
break;
|
|
1257
1312
|
|
|
1258
1313
|
case 'mlgym_pools_get_stats':
|
|
1259
|
-
|
|
1314
|
+
response = await getPoolStats(args);
|
|
1315
|
+
break;
|
|
1260
1316
|
|
|
1261
1317
|
case 'mlgym_pools_select_optimal':
|
|
1262
|
-
|
|
1318
|
+
response = await selectOptimalPool(args);
|
|
1319
|
+
break;
|
|
1263
1320
|
|
|
1264
1321
|
case 'mlgym_regions_select_isp':
|
|
1265
|
-
|
|
1322
|
+
response = await selectISP(args);
|
|
1323
|
+
break;
|
|
1266
1324
|
|
|
1267
1325
|
case 'mlgym_health_get_report':
|
|
1268
|
-
|
|
1326
|
+
response = await getHealthReport(args);
|
|
1327
|
+
break;
|
|
1269
1328
|
|
|
1270
1329
|
case 'mlgym_health_check_pool':
|
|
1271
|
-
|
|
1330
|
+
response = await checkPoolHealth(args);
|
|
1331
|
+
break;
|
|
1272
1332
|
|
|
1273
1333
|
case 'mlgym_health_check_node':
|
|
1274
|
-
|
|
1334
|
+
response = await checkNodeHealth(args);
|
|
1335
|
+
break;
|
|
1275
1336
|
|
|
1276
1337
|
case 'mlgym_metrics_get_deployment_metrics':
|
|
1277
|
-
|
|
1338
|
+
response = await getDeploymentMetrics(args);
|
|
1339
|
+
break;
|
|
1278
1340
|
|
|
1279
1341
|
case 'mlgym_metrics_get_pool_utilization':
|
|
1280
|
-
|
|
1342
|
+
response = await getPoolUtilization(args);
|
|
1343
|
+
break;
|
|
1281
1344
|
|
|
1282
1345
|
case 'mlgym_git_get_remote_url':
|
|
1283
|
-
|
|
1346
|
+
response = await getGitRemoteUrl(args);
|
|
1347
|
+
break;
|
|
1284
1348
|
|
|
1285
1349
|
case 'mlgym_git_setup_push':
|
|
1286
|
-
|
|
1350
|
+
response = await setupGitPush(args);
|
|
1351
|
+
break;
|
|
1287
1352
|
|
|
1288
1353
|
case 'mlgym_git_get_clone_command':
|
|
1289
|
-
|
|
1354
|
+
response = await getGitCloneCommand(args);
|
|
1355
|
+
break;
|
|
1290
1356
|
|
|
1291
1357
|
case 'mlgym_deployments_rollback':
|
|
1292
|
-
|
|
1358
|
+
response = await rollbackDeployment(args);
|
|
1359
|
+
break;
|
|
1293
1360
|
|
|
1294
1361
|
case 'mlgym_deployments_scale':
|
|
1295
|
-
|
|
1362
|
+
response = await scaleDeployment(args);
|
|
1363
|
+
break;
|
|
1296
1364
|
|
|
1297
1365
|
case 'mlgym_auth_logout':
|
|
1298
|
-
|
|
1366
|
+
response = await logoutUser(args);
|
|
1367
|
+
break;
|
|
1299
1368
|
|
|
1300
1369
|
case 'mlgym_auth_refresh_token':
|
|
1301
|
-
|
|
1370
|
+
response = await refreshToken(args);
|
|
1371
|
+
break;
|
|
1302
1372
|
|
|
1303
1373
|
case 'mlgym_auth_login_to_isp':
|
|
1304
|
-
|
|
1374
|
+
response = await loginToISP(args);
|
|
1375
|
+
break;
|
|
1305
1376
|
|
|
1306
1377
|
case 'mlgym_keys_generate_pair':
|
|
1307
|
-
|
|
1378
|
+
response = await generateKeyPair(args);
|
|
1379
|
+
break;
|
|
1308
1380
|
|
|
1309
1381
|
case 'mlgym_config_set_environment':
|
|
1310
|
-
|
|
1382
|
+
response = await setEnvironment(args);
|
|
1383
|
+
break;
|
|
1311
1384
|
|
|
1312
1385
|
case 'mlgym_config_get_endpoints':
|
|
1313
|
-
|
|
1386
|
+
response = await getEndpoints(args);
|
|
1387
|
+
break;
|
|
1314
1388
|
|
|
1315
1389
|
case 'mlgym_config_set_default_pool':
|
|
1316
|
-
|
|
1390
|
+
response = await setDefaultPool(args);
|
|
1391
|
+
break;
|
|
1317
1392
|
|
|
1318
1393
|
case 'mlgym_webhooks_setup':
|
|
1319
|
-
|
|
1394
|
+
response = await setupWebhook(args);
|
|
1395
|
+
break;
|
|
1320
1396
|
|
|
1321
1397
|
case 'mlgym_webhooks_test':
|
|
1322
|
-
|
|
1398
|
+
response = await testWebhook(args);
|
|
1399
|
+
break;
|
|
1323
1400
|
|
|
1324
1401
|
case 'mlgym_webhooks_get_logs':
|
|
1325
|
-
|
|
1402
|
+
response = await getWebhookLogs(args);
|
|
1403
|
+
break;
|
|
1326
1404
|
|
|
1327
1405
|
case 'mlgym_federation_get_status':
|
|
1328
|
-
|
|
1406
|
+
response = await getFederationStatus(args);
|
|
1407
|
+
break;
|
|
1329
1408
|
|
|
1330
1409
|
case 'mlgym_federation_list_peers':
|
|
1331
|
-
|
|
1410
|
+
response = await listFederationPeers(args);
|
|
1411
|
+
break;
|
|
1332
1412
|
|
|
1333
1413
|
case 'mlgym_federation_replicate_project':
|
|
1334
|
-
|
|
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) => {
|