@ateam-ai/mcp 0.3.4 → 0.3.6

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.
Files changed (2) hide show
  1. package/package.json +1 -1
  2. package/src/tools.js +126 -21
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ateam-ai/mcp",
3
- "version": "0.3.4",
3
+ "version": "0.3.6",
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",
package/src/tools.js CHANGED
@@ -120,18 +120,22 @@ export const tools = [
120
120
  name: "ateam_build_and_run",
121
121
  core: true,
122
122
  description:
123
- "Build and deploy a governed AI Team solution in one step. ⚠️ HEAVIEST OPERATION (60-180s): validates solution+skills → deploys all connectors+skills to A-Team Core (regenerates MCP servers) → health-checks → optionally runs a warm test → auto-pushes to GitHub. Use this instead of calling validate, deploy, and health separately. For small changes to an already-deployed solution, prefer ateam_patch (faster, incremental). Requires authentication.",
123
+ "Build and deploy a governed AI Team solution in one step. ⚠️ HEAVIEST OPERATION (60-180s): validates solution+skills → deploys all connectors+skills to A-Team Core (regenerates MCP servers) → health-checks → optionally runs a warm test → auto-pushes to GitHub. AUTO-DETECTS GitHub repo: if you omit mcp_store and a repo exists, connector code is pulled from GitHub automatically. First deploy requires mcp_store. After that, write files via ateam_github_write, then just call build_and_run without mcp_store. For small changes to an already-deployed solution, prefer ateam_patch (faster, incremental). Requires authentication.",
124
124
  inputSchema: {
125
125
  type: "object",
126
126
  properties: {
127
+ solution_id: {
128
+ type: "string",
129
+ description: "The solution ID. Use this INSTEAD of passing the full solution object — the solution definition is auto-pulled from GitHub. Required if solution object is omitted.",
130
+ },
127
131
  solution: {
128
132
  type: "object",
129
- description: "Solution architecture identity, grants, handoffs, routing",
133
+ description: "Full solution definition. Required on first deploy. After first deploy, just pass solution_id instead — everything is auto-pulled from GitHub.",
130
134
  },
131
135
  skills: {
132
136
  type: "array",
133
137
  items: { type: "object" },
134
- description: "Array of full skill definitions",
138
+ description: "Optional after first deploy: skill definitions. If omitted, auto-pulled from GitHub repo (skills/{id}/skill.json).",
135
139
  },
136
140
  connectors: {
137
141
  type: "array",
@@ -144,7 +148,7 @@ export const tools = [
144
148
  },
145
149
  github: {
146
150
  type: "boolean",
147
- description: "Optional: if true, pull connector source code from the solution's GitHub repo instead of requiring mcp_store. Use this after the first deploy (which creates the repo). Cannot be used on first deploy.",
151
+ description: "Optional: if true, pull connector source code from the solution's GitHub repo. AUTO-DETECTED: if you omit both mcp_store and github, the system checks if a repo exists and pulls from it automatically. You rarely need to set this explicitly.",
148
152
  },
149
153
  test_message: {
150
154
  type: "string",
@@ -155,7 +159,7 @@ export const tools = [
155
159
  description: "Optional: which skill to test (defaults to the first skill).",
156
160
  },
157
161
  },
158
- required: ["solution", "skills"],
162
+ required: [],
159
163
  },
160
164
  },
161
165
  {
@@ -850,6 +854,36 @@ export const tools = [
850
854
  required: ["solution_id", "path"],
851
855
  },
852
856
  },
857
+ {
858
+ name: "ateam_github_write",
859
+ core: true,
860
+ description:
861
+ "Write a file to the solution's GitHub repo. Use this to create new connector files or replace existing ones — one file per call. " +
862
+ "This is the PRIMARY way to write connector code after first deploy. " +
863
+ "Write each file individually (server.js, package.json, UI assets), then call ateam_build_and_run() to deploy.",
864
+ inputSchema: {
865
+ type: "object",
866
+ properties: {
867
+ solution_id: {
868
+ type: "string",
869
+ description: "The solution ID",
870
+ },
871
+ path: {
872
+ type: "string",
873
+ description: "File path to write (e.g. 'connectors/my-mcp/server.js', 'connectors/my-mcp/package.json')",
874
+ },
875
+ content: {
876
+ type: "string",
877
+ description: "The full file content",
878
+ },
879
+ message: {
880
+ type: "string",
881
+ description: "Optional commit message (default: 'Write <path>')",
882
+ },
883
+ },
884
+ required: ["solution_id", "path", "content"],
885
+ },
886
+ },
853
887
  {
854
888
  name: "ateam_github_log",
855
889
  core: true,
@@ -1084,7 +1118,7 @@ const handlers = {
1084
1118
  { step: 1, action: "Learn", description: "Get the spec and study examples", tools: ["ateam_get_spec", "ateam_get_examples"] },
1085
1119
  { step: 2, action: "Build & Run", description: "Define your solution + skills + connector code, then validate, deploy, and health-check in one call. Include mcp_store with connector source code on the first deploy.", tools: ["ateam_build_and_run"] },
1086
1120
  { step: 3, action: "Version", description: "Every deploy auto-pushes to main on GitHub. The repo (tenant--solution-id) is the source of truth for connector code.", tools: ["ateam_github_status", "ateam_github_log"] },
1087
- { step: 4, action: "Iterate", description: "Edit connector code via ateam_github_patch (commits to main), then redeploy with ateam_build_and_run(github:true). For skill definition changes, use ateam_patch (also pushes to main).", tools: ["ateam_github_patch", "ateam_build_and_run", "ateam_patch"] },
1121
+ { step: 4, action: "Iterate", description: "Edit connector code ONE FILE AT A TIME via ateam_github_patch, then redeploy with ateam_build_and_run (auto-pulls from GitHub). NEVER re-pass all connector code inline after first deploy. For skill definitions, use ateam_patch.", tools: ["ateam_github_patch", "ateam_build_and_run", "ateam_patch"] },
1088
1122
  { step: 5, action: "Test & Debug", description: "Test the decision pipeline or full execution, then diagnose with logs and metrics. For voice-enabled solutions, use ateam_test_voice to simulate phone conversations.", tools: ["ateam_test_pipeline", "ateam_test_skill", "ateam_test_voice", "ateam_get_execution_logs", "ateam_get_metrics"] },
1089
1123
  { step: 6, action: "Checkpoint", description: "When solution is in a good state, create a checkpoint (safe point). You can rollback to any checkpoint if something breaks.", tools: ["ateam_github_promote", "ateam_github_list_versions"] },
1090
1124
  ],
@@ -1114,16 +1148,18 @@ const handlers = {
1114
1148
  branch: "main — the only branch. All changes land here directly.",
1115
1149
  checkpoints: "safe-YYYY-MM-DD-NNN tags mark safe rollback points. Create with ateam_github_promote().",
1116
1150
  iteration_workflow: {
1117
- code_changes: "ateam_github_patch (commits to main) → ateam_build_and_run(github:true) (pulls from main, redeploys)",
1151
+ code_changes: "ateam_github_patch (one file at a time, commits to main) → ateam_build_and_run() (auto-pulls from GitHub, redeploys)",
1118
1152
  definition_changes: "ateam_patch (updates + redeploys + auto-pushes to main)",
1119
1153
  first_deploy: "Must include mcp_store — this creates the GitHub repo",
1154
+ after_first_deploy: "NEVER pass mcp_store again. Write files via ateam_github_patch, then ateam_build_and_run() auto-detects the repo.",
1120
1155
  checkpoint: "ateam_github_promote(solution_id) — tag current state as a safe rollback point",
1121
1156
  },
1122
1157
  when_to_use_what: {
1123
- ateam_github_patch: "Edit connector source code on main (server.js, utils, package.json, UI assets)",
1158
+ ateam_github_write: "Write/create connector files on main — ONE FILE PER CALL (server.js, package.json, UI assets). Use this after first deploy.",
1159
+ ateam_github_patch: "Edit existing files with search/replace (surgical edits to large files)",
1124
1160
  ateam_patch: "Edit skill definitions (intents, tools, policy) — auto-pushes to main",
1125
- "ateam_build_and_run(github:true)": "Redeploy solution pulling latest connector code from main",
1126
- "ateam_build_and_run(mcp_store)": "First deploy or when you want to pass connector code inline",
1161
+ "ateam_build_and_run()": "Redeploy auto-pulls from GitHub if repo exists. No need to pass mcp_store or github flag.",
1162
+ "ateam_build_and_run(mcp_store)": "FIRST DEPLOY ONLY creates the GitHub repo. Never use mcp_store again after first deploy.",
1127
1163
  ateam_github_promote: "Create a checkpoint (safe-* tag) — use before risky changes",
1128
1164
  ateam_github_rollback: "Revert main to a previous checkpoint",
1129
1165
  },
@@ -1179,6 +1215,8 @@ const handlers = {
1179
1215
  "Dump raw spec unless requested",
1180
1216
  "Write connector code that starts a web server — connectors MUST use stdio transport",
1181
1217
  "Mention dev branch — there is no dev branch, everything is on main",
1218
+ "Pass large connector code via mcp_store after the first deploy — use ateam_github_write/ateam_github_patch one file at a time instead",
1219
+ "Try to pass ALL connector files at once in a single tool call — write them individually to GitHub",
1182
1220
  ],
1183
1221
  },
1184
1222
  }),
@@ -1257,32 +1295,76 @@ const handlers = {
1257
1295
  // Validates → Deploys → Health-checks → Optionally tests
1258
1296
  // One call replaces: validate_solution + deploy_solution + get_solution(health)
1259
1297
 
1260
- ateam_build_and_run: async ({ solution, skills, connectors, mcp_store, github, test_message, test_skill_id }, sid) => {
1298
+ ateam_build_and_run: async ({ solution_id: solIdArg, solution: solutionArg, skills, connectors, mcp_store, github, test_message, test_skill_id }, sid) => {
1299
+ let solution = solutionArg;
1300
+ // If only solution_id passed (no full solution), we'll pull from GitHub
1301
+ const solutionId = solution?.id || solIdArg;
1302
+ if (!solutionId) {
1303
+ return { ok: false, phase: "pre_check", error: "Provide either solution (object) or solution_id (string)." };
1304
+ }
1261
1305
  const phases = [];
1262
1306
 
1263
- // Phase 0: GitHub pull (if github:true pull connector source from repo)
1307
+ // Guard: reject large mcp_storeagent should use github_patch instead
1308
+ if (mcp_store) {
1309
+ const totalSize = Object.values(mcp_store).reduce((sum, files) => {
1310
+ return sum + (Array.isArray(files) ? files.reduce((s, f) => s + (f.content?.length || 0), 0) : 0);
1311
+ }, 0);
1312
+ if (totalSize > 200_000) {
1313
+ return {
1314
+ ok: false,
1315
+ phase: "pre_check",
1316
+ error: `mcp_store is too large (${Math.round(totalSize / 1024)}KB). Max ~200KB inline.`,
1317
+ message: "Connector code is too large to pass inline. Write files individually to GitHub, then deploy from there.",
1318
+ _fix: [
1319
+ "1. Write each file: ateam_github_patch(solution_id, path: 'connectors/<id>/server.js', content: '...')",
1320
+ "2. Repeat for package.json, UI assets, etc.",
1321
+ "3. Deploy: ateam_build_and_run(solution, skills) — will auto-pull from GitHub",
1322
+ ],
1323
+ };
1324
+ }
1325
+ }
1326
+
1327
+ // Phase 0: Auto-detect GitHub repo — if no mcp_store passed and repo exists, pull bundle from GitHub
1264
1328
  let effectiveMcpStore = mcp_store;
1329
+ let effectiveSkills = skills;
1330
+ if (!mcp_store) {
1331
+ try {
1332
+ const ghStatus = await get(`/deploy/solutions/${solutionId}/github/status`, sid);
1333
+ if (ghStatus?.repo_url) {
1334
+ github = true;
1335
+ }
1336
+ } catch { /* no repo — first deploy, mcp_store expected */ }
1337
+ }
1265
1338
  if (github && !mcp_store) {
1266
1339
  try {
1267
1340
  const pullResult = await post(
1268
- `/deploy/solutions/${solution.id}/github/pull-connectors`,
1341
+ `/deploy/solutions/${solutionId}/github/pull-bundle`,
1269
1342
  {},
1270
1343
  sid,
1271
- { timeoutMs: 30_000 },
1344
+ { timeoutMs: 60_000 },
1272
1345
  );
1273
1346
  if (!pullResult.ok) {
1274
1347
  return {
1275
1348
  ok: false,
1276
1349
  phase: "github_pull",
1277
- error: pullResult.error || "Failed to pull connectors from GitHub",
1350
+ error: pullResult.error || "Failed to pull bundle from GitHub",
1278
1351
  hint: pullResult.hint || "Deploy the solution first (with mcp_store) to auto-create the GitHub repo.",
1279
- message: "Cannot pull connector code from GitHub. The repo may not exist yet — deploy with mcp_store first.",
1352
+ message: "Cannot pull from GitHub. The repo may not exist yet — deploy with mcp_store first.",
1280
1353
  };
1281
1354
  }
1282
- effectiveMcpStore = pullResult.mcp_store;
1355
+ effectiveMcpStore = pullResult.mcp_store || {};
1356
+ // Use solution from GitHub if not passed inline
1357
+ if (!solution && pullResult.solution) {
1358
+ solution = pullResult.solution;
1359
+ }
1360
+ // Use skills from GitHub if not passed inline
1361
+ if (!effectiveSkills?.length && pullResult.skills?.length) {
1362
+ effectiveSkills = pullResult.skills;
1363
+ }
1283
1364
  phases.push({
1284
1365
  phase: "github_pull",
1285
1366
  status: "done",
1367
+ skills_found: pullResult.skills_found || 0,
1286
1368
  connectors_found: pullResult.connectors_found || 0,
1287
1369
  files_loaded: pullResult.files_loaded || 0,
1288
1370
  });
@@ -1291,15 +1373,35 @@ const handlers = {
1291
1373
  ok: false,
1292
1374
  phase: "github_pull",
1293
1375
  error: err.message,
1294
- message: "Failed to pull connector code from GitHub. The repo may not exist yet — deploy with mcp_store first.",
1376
+ message: "Failed to pull from GitHub. The repo may not exist yet — deploy with mcp_store first.",
1295
1377
  };
1296
1378
  }
1297
1379
  }
1298
1380
 
1381
+ // Guard: solution required (either inline or from GitHub)
1382
+ if (!solution) {
1383
+ return {
1384
+ ok: false,
1385
+ phase: "pre_check",
1386
+ error: "No solution provided and none found in GitHub repo.",
1387
+ message: "Pass solution inline or ensure solution.json exists in the GitHub repo.",
1388
+ };
1389
+ }
1390
+
1391
+ // Guard: skills required (either inline or from GitHub)
1392
+ if (!effectiveSkills?.length) {
1393
+ return {
1394
+ ok: false,
1395
+ phase: "pre_check",
1396
+ error: "No skills provided and none found in GitHub repo.",
1397
+ message: "Pass skills inline or ensure they exist in the GitHub repo (skills/{id}/skill.json).",
1398
+ };
1399
+ }
1400
+
1299
1401
  // Phase 1: Validate
1300
1402
  let validation;
1301
1403
  try {
1302
- validation = await post("/validate/solution", { solution, skills, connectors, mcp_store: effectiveMcpStore }, sid, { timeoutMs: 120_000 });
1404
+ validation = await post("/validate/solution", { solution, skills: effectiveSkills, connectors, mcp_store: effectiveMcpStore }, sid, { timeoutMs: 120_000 });
1303
1405
  phases.push({ phase: "validate", status: "done" });
1304
1406
  } catch (err) {
1305
1407
  return {
@@ -1325,7 +1427,7 @@ const handlers = {
1325
1427
  // Phase 2: Deploy
1326
1428
  let deploy;
1327
1429
  try {
1328
- deploy = await post("/deploy/solution", { solution, skills, connectors, mcp_store: effectiveMcpStore }, sid, { timeoutMs: 300_000, retries: 2 });
1430
+ deploy = await post("/deploy/solution", { solution, skills: effectiveSkills, connectors, mcp_store: effectiveMcpStore }, sid, { timeoutMs: 300_000, retries: 2 });
1329
1431
  phases.push({ phase: "deploy", status: deploy.ok ? "done" : "failed" });
1330
1432
  } catch (err) {
1331
1433
  return {
@@ -1363,7 +1465,7 @@ const handlers = {
1363
1465
  // Phase 4: Warm test (optional)
1364
1466
  let test_result;
1365
1467
  if (test_message) {
1366
- const skillId = test_skill_id || skills?.[0]?.id;
1468
+ const skillId = test_skill_id || effectiveSkills?.[0]?.id;
1367
1469
  if (skillId) {
1368
1470
  try {
1369
1471
  test_result = await post(
@@ -1648,6 +1750,9 @@ const handlers = {
1648
1750
  ateam_github_patch: async ({ solution_id, path: filePath, content, search, replace, message }, sid) =>
1649
1751
  post(`/deploy/solutions/${solution_id}/github/patch`, { path: filePath, content, search, replace, message }, sid),
1650
1752
 
1753
+ ateam_github_write: async ({ solution_id, path: filePath, content, message }, sid) =>
1754
+ post(`/deploy/solutions/${solution_id}/github/patch`, { path: filePath, content, message }, sid),
1755
+
1651
1756
  ateam_github_log: async ({ solution_id, limit }, sid) => {
1652
1757
  const qs = limit ? `?limit=${limit}` : "";
1653
1758
  return get(`/deploy/solutions/${solution_id}/github/log${qs}`, sid);