@ateam-ai/mcp 0.4.53 → 0.4.58
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 +133 -2
package/package.json
CHANGED
package/src/tools.js
CHANGED
|
@@ -512,6 +512,19 @@ export const tools = [
|
|
|
512
512
|
{
|
|
513
513
|
name: "ateam_design_advisor",
|
|
514
514
|
core: true,
|
|
515
|
+
// MEASURED, not estimated. 6 successful calls against dev on 2026-08-21,
|
|
516
|
+
// distinct goals, spaced to avoid provider rate-limiting:
|
|
517
|
+
// 19048 21123 23359 23739 24462 24699 ms (median 23.7s, max 24.7s)
|
|
518
|
+
// It is ONE LLM call over the capability catalog, so the cost is provider
|
|
519
|
+
// latency and there is no meaningful warm path to under-report.
|
|
520
|
+
//
|
|
521
|
+
// WHY IT MATTERS: Core derives its timeout from this (p95 x 4, floored at
|
|
522
|
+
// 30s). Undeclared, the advisor sat under a 30s default while taking ~25s —
|
|
523
|
+
// one bad provider spike from failing, and it failed exactly that way on
|
|
524
|
+
// 2026-08-21 ("HTTP connector timeout after 30000ms"). It is also the FIRST
|
|
525
|
+
// call a building agent makes and it carries the storage decision, so when
|
|
526
|
+
// it times out the run proceeds with no capability guidance at all.
|
|
527
|
+
monitoring: { safe: true, cost: "normal", latency_ms_p95: 25000, output: "bounded" },
|
|
515
528
|
description:
|
|
516
529
|
"CONSULT THIS DURING DESIGN — before and while you design a skill/solution. Describe what you're building; it returns POINTERS to the platform capabilities that fit (per-actor storage, widgets, triggers, sub-agents, mobile data, run-scripts, multi-skill, GitHub, …), each with the /spec topic to read next (via ateam_get_spec) and the tool to wire it. Also returns 'missing' hints (capabilities your goal implies but the design hasn't wired) and lifecycle hints (e.g. connect GitHub when the project will iterate). ADVISORY ONLY — you decide and own the design. Stateless: pass the current design_state each call; consult it as often as you like as the design evolves.",
|
|
517
530
|
inputSchema: {
|
|
@@ -1017,6 +1030,59 @@ export const tools = [
|
|
|
1017
1030
|
},
|
|
1018
1031
|
},
|
|
1019
1032
|
|
|
1033
|
+
{
|
|
1034
|
+
name: "ateam_log_lesson",
|
|
1035
|
+
core: true,
|
|
1036
|
+
description:
|
|
1037
|
+
"Record ONE lesson this run learned, so the NEXT run does not relearn it. " +
|
|
1038
|
+
"A building agent starts every run empty — it does not know which tool " +
|
|
1039
|
+
"misled the last run or the workaround that got past it. Log a lesson the " +
|
|
1040
|
+
"moment a tool misleads you AND you find a way through.\n\n" +
|
|
1041
|
+
"APPEND-ONLY. You cannot edit or delete earlier lessons, and you do not " +
|
|
1042
|
+
"supply the timestamp, job or actor — the server stamps those.\n\n" +
|
|
1043
|
+
"LOG ONLY WHAT YOU OBSERVED. Quote the error VERBATIM; never paraphrase it " +
|
|
1044
|
+
"and never write a theory about platform internals. A wrong lesson is worse " +
|
|
1045
|
+
"than no lesson, because the next run cannot check it and will act on it.\n\n" +
|
|
1046
|
+
"Use kind='misleading_success' when a call REPORTED success while the thing " +
|
|
1047
|
+
"you wanted did not happen — that class is the most expensive to rediscover " +
|
|
1048
|
+
"and it is invisible to a failures-only log.",
|
|
1049
|
+
inputSchema: {
|
|
1050
|
+
type: "object",
|
|
1051
|
+
properties: {
|
|
1052
|
+
solution_id: { type: "string", description: "The solution this lesson belongs to" },
|
|
1053
|
+
tool: { type: "string", description: "The tool that misled you, e.g. \"ateam_build_and_run\"" },
|
|
1054
|
+
error: { type: "string", description: "The VERBATIM error or failed_steps fragment. Not a paraphrase." },
|
|
1055
|
+
workaround: { type: "string", description: "What you did instead (optional)" },
|
|
1056
|
+
worked: { type: "boolean", description: "Did the workaround work? Omit if you never found out — 'unknown' is a real answer" },
|
|
1057
|
+
kind: {
|
|
1058
|
+
type: "string",
|
|
1059
|
+
enum: ["failure", "surprise", "misleading_success"],
|
|
1060
|
+
description: "failure = it errored; surprise = it worked but not as documented; misleading_success = it REPORTED success while the intended effect did not happen",
|
|
1061
|
+
},
|
|
1062
|
+
},
|
|
1063
|
+
required: ["solution_id", "tool", "error"],
|
|
1064
|
+
},
|
|
1065
|
+
},
|
|
1066
|
+
|
|
1067
|
+
{
|
|
1068
|
+
name: "ateam_get_lessons",
|
|
1069
|
+
core: true,
|
|
1070
|
+
description:
|
|
1071
|
+
"Read what EARLIER runs on this solution learned — newest first, bounded. " +
|
|
1072
|
+
"Call this during orientation, BEFORE planning: it is the only thing that " +
|
|
1073
|
+
"carries context across runs, and it is cheap. Each entry says which tool " +
|
|
1074
|
+
"misled a previous run, the verbatim error, what was tried instead, and " +
|
|
1075
|
+
"whether that worked. An empty list is a real answer (nothing learned yet).",
|
|
1076
|
+
inputSchema: {
|
|
1077
|
+
type: "object",
|
|
1078
|
+
properties: {
|
|
1079
|
+
solution_id: { type: "string", description: "The solution ID" },
|
|
1080
|
+
limit: { type: "number", description: "Max entries, newest first (default 20)" },
|
|
1081
|
+
},
|
|
1082
|
+
required: ["solution_id"],
|
|
1083
|
+
},
|
|
1084
|
+
},
|
|
1085
|
+
|
|
1020
1086
|
{
|
|
1021
1087
|
name: "ateam_create_connector",
|
|
1022
1088
|
core: true,
|
|
@@ -2287,7 +2353,22 @@ function toText(data) { return { content: [{ type: "text", text: JSON.stringify(
|
|
|
2287
2353
|
// into the call args; refuse to operate without it (prevents cross-actor leaks).
|
|
2288
2354
|
function getActorId(args) {
|
|
2289
2355
|
const id = args?._adas_actor;
|
|
2290
|
-
|
|
2356
|
+
// Name BOTH causes. "actor context missing" reads as "Core did not send it",
|
|
2357
|
+
// and that misreading cost a full day on 2026-08-20: Core HAD injected it and
|
|
2358
|
+
// the connector's own schema validation stripped it, because that one tool's
|
|
2359
|
+
// inputSchema omitted _adas_actor. An MCP server drops arguments a tool did
|
|
2360
|
+
// not declare, so the field vanishes silently — and only on the tools that
|
|
2361
|
+
// forgot it, which is why read tools kept working and the first write failed.
|
|
2362
|
+
if (!id) {
|
|
2363
|
+
throw new Error(
|
|
2364
|
+
"${connectorId}: no actor context — _adas_actor missing. TWO possible causes: " +
|
|
2365
|
+
"(1) this tool's inputSchema does not DECLARE _adas_actor, so MCP stripped it " +
|
|
2366
|
+
"before your handler ran — add it to inputSchema.properties (see toolSchemas() " +
|
|
2367
|
+
"below, every data tool must spread ...actor); or " +
|
|
2368
|
+
"(2) the caller is not actor-scoped — ateam_test_connector runs as _system_service, " +
|
|
2369
|
+
"so use ateam_test_skill or a real conversation to exercise per-user tools."
|
|
2370
|
+
);
|
|
2371
|
+
}
|
|
2291
2372
|
return id;
|
|
2292
2373
|
}
|
|
2293
2374
|
${uiCapable ? `
|
|
@@ -2317,6 +2398,13 @@ function discoverPlugins() {
|
|
|
2317
2398
|
// ── Tool definitions ── Core reads this list. A tool named "ui.listPlugins"
|
|
2318
2399
|
// is how Core knows this connector is UI-capable.
|
|
2319
2400
|
function toolSchemas() {
|
|
2401
|
+
// MUST be spread into the inputSchema.properties of EVERY per-actor tool.
|
|
2402
|
+
// Not decoration: MCP strips arguments a tool did not declare, so a tool that
|
|
2403
|
+
// omits these gets them removed before the handler runs and getActorId()
|
|
2404
|
+
// throws — while the tools that DID declare them keep working. The result is
|
|
2405
|
+
// a connector that looks healthy (deploys, lists tools, answers reads) and
|
|
2406
|
+
// fails on the first write. Do not "fix" that with a default actor id: one
|
|
2407
|
+
// shared actor pools every user's data.
|
|
2320
2408
|
const actor = { _adas_actor: { type: "string" }, _adas_tenant: { type: "string" } };
|
|
2321
2409
|
return [
|
|
2322
2410
|
{
|
|
@@ -2340,7 +2428,33 @@ async function handle(req) {
|
|
|
2340
2428
|
|
|
2341
2429
|
if (method === "tools/call") {
|
|
2342
2430
|
const name = params?.name;
|
|
2343
|
-
|
|
2431
|
+
// CALLER CONTEXT COMES FROM THE ENVELOPE FIRST.
|
|
2432
|
+
//
|
|
2433
|
+
// Core sends identity two ways: as _adas_* ARGUMENTS, and on params._meta
|
|
2434
|
+
// beside the arguments object. The argument channel is fragile — a server drops
|
|
2435
|
+
// arguments a tool did not declare, so a tool whose inputSchema omits
|
|
2436
|
+
// _adas_actor loses it silently and only per-user WRITES fail, while reads
|
|
2437
|
+
// keep working. The envelope cannot be stripped: it is not part of the
|
|
2438
|
+
// validated argument object.
|
|
2439
|
+
//
|
|
2440
|
+
// This server reads params directly (no SDK zod validation), so _meta is
|
|
2441
|
+
// simply available — no wrapper, no callback plumbing. Merge it UNDER args
|
|
2442
|
+
// so an explicitly declared argument still wins, which keeps a delegation
|
|
2443
|
+
// tool's own actor_id PARAMETER untouched: caller identity is transport,
|
|
2444
|
+
// subject identity is payload, and they must not collide.
|
|
2445
|
+
//
|
|
2446
|
+
// ONLY the _adas_ prefix. _meta is the MCP envelope's OWN namespace, not
|
|
2447
|
+
// ours — the spec puts progressToken in there, and clients that request
|
|
2448
|
+
// progress send it on every call. Spreading the whole envelope would hand a
|
|
2449
|
+
// transport token to tools as a user argument: schemas with
|
|
2450
|
+
// additionalProperties:false would start rejecting previously-valid calls,
|
|
2451
|
+
// tools that log or persist their arguments would record it as user data,
|
|
2452
|
+
// and a future _meta key colliding with a real parameter name would
|
|
2453
|
+
// overwrite it. Read the namespace we own; do not treat the envelope as input.
|
|
2454
|
+
const ctx = Object.fromEntries(
|
|
2455
|
+
Object.entries(params?._meta || {}).filter(([k]) => k.startsWith("_adas_")),
|
|
2456
|
+
);
|
|
2457
|
+
const args = { ...ctx, ...(params?.arguments || {}) };
|
|
2344
2458
|
try {
|
|
2345
2459
|
${uiCapable ? ` // ── UI registry plumbing (no actor required) ──
|
|
2346
2460
|
if (name === "ui.listPlugins") {
|
|
@@ -4954,6 +5068,23 @@ const handlers = {
|
|
|
4954
5068
|
};
|
|
4955
5069
|
},
|
|
4956
5070
|
|
|
5071
|
+
ateam_log_lesson: async ({ solution_id, tool, error, workaround, worked, kind }, sid) => {
|
|
5072
|
+
if (!solution_id) throw new Error("solution_id required");
|
|
5073
|
+
if (!tool) throw new Error("tool required — the tool that misled you");
|
|
5074
|
+
if (!error) throw new Error("error required — quote it VERBATIM, do not paraphrase");
|
|
5075
|
+
return await post(
|
|
5076
|
+
`/deploy/solutions/${solution_id}/lessons`,
|
|
5077
|
+
{ tool, error, workaround, worked, kind },
|
|
5078
|
+
sid,
|
|
5079
|
+
);
|
|
5080
|
+
},
|
|
5081
|
+
|
|
5082
|
+
ateam_get_lessons: async ({ solution_id, limit }, sid) => {
|
|
5083
|
+
if (!solution_id) throw new Error("solution_id required");
|
|
5084
|
+
const qs = Number.isFinite(limit) ? `?limit=${limit}` : "";
|
|
5085
|
+
return await get(`/deploy/solutions/${solution_id}/lessons${qs}`, sid);
|
|
5086
|
+
},
|
|
5087
|
+
|
|
4957
5088
|
ateam_show_solution_minimal: async ({ solution_id }, sid) => {
|
|
4958
5089
|
if (!solution_id) throw new Error("solution_id required");
|
|
4959
5090
|
const full = await get(`/deploy/solutions/${solution_id}/definition`, sid);
|