@ateam-ai/mcp 0.4.73 → 0.4.75
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 +2 -2
- package/src/tools.js +67 -7
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@ateam-ai/mcp",
|
|
3
|
-
"version": "0.4.
|
|
3
|
+
"version": "0.4.75",
|
|
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",
|
|
@@ -13,7 +13,7 @@
|
|
|
13
13
|
"start:http": "node src/index.js --http",
|
|
14
14
|
"dev": "node --watch src/index.js",
|
|
15
15
|
"dev:http": "node --watch src/index.js --http",
|
|
16
|
-
"test": "node test/session-isolation.test.mjs"
|
|
16
|
+
"test": "node test/session-isolation.test.mjs && node test/widget-protocol.test.mjs"
|
|
17
17
|
},
|
|
18
18
|
"keywords": [
|
|
19
19
|
"mcp",
|
package/src/tools.js
CHANGED
|
@@ -239,21 +239,81 @@ function _widgetHasRender(r) {
|
|
|
239
239
|
//
|
|
240
240
|
// Detected here rather than left to a person noticing an empty panel, and
|
|
241
241
|
// reported with the repair attached — a signal the reasoning engine can act on.
|
|
242
|
-
|
|
242
|
+
// Extract the FULL argument object of each postMessage(...) call by matching
|
|
243
|
+
// braces, so every call is judged on its own text. The previous version took a
|
|
244
|
+
// fixed 400-character window and concatenated all of them: a send object longer
|
|
245
|
+
// than the window was inspected in part, and `source:"adas-plugin"` in one call
|
|
246
|
+
// could make an unrelated postMessage elsewhere on the page be judged as the
|
|
247
|
+
// ADAS protocol. Both were rejected in review, correctly — an approximate
|
|
248
|
+
// boundary is not a structural one.
|
|
249
|
+
function _postMessageObjects(html) {
|
|
250
|
+
const out = [];
|
|
251
|
+
const re = /postMessage\s*\(\s*\{/g;
|
|
252
|
+
let m;
|
|
253
|
+
while ((m = re.exec(html)) !== null) {
|
|
254
|
+
const open = html.indexOf("{", m.index);
|
|
255
|
+
let depth = 0, i = open, inStr = null, esc = false;
|
|
256
|
+
for (; i < html.length; i++) {
|
|
257
|
+
const c = html[i];
|
|
258
|
+
if (inStr) {
|
|
259
|
+
if (esc) { esc = false; continue; }
|
|
260
|
+
if (c === "\\") { esc = true; continue; }
|
|
261
|
+
if (c === inStr) inStr = null;
|
|
262
|
+
continue;
|
|
263
|
+
}
|
|
264
|
+
if (c === '"' || c === "'" || c === "`") { inStr = c; continue; }
|
|
265
|
+
if (c === "{") depth++;
|
|
266
|
+
else if (c === "}") { depth--; if (depth === 0) { i++; break; } }
|
|
267
|
+
}
|
|
268
|
+
// Unbalanced (minified truncation, template weirdness) → skip rather than
|
|
269
|
+
// guess. A message we cannot delimit is one we must not judge.
|
|
270
|
+
if (depth === 0) out.push(html.slice(open, i));
|
|
271
|
+
re.lastIndex = Math.max(re.lastIndex, i);
|
|
272
|
+
}
|
|
273
|
+
return out;
|
|
274
|
+
}
|
|
275
|
+
|
|
276
|
+
export function _widgetProtocolProblems(html) {
|
|
243
277
|
if (typeof html !== "string" || !html.includes("postMessage")) return [];
|
|
278
|
+
|
|
244
279
|
const problems = [];
|
|
245
|
-
|
|
246
|
-
|
|
280
|
+
const seen = new Set();
|
|
281
|
+
const add = (p) => { if (!seen.has(p)) { seen.add(p); problems.push(p); } };
|
|
282
|
+
|
|
283
|
+
// Judge each host-directed send INDEPENDENTLY. A page may legitimately
|
|
284
|
+
// postMessage to other targets; only objects that identify themselves as the
|
|
285
|
+
// ADAS plugin channel are the protocol.
|
|
286
|
+
for (const obj of _postMessageObjects(html)) {
|
|
287
|
+
if (!/source\s*:\s*["']adas-plugin["']/.test(obj)) continue;
|
|
288
|
+
|
|
289
|
+
if (/type\s*:\s*["']tool\.call["']/.test(obj)) {
|
|
290
|
+
add('sends message.type:"tool.call" — the host has NEVER accepted it, at any version (silent timeout, no error). Send message:{action:"mcp-call",payload:{requestId,connectorId,tool,args}}.');
|
|
291
|
+
} else if (!/action\s*:\s*["']mcp-call["']/.test(obj)) {
|
|
292
|
+
if (/type\s*:\s*["']mcp-call["']/.test(obj)) {
|
|
293
|
+
add('sends message.TYPE:"mcp-call" — the host matches on message.ACTION for sends, so this is ignored. Use message:{action:"mcp-call",payload:{...}}.');
|
|
294
|
+
} else {
|
|
295
|
+
add('never sends action:"mcp-call" — the host ignores the message entirely.');
|
|
296
|
+
}
|
|
297
|
+
}
|
|
298
|
+
if (/payload\s*:\s*\{[^}]*correlationId/.test(obj) || /correlationId\s*:\s*correlationId/.test(obj)) {
|
|
299
|
+
add('sends the request id as correlationId — the host echoes payload.requestId, so responses never match the pending request and every call times out even when the host answered.');
|
|
300
|
+
}
|
|
247
301
|
}
|
|
248
|
-
|
|
249
|
-
|
|
302
|
+
|
|
303
|
+
// RECEIVE side: only reading correlationId OFF THE HOST PAYLOAD counts.
|
|
304
|
+
if (/payload\s*(\?\.|\.)\s*correlationId/.test(html) ||
|
|
305
|
+
/payload\s*&&\s*[\w$.]*payload\.correlationId/.test(html) ||
|
|
306
|
+
/\{\s*correlationId[^}]*\}\s*=\s*[\w$.]*payload/.test(html)) {
|
|
307
|
+
add('reads payload.correlationId from the host response — the host sends payload.requestId, so the pending request is never matched.');
|
|
250
308
|
}
|
|
251
|
-
if (/
|
|
252
|
-
|
|
309
|
+
if (/type\s*===?\s*["']tool\.response["']/.test(html)) {
|
|
310
|
+
add('listens for message.type:"tool.response" — the host replies with "mcp-result".');
|
|
253
311
|
}
|
|
312
|
+
|
|
254
313
|
return problems;
|
|
255
314
|
}
|
|
256
315
|
|
|
316
|
+
|
|
257
317
|
async function verifyWidgetHealth(solution_id, sid) {
|
|
258
318
|
// 1. Declared plugins — solution.ui_plugins[]
|
|
259
319
|
let declared = [];
|