@ateam-ai/mcp 0.4.45 → 0.4.47
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/api.js +14 -8
- package/src/tools.js +16 -3
package/package.json
CHANGED
package/src/api.js
CHANGED
|
@@ -467,14 +467,14 @@ function formatError(method, path, status, body, baseUrl) {
|
|
|
467
467
|
// the caller as a bare "returned 422", throwing away the very thing it was
|
|
468
468
|
// asked to produce. Serialize objects too, capped the same way.
|
|
469
469
|
let detail = "";
|
|
470
|
-
|
|
471
|
-
|
|
472
|
-
|
|
473
|
-
|
|
474
|
-
|
|
475
|
-
|
|
476
|
-
|
|
477
|
-
|
|
470
|
+
const asText = typeof body === "string"
|
|
471
|
+
? body
|
|
472
|
+
: (body && typeof body === "object" ? (() => { try { return JSON.stringify(body); } catch { return ""; } })() : "");
|
|
473
|
+
if (asText.length > 0) {
|
|
474
|
+
// Previously a body of 2000+ chars was dropped ENTIRELY, so the richer the
|
|
475
|
+
// error the less the caller was told — a 422 carrying the full diagnosis
|
|
476
|
+
// arrived as a bare status code. Truncate instead of discarding.
|
|
477
|
+
detail = asText.length < 2000 ? asText : asText.slice(0, 2000) + "… (truncated)";
|
|
478
478
|
}
|
|
479
479
|
|
|
480
480
|
// Always show the FULL URL actually hit — ateam-mcp is a PUBLIC MCP with a
|
|
@@ -539,6 +539,12 @@ async function request(method, path, body, sessionId, opts = {}) {
|
|
|
539
539
|
// on this to NOT scaffold-clobber an existing skill on a read error.
|
|
540
540
|
const e = new Error(formatError(method, path, res.status, text, baseUrl));
|
|
541
541
|
e.status = res.status;
|
|
542
|
+
// Keep the RAW body on the error. formatError truncates for humans, and
|
|
543
|
+
// an endpoint that answers 4xx WITH the diagnosis (ui.surfaceProbe's 422
|
|
544
|
+
// carries the failures explaining why a surface is broken) is exactly the
|
|
545
|
+
// case where the body matters more than the status. A caller that knows
|
|
546
|
+
// how to read its own error shape should not have to scrape a message.
|
|
547
|
+
e.body = text;
|
|
542
548
|
throw e;
|
|
543
549
|
}
|
|
544
550
|
|
package/src/tools.js
CHANGED
|
@@ -2168,6 +2168,20 @@ function _scaffoldConnectorFiles({ connectorId, displayName, uiCapable }) {
|
|
|
2168
2168
|
//
|
|
2169
2169
|
// Fill in your real tools below (see TOOLS + the tools/call dispatch). The
|
|
2170
2170
|
// JSON-RPC framing, actor isolation, stdio loop${uiCapable ? ", and ui-dist plugin discovery" : ""} are template-provided.
|
|
2171
|
+
//
|
|
2172
|
+
// ⚠️ NEVER SWALLOW A FAILURE. If something this tool depends on fails — a fetch,
|
|
2173
|
+
// a platform call, a store read — RETURN THE ERROR. Do not catch it and answer
|
|
2174
|
+
// with empty data:
|
|
2175
|
+
//
|
|
2176
|
+
// BAD: try { rows = await load(); } catch { rows = []; } // renders 0.00 forever
|
|
2177
|
+
// GOOD: try { rows = await load(); }
|
|
2178
|
+
// catch (e) { return toText({ ok: false, error: String(e.message || e) }); }
|
|
2179
|
+
//
|
|
2180
|
+
// A tool that returns ok:true with an empty result when its dependency is broken
|
|
2181
|
+
// is INDISTINGUISHABLE from one that genuinely has no data — to the widget, to
|
|
2182
|
+
// the person reading the screen, and to the agent trying to fix it. That exact
|
|
2183
|
+
// shape cost a full day: a connector caught a 401, returned an empty ledger, and
|
|
2184
|
+
// the dashboard showed 0.00 while every check reported success.
|
|
2171
2185
|
${uiCapable ? `
|
|
2172
2186
|
import { readdirSync, readFileSync, existsSync } from "node:fs";
|
|
2173
2187
|
import { fileURLToPath } from "node:url";
|
|
@@ -4047,10 +4061,9 @@ const handlers = {
|
|
|
4047
4061
|
// generic error path turned into "returned 422" — hiding the failures that
|
|
4048
4062
|
// say WHY the screen is broken, and leaving the caller as blind as before
|
|
4049
4063
|
// it ran the probe. Hand the verdict back as a result instead of throwing.
|
|
4050
|
-
|
|
4051
|
-
if (m) {
|
|
4064
|
+
if (typeof err?.body === "string" && err.body) {
|
|
4052
4065
|
try {
|
|
4053
|
-
const parsed = JSON.parse(
|
|
4066
|
+
const parsed = JSON.parse(err.body);
|
|
4054
4067
|
if (parsed && (parsed.verdict || Array.isArray(parsed.failures))) return parsed;
|
|
4055
4068
|
} catch { /* not the probe's body — fall through */ }
|
|
4056
4069
|
}
|