@ateam-ai/mcp 0.4.67 → 0.4.69
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/http.js +34 -0
- package/src/tools.js +29 -6
package/package.json
CHANGED
package/src/http.js
CHANGED
|
@@ -31,6 +31,22 @@ import {
|
|
|
31
31
|
import { mountOAuth } from "./oauth.js";
|
|
32
32
|
import { connectGithubPage } from "./pages.js";
|
|
33
33
|
|
|
34
|
+
// Read once at import: the version of the code in THIS process, and when it
|
|
35
|
+
// started. See the /health handler for why both matter.
|
|
36
|
+
const PKG_VERSION = await (async () => {
|
|
37
|
+
try {
|
|
38
|
+
const { readFileSync } = await import("node:fs");
|
|
39
|
+
const { fileURLToPath } = await import("node:url");
|
|
40
|
+
const { dirname, join } = await import("node:path");
|
|
41
|
+
const here = dirname(fileURLToPath(import.meta.url));
|
|
42
|
+
return JSON.parse(readFileSync(join(here, "..", "package.json"), "utf8")).version || "unknown";
|
|
43
|
+
} catch {
|
|
44
|
+
// Never let a liveness probe fail over its own labelling.
|
|
45
|
+
return "unknown";
|
|
46
|
+
}
|
|
47
|
+
})();
|
|
48
|
+
const STARTED_AT = new Date().toISOString();
|
|
49
|
+
|
|
34
50
|
// Active sessions
|
|
35
51
|
const transports = {};
|
|
36
52
|
|
|
@@ -213,10 +229,28 @@ export function startHttpServer(port = 3100) {
|
|
|
213
229
|
}
|
|
214
230
|
|
|
215
231
|
// ─── Health check ─────────────────────────────────────────────
|
|
232
|
+
//
|
|
233
|
+
// version + startedAt are the whole point of this probe, not decoration.
|
|
234
|
+
//
|
|
235
|
+
// Without them every field here was TRUE while the agent served seven-day-old
|
|
236
|
+
// code: ok, service, transport and sessions all reported correctly, and not
|
|
237
|
+
// one of them could reveal that the process had been running since Aug 15
|
|
238
|
+
// across ~10 publishes. A liveness probe that cannot answer "is this the code
|
|
239
|
+
// I shipped?" is the truthful-but-useless shape — and a stale server that
|
|
240
|
+
// ANSWERS is worse than one that is down, because its errors describe bugs
|
|
241
|
+
// that were already fixed. (2026-08-22: it returned a 401 from a code path
|
|
242
|
+
// deleted in 2ff2a34, and a session went debugging a system that was correct.)
|
|
243
|
+
//
|
|
244
|
+
// version comes from the package.json NEXT TO THIS FILE, read at import, so it
|
|
245
|
+
// describes the code actually loaded — not what npm has, and not what a
|
|
246
|
+
// container was built with.
|
|
216
247
|
app.get("/health", (_req, res) => {
|
|
217
248
|
res.json({
|
|
218
249
|
ok: true,
|
|
219
250
|
service: "ateam-mcp",
|
|
251
|
+
version: PKG_VERSION,
|
|
252
|
+
startedAt: STARTED_AT,
|
|
253
|
+
uptime_s: Math.round(process.uptime()),
|
|
220
254
|
transport: "http",
|
|
221
255
|
sessions: getSessionStats(),
|
|
222
256
|
});
|
package/src/tools.js
CHANGED
|
@@ -1500,8 +1500,8 @@ export const tools = [
|
|
|
1500
1500
|
description:
|
|
1501
1501
|
"Inspect the full chain tree — the whole run rooted at chain_id, walking down through every handoff and askAnySkill subcall.\n\n" +
|
|
1502
1502
|
"Use when a chain has already run and you want to analyze the structure: which skill called which, how deep the call tree went, which tool inside which job invoked which sub-tool. The two main shapes:\n" +
|
|
1503
|
-
" • response.
|
|
1504
|
-
" • response.
|
|
1503
|
+
" • response.data.chainJobs[] — one entry per job in the chain. Fields: jobId, skill, status, iteration, depth (0 = root, +1 per askAnySkill subcall hop), relation ('root' | 'subcall' | 'handoff'), parentJobId, parentSkill, goal.\n" +
|
|
1504
|
+
" • response.data.executionSteps[] — every tool call across all chain jobs, tagged with _skill, _jobId, _depth (= job depth), _relation, _parentSkill, _parentJobId, _toolDepth (tool-in-tool nesting via opId/parentOpId).\n\n" +
|
|
1505
1505
|
"Differs from ateam_test_status by purpose: status is for live polling of a job you just kicked off; get_chain is for post-hoc tree analysis (debugging multi-skill flows, regression testing, comparing two runs).\n\n" +
|
|
1506
1506
|
"Auth: forwards your authed api_key. Tenant scoped by the key itself. Actor scoping: you can only inspect chains rooted at jobs your actor has access to.",
|
|
1507
1507
|
inputSchema: {
|
|
@@ -2882,6 +2882,30 @@ module.exports.default = plugin;
|
|
|
2882
2882
|
}
|
|
2883
2883
|
|
|
2884
2884
|
|
|
2885
|
+
|
|
2886
|
+
// WHERE THE CHAIN ACTUALLY LIVES IN THE RESPONSE.
|
|
2887
|
+
//
|
|
2888
|
+
// The agent API answers {ok, success, data:{...}}, so the tree is at
|
|
2889
|
+
// data.chainJobs / data.executionSteps — NOT at chain.chainJobs, which is what
|
|
2890
|
+
// ateam_get_chain's own description has been telling readers (and what I wrote
|
|
2891
|
+
// the chain-aware tools against). Reading the wrong path does not throw: it
|
|
2892
|
+
// yields job_count 0, step_count 0, ok:true — a GREEN, EMPTY answer, which is
|
|
2893
|
+
// the single most misleading result this platform can produce and the thing its
|
|
2894
|
+
// own docs warn about. Verified against a live 2-skill chain
|
|
2895
|
+
// (auto-orchestrator -> staff-scheduling): 2 jobs, 3 steps.
|
|
2896
|
+
//
|
|
2897
|
+
// Accepts every wrapping rather than betting on one, so a shape change degrades
|
|
2898
|
+
// to "still finds it" instead of "silently reports an empty run".
|
|
2899
|
+
function chainTreeOf(resp) {
|
|
2900
|
+
const c = resp?.data || resp?.chain || resp || {};
|
|
2901
|
+
const inner = c.chain || c;
|
|
2902
|
+
return {
|
|
2903
|
+
jobs: inner.chainJobs || c.chainJobs || [],
|
|
2904
|
+
steps: inner.executionSteps || c.executionSteps || [],
|
|
2905
|
+
skillChain: inner.skillChain || c.skillChain || [],
|
|
2906
|
+
};
|
|
2907
|
+
}
|
|
2908
|
+
|
|
2885
2909
|
const handlers = {
|
|
2886
2910
|
ateam_bootstrap: async () => ({
|
|
2887
2911
|
runtime: {
|
|
@@ -4398,8 +4422,7 @@ const handlers = {
|
|
|
4398
4422
|
// step across the whole tree — the actual "what ran". (2026-08-22.)
|
|
4399
4423
|
if (!job_id && chain_id) {
|
|
4400
4424
|
const chain = await get(`/deploy/jobs/${encodeURIComponent(chain_id)}/chain`, sid);
|
|
4401
|
-
const jobs = chain
|
|
4402
|
-
const steps = chain?.chain?.executionSteps || [];
|
|
4425
|
+
const { jobs, steps } = chainTreeOf(chain);
|
|
4403
4426
|
return {
|
|
4404
4427
|
ok: true,
|
|
4405
4428
|
scope: "chain",
|
|
@@ -4874,7 +4897,7 @@ const handlers = {
|
|
|
4874
4897
|
// each one, rather than quietly doing a fraction of what it claims.
|
|
4875
4898
|
if (chain_id && !job_id) {
|
|
4876
4899
|
const chain = await get(`/deploy/jobs/${encodeURIComponent(chain_id)}/chain`, sid);
|
|
4877
|
-
const jobs = chain
|
|
4900
|
+
const { jobs } = chainTreeOf(chain);
|
|
4878
4901
|
if (!jobs.length) {
|
|
4879
4902
|
return { ok: false, scope: "chain", chain_id, error: `No jobs found for chain "${chain_id}".`,
|
|
4880
4903
|
hint: "The chain may belong to another solution or another actor. ateam_get_execution_logs(chain_id) shows what is visible to you." };
|
|
@@ -4998,7 +5021,7 @@ const handlers = {
|
|
|
4998
5021
|
// never by silently reporting the root and calling that the chain.
|
|
4999
5022
|
if (!job_id && chain_id) {
|
|
5000
5023
|
const chain = await get(`/deploy/jobs/${encodeURIComponent(chain_id)}/chain`, sid);
|
|
5001
|
-
const jobs = chain
|
|
5024
|
+
const { jobs } = chainTreeOf(chain);
|
|
5002
5025
|
const CAP = 10;
|
|
5003
5026
|
const measured = jobs.slice(0, CAP);
|
|
5004
5027
|
const per_job = [];
|