@mushi-mushi/mcp 0.17.1 → 0.18.0

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/dist/server.js CHANGED
@@ -2,13 +2,14 @@ import {
2
2
  CODEBASE_TOOL_CATALOG,
3
3
  TDD_TOOL_CATALOG,
4
4
  TOOL_CATALOG
5
- } from "./chunk-7UOTJ2LI.js";
5
+ } from "./chunk-KNVB6HA7.js";
6
6
  import {
7
7
  MUSHI_SERVER_METADATA
8
8
  } from "./chunk-EANW5YTI.js";
9
9
  import {
10
+ DEPRECATED_TOOL_ALIASES,
10
11
  toolMatchesFeatures
11
- } from "./chunk-PW4AK6SV.js";
12
+ } from "./chunk-VBXXUK5G.js";
12
13
 
13
14
  // src/server.ts
14
15
  import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
@@ -45,8 +46,8 @@ var MUSHI_DOCS_INDEX = [
45
46
  {
46
47
  title: "Cursor MCP troubleshooting",
47
48
  path: `${BASE}/guides/mcp-setup`,
48
- keywords: ["cursor", "mcp.json", "red badge", "transport error", "stdout", "stderr", "json-rpc", "INVALID_TOKEN", "syntax helper", "diagnose_connection"],
49
- excerpt: "Cursor stdio MCP requires stdout to contain only JSON-RPC. Use the console syntax helper, restart Cursor MCP, then run diagnose_connection."
49
+ keywords: ["cursor", "mcp.json", "red badge", "transport error", "stdout", "stderr", "json-rpc", "INVALID_TOKEN", "syntax helper", "diagnose_setup"],
50
+ excerpt: "Cursor stdio MCP requires stdout to contain only JSON-RPC. Use the console syntax helper, restart Cursor MCP, then run diagnose_setup."
50
51
  },
51
52
  {
52
53
  title: "Judge loop",
@@ -502,14 +503,14 @@ function createMushiServer(config) {
502
503
  }
503
504
  );
504
505
  server.registerTool(
505
- "graph_neighborhood",
506
+ "get_graph_neighborhood",
506
507
  {
507
- title: titleOf("graph_neighborhood"),
508
- description: descOf("graph_neighborhood"),
509
- annotations: annotationsFor("graph_neighborhood"),
508
+ title: titleOf("get_graph_neighborhood"),
509
+ description: descOf("get_graph_neighborhood"),
510
+ annotations: annotationsFor("get_graph_neighborhood"),
510
511
  inputSchema: {
511
- seed: z.string().describe("Starting node id or label"),
512
- depth: z.number().optional().describe("Traversal depth (default 2, max 4)")
512
+ seed: z.string().describe("Starting graph node id or label to expand around (e.g. an inventory Action id or component name)"),
513
+ depth: z.number().int().min(1).max(4).optional().describe("BFS hops to traverse outward. Default 2; clamped to a max of 4.")
513
514
  }
514
515
  },
515
516
  async (args) => {
@@ -521,65 +522,65 @@ function createMushiServer(config) {
521
522
  }
522
523
  );
523
524
  server.registerTool(
524
- "graph_node_status",
525
+ "get_graph_node",
525
526
  {
526
- title: titleOf("graph_node_status"),
527
- description: descOf("graph_node_status"),
528
- annotations: annotationsFor("graph_node_status"),
529
- inputSchema: { nodeId: z.string().describe("graph_nodes.id") }
527
+ title: titleOf("get_graph_node"),
528
+ description: descOf("get_graph_node"),
529
+ annotations: annotationsFor("get_graph_node"),
530
+ inputSchema: { nodeId: z.string().describe("The graph_nodes.id of the node to fetch (UUID).") }
530
531
  },
531
532
  async (args) => jsonText(await apiCall(`/v1/admin/graph/node/${args.nodeId}`))
532
533
  );
533
534
  server.registerTool(
534
- "inventory_get",
535
+ "get_inventory",
535
536
  {
536
- title: titleOf("inventory_get"),
537
- description: descOf("inventory_get"),
538
- annotations: annotationsFor("inventory_get"),
537
+ title: titleOf("get_inventory"),
538
+ description: descOf("get_inventory"),
539
+ annotations: annotationsFor("get_inventory"),
539
540
  inputSchema: {
540
541
  projectId: z.string().optional().describe("Project UUID \u2014 defaults to the server-configured project when omitted")
541
542
  }
542
543
  },
543
544
  async (args) => {
544
545
  const pid = args.projectId ?? projectId;
545
- if (!pid) throw new MushiApiError(400, "MISSING_PROJECT", "projectId is required for inventory_get");
546
+ if (!pid) throw new MushiApiError(400, "MISSING_PROJECT", "projectId is required for get_inventory");
546
547
  return jsonText(await apiCall(`/v1/admin/inventory/${pid}`));
547
548
  }
548
549
  );
549
550
  server.registerTool(
550
- "inventory_diff",
551
+ "diff_inventory",
551
552
  {
552
- title: titleOf("inventory_diff"),
553
- description: descOf("inventory_diff"),
554
- annotations: annotationsFor("inventory_diff"),
553
+ title: titleOf("diff_inventory"),
554
+ description: descOf("diff_inventory"),
555
+ annotations: annotationsFor("diff_inventory"),
555
556
  inputSchema: {
556
557
  projectId: z.string().optional().describe("Project UUID \u2014 defaults to configured project"),
557
- fromSha: z.string().describe("Older commit SHA (baseline)"),
558
- toSha: z.string().describe("Newer commit SHA (candidate)")
558
+ fromSha: z.string().describe("Older commit SHA (the baseline to diff from)"),
559
+ toSha: z.string().describe("Newer commit SHA (the candidate to diff to)")
559
560
  }
560
561
  },
561
562
  async (args) => {
562
563
  const pid = args.projectId ?? projectId;
563
- if (!pid) throw new MushiApiError(400, "MISSING_PROJECT", "projectId is required for inventory_diff");
564
+ if (!pid) throw new MushiApiError(400, "MISSING_PROJECT", "projectId is required for diff_inventory");
564
565
  const q = new URLSearchParams({ from: args.fromSha, to: args.toSha });
565
566
  return jsonText(await apiCall(`/v1/admin/inventory/${pid}/diff?${q}`));
566
567
  }
567
568
  );
568
569
  server.registerTool(
569
- "inventory_findings",
570
+ "list_gate_findings",
570
571
  {
571
- title: titleOf("inventory_findings"),
572
- description: descOf("inventory_findings"),
573
- annotations: annotationsFor("inventory_findings"),
572
+ title: titleOf("list_gate_findings"),
573
+ description: descOf("list_gate_findings"),
574
+ annotations: annotationsFor("list_gate_findings"),
574
575
  inputSchema: {
575
576
  projectId: z.string().optional().describe("Project UUID \u2014 defaults to configured project"),
576
- gate: z.string().optional().describe("Filter by gate id (e.g. dead_handler, status_claim)"),
577
- severity: z.string().optional().describe("Filter findings by severity")
577
+ gate: z.string().optional().describe("Filter to one gate id: dead-handler | mock-leak | crawl | status-claim"),
578
+ severity: z.string().optional().describe("Minimum severity to include: low | medium | high | critical")
578
579
  }
579
580
  },
580
581
  async (args) => {
581
582
  const pid = args.projectId ?? projectId;
582
- if (!pid) throw new MushiApiError(400, "MISSING_PROJECT", "projectId is required for inventory_findings");
583
+ if (!pid) throw new MushiApiError(400, "MISSING_PROJECT", "projectId is required for list_gate_findings");
583
584
  const q = new URLSearchParams();
584
585
  if (args.gate) q.set("gate", args.gate);
585
586
  if (args.severity) q.set("severity", args.severity);
@@ -588,17 +589,25 @@ function createMushiServer(config) {
588
589
  }
589
590
  );
590
591
  server.registerTool(
591
- "fix_suggest",
592
+ "suggest_fix",
592
593
  {
593
- title: titleOf("fix_suggest"),
594
- description: descOf("fix_suggest"),
595
- annotations: annotationsFor("fix_suggest"),
596
- inputSchema: { reportId: z.string().describe("Report UUID") }
594
+ title: titleOf("suggest_fix"),
595
+ description: descOf("suggest_fix"),
596
+ annotations: annotationsFor("suggest_fix"),
597
+ inputSchema: { reportId: z.string().describe("Report UUID to read the Stage-2 suggested-fix slice for") },
598
+ outputSchema: {
599
+ reportId: z.string().describe("The report this slice was read from"),
600
+ rootCause: z.unknown().describe("Stage-2 root-cause hint, or null if not yet classified"),
601
+ suggestedFix: z.unknown().describe("Stage-2 suggested fix, or null if not yet classified"),
602
+ reproductionSteps: z.unknown().describe("Reproduction steps recorded on the report (array; [] if none)"),
603
+ summary: z.unknown().describe("One-line report summary, or null"),
604
+ component: z.unknown().describe("Component/page the bug was attributed to, or null")
605
+ }
597
606
  },
598
607
  async (args) => {
599
608
  const report = await apiCall(`/v1/admin/reports/${args.reportId}`);
600
609
  const s2 = report.stage2_analysis;
601
- return jsonText({
610
+ return jsonResult({
602
611
  reportId: args.reportId,
603
612
  rootCause: s2?.rootCause ?? null,
604
613
  suggestedFix: s2?.suggestedFix ?? null,
@@ -624,73 +633,6 @@ function createMushiServer(config) {
624
633
  return jsonText(data);
625
634
  }
626
635
  );
627
- server.registerTool(
628
- "setup_check",
629
- {
630
- title: titleOf("setup_check"),
631
- description: descOf("setup_check"),
632
- annotations: annotationsFor("setup_check"),
633
- inputSchema: {
634
- projectId: z.string().optional().describe(
635
- "Project UUID to check. Falls back to the projectId the server was initialised with."
636
- )
637
- }
638
- },
639
- async (args) => {
640
- const resolvedId = args.projectId ?? projectId;
641
- if (!resolvedId) {
642
- return jsonText({
643
- ok: false,
644
- error: "No projectId provided and none configured on the MCP server. Pass projectId explicitly."
645
- });
646
- }
647
- const data = await apiCall(`/v1/admin/projects/${resolvedId}/preflight`);
648
- const summary = data.checks.map((c) => ({
649
- check: c.key,
650
- label: c.label,
651
- passed: c.ready,
652
- hint: c.hint,
653
- fixPath: c.fixHref
654
- }));
655
- return jsonText({
656
- ready: data.ready,
657
- repoUrl: data.repoUrl ?? null,
658
- checks: summary,
659
- // Human-readable summary for agents that paste the result into a prompt
660
- summary: data.ready ? `Project ${resolvedId} is ready to dispatch auto-fixes${data.repoUrl ? ` (target: ${data.repoUrl})` : ""}.` : `Project ${resolvedId} cannot dispatch yet \u2014 ${summary.filter((c) => !c.passed).map((c) => c.label).join(", ")}.`
661
- });
662
- }
663
- );
664
- server.registerTool(
665
- "ingest_setup_check",
666
- {
667
- title: titleOf("ingest_setup_check"),
668
- description: descOf("ingest_setup_check"),
669
- annotations: annotationsFor("ingest_setup_check"),
670
- inputSchema: NO_ARG_INPUT
671
- },
672
- async () => {
673
- const data = await apiCall("/v1/sync/ingest-setup");
674
- const failed = data.steps.filter((s) => s.required && !s.complete);
675
- const summary = data.ready ? `Ingest setup complete (${data.required_complete}/${data.required_total}) for ${data.project_name}.` : `Ingest incomplete (${data.required_complete}/${data.required_total}) \u2014 still need: ${failed.map((s) => s.label).join(", ")}.`;
676
- return jsonText({
677
- ready: data.ready,
678
- projectId: data.project_id,
679
- projectName: data.project_name,
680
- requiredComplete: data.required_complete,
681
- requiredTotal: data.required_total,
682
- steps: data.steps.map((s) => ({
683
- id: s.id,
684
- label: s.label,
685
- passed: s.complete,
686
- required: s.required,
687
- hint: s.hint
688
- })),
689
- diagnostic: data.diagnostic ?? null,
690
- summary
691
- });
692
- }
693
- );
694
636
  server.registerTool(
695
637
  "diagnose_setup",
696
638
  {
@@ -708,7 +650,8 @@ function createMushiServer(config) {
708
650
  summary: z.string(),
709
651
  nextAction: z.string().optional(),
710
652
  ingest: z.unknown().optional(),
711
- dispatch: z.unknown().optional()
653
+ dispatch: z.unknown().optional(),
654
+ connection: z.unknown().optional()
712
655
  }
713
656
  },
714
657
  async (args) => {
@@ -748,162 +691,99 @@ function createMushiServer(config) {
748
691
  dispatch: { repoUrl: data.repoUrl ?? null, checks: data.checks }
749
692
  });
750
693
  }
751
- const ingest = await apiCall("/v1/sync/ingest-setup");
752
- let dispatchReady = true;
753
- let dispatchBlock;
754
- let dispatchChecks = null;
755
- if (resolvedId) {
756
- try {
757
- const preflight = await apiCall(`/v1/admin/projects/${resolvedId}/preflight`);
758
- dispatchReady = preflight.ready;
759
- dispatchChecks = preflight.checks;
760
- if (!preflight.ready) {
761
- const failed = preflight.checks.filter((c) => !c.ready);
762
- dispatchBlock = failed[0]?.hint;
763
- }
764
- } catch (err) {
765
- dispatchReady = false;
766
- const detail = err instanceof Error ? err.message : String(err);
767
- dispatchBlock = `Could not run dispatch preflight \u2014 ${detail}`;
768
- apiLog.warn("diagnose_setup dispatch preflight failed", { error: detail });
769
- }
770
- }
771
- const ingestFailed = ingest.steps.filter((s) => s.required && !s.complete);
772
- const ingestBlock = ingestFailed[0]?.hint;
773
- const ready = ingest.ready && dispatchReady;
774
- const nextAction = !ingest.ready ? ingestBlock ?? "Complete SDK ingest setup." : !dispatchReady ? dispatchBlock ?? "Complete dispatch preflight in Settings \u2192 Integrations." : "All setup checks pass \u2014 submit a test report to confirm end-to-end.";
775
- const summary = ready ? "Mushi ingest and dispatch setup look healthy." : !ingest.ready ? `Ingest incomplete \u2014 ${ingestFailed.map((s) => s.label).join(", ")}.` : "Ingest OK; dispatch preflight still has blockers.";
776
- return jsonResult({
777
- mode: "full",
778
- ready,
779
- summary,
780
- nextAction,
781
- ingest: { ready: ingest.ready, steps: ingest.steps },
782
- dispatch: resolvedId ? { ready: dispatchReady, checks: dispatchChecks } : null
783
- });
784
- }
785
- );
786
- server.registerTool(
787
- "diagnose_connection",
788
- {
789
- title: titleOf("diagnose_connection"),
790
- description: descOf("diagnose_connection"),
791
- annotations: annotationsFor("diagnose_connection"),
792
- inputSchema: NO_ARG_INPUT,
793
- outputSchema: {
794
- ready: z.boolean(),
795
- healthOk: z.boolean(),
796
- ingestReady: z.boolean(),
797
- dispatchReady: z.boolean(),
798
- endpoint: z.string().nullable(),
799
- projectId: z.string().nullable(),
800
- accessibleProjectCount: z.number().nullable(),
801
- issues: z.array(z.unknown()),
802
- nextAction: z.string(),
803
- summary: z.string()
804
- }
805
- },
806
- async () => {
807
- const issues = [];
694
+ const connIssues = [];
695
+ let healthOk = false;
808
696
  if (!apiKey?.startsWith("mushi_")) {
809
- issues.push({
697
+ connIssues.push({
810
698
  check: "mcp_api_key",
811
- detail: "MCP server API key missing or malformed",
812
- fix: "Run `mushi connect` to write MUSHI_API_KEY into .cursor/mcp.json, then restart the MCP server."
699
+ detail: "MCP server API key missing or malformed (expected prefix: mushi_)",
700
+ fix: "Run `mushi connect` or set MUSHI_API_KEY to a valid key in your MCP config."
813
701
  });
814
702
  }
815
703
  if (!apiEndpoint) {
816
- issues.push({
704
+ connIssues.push({
817
705
  check: "mcp_endpoint",
818
706
  detail: "No API endpoint configured",
819
- fix: "Set MUSHI_API_ENDPOINT to your `\u2026/functions/v1/api` URL in .cursor/mcp.json."
707
+ fix: "Set MUSHI_API_ENDPOINT to your `.../functions/v1/api` URL in your MCP config."
820
708
  });
821
- }
822
- let healthOk = false;
823
- if (apiEndpoint) {
709
+ } else {
824
710
  try {
825
711
  const healthRes = await doFetch(`${apiEndpoint.replace(/\/$/, "")}/health`, {
826
712
  signal: AbortSignal.timeout(5e3)
827
713
  });
828
714
  healthOk = healthRes.status === 200;
829
715
  if (!healthOk) {
830
- issues.push({
716
+ connIssues.push({
831
717
  check: "endpoint_health",
832
718
  detail: `GET /health \u2192 HTTP ${healthRes.status}`,
833
719
  fix: "Verify MUSHI_API_ENDPOINT and that the Supabase edge function is deployed."
834
720
  });
835
721
  }
836
722
  } catch (err) {
837
- issues.push({
723
+ connIssues.push({
838
724
  check: "endpoint_health",
839
725
  detail: err instanceof Error ? err.message : String(err),
840
- fix: "Check network connectivity and the endpoint URL in .cursor/mcp.json."
726
+ fix: "Check network connectivity and MUSHI_API_ENDPOINT in your MCP config."
841
727
  });
842
728
  }
843
729
  }
844
- let ingestReady = false;
845
- let dispatchReady = false;
846
730
  let accessibleProjectCount = null;
847
- if (!projectId && healthOk) {
731
+ if (!resolvedId && healthOk) {
848
732
  try {
849
- const overview = await apiCall("/v1/admin/mcp/account-overview");
733
+ const overview = await apiCall(
734
+ "/v1/admin/mcp/account-overview"
735
+ );
850
736
  accessibleProjectCount = overview.total;
851
737
  if (overview.total === 0) {
852
- issues.push({
738
+ connIssues.push({
853
739
  check: "no_accessible_projects",
854
740
  detail: "API key has no accessible projects",
855
- fix: "Mint an API key on a project (console \u2192 Projects \u2192 API Keys) or add MUSHI_PROJECT_ID to restrict to a single project."
741
+ fix: "Mint an API key on a project (console \u2192 Projects \u2192 API Keys) or add MUSHI_PROJECT_ID."
856
742
  });
857
743
  }
858
744
  } catch {
859
745
  }
860
746
  }
861
- try {
862
- const ingest = await apiCall("/v1/sync/ingest-setup");
863
- ingestReady = ingest.ready;
864
- if (!ingest.ready) {
865
- const failed = ingest.steps.filter((s) => s.required && !s.complete);
866
- issues.push({
867
- check: "ingest_setup",
868
- detail: `Incomplete: ${failed.map((s) => s.label).join(", ")}`,
869
- fix: failed[0]?.hint ?? "Paste the SDK snippet, start your dev server, submit a test report."
870
- });
871
- }
872
- } catch (err) {
873
- issues.push({
874
- check: "ingest_setup",
875
- detail: err instanceof Error ? err.message : String(err),
876
- fix: "Confirm API key is active for this project (Projects \u2192 API Keys)."
877
- });
878
- }
879
- if (projectId) {
747
+ const ingest = await apiCall("/v1/sync/ingest-setup");
748
+ let dispatchReady = true;
749
+ let dispatchBlock;
750
+ let dispatchChecks = null;
751
+ if (resolvedId) {
880
752
  try {
881
- const preflight = await apiCall(`/v1/admin/projects/${projectId}/preflight`);
753
+ const preflight = await apiCall(`/v1/admin/projects/${resolvedId}/preflight`);
882
754
  dispatchReady = preflight.ready;
755
+ dispatchChecks = preflight.checks;
883
756
  if (!preflight.ready) {
884
757
  const failed = preflight.checks.filter((c) => !c.ready);
885
- issues.push({
886
- check: "dispatch_preflight",
887
- detail: `Blocked: ${failed.map((c) => c.label).join(", ")}`,
888
- fix: failed[0]?.hint ?? "Open Settings \u2192 Integrations and complete GitHub + BYOK setup."
889
- });
758
+ dispatchBlock = failed[0]?.hint;
890
759
  }
891
- } catch {
760
+ } catch (err) {
761
+ dispatchReady = false;
762
+ const detail = err instanceof Error ? err.message : String(err);
763
+ dispatchBlock = `Could not run dispatch preflight \u2014 ${detail}`;
764
+ apiLog.warn("diagnose_setup dispatch preflight failed", { error: detail });
892
765
  }
893
766
  }
894
- const ready = issues.length === 0 && healthOk && ingestReady;
895
- const nextAction = issues[0]?.fix ?? (ready ? "Connection healthy \u2014 SDK ingest is working. Submit a report to confirm end-to-end." : "Run `mushi doctor` in your app repo for a full local checklist.");
767
+ const ingestFailed = ingest.steps.filter((s) => s.required && !s.complete);
768
+ const ingestBlock = ingestFailed[0]?.hint;
769
+ const connOk = connIssues.length === 0;
770
+ const ready = connOk && ingest.ready && dispatchReady;
771
+ const nextAction = !connOk ? connIssues[0]?.fix ?? "Fix the connection issue above." : !ingest.ready ? ingestBlock ?? "Complete SDK ingest setup." : !dispatchReady ? dispatchBlock ?? "Complete dispatch preflight in Settings \u2192 Integrations." : "All setup checks pass \u2014 submit a test report to confirm end-to-end.";
772
+ const summary = ready ? "Mushi connection, ingest, and dispatch setup look healthy." : !connOk ? `Connection issue \u2014 ${connIssues[0]?.check}: ${connIssues[0]?.detail}` : !ingest.ready ? `Ingest incomplete \u2014 ${ingestFailed.map((s) => s.label).join(", ")}.` : "Ingest OK; dispatch preflight still has blockers.";
896
773
  return jsonResult({
774
+ mode: "full",
897
775
  ready,
898
- healthOk,
899
- ingestReady,
900
- dispatchReady,
901
- endpoint: apiEndpoint ?? null,
902
- projectId: projectId ?? null,
903
- accessibleProjectCount,
904
- issues,
776
+ summary,
905
777
  nextAction,
906
- summary: ready ? "MCP credentials valid; ingest pipeline ready." : `Connection issue \u2014 ${issues[0]?.check ?? "unknown"}: ${nextAction}`
778
+ connection: {
779
+ healthOk,
780
+ endpoint: apiEndpoint ?? null,
781
+ projectId: resolvedId ?? null,
782
+ accessibleProjectCount,
783
+ issues: connIssues
784
+ },
785
+ ingest: { ready: ingest.ready, steps: ingest.steps },
786
+ dispatch: resolvedId ? { ready: dispatchReady, checks: dispatchChecks } : null
907
787
  });
908
788
  }
909
789
  );
@@ -1316,8 +1196,8 @@ function createMushiServer(config) {
1316
1196
  server.registerTool(
1317
1197
  "merge_fix",
1318
1198
  {
1319
- title: "Merge fix PR",
1320
- description: "Squash-merge a fix attempt PR and mark the linked report fixed.",
1199
+ title: titleOf("merge_fix"),
1200
+ description: descOf("merge_fix"),
1321
1201
  annotations: annotationsFor("merge_fix"),
1322
1202
  inputSchema: {
1323
1203
  fixId: z.string().describe("Fix attempt UUID"),
@@ -1335,8 +1215,8 @@ function createMushiServer(config) {
1335
1215
  server.registerTool(
1336
1216
  "refresh_ci",
1337
1217
  {
1338
- title: "Refresh fix CI status",
1339
- description: "Pull the latest GitHub check-run status for a fix attempt.",
1218
+ title: titleOf("refresh_ci"),
1219
+ description: descOf("refresh_ci"),
1340
1220
  annotations: annotationsFor("refresh_ci"),
1341
1221
  inputSchema: {
1342
1222
  fixId: z.string().describe("Fix attempt UUID")
@@ -1618,6 +1498,22 @@ function createMushiServer(config) {
1618
1498
  };
1619
1499
  }
1620
1500
  );
1501
+ server.registerTool(
1502
+ "activation_status",
1503
+ {
1504
+ title: titleOf("activation_status"),
1505
+ description: descOf("activation_status"),
1506
+ annotations: annotationsFor("activation_status"),
1507
+ inputSchema: {
1508
+ project_id: z.string().optional().describe("Project UUID (defaults to the configured project).")
1509
+ }
1510
+ },
1511
+ async (args) => {
1512
+ const pid = args.project_id ?? projectId;
1513
+ const qs = pid ? `?project_id=${encodeURIComponent(pid)}` : "";
1514
+ return jsonResult(await apiCall(`/v1/admin/activation${qs}`));
1515
+ }
1516
+ );
1621
1517
  server.resource(
1622
1518
  "activation_status",
1623
1519
  "mushi://activation",
@@ -1716,7 +1612,7 @@ Prefer items that are bottlenecks or critical severity. Skip filler.`
1716
1612
  text: `You are a Mushi onboarding copilot. Use the MCP tools:
1717
1613
  1. Read mushi://activation for unified setup posture.
1718
1614
  2. Read project://integration-health if GitHub or Sentry looks blocked.
1719
- 3. Call get_activation_status if the resource is unavailable.
1615
+ 3. Call diagnose_setup if the resource is unavailable.
1720
1616
 
1721
1617
  Then output:
1722
1618
  - **Status:** one sentence on what is done vs blocked
@@ -2149,36 +2045,6 @@ Be specific. No generic advice.`
2149
2045
  return jsonText({ ok: true, message: `Step ${step_index} \u2192 ${args.status}` });
2150
2046
  }
2151
2047
  );
2152
- server.registerTool(
2153
- "get_activation_status",
2154
- {
2155
- title: titleOf("get_activation_status"),
2156
- description: descOf("get_activation_status"),
2157
- annotations: annotationsFor("get_activation_status"),
2158
- inputSchema: {
2159
- project_id: z.string().optional().describe("Optional project UUID override")
2160
- }
2161
- },
2162
- async (args) => {
2163
- const qs = args.project_id ? `?project_id=${encodeURIComponent(args.project_id)}` : "";
2164
- const data = await apiCall(`/v1/admin/activation${qs}`);
2165
- return jsonText(data);
2166
- }
2167
- );
2168
- server.registerTool(
2169
- "get_reporter_thread",
2170
- {
2171
- title: titleOf("get_reporter_thread"),
2172
- description: descOf("get_reporter_thread"),
2173
- annotations: annotationsFor("get_reporter_thread"),
2174
- inputSchema: { reportId: z.string().describe("The report UUID") }
2175
- },
2176
- // The reporter thread is the `comments` lane of the unified report
2177
- // timeline. There is no standalone admin `/comments` route (only the
2178
- // reporter-token-gated `/v1/reporter/reports/:id/comments`), so we read the
2179
- // admin-authed timeline, which also carries fix / QA / status lanes.
2180
- async (args) => jsonText(await apiCall(`/v1/admin/reports/${args.reportId}/timeline`))
2181
- );
2182
2048
  server.registerTool(
2183
2049
  "ask_codebase",
2184
2050
  {
@@ -2395,6 +2261,39 @@ Be specific. No generic advice.`
2395
2261
  return result;
2396
2262
  });
2397
2263
  }
2264
+ {
2265
+ const llAliasServer = server.server;
2266
+ const innerHandler = llAliasServer?._requestHandlers?.get("tools/call");
2267
+ if (typeof innerHandler === "function") {
2268
+ llAliasServer._requestHandlers.set("tools/call", async (...args) => {
2269
+ const req = args[0];
2270
+ const originalName = req?.params?.name;
2271
+ const canonicalName = originalName ? DEPRECATED_TOOL_ALIASES[originalName] : void 0;
2272
+ if (canonicalName) {
2273
+ const rewritten = {
2274
+ ...args[0],
2275
+ params: { ...req?.params ?? {}, name: canonicalName }
2276
+ };
2277
+ const result = await innerHandler(rewritten, ...args.slice(1));
2278
+ if (result != null && typeof result === "object" && "content" in result && Array.isArray(result.content)) {
2279
+ const r = result;
2280
+ return {
2281
+ ...r,
2282
+ content: [
2283
+ {
2284
+ type: "text",
2285
+ text: `\u26A0\uFE0F Deprecated: \`${originalName}\` was renamed to \`${canonicalName}\`. Update your agent config \u2014 this alias will be removed in the next release.`
2286
+ },
2287
+ ...r.content
2288
+ ]
2289
+ };
2290
+ }
2291
+ return result;
2292
+ }
2293
+ return innerHandler(...args);
2294
+ });
2295
+ }
2296
+ }
2398
2297
  return server;
2399
2298
  }
2400
2299
  export {
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@mushi-mushi/mcp",
3
3
  "mcpName": "io.github.kensaurus/mushi-mushi",
4
- "version": "0.17.1",
4
+ "version": "0.18.0",
5
5
  "license": "MIT",
6
6
  "description": "MCP server for Mushi Mushi — triage user-felt bugs, pull evidence (screenshots, console logs, network requests), check blast radius, and dispatch fix PRs, all from your AI coding agent",
7
7
  "type": "module",