@ateam-ai/mcp 0.3.0 → 0.3.1

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 (3) hide show
  1. package/package.json +1 -1
  2. package/src/api.js +65 -41
  3. package/src/tools.js +3 -3
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ateam-ai/mcp",
3
- "version": "0.3.0",
3
+ "version": "0.3.1",
4
4
  "mcpName": "io.github.ariekogan/ateam-mcp",
5
5
  "description": "A-Team MCP Server — build, validate, and deploy multi-agent solutions from any AI environment",
6
6
  "type": "module",
package/src/api.js CHANGED
@@ -353,50 +353,74 @@ function formatError(method, path, status, body) {
353
353
  */
354
354
  async function request(method, path, body, sessionId, opts = {}) {
355
355
  const timeoutMs = opts.timeoutMs || REQUEST_TIMEOUT_MS;
356
- const controller = new AbortController();
357
- const timeout = setTimeout(() => controller.abort(), timeoutMs);
356
+ const maxRetries = opts.retries ?? 0;
358
357
  const baseUrl = getBaseUrl(sessionId);
359
358
 
360
- try {
361
- const fetchOpts = {
362
- method,
363
- headers: headers(sessionId),
364
- signal: controller.signal,
365
- };
366
- if (body !== undefined) {
367
- fetchOpts.body = JSON.stringify(body);
368
- }
369
-
370
- const res = await fetch(`${baseUrl}${path}`, fetchOpts);
371
-
372
- if (!res.ok) {
373
- const text = await res.text().catch(() => "");
374
- throw new Error(formatError(method, path, res.status, text));
375
- }
376
-
377
- return res.json();
378
- } catch (err) {
379
- if (err.name === "AbortError") {
380
- throw new Error(
381
- `A-Team API timeout: ${method} ${path} did not respond within ${timeoutMs / 1000}s.\n` +
382
- `Hint: The A-Team API at ${baseUrl} may be down. Check ${baseUrl}/health`
383
- );
384
- }
385
- if (err.cause?.code === "ECONNREFUSED") {
386
- throw new Error(
387
- `Cannot connect to A-Team API at ${baseUrl}.\n` +
388
- `Hint: The service may be down. Check ${baseUrl}/health`
389
- );
359
+ for (let attempt = 0; attempt <= maxRetries; attempt++) {
360
+ const controller = new AbortController();
361
+ const timeout = setTimeout(() => controller.abort(), timeoutMs);
362
+
363
+ try {
364
+ const fetchOpts = {
365
+ method,
366
+ headers: headers(sessionId),
367
+ signal: controller.signal,
368
+ };
369
+ if (body !== undefined) {
370
+ fetchOpts.body = JSON.stringify(body);
371
+ }
372
+
373
+ const res = await fetch(`${baseUrl}${path}`, fetchOpts);
374
+
375
+ // Auto-retry on 502/504 (proxy timeout during long deploys)
376
+ if ((res.status === 502 || res.status === 504) && attempt < maxRetries) {
377
+ const wait = Math.min(5000 * (attempt + 1), 15000);
378
+ console.error(`[MCP] ${method} ${path} returned ${res.status}, retrying in ${wait / 1000}s (attempt ${attempt + 1}/${maxRetries})...`);
379
+ await new Promise(r => setTimeout(r, wait));
380
+ continue;
381
+ }
382
+
383
+ if (!res.ok) {
384
+ const text = await res.text().catch(() => "");
385
+ throw new Error(formatError(method, path, res.status, text));
386
+ }
387
+
388
+ return res.json();
389
+ } catch (err) {
390
+ if (err.name === "AbortError") {
391
+ if (attempt < maxRetries) {
392
+ const wait = Math.min(5000 * (attempt + 1), 15000);
393
+ console.error(`[MCP] ${method} ${path} timed out, retrying in ${wait / 1000}s (attempt ${attempt + 1}/${maxRetries})...`);
394
+ await new Promise(r => setTimeout(r, wait));
395
+ continue;
396
+ }
397
+ throw new Error(
398
+ `A-Team API timeout: ${method} ${path} did not respond within ${timeoutMs / 1000}s.\n` +
399
+ `Hint: The A-Team API at ${baseUrl} may be down. Check ${baseUrl}/health`
400
+ );
401
+ }
402
+ if (err.cause?.code === "ECONNREFUSED") {
403
+ if (attempt < maxRetries) {
404
+ const wait = Math.min(5000 * (attempt + 1), 15000);
405
+ console.error(`[MCP] ${method} ${path} connection refused, retrying in ${wait / 1000}s (attempt ${attempt + 1}/${maxRetries})...`);
406
+ await new Promise(r => setTimeout(r, wait));
407
+ continue;
408
+ }
409
+ throw new Error(
410
+ `Cannot connect to A-Team API at ${baseUrl}.\n` +
411
+ `Hint: The service may be down. Check ${baseUrl}/health`
412
+ );
413
+ }
414
+ if (err.cause?.code === "ENOTFOUND") {
415
+ throw new Error(
416
+ `Cannot resolve A-Team API host: ${baseUrl}.\n` +
417
+ `Hint: Check your internet connection and ADAS_API_URL setting.`
418
+ );
419
+ }
420
+ throw err;
421
+ } finally {
422
+ clearTimeout(timeout);
390
423
  }
391
- if (err.cause?.code === "ENOTFOUND") {
392
- throw new Error(
393
- `Cannot resolve A-Team API host: ${baseUrl}.\n` +
394
- `Hint: Check your internet connection and ADAS_API_URL setting.`
395
- );
396
- }
397
- throw err;
398
- } finally {
399
- clearTimeout(timeout);
400
424
  }
401
425
  }
402
426
 
package/src/tools.js CHANGED
@@ -1268,7 +1268,7 @@ const handlers = {
1268
1268
  // Phase 2: Deploy
1269
1269
  let deploy;
1270
1270
  try {
1271
- deploy = await post("/deploy/solution", { solution, skills, connectors, mcp_store: effectiveMcpStore }, sid, { timeoutMs: 300_000 });
1271
+ deploy = await post("/deploy/solution", { solution, skills, connectors, mcp_store: effectiveMcpStore }, sid, { timeoutMs: 300_000, retries: 2 });
1272
1272
  phases.push({ phase: "deploy", status: deploy.ok ? "done" : "failed" });
1273
1273
  } catch (err) {
1274
1274
  return {
@@ -1558,7 +1558,7 @@ const handlers = {
1558
1558
  post(`/deploy/solutions/${solution_id}/github/push`, { message }, sid, { timeoutMs: 60_000 }),
1559
1559
 
1560
1560
  ateam_github_pull: async ({ solution_id }, sid) =>
1561
- post(`/deploy/solutions/${solution_id}/github/pull`, {}, sid, { timeoutMs: 300_000 }),
1561
+ post(`/deploy/solutions/${solution_id}/github/pull`, {}, sid, { timeoutMs: 300_000, retries: 2 }),
1562
1562
 
1563
1563
  ateam_github_status: async ({ solution_id }, sid) =>
1564
1564
  get(`/deploy/solutions/${solution_id}/github/status`, sid),
@@ -1593,7 +1593,7 @@ const handlers = {
1593
1593
  const endpoint = skill_id
1594
1594
  ? `/deploy/solutions/${solution_id}/skills/${skill_id}/redeploy`
1595
1595
  : `/deploy/solutions/${solution_id}/redeploy`;
1596
- const result = await post(endpoint, {}, sid, { timeoutMs: 300_000 });
1596
+ const result = await post(endpoint, {}, sid, { timeoutMs: 300_000, retries: 2 });
1597
1597
  return {
1598
1598
  ok: result.ok,
1599
1599
  solution_id,