@ateam-ai/mcp 0.3.5 → 0.3.7
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/package.json +1 -1
- package/src/tools.js +104 -35
package/package.json
CHANGED
package/src/tools.js
CHANGED
|
@@ -124,14 +124,18 @@ export const tools = [
|
|
|
124
124
|
inputSchema: {
|
|
125
125
|
type: "object",
|
|
126
126
|
properties: {
|
|
127
|
+
solution_id: {
|
|
128
|
+
type: "string",
|
|
129
|
+
description: "The solution ID. Use this INSTEAD of passing the full solution object — the solution definition is auto-pulled from GitHub. Required if solution object is omitted.",
|
|
130
|
+
},
|
|
127
131
|
solution: {
|
|
128
132
|
type: "object",
|
|
129
|
-
description: "
|
|
133
|
+
description: "Full solution definition. Required on first deploy. After first deploy, just pass solution_id instead — everything is auto-pulled from GitHub.",
|
|
130
134
|
},
|
|
131
135
|
skills: {
|
|
132
136
|
type: "array",
|
|
133
137
|
items: { type: "object" },
|
|
134
|
-
description: "
|
|
138
|
+
description: "Optional after first deploy: skill definitions. If omitted, auto-pulled from GitHub repo (skills/{id}/skill.json).",
|
|
135
139
|
},
|
|
136
140
|
connectors: {
|
|
137
141
|
type: "array",
|
|
@@ -155,7 +159,7 @@ export const tools = [
|
|
|
155
159
|
description: "Optional: which skill to test (defaults to the first skill).",
|
|
156
160
|
},
|
|
157
161
|
},
|
|
158
|
-
required: [
|
|
162
|
+
required: [],
|
|
159
163
|
},
|
|
160
164
|
},
|
|
161
165
|
{
|
|
@@ -1291,7 +1295,13 @@ const handlers = {
|
|
|
1291
1295
|
// Validates → Deploys → Health-checks → Optionally tests
|
|
1292
1296
|
// One call replaces: validate_solution + deploy_solution + get_solution(health)
|
|
1293
1297
|
|
|
1294
|
-
ateam_build_and_run: async ({ solution, skills, connectors, mcp_store, github, test_message, test_skill_id }, sid) => {
|
|
1298
|
+
ateam_build_and_run: async ({ solution_id: solIdArg, solution: solutionArg, skills, connectors, mcp_store, github, test_message, test_skill_id }, sid) => {
|
|
1299
|
+
let solution = solutionArg;
|
|
1300
|
+
// If only solution_id passed (no full solution), we'll pull from GitHub
|
|
1301
|
+
const solutionId = solution?.id || solIdArg;
|
|
1302
|
+
if (!solutionId) {
|
|
1303
|
+
return { ok: false, phase: "pre_check", error: "Provide either solution (object) or solution_id (string)." };
|
|
1304
|
+
}
|
|
1295
1305
|
const phases = [];
|
|
1296
1306
|
|
|
1297
1307
|
// Guard: reject large mcp_store — agent should use github_patch instead
|
|
@@ -1314,13 +1324,13 @@ const handlers = {
|
|
|
1314
1324
|
}
|
|
1315
1325
|
}
|
|
1316
1326
|
|
|
1317
|
-
// Phase 0: Auto-detect GitHub repo — if no mcp_store passed and repo exists, pull from GitHub
|
|
1327
|
+
// Phase 0: Auto-detect GitHub repo — if no mcp_store passed and repo exists, pull bundle from GitHub
|
|
1318
1328
|
let effectiveMcpStore = mcp_store;
|
|
1329
|
+
let effectiveSkills = skills;
|
|
1319
1330
|
if (!mcp_store) {
|
|
1320
1331
|
try {
|
|
1321
|
-
const ghStatus = await get(`/deploy/solutions/${
|
|
1332
|
+
const ghStatus = await get(`/deploy/solutions/${solutionId}/github/status`, sid);
|
|
1322
1333
|
if (ghStatus?.repo_url) {
|
|
1323
|
-
// Repo exists — auto-pull from GitHub
|
|
1324
1334
|
github = true;
|
|
1325
1335
|
}
|
|
1326
1336
|
} catch { /* no repo — first deploy, mcp_store expected */ }
|
|
@@ -1328,24 +1338,33 @@ const handlers = {
|
|
|
1328
1338
|
if (github && !mcp_store) {
|
|
1329
1339
|
try {
|
|
1330
1340
|
const pullResult = await post(
|
|
1331
|
-
`/deploy/solutions/${
|
|
1341
|
+
`/deploy/solutions/${solutionId}/github/pull-bundle`,
|
|
1332
1342
|
{},
|
|
1333
1343
|
sid,
|
|
1334
|
-
{ timeoutMs:
|
|
1344
|
+
{ timeoutMs: 60_000 },
|
|
1335
1345
|
);
|
|
1336
1346
|
if (!pullResult.ok) {
|
|
1337
1347
|
return {
|
|
1338
1348
|
ok: false,
|
|
1339
1349
|
phase: "github_pull",
|
|
1340
|
-
error: pullResult.error || "Failed to pull
|
|
1350
|
+
error: pullResult.error || "Failed to pull bundle from GitHub",
|
|
1341
1351
|
hint: pullResult.hint || "Deploy the solution first (with mcp_store) to auto-create the GitHub repo.",
|
|
1342
|
-
message: "Cannot pull
|
|
1352
|
+
message: "Cannot pull from GitHub. The repo may not exist yet — deploy with mcp_store first.",
|
|
1343
1353
|
};
|
|
1344
1354
|
}
|
|
1345
|
-
effectiveMcpStore = pullResult.mcp_store;
|
|
1355
|
+
effectiveMcpStore = pullResult.mcp_store || {};
|
|
1356
|
+
// Use solution from GitHub if not passed inline
|
|
1357
|
+
if (!solution && pullResult.solution) {
|
|
1358
|
+
solution = pullResult.solution;
|
|
1359
|
+
}
|
|
1360
|
+
// Use skills from GitHub if not passed inline
|
|
1361
|
+
if (!effectiveSkills?.length && pullResult.skills?.length) {
|
|
1362
|
+
effectiveSkills = pullResult.skills;
|
|
1363
|
+
}
|
|
1346
1364
|
phases.push({
|
|
1347
1365
|
phase: "github_pull",
|
|
1348
1366
|
status: "done",
|
|
1367
|
+
skills_found: pullResult.skills_found || 0,
|
|
1349
1368
|
connectors_found: pullResult.connectors_found || 0,
|
|
1350
1369
|
files_loaded: pullResult.files_loaded || 0,
|
|
1351
1370
|
});
|
|
@@ -1354,15 +1373,35 @@ const handlers = {
|
|
|
1354
1373
|
ok: false,
|
|
1355
1374
|
phase: "github_pull",
|
|
1356
1375
|
error: err.message,
|
|
1357
|
-
message: "Failed to pull
|
|
1376
|
+
message: "Failed to pull from GitHub. The repo may not exist yet — deploy with mcp_store first.",
|
|
1358
1377
|
};
|
|
1359
1378
|
}
|
|
1360
1379
|
}
|
|
1361
1380
|
|
|
1381
|
+
// Guard: solution required (either inline or from GitHub)
|
|
1382
|
+
if (!solution) {
|
|
1383
|
+
return {
|
|
1384
|
+
ok: false,
|
|
1385
|
+
phase: "pre_check",
|
|
1386
|
+
error: "No solution provided and none found in GitHub repo.",
|
|
1387
|
+
message: "Pass solution inline or ensure solution.json exists in the GitHub repo.",
|
|
1388
|
+
};
|
|
1389
|
+
}
|
|
1390
|
+
|
|
1391
|
+
// Guard: skills required (either inline or from GitHub)
|
|
1392
|
+
if (!effectiveSkills?.length) {
|
|
1393
|
+
return {
|
|
1394
|
+
ok: false,
|
|
1395
|
+
phase: "pre_check",
|
|
1396
|
+
error: "No skills provided and none found in GitHub repo.",
|
|
1397
|
+
message: "Pass skills inline or ensure they exist in the GitHub repo (skills/{id}/skill.json).",
|
|
1398
|
+
};
|
|
1399
|
+
}
|
|
1400
|
+
|
|
1362
1401
|
// Phase 1: Validate
|
|
1363
1402
|
let validation;
|
|
1364
1403
|
try {
|
|
1365
|
-
validation = await post("/validate/solution", { solution, skills, connectors, mcp_store: effectiveMcpStore }, sid, { timeoutMs: 120_000 });
|
|
1404
|
+
validation = await post("/validate/solution", { solution, skills: effectiveSkills, connectors, mcp_store: effectiveMcpStore }, sid, { timeoutMs: 120_000 });
|
|
1366
1405
|
phases.push({ phase: "validate", status: "done" });
|
|
1367
1406
|
} catch (err) {
|
|
1368
1407
|
return {
|
|
@@ -1388,7 +1427,7 @@ const handlers = {
|
|
|
1388
1427
|
// Phase 2: Deploy
|
|
1389
1428
|
let deploy;
|
|
1390
1429
|
try {
|
|
1391
|
-
deploy = await post("/deploy/solution", { solution, skills, connectors, mcp_store: effectiveMcpStore }, sid, { timeoutMs: 300_000, retries: 2 });
|
|
1430
|
+
deploy = await post("/deploy/solution", { solution, skills: effectiveSkills, connectors, mcp_store: effectiveMcpStore }, sid, { timeoutMs: 300_000, retries: 2 });
|
|
1392
1431
|
phases.push({ phase: "deploy", status: deploy.ok ? "done" : "failed" });
|
|
1393
1432
|
} catch (err) {
|
|
1394
1433
|
return {
|
|
@@ -1412,11 +1451,35 @@ const handlers = {
|
|
|
1412
1451
|
};
|
|
1413
1452
|
}
|
|
1414
1453
|
|
|
1454
|
+
// Phase 2.5: Restart connectors that have source code (upload triggers stop+start)
|
|
1455
|
+
if (effectiveMcpStore && Object.keys(effectiveMcpStore).length > 0) {
|
|
1456
|
+
const connectorResults = [];
|
|
1457
|
+
for (const [connId, files] of Object.entries(effectiveMcpStore)) {
|
|
1458
|
+
if (!Array.isArray(files) || files.length === 0) continue;
|
|
1459
|
+
try {
|
|
1460
|
+
const uploadResult = await post(
|
|
1461
|
+
`/deploy/solutions/${solutionId}/connectors/${connId}/upload`,
|
|
1462
|
+
{ files },
|
|
1463
|
+
sid,
|
|
1464
|
+
{ timeoutMs: 120_000 },
|
|
1465
|
+
);
|
|
1466
|
+
connectorResults.push({ id: connId, ok: true, tools: uploadResult.tools || 0 });
|
|
1467
|
+
} catch (err) {
|
|
1468
|
+
connectorResults.push({ id: connId, ok: false, error: err.message });
|
|
1469
|
+
}
|
|
1470
|
+
}
|
|
1471
|
+
phases.push({
|
|
1472
|
+
phase: "connector_restart",
|
|
1473
|
+
status: connectorResults.every(r => r.ok) ? "done" : "partial",
|
|
1474
|
+
connectors: connectorResults,
|
|
1475
|
+
});
|
|
1476
|
+
}
|
|
1477
|
+
|
|
1415
1478
|
// Phase 3: Health check (with brief wait for propagation)
|
|
1416
1479
|
let health;
|
|
1417
1480
|
try {
|
|
1418
1481
|
await sleep(2000);
|
|
1419
|
-
health = await get(`/deploy/solutions/${
|
|
1482
|
+
health = await get(`/deploy/solutions/${solutionId}/health`, sid);
|
|
1420
1483
|
phases.push({ phase: "health", status: "done" });
|
|
1421
1484
|
} catch (err) {
|
|
1422
1485
|
health = { error: err.message };
|
|
@@ -1426,11 +1489,11 @@ const handlers = {
|
|
|
1426
1489
|
// Phase 4: Warm test (optional)
|
|
1427
1490
|
let test_result;
|
|
1428
1491
|
if (test_message) {
|
|
1429
|
-
const skillId = test_skill_id ||
|
|
1492
|
+
const skillId = test_skill_id || effectiveSkills?.[0]?.id;
|
|
1430
1493
|
if (skillId) {
|
|
1431
1494
|
try {
|
|
1432
1495
|
test_result = await post(
|
|
1433
|
-
`/deploy/solutions/${
|
|
1496
|
+
`/deploy/solutions/${solutionId}/skills/${skillId}/test`,
|
|
1434
1497
|
{ message: test_message },
|
|
1435
1498
|
sid,
|
|
1436
1499
|
{ timeoutMs: 90_000 },
|
|
@@ -1443,28 +1506,34 @@ const handlers = {
|
|
|
1443
1506
|
}
|
|
1444
1507
|
}
|
|
1445
1508
|
|
|
1446
|
-
// Phase 5: GitHub push (
|
|
1509
|
+
// Phase 5: GitHub push (skip if we just pulled from GitHub — don't overwrite source of truth)
|
|
1447
1510
|
let github_result;
|
|
1448
|
-
|
|
1449
|
-
|
|
1450
|
-
|
|
1451
|
-
|
|
1452
|
-
|
|
1453
|
-
|
|
1454
|
-
|
|
1455
|
-
|
|
1456
|
-
|
|
1457
|
-
|
|
1458
|
-
|
|
1459
|
-
|
|
1460
|
-
|
|
1461
|
-
|
|
1462
|
-
|
|
1511
|
+
if (github) {
|
|
1512
|
+
// We pulled from GitHub → GitHub IS the source of truth. Don't push stale Core state back.
|
|
1513
|
+
github_result = { skipped: true, reason: 'Deployed from GitHub — skipping push-back to avoid overwriting source of truth.' };
|
|
1514
|
+
phases.push({ phase: "github", status: "skipped", reason: "pulled_from_github" });
|
|
1515
|
+
} else {
|
|
1516
|
+
try {
|
|
1517
|
+
github_result = await post(
|
|
1518
|
+
`/deploy/solutions/${solutionId}/github/push`,
|
|
1519
|
+
{ message: `Deploy: ${solution.name || solutionId}` },
|
|
1520
|
+
sid,
|
|
1521
|
+
{ timeoutMs: 60_000 },
|
|
1522
|
+
);
|
|
1523
|
+
phases.push({
|
|
1524
|
+
phase: "github",
|
|
1525
|
+
status: github_result.skipped ? "skipped" : "done",
|
|
1526
|
+
...(github_result.repo_url && { repo_url: github_result.repo_url }),
|
|
1527
|
+
});
|
|
1528
|
+
} catch (err) {
|
|
1529
|
+
github_result = { error: err.message };
|
|
1530
|
+
phases.push({ phase: "github", status: "error", error: err.message });
|
|
1531
|
+
}
|
|
1463
1532
|
}
|
|
1464
1533
|
|
|
1465
1534
|
return {
|
|
1466
1535
|
ok: true,
|
|
1467
|
-
solution_id:
|
|
1536
|
+
solution_id: solutionId,
|
|
1468
1537
|
branch: 'main',
|
|
1469
1538
|
phases,
|
|
1470
1539
|
deploy: {
|