@ateam-ai/mcp 0.4.81 → 0.4.83

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 CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ateam-ai/mcp",
3
- "version": "0.4.81",
3
+ "version": "0.4.83",
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 && node test/widget-protocol.test.mjs && node test/actor-binding.test.mjs"
16
+ "test": "node test/session-isolation.test.mjs && node test/widget-protocol.test.mjs && node test/actor-binding.test.mjs && node test/spec-topics.test.mjs"
17
17
  },
18
18
  "keywords": [
19
19
  "mcp",
package/src/api.js CHANGED
@@ -493,8 +493,11 @@ function headers(sessionId) {
493
493
 
494
494
  /**
495
495
  * Format an API error into a user-friendly message with actionable hints.
496
+ *
497
+ * Exported so the hints can be TESTED as behaviour rather than as source text.
498
+ * A test that greps for the right-looking code passes on code that never runs.
496
499
  */
497
- function formatError(method, path, status, body, baseUrl) {
500
+ export function formatError(method, path, status, body, baseUrl) {
498
501
  const hints = {
499
502
  400: "Bad request — see the error details above for what to fix.",
500
503
  401: "Your API key may be invalid or expired. Get a valid key at https://mcp.ateam-ai.com/get-api-key then call ateam_auth(api_key: \"your_key\").",
@@ -532,6 +535,23 @@ function formatError(method, path, status, body, baseUrl) {
532
535
  }
533
536
  }
534
537
 
538
+ // A 404 ON /spec IS NOT A MISSING SOLUTION.
539
+ //
540
+ // The table answers every 404 with "check the solution_id or skill_id".
541
+ // /spec/* takes neither. Asking for a topic this deployment does not serve —
542
+ // which happens the moment the tool ships ahead of the backend, as
543
+ // device-capabilities did on 2026-09-04 — sent the reader looking for a
544
+ // solution that was never involved. The environment is the whole answer, so
545
+ // name it: the same call against a newer deployment succeeds.
546
+ if (status === 404 && /^\/spec(\/|$)/.test(String(path || ""))) {
547
+ const topic = String(path).replace(/^\/spec\/?/, "") || "(index)";
548
+ hints[404] =
549
+ `Nothing to do with solutions — /spec takes no solution_id or skill_id. The A-Team API at ` +
550
+ `${baseUrl || "this URL"} does not serve the topic "${topic}". Either the topic name is wrong (ateam_get_spec ` +
551
+ `with topic:"overview" lists what this deployment has), or this backend is OLDER than the tool you are ` +
552
+ `calling from and the topic has not been deployed here yet. Retrying will not change either.`;
553
+ }
554
+
535
555
  // A 500 THAT NAMES A MISSING CONFIGURATION IS NOT "TRY AGAIN IN A MINUTE".
536
556
  //
537
557
  // /chat answered 500 {"message":"OPENAI_API_KEY is not set"} and this table
package/src/tools.js CHANGED
@@ -594,9 +594,9 @@ export const tools = [
594
594
  properties: {
595
595
  topic: {
596
596
  type: "string",
597
- enum: ["overview", "skill", "solution", "enums", "connector-multi-user", "python_helpers", "widgets", "ui-plugins", "actor-storage", "voice", "voice-native", "triggers", "sub-agent", "consumer-roles", "mobile-connector", "monitoring"],
597
+ enum: ["overview", "skill", "solution", "enums", "connector-multi-user", "python_helpers", "widgets", "ui-plugins", "actor-storage", "voice", "voice-native", "triggers", "sub-agent", "consumer-roles", "mobile-connector", "device-capabilities", "monitoring"],
598
598
  description:
599
- "What to fetch: 'overview' = API overview + endpoints, 'skill' = full skill spec, 'solution' = full solution spec, 'enums' = all enum values, 'connector-multi-user' = multi-user connector guide, 'python_helpers' = adas.* helper namespace for run_python_script orchestration (read this when designing personas that read state → call tools → checkpoint → status; without it, scripts hand-roll JSON parsing and tool delegation = 5-10x larger and brittler), 'widgets' = widget (UI plugin) spec: catalog model, how_to_use block shape (solution.json snippet + opener_call + persona_phrasing + binding_notes), and rules for declaring ui_plugins. Pair with ateam_get_widget_catalog for the live per-tenant inventory. 'ui-plugins' = the DEEP React Native (mobile) plugin build guide: author in rn-src/, compile with a build:rn esbuild script (format=cjs, target=es2015, external react/react-native/@adas/plugin-sdk) to rn-bundle/index.bundle.js, plain-object export — read this before authoring any MOBILE widget. 'monitoring' = THE MONITORING CONTRACT: which tools are safe to call in a poll loop (with cost / poll interval / whether output stays bounded as the run grows), which are not and what to use instead, plus the running ateam-mcp version. Read this BEFORE writing any loop that watches a build — the safe poll is ateam_chain_status, never ateam_get_chain.",
599
+ "What to fetch: 'overview' = API overview + endpoints, 'skill' = full skill spec, 'solution' = full solution spec, 'enums' = all enum values, 'connector-multi-user' = multi-user connector guide, 'python_helpers' = adas.* helper namespace for run_python_script orchestration (read this when designing personas that read state → call tools → checkpoint → status; without it, scripts hand-roll JSON parsing and tool delegation = 5-10x larger and brittler), 'widgets' = widget (UI plugin) spec: catalog model, how_to_use block shape (solution.json snippet + opener_call + persona_phrasing + binding_notes), and rules for declaring ui_plugins. Pair with ateam_get_widget_catalog for the live per-tenant inventory. 'ui-plugins' = the DEEP React Native (mobile) plugin build guide: author in rn-src/, compile with a build:rn esbuild script (format=cjs, target=es2015, external react/react-native/@adas/plugin-sdk) to rn-bundle/index.bundle.js, plain-object export — read this before authoring any MOBILE widget. 'device-capabilities' = THE DEVICE CAPABILITY MATRIX, GENERATED from the mobile SDK's own artefacts and stamped with their hashes: every native.* API (mechanical one-shot verbs), every deviceState.* domain (semantic state a reasoning loop reads, with freshness + confidence) and every server-called device.* tool, each with status (done / partial / shape-only / missing) and what is left. READ THIS before concluding the phone cannot do something — camera, video, scanning, vision, sensors, location, on-device storage. Absence from any other spec topic is NOT evidence. 'monitoring' = THE MONITORING CONTRACT: which tools are safe to call in a poll loop (with cost / poll interval / whether output stays bounded as the run grows), which are not and what to use instead, plus the running ateam-mcp version. Read this BEFORE writing any loop that watches a build — the safe poll is ateam_chain_status, never ateam_get_chain.",
600
600
  },
601
601
  section: {
602
602
  type: "string",
@@ -2497,6 +2497,10 @@ const SPEC_PATHS = {
2497
2497
  "sub-agent": "/spec/sub-agent",
2498
2498
  "consumer-roles": "/spec/consumer-roles",
2499
2499
  "mobile-connector": "/spec/mobile-connector",
2500
+ // GENERATED from the mobile SDK's own contract + status doc, not written by
2501
+ // hand: the hand-written version drifted in 19 days and a builder designed
2502
+ // away from a capability that had shipped.
2503
+ "device-capabilities": "/spec/device-capabilities",
2500
2504
  };
2501
2505
 
2502
2506
  const EXAMPLE_PATHS = {