@ateam-ai/mcp 0.4.50 → 0.4.51
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 +41 -43
package/package.json
CHANGED
package/src/tools.js
CHANGED
|
@@ -1324,7 +1324,10 @@ export const tools = [
|
|
|
1324
1324
|
},
|
|
1325
1325
|
{
|
|
1326
1326
|
name: "ateam_get_execution_logs",
|
|
1327
|
-
core:
|
|
1327
|
+
// Advertised (was core:false): these are the RUNTIME DIAGNOSTICS a caller needs
|
|
1328
|
+
// mid-run, but a connector-wildcard grant expands over ADVERTISED tools only, so
|
|
1329
|
+
// hiding them made them ungrantable — invisible to every agent that needed them.
|
|
1330
|
+
core: true,
|
|
1328
1331
|
description:
|
|
1329
1332
|
"Get execution logs for a solution — recent jobs with step traces, tool calls, errors, and timing. Essential for debugging what actually happened during skill execution. (Advanced.)",
|
|
1330
1333
|
inputSchema: {
|
|
@@ -1540,7 +1543,10 @@ export const tools = [
|
|
|
1540
1543
|
},
|
|
1541
1544
|
{
|
|
1542
1545
|
name: "ateam_get_metrics",
|
|
1543
|
-
core:
|
|
1546
|
+
// Advertised (was core:false): these are the RUNTIME DIAGNOSTICS a caller needs
|
|
1547
|
+
// mid-run, but a connector-wildcard grant expands over ADVERTISED tools only, so
|
|
1548
|
+
// hiding them made them ungrantable — invisible to every agent that needed them.
|
|
1549
|
+
core: true,
|
|
1544
1550
|
description:
|
|
1545
1551
|
"Get execution metrics — timing, tool stats, bottlenecks, signals, and recommendations. (Advanced.)",
|
|
1546
1552
|
inputSchema: {
|
|
@@ -4178,12 +4184,9 @@ const handlers = {
|
|
|
4178
4184
|
while (Date.now() - startedAt < totalTimeoutMs) {
|
|
4179
4185
|
const qs = new URLSearchParams();
|
|
4180
4186
|
qs.set("skillSlug", skill_id);
|
|
4181
|
-
|
|
4182
|
-
|
|
4183
|
-
|
|
4184
|
-
signal: AbortSignal.timeout(15_000),
|
|
4185
|
-
}).catch(err => ({ ok: false, _err: err.message }));
|
|
4186
|
-
const data = res.ok === false && res._err ? { ok: false, error: res._err } : await res.json().catch(() => ({ ok: false, error: "non-json chain response" }));
|
|
4187
|
+
// Builder proxy, not ADAS_CORE_URL (docker-internal; see ateam_chain_status).
|
|
4188
|
+
const data = await get(`/deploy/jobs/${encodeURIComponent(rootJobId)}/chain?${qs}`, sid)
|
|
4189
|
+
.catch(err => ({ ok: false, error: err.message }));
|
|
4187
4190
|
lastChain = data;
|
|
4188
4191
|
const jobs = Array.isArray(data?.chainJobsList) ? data.chainJobsList : Array.isArray(data?.chainJobs) ? data.chainJobs : null;
|
|
4189
4192
|
if (jobs && jobs.length > 0 && jobs.every(j => isTerminal(j.status))) {
|
|
@@ -4337,15 +4340,11 @@ const handlers = {
|
|
|
4337
4340
|
const creds = getCredentials(sid);
|
|
4338
4341
|
const apiKey = creds?.apiKey;
|
|
4339
4342
|
if (!apiKey) return { ...single, chain: { ok: false, error: "include_chain requires api-key auth (call ateam_auth)" } };
|
|
4340
|
-
const coreUrl = process.env.ADAS_CORE_URL || "http://adas-backend:4000";
|
|
4341
4343
|
const qs = new URLSearchParams();
|
|
4342
4344
|
if (skill_id) qs.set("skillSlug", skill_id);
|
|
4343
|
-
|
|
4344
|
-
|
|
4345
|
-
|
|
4346
|
-
signal: AbortSignal.timeout(15_000),
|
|
4347
|
-
}).catch(err => ({ ok: false, _err: err.message }));
|
|
4348
|
-
const chain = res.ok === false && res._err ? { ok: false, error: res._err } : await res.json().catch(() => ({ ok: false, error: "non-json chain response" }));
|
|
4345
|
+
// Builder proxy, not ADAS_CORE_URL (docker-internal; see ateam_chain_status).
|
|
4346
|
+
const chain = await get(`/deploy/jobs/${encodeURIComponent(job_id)}/chain?${qs}`, sid)
|
|
4347
|
+
.catch(err => ({ ok: false, error: err.message }));
|
|
4349
4348
|
return { ...single, chain };
|
|
4350
4349
|
},
|
|
4351
4350
|
|
|
@@ -4354,21 +4353,12 @@ const handlers = {
|
|
|
4354
4353
|
const creds = getCredentials(sid);
|
|
4355
4354
|
const apiKey = creds?.apiKey;
|
|
4356
4355
|
if (!apiKey) throw new Error("No api_key in session — call ateam_auth(api_key) first.");
|
|
4357
|
-
|
|
4356
|
+
// Via the Builder proxy (see ateam_chain_status) — Core's hostname is
|
|
4357
|
+
// docker-internal and unreachable from a desktop/laptop MCP process.
|
|
4358
4358
|
const qs = new URLSearchParams();
|
|
4359
4359
|
if (skill_slug) qs.set("skillSlug", skill_slug);
|
|
4360
|
-
const
|
|
4361
|
-
|
|
4362
|
-
headers: { "x-api-key": apiKey, "X-ADAS-SERVICE": "ateam-mcp.get_chain" },
|
|
4363
|
-
signal: AbortSignal.timeout(15_000),
|
|
4364
|
-
});
|
|
4365
|
-
const text = await res.text();
|
|
4366
|
-
let data;
|
|
4367
|
-
try { data = JSON.parse(text); } catch { data = { ok: false, error: text.slice(0, 400) }; }
|
|
4368
|
-
if (!res.ok) {
|
|
4369
|
-
throw new Error(`Core /api/job/${job_id}/chain returned ${res.status}: ${data.error || JSON.stringify(data).slice(0, 200)}`);
|
|
4370
|
-
}
|
|
4371
|
-
return data;
|
|
4360
|
+
const suffix = qs.toString() ? `?${qs}` : "";
|
|
4361
|
+
return await get(`/deploy/jobs/${encodeURIComponent(job_id)}/chain${suffix}`, sid);
|
|
4372
4362
|
},
|
|
4373
4363
|
|
|
4374
4364
|
// SLIM chain status — the chip-quick poll. Hits Core /api/job/:id/status
|
|
@@ -4380,21 +4370,26 @@ const handlers = {
|
|
|
4380
4370
|
ateam_chain_status: async ({ chain_id, job_id }, sid) => {
|
|
4381
4371
|
const id = chain_id || job_id;
|
|
4382
4372
|
if (!id) throw new Error("chain_id required");
|
|
4383
|
-
|
|
4384
|
-
|
|
4385
|
-
|
|
4386
|
-
|
|
4387
|
-
|
|
4388
|
-
|
|
4389
|
-
|
|
4390
|
-
|
|
4391
|
-
|
|
4392
|
-
|
|
4393
|
-
|
|
4394
|
-
|
|
4395
|
-
|
|
4396
|
-
|
|
4397
|
-
|
|
4373
|
+
// Routed through the BUILDER proxy (/deploy/jobs/:id/status), not
|
|
4374
|
+
// ADAS_CORE_URL directly. Core is the only holder of job state, but its
|
|
4375
|
+
// hostname is docker-internal — every laptop MCP session got a bare "fetch
|
|
4376
|
+
// failed" that read as "job not found" (2026-08-15: a full day spent reading
|
|
4377
|
+
// Mongo by hand to answer "is this run alive?"). Same reason ateam_verify
|
|
4378
|
+
// proxies. `get()` also carries the session's auth/tenant headers.
|
|
4379
|
+
const data = await get(`/deploy/jobs/${encodeURIComponent(id)}/status`, sid);
|
|
4380
|
+
// LAST ACTIVITY — the running-vs-corpse discriminator. `status:"running"` is
|
|
4381
|
+
// true for a healthy build AND a dead one; the only way to tell them apart
|
|
4382
|
+
// was querying llm_traces for the newest timestamp. Core bumps job.lastUpdate
|
|
4383
|
+
// in the same setStatus() call that writes job.subStatus, so the timestamp
|
|
4384
|
+
// and "what it was doing" move together — one cheap read, no tree walk, so
|
|
4385
|
+
// this stays safe to poll. idle_seconds alone needs interpreting (a live
|
|
4386
|
+
// build can sit minutes inside one provider call), which is why
|
|
4387
|
+
// activity_source ships with it: "idle 180s — in provider call" is a state
|
|
4388
|
+
// you can act on; "idle 180s" is a number you have to guess about.
|
|
4389
|
+
const lastActivityAt = data.lastUpdate ?? data.last_update ?? null;
|
|
4390
|
+
const idleSeconds = lastActivityAt
|
|
4391
|
+
? Math.max(0, Math.round((Date.now() - new Date(lastActivityAt).getTime()) / 1000))
|
|
4392
|
+
: null;
|
|
4398
4393
|
// Surface the chain-aggregate truth as the primary fields; keep the raw
|
|
4399
4394
|
// slim job under `job` for callers that want per-job detail.
|
|
4400
4395
|
return {
|
|
@@ -4404,6 +4399,9 @@ const handlers = {
|
|
|
4404
4399
|
pending_question: data.pendingQuestion || null,
|
|
4405
4400
|
result: data.result ?? null,
|
|
4406
4401
|
progress: data.progress || null,
|
|
4402
|
+
last_activity_at: lastActivityAt,
|
|
4403
|
+
idle_seconds: idleSeconds,
|
|
4404
|
+
activity_source: data.subStatus || null,
|
|
4407
4405
|
job: data,
|
|
4408
4406
|
};
|
|
4409
4407
|
},
|