@ateam-ai/mcp 0.4.77 → 0.4.78
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 +24 -0
- package/src/tools.js +24 -1
package/package.json
CHANGED
package/src/api.js
CHANGED
|
@@ -487,6 +487,30 @@ function formatError(method, path, status, body, baseUrl) {
|
|
|
487
487
|
503: "A-Team API is temporarily unavailable. Try again in a minute.",
|
|
488
488
|
};
|
|
489
489
|
|
|
490
|
+
// A 401 IS NOT ALWAYS AN AUTH PROBLEM, AND SAYING SO COSTS A RUN.
|
|
491
|
+
//
|
|
492
|
+
// The table below attaches "your API key may be invalid or expired — get a
|
|
493
|
+
// new key and call ateam_auth" to EVERY 401, by status code, never by cause.
|
|
494
|
+
// Core also returns 401 for `Actor "X" not found`, where the key is perfectly
|
|
495
|
+
// valid and the actor is the problem. A PROD agent believed that hint this
|
|
496
|
+
// morning, stopped, and asked the admin to paste an API key — for an error
|
|
497
|
+
// that had nothing to do with keys. An error naming the wrong remedy does not
|
|
498
|
+
// just fail; it sends someone competent in the wrong direction.
|
|
499
|
+
if (status === 401) {
|
|
500
|
+
const t = typeof body === "string"
|
|
501
|
+
? body
|
|
502
|
+
: (() => { try { return JSON.stringify(body || ""); } catch { return ""; } })();
|
|
503
|
+
const m = /Actor\s+\\?"([^"\\]+)\\?"\s+not found|unknown actor\s+\\?"?([^"\\,}]+)/i.exec(t);
|
|
504
|
+
if (m) {
|
|
505
|
+
const who = (m[1] || m[2] || "").trim();
|
|
506
|
+
hints[401] =
|
|
507
|
+
`NOT an auth problem — your key is fine. Core does not recognise the ACTOR "${who}" in this tenant. ` +
|
|
508
|
+
`Re-authenticating will not help. Either pass a real actor id (the one ateam_conversation returned for the thread), ` +
|
|
509
|
+
`or omit the actor entirely to act as the tenant. If you never sent an actor, the session is bound to a stale one: ` +
|
|
510
|
+
`call ateam_auth again to reset the session binding.`;
|
|
511
|
+
}
|
|
512
|
+
}
|
|
513
|
+
|
|
490
514
|
// A 500 THAT NAMES A MISSING CONFIGURATION IS NOT "TRY AGAIN IN A MINUTE".
|
|
491
515
|
//
|
|
492
516
|
// /chat answered 500 {"message":"OPENAI_API_KEY is not set"} and this table
|
package/src/tools.js
CHANGED
|
@@ -19,6 +19,17 @@ import {
|
|
|
19
19
|
// (tenant + the app URL to view the change). ateam-mcp is a PUBLIC MCP used
|
|
20
20
|
// from non-desktop clients too, so the location must live IN the tool result
|
|
21
21
|
// — not only in a desktop plugin's SKILL.md. Read-only/global tools skip it.
|
|
22
|
+
// Tools that START a run and therefore MINT the actor that ran it. Only these
|
|
23
|
+
// may rebind the session's actor — see the call site for what accepting it from
|
|
24
|
+
// any result cost.
|
|
25
|
+
const ACTOR_MINTING_TOOLS = new Set([
|
|
26
|
+
"ateam_conversation",
|
|
27
|
+
"ateam_test_skill",
|
|
28
|
+
"ateam_solution_chat",
|
|
29
|
+
"ateam_test_pipeline",
|
|
30
|
+
"ateam_test_voice",
|
|
31
|
+
]);
|
|
32
|
+
|
|
22
33
|
const STAMP_WHERE_TOOLS = new Set([
|
|
23
34
|
"ateam_build_and_run", "ateam_patch", "ateam_upload_connector", "ateam_redeploy",
|
|
24
35
|
"ateam_create_skill", "ateam_create_connector", "ateam_create_plugin",
|
|
@@ -6129,7 +6140,19 @@ export async function handleToolCall(name, args, sessionId) {
|
|
|
6129
6140
|
// it on the way out so the follow-up ateam_get_execution_logs /
|
|
6130
6141
|
// ateam_get_metrics on that very job is not refused for not knowing who ran
|
|
6131
6142
|
// it — the single most common dead end when debugging a run.
|
|
6132
|
-
|
|
6143
|
+
//
|
|
6144
|
+
// ONLY FROM TOOLS THAT ACTUALLY MINT ONE. This used to accept `actor_id` off
|
|
6145
|
+
// ANY tool's result, so a single unrelated payload carrying that field
|
|
6146
|
+
// silently repointed the whole session — observed on a clean e2e where every
|
|
6147
|
+
// later call 401'd with `Actor "dev" not found`, from an agent that had
|
|
6148
|
+
// never sent an actor at all. A session that binds to a non-existent actor
|
|
6149
|
+
// never recovers on its own, because nothing ever unbinds it.
|
|
6150
|
+
//
|
|
6151
|
+
// The generated-thread-key filter in api.js does not help here: it rejects
|
|
6152
|
+
// test_<ts>_<rand>, and a short literal like "dev" walks straight past it.
|
|
6153
|
+
// An allow-list of minting tools is the honest boundary — "who ran this job"
|
|
6154
|
+
// is knowledge only the tools that START a job possess.
|
|
6155
|
+
if (result && typeof result === "object" && result.actor_id && ACTOR_MINTING_TOOLS.has(name)) {
|
|
6133
6156
|
touchSession(sessionId, { actorId: result.actor_id });
|
|
6134
6157
|
}
|
|
6135
6158
|
|