@ateam-ai/mcp 0.3.55 → 0.3.57
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 +150 -21
package/package.json
CHANGED
package/src/tools.js
CHANGED
|
@@ -131,15 +131,15 @@ export const tools = [
|
|
|
131
131
|
name: "ateam_get_spec",
|
|
132
132
|
core: true,
|
|
133
133
|
description:
|
|
134
|
-
"Get the A-Team specification — schemas, validation rules, system tools, agent guides, and templates. Start here after bootstrap to understand how to build skills and solutions. Use 'section' to get just one part of the skill spec (much smaller than the full spec). Use 'search' to find specific fields or concepts across the spec.\n\nWhen designing a persona that orchestrates logic via run_python_script (the Python-as-orchestrator pattern), also fetch topic='python_helpers' — that returns the adas.* helper namespace reference. Skills designed without knowing about adas.* produce 5-10x larger / brittler scripts.",
|
|
134
|
+
"Get the A-Team specification — schemas, validation rules, system tools, agent guides, and templates. Start here after bootstrap to understand how to build skills and solutions. Use 'section' to get just one part of the skill spec (much smaller than the full spec). Use 'search' to find specific fields or concepts across the spec.\n\nWhen designing a persona that orchestrates logic via run_python_script (the Python-as-orchestrator pattern), also fetch topic='python_helpers' — that returns the adas.* helper namespace reference. Skills designed without knowing about adas.* produce 5-10x larger / brittler scripts.\n\nWhen wiring widgets (UI plugins) into a solution, fetch topic='widgets' — that returns the widget spec (catalog model, how_to_use blocks, opener_call shape, persona phrasing rules, binding semantics) so you can declare `ui_plugins` correctly. For the live catalog of widgets actually available in a deployed tenant, use ateam_get_widget_catalog instead.",
|
|
135
135
|
inputSchema: {
|
|
136
136
|
type: "object",
|
|
137
137
|
properties: {
|
|
138
138
|
topic: {
|
|
139
139
|
type: "string",
|
|
140
|
-
enum: ["overview", "skill", "solution", "enums", "connector-multi-user", "python_helpers"],
|
|
140
|
+
enum: ["overview", "skill", "solution", "enums", "connector-multi-user", "python_helpers", "widgets"],
|
|
141
141
|
description:
|
|
142
|
-
"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).",
|
|
142
|
+
"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.",
|
|
143
143
|
},
|
|
144
144
|
section: {
|
|
145
145
|
type: "string",
|
|
@@ -673,18 +673,16 @@ export const tools = [
|
|
|
673
673
|
name: "ateam_upload_connector",
|
|
674
674
|
core: true,
|
|
675
675
|
description:
|
|
676
|
-
"Upload connector code to Core and restart — WITHOUT redeploying skills
|
|
677
|
-
"
|
|
678
|
-
"
|
|
679
|
-
"
|
|
680
|
-
"
|
|
681
|
-
"
|
|
682
|
-
"
|
|
683
|
-
"
|
|
684
|
-
"
|
|
685
|
-
"
|
|
686
|
-
"STALE. Either promote first (ateam_github_promote dev→main) then github=true, or pass `files` " +
|
|
687
|
-
"directly for a dev-only deploy.",
|
|
676
|
+
"Upload connector code to Core and restart — WITHOUT redeploying skills.\n\n" +
|
|
677
|
+
"MERGES with the GitHub state at `ref` by default (default ref: 'dev'). Sending a partial file set ONLY overlays those files — the rest of the connector is preserved from GitHub. To fully replace the connector dir (historical behavior), pass replace:true.\n\n" +
|
|
678
|
+
"Modes:\n" +
|
|
679
|
+
" • github:true (no files) — deploy the GitHub state at `ref` as-is.\n" +
|
|
680
|
+
" • github:true + files:[] — GitHub state at `ref` as BASE, your files overlay on top (incoming wins).\n" +
|
|
681
|
+
" • files:[] (no github) — default MERGE with GitHub state at `ref`. Refuses if no GitHub base exists (no silent nuke).\n" +
|
|
682
|
+
" • files:[] + replace:true — full replace. Wipes connector dir + writes only the provided files. Use deliberately.\n\n" +
|
|
683
|
+
"Common traps this design prevents:\n" +
|
|
684
|
+
" • Pre-fix bug (2026-06-06): sending just ui-dist HTML wiped server.js + node_modules — connector broke until a full re-upload. Now: those files merge with the GitHub base.\n" +
|
|
685
|
+
" • Pre-fix bug: github:true silently read from `main` even when patches were on `dev`. Now: defaults to dev; pass ref:'main' to opt into the legacy path.",
|
|
688
686
|
inputSchema: {
|
|
689
687
|
type: "object",
|
|
690
688
|
properties: {
|
|
@@ -698,7 +696,11 @@ export const tools = [
|
|
|
698
696
|
},
|
|
699
697
|
github: {
|
|
700
698
|
type: "boolean",
|
|
701
|
-
description: "If true, pull
|
|
699
|
+
description: "If true, pull connector files from GitHub repo at `ref`. Default: false. Combine with files:[] to use GitHub as the base and overlay your files.",
|
|
700
|
+
},
|
|
701
|
+
ref: {
|
|
702
|
+
type: "string",
|
|
703
|
+
description: "GitHub branch to read from for the BASE state. Default: 'dev' (matches ateam_github_patch). Pass 'main' to read from production. Pre-2026-06-05 callers that relied on the silent-main default must pass ref:'main' explicitly.",
|
|
702
704
|
},
|
|
703
705
|
files: {
|
|
704
706
|
type: "array",
|
|
@@ -710,7 +712,11 @@ export const tools = [
|
|
|
710
712
|
},
|
|
711
713
|
required: ["path", "content"],
|
|
712
714
|
},
|
|
713
|
-
description: "Files to upload.
|
|
715
|
+
description: "Files to upload. By default merges with the GitHub state at `ref`. Set replace:true to wipe the connector dir and write only these files.",
|
|
716
|
+
},
|
|
717
|
+
replace: {
|
|
718
|
+
type: "boolean",
|
|
719
|
+
description: "Opt into FULL REPLACE: wipe the connector dir and write only the provided `files`. Default: false (= merge with GitHub state at `ref`). Use with intent — sending an incomplete file set with replace:true will break the connector.",
|
|
714
720
|
},
|
|
715
721
|
},
|
|
716
722
|
required: ["solution_id", "connector_id"],
|
|
@@ -828,8 +834,7 @@ export const tools = [
|
|
|
828
834
|
name: "ateam_upload_connector_files",
|
|
829
835
|
core: false,
|
|
830
836
|
description:
|
|
831
|
-
"Upload source files for a connector's MCP server. Use this INSTEAD of mcp_store in ateam_build_and_run when the source code is too large to inline. Upload files first, then build_and_run without mcp_store. (Advanced.)
|
|
832
|
-
"⚠️ STAGES ONLY — these files are saved for your NEXT solution deploy; they do NOT update the running connector (the response says \"staged for next deploy\"). To push connector code to the LIVE runtime and restart it immediately, use ateam_upload_connector (which replaces the whole connector dir).",
|
|
837
|
+
"Upload source files for a connector's MCP server. Use this INSTEAD of mcp_store in ateam_build_and_run when the source code is too large to inline. Upload files first, then build_and_run without mcp_store. (Advanced.)",
|
|
833
838
|
inputSchema: {
|
|
834
839
|
type: "object",
|
|
835
840
|
properties: {
|
|
@@ -988,6 +993,45 @@ export const tools = [
|
|
|
988
993
|
required: ["job_id"],
|
|
989
994
|
},
|
|
990
995
|
},
|
|
996
|
+
{
|
|
997
|
+
name: "ateam_get_widget_catalog",
|
|
998
|
+
core: true,
|
|
999
|
+
description:
|
|
1000
|
+
"Get the live catalog of widgets (UI plugins) available in this tenant's solution. Returns platform-bundled + solution-bundled + skill-declared widgets, each with a paste-ready how_to_use block (solution.json snippet + opener_call + persona_phrasing + binding_notes).\n\n" +
|
|
1001
|
+
"Use this when wiring widgets into a skill or solution — the how_to_use block is designed to be copied verbatim into the solution.json ui_plugins[] entry and into the persona's opener phrasing, so you don't have to hand-roll either. The catalog reflects what is actually deployed in the tenant right now, not the abstract spec (for the spec itself, use ateam_get_spec topic='widgets').\n\n" +
|
|
1002
|
+
"Origins:\n" +
|
|
1003
|
+
" • 'platform' = widgets bundled with the platform (always available).\n" +
|
|
1004
|
+
" • 'solution' = widgets bundled with this tenant's solution.\n" +
|
|
1005
|
+
" • 'skill' = widgets declared by a specific skill in the solution.\n\n" +
|
|
1006
|
+
"Auth: forwards your authed api_key to Core (no master-secret involvement). Tenant scope is pinned by the key itself.",
|
|
1007
|
+
inputSchema: {
|
|
1008
|
+
type: "object",
|
|
1009
|
+
properties: {
|
|
1010
|
+
solution_id: {
|
|
1011
|
+
type: "string",
|
|
1012
|
+
description: "Optional. The solution to query. Defaults to the tenant's current solution.",
|
|
1013
|
+
},
|
|
1014
|
+
origin: {
|
|
1015
|
+
type: "string",
|
|
1016
|
+
enum: ["all", "platform", "solution", "skill"],
|
|
1017
|
+
description:
|
|
1018
|
+
"Optional. Filter by widget origin. 'all' (default) returns everything. 'platform' = platform-bundled only. 'solution' = solution-bundled only. 'skill' = skill-declared only.",
|
|
1019
|
+
},
|
|
1020
|
+
include_unused: {
|
|
1021
|
+
type: "boolean",
|
|
1022
|
+
description:
|
|
1023
|
+
"Optional. If true, includes widgets that are available but not currently referenced by any skill or ui_plugins entry. Default false (only widgets actually wired into the solution).",
|
|
1024
|
+
},
|
|
1025
|
+
format: {
|
|
1026
|
+
type: "string",
|
|
1027
|
+
enum: ["summary", "full"],
|
|
1028
|
+
description:
|
|
1029
|
+
"Optional. 'full' (default) returns each widget with its paste-ready how_to_use block (solution.json snippet, opener_call, persona_phrasing, binding_notes). 'summary' returns just id/name/origin/description for a quick overview.",
|
|
1030
|
+
},
|
|
1031
|
+
},
|
|
1032
|
+
required: [],
|
|
1033
|
+
},
|
|
1034
|
+
},
|
|
991
1035
|
{
|
|
992
1036
|
name: "ateam_test_abort",
|
|
993
1037
|
core: true,
|
|
@@ -1507,6 +1551,7 @@ const SPEC_PATHS = {
|
|
|
1507
1551
|
enums: "/spec/enums",
|
|
1508
1552
|
"connector-multi-user": "/spec/multi-user-connector",
|
|
1509
1553
|
python_helpers: "/spec/python_helpers",
|
|
1554
|
+
widgets: "/spec/widgets",
|
|
1510
1555
|
};
|
|
1511
1556
|
|
|
1512
1557
|
const EXAMPLE_PATHS = {
|
|
@@ -1549,6 +1594,7 @@ const TENANT_TOOLS = new Set([
|
|
|
1549
1594
|
"ateam_test_status",
|
|
1550
1595
|
"ateam_test_abort",
|
|
1551
1596
|
"ateam_get_chain",
|
|
1597
|
+
"ateam_get_widget_catalog",
|
|
1552
1598
|
"ateam_get_connector_source",
|
|
1553
1599
|
"ateam_get_metrics",
|
|
1554
1600
|
"ateam_diff",
|
|
@@ -3092,6 +3138,84 @@ const handlers = {
|
|
|
3092
3138
|
return data;
|
|
3093
3139
|
},
|
|
3094
3140
|
|
|
3141
|
+
ateam_get_widget_catalog: async ({ origin, format }, sid) => {
|
|
3142
|
+
// Wraps Core's existing GET /api/ui-plugins (merged tenant plugin list)
|
|
3143
|
+
// and enriches each entry with the documentation/how-to-use layer.
|
|
3144
|
+
// Filtering by origin and the summary/full format projection happen
|
|
3145
|
+
// client-side here — Core just returns the raw merged plugins[].
|
|
3146
|
+
const creds = getCredentials(sid);
|
|
3147
|
+
const apiKey = creds?.apiKey;
|
|
3148
|
+
if (!apiKey) throw new Error("No api_key in session — call ateam_auth(api_key) first.");
|
|
3149
|
+
const coreUrl = process.env.ADAS_CORE_URL || "http://adas-backend:4000";
|
|
3150
|
+
const res = await fetch(`${coreUrl}/api/ui-plugins`, {
|
|
3151
|
+
method: "GET",
|
|
3152
|
+
headers: { "x-api-key": apiKey, "X-ADAS-SERVICE": "ateam-mcp.get_widget_catalog" },
|
|
3153
|
+
signal: AbortSignal.timeout(15_000),
|
|
3154
|
+
});
|
|
3155
|
+
const text = await res.text();
|
|
3156
|
+
let data;
|
|
3157
|
+
try { data = JSON.parse(text); } catch { data = { ok: false, error: text.slice(0, 400) }; }
|
|
3158
|
+
if (!res.ok) {
|
|
3159
|
+
throw new Error(`Core /api/ui-plugins returned ${res.status}: ${data.error || JSON.stringify(data).slice(0, 200)}`);
|
|
3160
|
+
}
|
|
3161
|
+
|
|
3162
|
+
// Project each plugin into the catalog shape with how_to_use guidance.
|
|
3163
|
+
const plugins = Array.isArray(data?.plugins) ? data.plugins : [];
|
|
3164
|
+
const wantSummary = format === "summary";
|
|
3165
|
+
const filterOrigin = origin && origin !== "all" ? origin : null;
|
|
3166
|
+
|
|
3167
|
+
const widgets = plugins.map((p) => {
|
|
3168
|
+
const id = p?.id || "";
|
|
3169
|
+
const shortId = id.split(":").pop() || id;
|
|
3170
|
+
// origin classification: platform vs solution vs skill
|
|
3171
|
+
const src = p?._source || "";
|
|
3172
|
+
const inferredOrigin = src === "mcp_introspection" ? "platform"
|
|
3173
|
+
: src === "skill_declared" ? "skill"
|
|
3174
|
+
: "solution";
|
|
3175
|
+
const opener = Array.isArray(p?.capabilities?.commands) && p.capabilities.commands.length > 0
|
|
3176
|
+
? `ui.${shortId}.${p.capabilities.commands[0].name || "open"}({ /* args per input_schema */ })`
|
|
3177
|
+
: `sys.focusUiPlugin({ plugin_id: "${id}" })`;
|
|
3178
|
+
const entry = {
|
|
3179
|
+
id,
|
|
3180
|
+
name: p?.name,
|
|
3181
|
+
version: p?.version,
|
|
3182
|
+
description: p?.description,
|
|
3183
|
+
type: p?.type || "ui",
|
|
3184
|
+
origin: inferredOrigin,
|
|
3185
|
+
owned_by_connector: p?._connector_id,
|
|
3186
|
+
render: p?.render,
|
|
3187
|
+
surface: p?.surface,
|
|
3188
|
+
capabilities: p?.capabilities,
|
|
3189
|
+
channels: p?.channels,
|
|
3190
|
+
commands: p?.capabilities?.commands || p?.commands || [],
|
|
3191
|
+
uiActions: p?.uiActions,
|
|
3192
|
+
};
|
|
3193
|
+
if (!wantSummary) {
|
|
3194
|
+
entry.how_to_use = {
|
|
3195
|
+
solution_json_snippet: { id, name: p?.name, version: p?.version, render: p?.render },
|
|
3196
|
+
opener_call: opener,
|
|
3197
|
+
persona_phrasing: `When the user wants to view ${(p?.description || p?.name || shortId).toString().toLowerCase()}, call ${opener.split("(")[0]}.`,
|
|
3198
|
+
binding_notes: {
|
|
3199
|
+
commands_input_schemas: (p?.capabilities?.commands || []).map(c => ({ command: c.name, schema: c.input_schema })),
|
|
3200
|
+
deeplink_template: p?.uiActions?.deeplink || null,
|
|
3201
|
+
view_entity_kinds: p?.uiActions?.intents?.view_entity?.entity_kinds || null,
|
|
3202
|
+
host_auto_routes_intents: Object.keys(p?.uiActions?.intents || {}),
|
|
3203
|
+
},
|
|
3204
|
+
};
|
|
3205
|
+
}
|
|
3206
|
+
return entry;
|
|
3207
|
+
});
|
|
3208
|
+
|
|
3209
|
+
const filtered = filterOrigin ? widgets.filter(w => w.origin === filterOrigin) : widgets;
|
|
3210
|
+
const counts = {
|
|
3211
|
+
total: filtered.length,
|
|
3212
|
+
platform: filtered.filter(w => w.origin === "platform").length,
|
|
3213
|
+
solution: filtered.filter(w => w.origin === "solution").length,
|
|
3214
|
+
skill: filtered.filter(w => w.origin === "skill").length,
|
|
3215
|
+
};
|
|
3216
|
+
return { ok: true, generated_at: new Date().toISOString(), counts, widgets: filtered };
|
|
3217
|
+
},
|
|
3218
|
+
|
|
3095
3219
|
ateam_test_abort: async ({ solution_id, skill_id, job_id }, sid) =>
|
|
3096
3220
|
del(`/deploy/solutions/${solution_id}/skills/${skill_id}/test/${job_id}`, sid),
|
|
3097
3221
|
|
|
@@ -3249,10 +3373,15 @@ const handlers = {
|
|
|
3249
3373
|
ateam_delete_connector: async ({ solution_id, connector_id }, sid) =>
|
|
3250
3374
|
del(`/deploy/solutions/${solution_id}/connectors/${connector_id}`, sid),
|
|
3251
3375
|
|
|
3252
|
-
ateam_upload_connector: async ({ solution_id, connector_id, github, files }, sid) =>
|
|
3376
|
+
ateam_upload_connector: async ({ solution_id, connector_id, github, files, ref, replace }, sid) =>
|
|
3253
3377
|
post(
|
|
3254
3378
|
`/deploy/solutions/${solution_id}/connectors/${connector_id}/upload`,
|
|
3255
|
-
{
|
|
3379
|
+
{
|
|
3380
|
+
github,
|
|
3381
|
+
files,
|
|
3382
|
+
...(ref ? { ref } : {}),
|
|
3383
|
+
...(replace === true ? { replace: true } : {}),
|
|
3384
|
+
},
|
|
3256
3385
|
sid,
|
|
3257
3386
|
{ timeoutMs: 300_000, retries: 1 },
|
|
3258
3387
|
),
|