@ateam-ai/mcp 0.3.23 → 0.3.25

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 +69 -1
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ateam-ai/mcp",
3
- "version": "0.3.23",
3
+ "version": "0.3.25",
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
@@ -1480,12 +1480,24 @@ const handlers = {
1480
1480
  if (!effectiveSkills?.length && pullResult.skills?.length) {
1481
1481
  effectiveSkills = pullResult.skills;
1482
1482
  }
1483
+ // Synthesize connectors[] metadata from mcp_store keys if not passed inline.
1484
+ // The pull-bundle endpoint returns mcp_store (files) and solution.platform_connectors
1485
+ // (declarations) but not a top-level connectors[] array. The validator/deploy
1486
+ // pipeline expects one, so build it from the mcp_store we just pulled.
1487
+ if (!connectors?.length && Object.keys(effectiveMcpStore).length > 0) {
1488
+ connectors = Object.keys(effectiveMcpStore).map((id) => ({
1489
+ id,
1490
+ name: id,
1491
+ transport: "stdio",
1492
+ }));
1493
+ }
1483
1494
  phases.push({
1484
1495
  phase: "github_pull",
1485
1496
  status: "done",
1486
1497
  skills_found: pullResult.skills_found || 0,
1487
1498
  connectors_found: pullResult.connectors_found || 0,
1488
1499
  files_loaded: pullResult.files_loaded || 0,
1500
+ connectors_synthesized: connectors?.length || 0,
1489
1501
  });
1490
1502
  } catch (err) {
1491
1503
  return {
@@ -1935,7 +1947,39 @@ const handlers = {
1935
1947
  return post(`/deploy/mcp-store/${connector_id}`, { files: resolved }, sid);
1936
1948
  },
1937
1949
 
1938
- ateam_list_solutions: async (_args, sid) => get("/deploy/solutions", sid),
1950
+ ateam_list_solutions: async (_args, sid) => {
1951
+ const raw = await get("/deploy/solutions", sid);
1952
+ // Enrich each solution with GitHub metadata (repo_url, branch, CLAUDE.md)
1953
+ // so an agent sees everything it needs to clone + onboard in one call.
1954
+ // Fetches run in parallel; failures are non-fatal (fall back to the raw row).
1955
+ const solutions = Array.isArray(raw?.solutions) ? raw.solutions : Array.isArray(raw) ? raw : [];
1956
+ const enriched = await Promise.all(solutions.map(async (s) => {
1957
+ const out = { ...s };
1958
+ try {
1959
+ const gh = await get(`/deploy/solutions/${s.id}/github/status`, sid);
1960
+ if (gh?.exists && gh.repo_url) {
1961
+ out.repo_url = gh.repo_url;
1962
+ out.github_full_name = gh.full_name || null;
1963
+ out.default_branch = gh.default_branch || "main";
1964
+ out.latest_commit_sha = gh.latest_commit?.sha || null;
1965
+ // Probe for agent-onboarding doc; swallow 404 etc.
1966
+ try {
1967
+ const probe = await get(`/deploy/solutions/${s.id}/github/read?path=CLAUDE.md`, sid);
1968
+ out.has_claude_md = Boolean(probe?.content);
1969
+ } catch { out.has_claude_md = false; }
1970
+ out.local_dev_quickstart = {
1971
+ _note: "Share these 3 lines with a developer (or their agent). They will clone the repo and, if CLAUDE.md is present, their agent sees the full onboarding on session start.",
1972
+ clone: `git clone ${gh.repo_url}`,
1973
+ cd: `cd ${(gh.full_name || "").split("/").pop() || s.id}`,
1974
+ auth_in_new_session: `ateam_auth(api_key: "adas_<tenant>_<hex>")`,
1975
+ needs_github_collaborator_access: !gh.repo_url.includes("public") ? true : false,
1976
+ };
1977
+ }
1978
+ } catch { /* non-fatal — leave the row as-is */ }
1979
+ return out;
1980
+ }));
1981
+ return { ...raw, solutions: enriched };
1982
+ },
1939
1983
 
1940
1984
  ateam_get_solution: async ({ solution_id, view, skill_id }, sid) => {
1941
1985
  const base = `/deploy/solutions/${solution_id}`;
@@ -2323,6 +2367,30 @@ export async function handleToolCall(name, args, sessionId) {
2323
2367
  last_tool_used: ctx.lastToolName || null,
2324
2368
  };
2325
2369
  }
2370
+ // If authenticated, attach a tenant onboarding block so the agent can
2371
+ // discover existing solutions + their repo URLs without extra round-trips.
2372
+ // This is what lets a fresh agent clone the right repo on first greet.
2373
+ try {
2374
+ const creds = getCredentials(sessionId);
2375
+ if (creds?.apiKey || creds?.masterKey) {
2376
+ const listed = await handlers.ateam_list_solutions({}, sessionId);
2377
+ const solutions = Array.isArray(listed?.solutions) ? listed.solutions : [];
2378
+ if (solutions.length > 0) {
2379
+ result.tenant_onboarding = {
2380
+ _note: "The authed key can see these solutions. For LOCAL development: clone the repo_url and open any Claude-Code-compatible agent in that directory — it will auto-load CLAUDE.md on session start. For REMOTE-only work: call ateam_github_read(solution_id, 'CLAUDE.md') to fetch the onboarding doc. If `git clone` returns 403, ask the solution owner to add your GitHub account as a collaborator on the repo (GitHub access is separate from the A-Team API key).",
2381
+ tenant: creds.tenant || null,
2382
+ solutions: solutions.map((s) => ({
2383
+ id: s.id,
2384
+ name: s.name,
2385
+ repo_url: s.repo_url || null,
2386
+ default_branch: s.default_branch || "main",
2387
+ has_claude_md: s.has_claude_md ?? null,
2388
+ clone_command: s.repo_url ? `git clone ${s.repo_url}` : null,
2389
+ })),
2390
+ };
2391
+ }
2392
+ }
2393
+ } catch { /* non-fatal — unauthed sessions or API blips shouldn't break bootstrap */ }
2326
2394
  }
2327
2395
 
2328
2396
  return {