@mushi-mushi/mcp 0.20.0 → 0.20.1
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/README.md +3 -3
- package/dist/catalog.js +1 -1
- package/dist/{chunk-OZJEY3QR.js → chunk-TP2QQWDJ.js} +22 -9
- package/dist/{chunk-VBXXUK5G.js → chunk-ZSVRLSW5.js} +4 -2
- package/dist/clients.d.ts +1 -1
- package/dist/clients.js +2 -2
- package/dist/feature-groups.js +1 -1
- package/dist/index.js +402 -195
- package/dist/server.js +378 -186
- package/package.json +1 -1
package/dist/server.js
CHANGED
|
@@ -3,14 +3,14 @@ import {
|
|
|
3
3
|
TDD_TOOL_CATALOG,
|
|
4
4
|
TOOL_CATALOG,
|
|
5
5
|
USE_MUSHI_INTENTS
|
|
6
|
-
} from "./chunk-
|
|
6
|
+
} from "./chunk-TP2QQWDJ.js";
|
|
7
7
|
import {
|
|
8
8
|
MUSHI_SERVER_METADATA
|
|
9
9
|
} from "./chunk-EANW5YTI.js";
|
|
10
10
|
import {
|
|
11
11
|
DEPRECATED_TOOL_ALIASES,
|
|
12
12
|
toolMatchesFeatures
|
|
13
|
-
} from "./chunk-
|
|
13
|
+
} from "./chunk-ZSVRLSW5.js";
|
|
14
14
|
|
|
15
15
|
// src/server.ts
|
|
16
16
|
import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
|
|
@@ -182,7 +182,7 @@ function createMushiServer(config) {
|
|
|
182
182
|
// Authorization is accepted by `adminOrApiKey` only as a JWT, but we
|
|
183
183
|
// still send it for endpoints still behind plain `jwtAuth` (legacy)
|
|
184
184
|
// and for transparent proxies that strip X-Mushi-* headers.
|
|
185
|
-
|
|
185
|
+
Authorization: `Bearer ${apiKey}`,
|
|
186
186
|
"X-Mushi-Api-Key": apiKey,
|
|
187
187
|
"X-Request-Id": requestId,
|
|
188
188
|
...projectId ? { "X-Mushi-Project-Id": projectId } : {},
|
|
@@ -233,9 +233,7 @@ function createMushiServer(config) {
|
|
|
233
233
|
}
|
|
234
234
|
if (projectId) return projectId;
|
|
235
235
|
try {
|
|
236
|
-
const data = await apiCall(
|
|
237
|
-
"/v1/admin/mcp/account-overview"
|
|
238
|
-
);
|
|
236
|
+
const data = await apiCall("/v1/admin/mcp/account-overview");
|
|
239
237
|
if (data.total === 1 && data.projects[0]) {
|
|
240
238
|
return data.projects[0].id;
|
|
241
239
|
}
|
|
@@ -346,9 +344,12 @@ function createMushiServer(config) {
|
|
|
346
344
|
params.set("limit", String(Math.min(args.limit ?? 20, 100)));
|
|
347
345
|
const pid = await resolveProjectId(args.project_id);
|
|
348
346
|
const extraHeaders = pid !== projectId ? { "X-Mushi-Project-Id": pid } : {};
|
|
349
|
-
const data = await apiCall(
|
|
350
|
-
|
|
351
|
-
|
|
347
|
+
const data = await apiCall(
|
|
348
|
+
`/v1/admin/reports?${params}`,
|
|
349
|
+
{
|
|
350
|
+
headers: extraHeaders
|
|
351
|
+
}
|
|
352
|
+
);
|
|
352
353
|
return jsonResult(data);
|
|
353
354
|
}
|
|
354
355
|
);
|
|
@@ -371,7 +372,10 @@ function createMushiServer(config) {
|
|
|
371
372
|
return {
|
|
372
373
|
...res,
|
|
373
374
|
resource_links: [
|
|
374
|
-
{
|
|
375
|
+
{
|
|
376
|
+
uri: `project://reports/${args.reportId}`,
|
|
377
|
+
title: `Report ${args.reportId.slice(0, 8)}\u2026`
|
|
378
|
+
}
|
|
375
379
|
]
|
|
376
380
|
};
|
|
377
381
|
}
|
|
@@ -475,17 +479,20 @@ function createMushiServer(config) {
|
|
|
475
479
|
const report = await apiCall(`/v1/admin/reports/${args.reportId}`, {
|
|
476
480
|
headers
|
|
477
481
|
});
|
|
478
|
-
return wrappedJsonResult(
|
|
479
|
-
|
|
480
|
-
|
|
481
|
-
|
|
482
|
-
|
|
483
|
-
|
|
484
|
-
|
|
485
|
-
|
|
486
|
-
|
|
487
|
-
|
|
488
|
-
|
|
482
|
+
return wrappedJsonResult(
|
|
483
|
+
{
|
|
484
|
+
report,
|
|
485
|
+
// Paste-ready fix prompt composed server-side by composeFixPacket()
|
|
486
|
+
// (diagnosis + repro + suggested fix + relevant code + blast radius).
|
|
487
|
+
// Hand this straight to the editing agent — no second LLM key needed.
|
|
488
|
+
fixPrompt: report.fix_packet ?? null,
|
|
489
|
+
reproductionSteps: report.reproduction_steps ?? [],
|
|
490
|
+
component: report.component,
|
|
491
|
+
rootCause: report.stage2_analysis?.rootCause,
|
|
492
|
+
bugOntologyTags: report.bug_ontology_tags
|
|
493
|
+
},
|
|
494
|
+
"fix context"
|
|
495
|
+
);
|
|
489
496
|
}
|
|
490
497
|
);
|
|
491
498
|
server.registerTool(
|
|
@@ -534,7 +541,9 @@ function createMushiServer(config) {
|
|
|
534
541
|
seed: args.seed,
|
|
535
542
|
depth: String(Math.min(args.depth ?? 2, 4))
|
|
536
543
|
});
|
|
537
|
-
const data = await apiCall(
|
|
544
|
+
const data = await apiCall(
|
|
545
|
+
`/v1/admin/graph/traverse?${params}`
|
|
546
|
+
);
|
|
538
547
|
return jsonResult(data);
|
|
539
548
|
}
|
|
540
549
|
);
|
|
@@ -545,7 +554,9 @@ function createMushiServer(config) {
|
|
|
545
554
|
description: descOf("get_graph_neighborhood"),
|
|
546
555
|
annotations: annotationsFor("get_graph_neighborhood"),
|
|
547
556
|
inputSchema: {
|
|
548
|
-
seed: z.string().describe(
|
|
557
|
+
seed: z.string().describe(
|
|
558
|
+
"Starting graph node id or label to expand around (e.g. an inventory Action id or component name)"
|
|
559
|
+
),
|
|
549
560
|
depth: z.number().int().min(1).max(4).optional().describe("BFS hops to traverse outward. Default 2; clamped to a max of 4.")
|
|
550
561
|
},
|
|
551
562
|
outputSchema: {
|
|
@@ -558,7 +569,9 @@ function createMushiServer(config) {
|
|
|
558
569
|
seed: args.seed,
|
|
559
570
|
depth: String(Math.min(args.depth ?? 2, 4))
|
|
560
571
|
});
|
|
561
|
-
const data = await apiCall(
|
|
572
|
+
const data = await apiCall(
|
|
573
|
+
`/v1/admin/graph/traverse?${params}`
|
|
574
|
+
);
|
|
562
575
|
return jsonResult(data);
|
|
563
576
|
}
|
|
564
577
|
);
|
|
@@ -568,7 +581,9 @@ function createMushiServer(config) {
|
|
|
568
581
|
title: titleOf("get_graph_node"),
|
|
569
582
|
description: descOf("get_graph_node"),
|
|
570
583
|
annotations: annotationsFor("get_graph_node"),
|
|
571
|
-
inputSchema: {
|
|
584
|
+
inputSchema: {
|
|
585
|
+
nodeId: z.string().describe("The graph_nodes.id of the node to fetch (UUID).")
|
|
586
|
+
},
|
|
572
587
|
outputSchema: {
|
|
573
588
|
node: z.unknown().describe("Single graph_nodes row including metadata (Action nodes carry v2 status)")
|
|
574
589
|
}
|
|
@@ -590,7 +605,8 @@ function createMushiServer(config) {
|
|
|
590
605
|
},
|
|
591
606
|
async (args) => {
|
|
592
607
|
const pid = args.projectId ?? projectId;
|
|
593
|
-
if (!pid)
|
|
608
|
+
if (!pid)
|
|
609
|
+
throw new MushiApiError(400, "MISSING_PROJECT", "projectId is required for get_inventory");
|
|
594
610
|
return jsonText(await apiCall(`/v1/admin/inventory/${pid}`));
|
|
595
611
|
}
|
|
596
612
|
);
|
|
@@ -608,7 +624,8 @@ function createMushiServer(config) {
|
|
|
608
624
|
},
|
|
609
625
|
async (args) => {
|
|
610
626
|
const pid = args.projectId ?? projectId;
|
|
611
|
-
if (!pid)
|
|
627
|
+
if (!pid)
|
|
628
|
+
throw new MushiApiError(400, "MISSING_PROJECT", "projectId is required for diff_inventory");
|
|
612
629
|
const q = new URLSearchParams({ from: args.fromSha, to: args.toSha });
|
|
613
630
|
return jsonText(await apiCall(`/v1/admin/inventory/${pid}/diff?${q}`));
|
|
614
631
|
}
|
|
@@ -631,12 +648,19 @@ function createMushiServer(config) {
|
|
|
631
648
|
},
|
|
632
649
|
async (args) => {
|
|
633
650
|
const pid = args.projectId ?? projectId;
|
|
634
|
-
if (!pid)
|
|
651
|
+
if (!pid)
|
|
652
|
+
throw new MushiApiError(
|
|
653
|
+
400,
|
|
654
|
+
"MISSING_PROJECT",
|
|
655
|
+
"projectId is required for list_gate_findings"
|
|
656
|
+
);
|
|
635
657
|
const q = new URLSearchParams();
|
|
636
658
|
if (args.gate) q.set("gate", args.gate);
|
|
637
659
|
if (args.severity) q.set("severity", args.severity);
|
|
638
660
|
const suffix = q.toString() ? `?${q}` : "";
|
|
639
|
-
const data = await apiCall(
|
|
661
|
+
const data = await apiCall(
|
|
662
|
+
`/v1/admin/inventory/${pid}/findings${suffix}`
|
|
663
|
+
);
|
|
640
664
|
return jsonResult(data);
|
|
641
665
|
}
|
|
642
666
|
);
|
|
@@ -646,7 +670,9 @@ function createMushiServer(config) {
|
|
|
646
670
|
title: titleOf("suggest_fix"),
|
|
647
671
|
description: descOf("suggest_fix"),
|
|
648
672
|
annotations: annotationsFor("suggest_fix"),
|
|
649
|
-
inputSchema: {
|
|
673
|
+
inputSchema: {
|
|
674
|
+
reportId: z.string().describe("Report UUID to read the Stage-2 suggested-fix slice for")
|
|
675
|
+
},
|
|
650
676
|
outputSchema: {
|
|
651
677
|
reportId: z.string().describe("The report this slice was read from"),
|
|
652
678
|
rootCause: z.unknown().describe("Stage-2 root-cause hint, or null if not yet classified"),
|
|
@@ -675,7 +701,11 @@ function createMushiServer(config) {
|
|
|
675
701
|
title: titleOf("run_nl_query"),
|
|
676
702
|
description: descOf("run_nl_query"),
|
|
677
703
|
annotations: annotationsFor("run_nl_query"),
|
|
678
|
-
inputSchema: {
|
|
704
|
+
inputSchema: {
|
|
705
|
+
question: z.string().describe(
|
|
706
|
+
'Question in plain English, e.g. "Which components had the most critical bugs this week?"'
|
|
707
|
+
)
|
|
708
|
+
}
|
|
679
709
|
},
|
|
680
710
|
async (args) => {
|
|
681
711
|
const data = await apiCall("/v1/admin/query", {
|
|
@@ -692,7 +722,9 @@ function createMushiServer(config) {
|
|
|
692
722
|
description: descOf("diagnose_setup"),
|
|
693
723
|
annotations: annotationsFor("diagnose_setup"),
|
|
694
724
|
inputSchema: {
|
|
695
|
-
mode: z.enum(["full", "ingest", "dispatch"]).optional().describe(
|
|
725
|
+
mode: z.enum(["full", "ingest", "dispatch"]).optional().describe(
|
|
726
|
+
"full (default) = ingest + dispatch; ingest = SDK pipeline only; dispatch = fix preflight only."
|
|
727
|
+
),
|
|
696
728
|
project_id: z.string().optional().describe("Project UUID for dispatch checks (defaults to configured project)."),
|
|
697
729
|
projectId: z.string().optional().describe("Alias for project_id.")
|
|
698
730
|
},
|
|
@@ -730,7 +762,11 @@ function createMushiServer(config) {
|
|
|
730
762
|
}
|
|
731
763
|
if (mode === "dispatch") {
|
|
732
764
|
if (!resolvedId) {
|
|
733
|
-
throw new MushiApiError(
|
|
765
|
+
throw new MushiApiError(
|
|
766
|
+
400,
|
|
767
|
+
"MISSING_PROJECT",
|
|
768
|
+
"project_id is required for dispatch mode"
|
|
769
|
+
);
|
|
734
770
|
}
|
|
735
771
|
const data = await apiCall(`/v1/admin/projects/${resolvedId}/preflight`);
|
|
736
772
|
const failed = data.checks.filter((c) => !c.ready);
|
|
@@ -864,7 +900,12 @@ function createMushiServer(config) {
|
|
|
864
900
|
async (args) => {
|
|
865
901
|
const query = args.query ?? "";
|
|
866
902
|
const hits = searchMushiDocs(query, args.limit ?? 8);
|
|
867
|
-
const results = hits.map(({ title, path, excerpt, score }) => ({
|
|
903
|
+
const results = hits.map(({ title, path, excerpt, score }) => ({
|
|
904
|
+
title,
|
|
905
|
+
path,
|
|
906
|
+
excerpt,
|
|
907
|
+
score
|
|
908
|
+
}));
|
|
868
909
|
return jsonResult({ query, results });
|
|
869
910
|
}
|
|
870
911
|
);
|
|
@@ -1014,7 +1055,9 @@ function createMushiServer(config) {
|
|
|
1014
1055
|
} : { error: String(reportRes.reason) };
|
|
1015
1056
|
return jsonText({
|
|
1016
1057
|
evidence,
|
|
1017
|
-
reporter_thread: timeline ?? {
|
|
1058
|
+
reporter_thread: timeline ?? {
|
|
1059
|
+
error: String(timelineRes.reason)
|
|
1060
|
+
}
|
|
1018
1061
|
});
|
|
1019
1062
|
}
|
|
1020
1063
|
);
|
|
@@ -1049,15 +1092,23 @@ function createMushiServer(config) {
|
|
|
1049
1092
|
const includeLogs = args.include_logs !== false;
|
|
1050
1093
|
const [reportRes, evidenceRes, similarRes, fixCtxRes, blastRes, logsRes] = await Promise.allSettled([
|
|
1051
1094
|
apiCall(`/v1/admin/reports/${args.report_id}`, { headers }),
|
|
1052
|
-
apiCall(`/v1/admin/reports/${args.report_id}/timeline`, {
|
|
1095
|
+
apiCall(`/v1/admin/reports/${args.report_id}/timeline`, {
|
|
1096
|
+
headers
|
|
1097
|
+
}),
|
|
1053
1098
|
apiCall(`/v1/admin/reports/similarity`, {
|
|
1054
1099
|
method: "POST",
|
|
1055
1100
|
headers,
|
|
1056
1101
|
body: JSON.stringify({ report_id: args.report_id })
|
|
1057
1102
|
}).catch(() => null),
|
|
1058
|
-
apiCall(`/v1/admin/reports/${args.report_id}/fix-context`, { headers }).catch(
|
|
1059
|
-
|
|
1060
|
-
|
|
1103
|
+
apiCall(`/v1/admin/reports/${args.report_id}/fix-context`, { headers }).catch(
|
|
1104
|
+
() => null
|
|
1105
|
+
),
|
|
1106
|
+
apiCall(`/v1/admin/reports/${args.report_id}/blast-radius`, { headers }).catch(
|
|
1107
|
+
() => null
|
|
1108
|
+
),
|
|
1109
|
+
includeLogs ? apiCall(`/v1/admin/mcp/logs/${pid}?limit=20&level=warn`, { headers }).catch(
|
|
1110
|
+
() => null
|
|
1111
|
+
) : Promise.resolve(null)
|
|
1061
1112
|
]);
|
|
1062
1113
|
const report = reportRes.status === "fulfilled" ? reportRes.value : null;
|
|
1063
1114
|
const severity = report ? report.severity : "unknown";
|
|
@@ -1124,7 +1175,10 @@ function createMushiServer(config) {
|
|
|
1124
1175
|
return {
|
|
1125
1176
|
...res,
|
|
1126
1177
|
resource_links: [
|
|
1127
|
-
{
|
|
1178
|
+
{
|
|
1179
|
+
uri: `project://reports/${args.report_id}`,
|
|
1180
|
+
title: `Report ${args.report_id.slice(0, 8)}\u2026`
|
|
1181
|
+
},
|
|
1128
1182
|
...pid ? [{ uri: `project://dashboard`, title: "Project dashboard" }] : []
|
|
1129
1183
|
]
|
|
1130
1184
|
};
|
|
@@ -1143,7 +1197,9 @@ function createMushiServer(config) {
|
|
|
1143
1197
|
filesChanged: z.array(z.string()).describe("Repo-relative paths modified by the fix"),
|
|
1144
1198
|
linesChanged: z.number().describe("Total lines added + removed across filesChanged"),
|
|
1145
1199
|
summary: z.string().describe("One-line human summary of what the fix changed"),
|
|
1146
|
-
idempotencyKey: z.string().uuid().optional().describe(
|
|
1200
|
+
idempotencyKey: z.string().uuid().optional().describe(
|
|
1201
|
+
"Optional UUID \u2014 resend the same key to safely retry without creating duplicate fix rows"
|
|
1202
|
+
)
|
|
1147
1203
|
},
|
|
1148
1204
|
outputSchema: {
|
|
1149
1205
|
ok: z.boolean().describe("True when the fix_attempt row was created and marked completed"),
|
|
@@ -1181,8 +1237,12 @@ function createMushiServer(config) {
|
|
|
1181
1237
|
inputSchema: {
|
|
1182
1238
|
reportId: z.string().uuid().describe("Report UUID to fix"),
|
|
1183
1239
|
agent: z.enum(["claude_code", "codex", "rest_worker", "mcp"]).optional().describe("Override the agent adapter"),
|
|
1184
|
-
idempotencyKey: z.string().uuid().optional().describe(
|
|
1185
|
-
|
|
1240
|
+
idempotencyKey: z.string().uuid().optional().describe(
|
|
1241
|
+
"Optional RFC 4122 UUID. Resend the same key to safely retry without dispatching a duplicate fix job (Idempotency-Key IETF draft)."
|
|
1242
|
+
),
|
|
1243
|
+
inventoryActionNodeId: z.string().uuid().optional().describe(
|
|
1244
|
+
"Optional inventory Action node UUID for spec-traceability (\xA72.10). When provided, the fix-worker embeds the expected_outcome contract in the LLM prompt and runs validateAgainstSpec before opening the PR."
|
|
1245
|
+
)
|
|
1186
1246
|
},
|
|
1187
1247
|
outputSchema: {
|
|
1188
1248
|
fixId: z.string(),
|
|
@@ -1255,11 +1315,19 @@ function createMushiServer(config) {
|
|
|
1255
1315
|
},
|
|
1256
1316
|
async (args) => {
|
|
1257
1317
|
const pid = args.projectId ?? projectId;
|
|
1258
|
-
if (!pid)
|
|
1259
|
-
|
|
1260
|
-
|
|
1261
|
-
|
|
1262
|
-
|
|
1318
|
+
if (!pid)
|
|
1319
|
+
throw new MushiApiError(
|
|
1320
|
+
400,
|
|
1321
|
+
"MISSING_PROJECT",
|
|
1322
|
+
"projectId is required for test_gen_from_report"
|
|
1323
|
+
);
|
|
1324
|
+
const data = await apiCall(
|
|
1325
|
+
`/v1/admin/inventory/${pid}/test-gen/from-report/${args.reportId}`,
|
|
1326
|
+
{
|
|
1327
|
+
method: "POST",
|
|
1328
|
+
body: JSON.stringify({})
|
|
1329
|
+
}
|
|
1330
|
+
);
|
|
1263
1331
|
return jsonText(data);
|
|
1264
1332
|
}
|
|
1265
1333
|
);
|
|
@@ -1338,7 +1406,17 @@ function createMushiServer(config) {
|
|
|
1338
1406
|
annotations: annotationsFor("transition_status"),
|
|
1339
1407
|
inputSchema: {
|
|
1340
1408
|
reportId: z.string().describe("Report UUID"),
|
|
1341
|
-
status: z.enum([
|
|
1409
|
+
status: z.enum([
|
|
1410
|
+
"pending",
|
|
1411
|
+
"classified",
|
|
1412
|
+
"grouped",
|
|
1413
|
+
"fixing",
|
|
1414
|
+
"fixed",
|
|
1415
|
+
"resolved",
|
|
1416
|
+
"verified",
|
|
1417
|
+
"reopened",
|
|
1418
|
+
"dismissed"
|
|
1419
|
+
]).describe("Target status"),
|
|
1342
1420
|
reason: z.string().optional().describe("Reason for the transition (audit trail)")
|
|
1343
1421
|
}
|
|
1344
1422
|
},
|
|
@@ -1362,7 +1440,12 @@ function createMushiServer(config) {
|
|
|
1362
1440
|
},
|
|
1363
1441
|
async (args) => {
|
|
1364
1442
|
const pid = args.projectId ?? projectId;
|
|
1365
|
-
if (!pid)
|
|
1443
|
+
if (!pid)
|
|
1444
|
+
throw new MushiApiError(
|
|
1445
|
+
400,
|
|
1446
|
+
"MISSING_PROJECT",
|
|
1447
|
+
"projectId is required for setup_repo_for_mushi"
|
|
1448
|
+
);
|
|
1366
1449
|
const data = await apiCall(`/v1/admin/projects/${pid}/repo/bootstrap`, {
|
|
1367
1450
|
method: "POST",
|
|
1368
1451
|
body: JSON.stringify({})
|
|
@@ -1427,23 +1510,45 @@ function createMushiServer(config) {
|
|
|
1427
1510
|
"project://stats",
|
|
1428
1511
|
{ description: "Report counts, category breakdown, severity distribution" },
|
|
1429
1512
|
async () => ({
|
|
1430
|
-
contents: [
|
|
1513
|
+
contents: [
|
|
1514
|
+
{
|
|
1515
|
+
uri: "project://stats",
|
|
1516
|
+
mimeType: "application/json",
|
|
1517
|
+
text: JSON.stringify(await apiCall("/v1/admin/stats"), null, 2)
|
|
1518
|
+
}
|
|
1519
|
+
]
|
|
1431
1520
|
})
|
|
1432
1521
|
);
|
|
1433
1522
|
server.resource(
|
|
1434
1523
|
"project_settings",
|
|
1435
1524
|
"project://settings",
|
|
1436
|
-
{
|
|
1525
|
+
{
|
|
1526
|
+
description: "Project configuration \u2014 autofix agent, plugins enabled, ontology, LLM budgets"
|
|
1527
|
+
},
|
|
1437
1528
|
async () => ({
|
|
1438
|
-
contents: [
|
|
1529
|
+
contents: [
|
|
1530
|
+
{
|
|
1531
|
+
uri: "project://settings",
|
|
1532
|
+
mimeType: "application/json",
|
|
1533
|
+
text: JSON.stringify(await apiCall("/v1/admin/settings"), null, 2)
|
|
1534
|
+
}
|
|
1535
|
+
]
|
|
1439
1536
|
})
|
|
1440
1537
|
);
|
|
1441
1538
|
server.resource(
|
|
1442
1539
|
"project_dashboard",
|
|
1443
1540
|
"project://dashboard",
|
|
1444
|
-
{
|
|
1541
|
+
{
|
|
1542
|
+
description: "PDCA health snapshot \u2014 stage counts, bottleneck, recent activity (same payload the admin console polls)"
|
|
1543
|
+
},
|
|
1445
1544
|
async () => ({
|
|
1446
|
-
contents: [
|
|
1545
|
+
contents: [
|
|
1546
|
+
{
|
|
1547
|
+
uri: "project://dashboard",
|
|
1548
|
+
mimeType: "application/json",
|
|
1549
|
+
text: JSON.stringify(await apiCall("/v1/admin/dashboard"), null, 2)
|
|
1550
|
+
}
|
|
1551
|
+
]
|
|
1447
1552
|
})
|
|
1448
1553
|
);
|
|
1449
1554
|
server.registerTool(
|
|
@@ -1458,14 +1563,16 @@ function createMushiServer(config) {
|
|
|
1458
1563
|
}
|
|
1459
1564
|
},
|
|
1460
1565
|
async ({ limit, range }) => ({
|
|
1461
|
-
content: [
|
|
1462
|
-
|
|
1463
|
-
|
|
1464
|
-
|
|
1465
|
-
|
|
1466
|
-
|
|
1467
|
-
|
|
1468
|
-
|
|
1566
|
+
content: [
|
|
1567
|
+
{
|
|
1568
|
+
type: "text",
|
|
1569
|
+
text: JSON.stringify(
|
|
1570
|
+
await apiCall(`/v1/admin/rewards/leaderboard?range=${range}&limit=${limit}`),
|
|
1571
|
+
null,
|
|
1572
|
+
2
|
|
1573
|
+
)
|
|
1574
|
+
}
|
|
1575
|
+
]
|
|
1469
1576
|
})
|
|
1470
1577
|
);
|
|
1471
1578
|
server.registerTool(
|
|
@@ -1481,18 +1588,20 @@ function createMushiServer(config) {
|
|
|
1481
1588
|
}
|
|
1482
1589
|
},
|
|
1483
1590
|
async ({ external_user_id, points, reason }) => ({
|
|
1484
|
-
content: [
|
|
1485
|
-
|
|
1486
|
-
|
|
1487
|
-
|
|
1488
|
-
|
|
1489
|
-
|
|
1490
|
-
|
|
1491
|
-
|
|
1492
|
-
|
|
1493
|
-
|
|
1494
|
-
|
|
1495
|
-
|
|
1591
|
+
content: [
|
|
1592
|
+
{
|
|
1593
|
+
type: "text",
|
|
1594
|
+
text: JSON.stringify(
|
|
1595
|
+
await apiCall("/v1/admin/rewards/bonus-points", {
|
|
1596
|
+
method: "POST",
|
|
1597
|
+
headers: { "Content-Type": "application/json" },
|
|
1598
|
+
body: JSON.stringify({ external_user_id, points, reason })
|
|
1599
|
+
}),
|
|
1600
|
+
null,
|
|
1601
|
+
2
|
|
1602
|
+
)
|
|
1603
|
+
}
|
|
1604
|
+
]
|
|
1496
1605
|
})
|
|
1497
1606
|
);
|
|
1498
1607
|
server.registerTool(
|
|
@@ -1508,18 +1617,20 @@ function createMushiServer(config) {
|
|
|
1508
1617
|
}
|
|
1509
1618
|
},
|
|
1510
1619
|
async ({ external_user_id, tier_slug, reason }) => ({
|
|
1511
|
-
content: [
|
|
1512
|
-
|
|
1513
|
-
|
|
1514
|
-
|
|
1515
|
-
|
|
1516
|
-
|
|
1517
|
-
|
|
1518
|
-
|
|
1519
|
-
|
|
1520
|
-
|
|
1521
|
-
|
|
1522
|
-
|
|
1620
|
+
content: [
|
|
1621
|
+
{
|
|
1622
|
+
type: "text",
|
|
1623
|
+
text: JSON.stringify(
|
|
1624
|
+
await apiCall("/v1/admin/rewards/set-tier", {
|
|
1625
|
+
method: "POST",
|
|
1626
|
+
headers: { "Content-Type": "application/json" },
|
|
1627
|
+
body: JSON.stringify({ external_user_id, tier_slug, reason })
|
|
1628
|
+
}),
|
|
1629
|
+
null,
|
|
1630
|
+
2
|
|
1631
|
+
)
|
|
1632
|
+
}
|
|
1633
|
+
]
|
|
1523
1634
|
})
|
|
1524
1635
|
);
|
|
1525
1636
|
server.resource(
|
|
@@ -1529,11 +1640,13 @@ function createMushiServer(config) {
|
|
|
1529
1640
|
description: "Returns the privacy posture for this project: storage region, LLM provider, whether BYOK is configured, data retention window, and last audit timestamp."
|
|
1530
1641
|
},
|
|
1531
1642
|
async () => ({
|
|
1532
|
-
contents: [
|
|
1533
|
-
|
|
1534
|
-
|
|
1535
|
-
|
|
1536
|
-
|
|
1643
|
+
contents: [
|
|
1644
|
+
{
|
|
1645
|
+
uri: "privacy://status",
|
|
1646
|
+
mimeType: "application/json",
|
|
1647
|
+
text: JSON.stringify(await apiCall("/v1/admin/privacy-status"), null, 2)
|
|
1648
|
+
}
|
|
1649
|
+
]
|
|
1537
1650
|
})
|
|
1538
1651
|
);
|
|
1539
1652
|
server.resource(
|
|
@@ -1543,15 +1656,19 @@ function createMushiServer(config) {
|
|
|
1543
1656
|
description: "Returns the project's last 30 days of judge scores, prompt promotions, fixed-bug count, and lesson inductions. Agents can read this to see whether the loop is converging (rising judge scores, falling recurrence) or stalling."
|
|
1544
1657
|
},
|
|
1545
1658
|
async () => ({
|
|
1546
|
-
contents: [
|
|
1547
|
-
|
|
1548
|
-
|
|
1549
|
-
|
|
1550
|
-
|
|
1551
|
-
|
|
1552
|
-
|
|
1553
|
-
|
|
1554
|
-
|
|
1659
|
+
contents: [
|
|
1660
|
+
{
|
|
1661
|
+
uri: "evolution://history",
|
|
1662
|
+
mimeType: "application/json",
|
|
1663
|
+
text: projectId ? JSON.stringify(
|
|
1664
|
+
await apiCall(
|
|
1665
|
+
`/v1/admin/projects/${encodeURIComponent(projectId)}/evolution-history`
|
|
1666
|
+
),
|
|
1667
|
+
null,
|
|
1668
|
+
2
|
|
1669
|
+
) : JSON.stringify({ ok: false, error: "project_id required" })
|
|
1670
|
+
}
|
|
1671
|
+
]
|
|
1555
1672
|
})
|
|
1556
1673
|
);
|
|
1557
1674
|
server.resource(
|
|
@@ -1561,11 +1678,13 @@ function createMushiServer(config) {
|
|
|
1561
1678
|
description: "Live health status of every configured BYOK channel (Sentry, GitHub, LangFuse, PagerDuty, \u2026). Orchestrators should check this before dispatching a fix to fail-fast on broken channels rather than burning LLM budget and discovering the failure mid-run."
|
|
1562
1679
|
},
|
|
1563
1680
|
async () => ({
|
|
1564
|
-
contents: [
|
|
1565
|
-
|
|
1566
|
-
|
|
1567
|
-
|
|
1568
|
-
|
|
1681
|
+
contents: [
|
|
1682
|
+
{
|
|
1683
|
+
uri: "project://integration-health",
|
|
1684
|
+
mimeType: "application/json",
|
|
1685
|
+
text: JSON.stringify(await apiCall("/v1/admin/integrations/health"), null, 2)
|
|
1686
|
+
}
|
|
1687
|
+
]
|
|
1569
1688
|
})
|
|
1570
1689
|
);
|
|
1571
1690
|
server.resource(
|
|
@@ -1577,11 +1696,13 @@ function createMushiServer(config) {
|
|
|
1577
1696
|
async () => {
|
|
1578
1697
|
const path = projectId ? `/v1/admin/inventory/${projectId}` : "/v1/admin/inventory";
|
|
1579
1698
|
return {
|
|
1580
|
-
contents: [
|
|
1581
|
-
|
|
1582
|
-
|
|
1583
|
-
|
|
1584
|
-
|
|
1699
|
+
contents: [
|
|
1700
|
+
{
|
|
1701
|
+
uri: "inventory://current",
|
|
1702
|
+
mimeType: "application/json",
|
|
1703
|
+
text: JSON.stringify(await apiCall(path), null, 2)
|
|
1704
|
+
}
|
|
1705
|
+
]
|
|
1585
1706
|
};
|
|
1586
1707
|
}
|
|
1587
1708
|
);
|
|
@@ -1610,11 +1731,13 @@ function createMushiServer(config) {
|
|
|
1610
1731
|
async () => {
|
|
1611
1732
|
const qs = projectId ? `?project_id=${encodeURIComponent(projectId)}` : "";
|
|
1612
1733
|
return {
|
|
1613
|
-
contents: [
|
|
1614
|
-
|
|
1615
|
-
|
|
1616
|
-
|
|
1617
|
-
|
|
1734
|
+
contents: [
|
|
1735
|
+
{
|
|
1736
|
+
uri: "mushi://activation",
|
|
1737
|
+
mimeType: "application/json",
|
|
1738
|
+
text: JSON.stringify(await apiCall(`/v1/admin/activation${qs}`), null, 2)
|
|
1739
|
+
}
|
|
1740
|
+
]
|
|
1618
1741
|
};
|
|
1619
1742
|
}
|
|
1620
1743
|
);
|
|
@@ -1623,11 +1746,12 @@ function createMushiServer(config) {
|
|
|
1623
1746
|
"Turn a Mushi report into a one-line root cause, smallest file set, repro steps, and blast-radius warnings. Use before asking an agent to write the patch.",
|
|
1624
1747
|
{ reportId: z.string().describe("The report UUID to summarize") },
|
|
1625
1748
|
({ reportId }) => ({
|
|
1626
|
-
messages: [
|
|
1627
|
-
|
|
1628
|
-
|
|
1629
|
-
|
|
1630
|
-
|
|
1749
|
+
messages: [
|
|
1750
|
+
{
|
|
1751
|
+
role: "user",
|
|
1752
|
+
content: {
|
|
1753
|
+
type: "text",
|
|
1754
|
+
text: `You are a senior engineer preparing a fix plan. Use the Mushi MCP tools to:
|
|
1631
1755
|
1. Call get_fix_context for reportId "${reportId}".
|
|
1632
1756
|
2. Call get_blast_radius if the report has a component node id.
|
|
1633
1757
|
3. Call get_similar_bugs with the component or summary as the query.
|
|
@@ -1640,8 +1764,9 @@ Then produce a markdown fix plan with exactly these sections:
|
|
|
1640
1764
|
- Confidence (low/medium/high) with a one-line justification
|
|
1641
1765
|
|
|
1642
1766
|
Lead with the fix. Skip the preamble.`
|
|
1767
|
+
}
|
|
1643
1768
|
}
|
|
1644
|
-
|
|
1769
|
+
]
|
|
1645
1770
|
})
|
|
1646
1771
|
);
|
|
1647
1772
|
server.prompt(
|
|
@@ -1649,11 +1774,12 @@ Lead with the fix. Skip the preamble.`
|
|
|
1649
1774
|
"Turn raw Sonnet-as-Judge scores into ship / iterate / dismiss guidance. Use after a fix attempt has been judged.",
|
|
1650
1775
|
{ fixId: z.string().describe("The fix_attempt UUID to explain") },
|
|
1651
1776
|
({ fixId }) => ({
|
|
1652
|
-
messages: [
|
|
1653
|
-
|
|
1654
|
-
|
|
1655
|
-
|
|
1656
|
-
|
|
1777
|
+
messages: [
|
|
1778
|
+
{
|
|
1779
|
+
role: "user",
|
|
1780
|
+
content: {
|
|
1781
|
+
type: "text",
|
|
1782
|
+
text: `You are a release engineer. Use the Mushi MCP tools:
|
|
1657
1783
|
1. Call get_fix_timeline for fixId "${fixId}" to see the full PDCA journey.
|
|
1658
1784
|
|
|
1659
1785
|
Then write a short verdict in this format:
|
|
@@ -1662,8 +1788,9 @@ Then write a short verdict in this format:
|
|
|
1662
1788
|
- **If iterate:** bullet list of the smallest next patch
|
|
1663
1789
|
|
|
1664
1790
|
No preamble, no score-by-score recap \u2014 the numbers are in the tool output.`
|
|
1791
|
+
}
|
|
1665
1792
|
}
|
|
1666
|
-
|
|
1793
|
+
]
|
|
1667
1794
|
})
|
|
1668
1795
|
);
|
|
1669
1796
|
server.prompt(
|
|
@@ -1671,11 +1798,12 @@ No preamble, no score-by-score recap \u2014 the numbers are in the tool output.`
|
|
|
1671
1798
|
'Answer "what should I focus on right now?" \u2014 five-item markdown list drawn from the dashboard + recent classified queue.',
|
|
1672
1799
|
{},
|
|
1673
1800
|
() => ({
|
|
1674
|
-
messages: [
|
|
1675
|
-
|
|
1676
|
-
|
|
1677
|
-
|
|
1678
|
-
|
|
1801
|
+
messages: [
|
|
1802
|
+
{
|
|
1803
|
+
role: "user",
|
|
1804
|
+
content: {
|
|
1805
|
+
type: "text",
|
|
1806
|
+
text: `You are a tech lead looking at the Mushi cockpit. Use the MCP tools:
|
|
1679
1807
|
1. Read the project://dashboard resource for the PDCA snapshot.
|
|
1680
1808
|
2. Call get_recent_reports with status="classified", limit=10.
|
|
1681
1809
|
|
|
@@ -1683,8 +1811,9 @@ Then output exactly 5 bullets, in priority order, each formatted as:
|
|
|
1683
1811
|
\`**Action** \u2014 why it matters \u2014 suggested tool call\`
|
|
1684
1812
|
|
|
1685
1813
|
Prefer items that are bottlenecks or critical severity. Skip filler.`
|
|
1814
|
+
}
|
|
1686
1815
|
}
|
|
1687
|
-
|
|
1816
|
+
]
|
|
1688
1817
|
})
|
|
1689
1818
|
);
|
|
1690
1819
|
server.prompt(
|
|
@@ -1692,11 +1821,12 @@ Prefer items that are bottlenecks or critical severity. Skip filler.`
|
|
|
1692
1821
|
"Diagnose why Mushi setup is stuck and return the single next command or console step to unblock it.",
|
|
1693
1822
|
{},
|
|
1694
1823
|
() => ({
|
|
1695
|
-
messages: [
|
|
1696
|
-
|
|
1697
|
-
|
|
1698
|
-
|
|
1699
|
-
|
|
1824
|
+
messages: [
|
|
1825
|
+
{
|
|
1826
|
+
role: "user",
|
|
1827
|
+
content: {
|
|
1828
|
+
type: "text",
|
|
1829
|
+
text: `You are a Mushi onboarding copilot. Use the MCP tools:
|
|
1700
1830
|
1. Read mushi://activation for unified setup posture.
|
|
1701
1831
|
2. Read project://integration-health if GitHub or Sentry looks blocked.
|
|
1702
1832
|
3. Call diagnose_setup if the resource is unavailable.
|
|
@@ -1708,8 +1838,9 @@ Then output:
|
|
|
1708
1838
|
- **If still stuck:** one diagnostic command (e.g. mushi doctor --fix)
|
|
1709
1839
|
|
|
1710
1840
|
Be specific. No generic advice.`
|
|
1841
|
+
}
|
|
1711
1842
|
}
|
|
1712
|
-
|
|
1843
|
+
]
|
|
1713
1844
|
})
|
|
1714
1845
|
);
|
|
1715
1846
|
server.registerTool(
|
|
@@ -1730,7 +1861,15 @@ Be specific. No generic advice.`
|
|
|
1730
1861
|
if (!projectId2) throw new MushiApiError(400, "MISSING_PROJECT", "projectId is required");
|
|
1731
1862
|
const data = await apiCall(
|
|
1732
1863
|
`/v1/admin/inventory/${projectId2}/map-from-live`,
|
|
1733
|
-
{
|
|
1864
|
+
{
|
|
1865
|
+
method: "POST",
|
|
1866
|
+
body: JSON.stringify({
|
|
1867
|
+
base_url: baseUrl,
|
|
1868
|
+
max_pages: maxPages,
|
|
1869
|
+
provider,
|
|
1870
|
+
cursor_cloud_refine: cursorCloudRefine
|
|
1871
|
+
})
|
|
1872
|
+
}
|
|
1734
1873
|
);
|
|
1735
1874
|
return { content: [{ type: "text", text: JSON.stringify(data, null, 2) }] };
|
|
1736
1875
|
}
|
|
@@ -1758,7 +1897,9 @@ Be specific. No generic advice.`
|
|
|
1758
1897
|
annotations: annotationsFor("generate_tdd_from_story", TDD_TOOL_CATALOG),
|
|
1759
1898
|
inputSchema: {
|
|
1760
1899
|
projectId: z.string().describe("Project UUID that owns the inventory story"),
|
|
1761
|
-
storyNodeId: z.string().describe(
|
|
1900
|
+
storyNodeId: z.string().describe(
|
|
1901
|
+
"User story node id/slug from accepted inventory (from map_user_stories or inventory.yaml)"
|
|
1902
|
+
),
|
|
1762
1903
|
automationMode: z.enum(["auto", "review", "approve"]).optional().describe("Approval gate for the generated qa_story (default review \u2192 pending_review)"),
|
|
1763
1904
|
baseUrl: z.string().url().optional().describe("Override the live app URL the Playwright test should target"),
|
|
1764
1905
|
openPr: z.boolean().optional().describe("Open a draft GitHub PR with the generated spec (default true)")
|
|
@@ -1772,10 +1913,14 @@ Be specific. No generic advice.`
|
|
|
1772
1913
|
},
|
|
1773
1914
|
async ({ projectId: projectId2, storyNodeId, automationMode, baseUrl, openPr }) => {
|
|
1774
1915
|
if (!projectId2) throw new MushiApiError(400, "MISSING_PROJECT", "projectId is required");
|
|
1775
|
-
const data = await apiCall(
|
|
1776
|
-
|
|
1777
|
-
|
|
1778
|
-
|
|
1916
|
+
const data = await apiCall(`/v1/admin/inventory/${projectId2}/stories/${storyNodeId}/generate-test`, {
|
|
1917
|
+
method: "POST",
|
|
1918
|
+
body: JSON.stringify({
|
|
1919
|
+
automation_mode: automationMode,
|
|
1920
|
+
base_url: baseUrl,
|
|
1921
|
+
open_pr: openPr
|
|
1922
|
+
})
|
|
1923
|
+
});
|
|
1779
1924
|
return jsonResult(data);
|
|
1780
1925
|
}
|
|
1781
1926
|
);
|
|
@@ -1790,10 +1935,10 @@ Be specific. No generic advice.`
|
|
|
1790
1935
|
}
|
|
1791
1936
|
},
|
|
1792
1937
|
async ({ projectId: projectId2 }) => {
|
|
1793
|
-
const data = await apiCall(
|
|
1794
|
-
"
|
|
1795
|
-
|
|
1796
|
-
);
|
|
1938
|
+
const data = await apiCall("/v1/admin/pdca/improve-qa-stories", {
|
|
1939
|
+
method: "POST",
|
|
1940
|
+
body: JSON.stringify({ project_id: projectId2 })
|
|
1941
|
+
});
|
|
1797
1942
|
return { content: [{ type: "text", text: JSON.stringify(data, null, 2) }] };
|
|
1798
1943
|
}
|
|
1799
1944
|
);
|
|
@@ -1827,7 +1972,9 @@ Be specific. No generic advice.`
|
|
|
1827
1972
|
}
|
|
1828
1973
|
},
|
|
1829
1974
|
async ({ projectId: projectId2 }) => {
|
|
1830
|
-
const data = await apiCall(
|
|
1975
|
+
const data = await apiCall(
|
|
1976
|
+
`/v1/admin/byok/keys?project_id=${encodeURIComponent(projectId2)}`
|
|
1977
|
+
);
|
|
1831
1978
|
return { content: [{ type: "text", text: JSON.stringify(data, null, 2) }] };
|
|
1832
1979
|
}
|
|
1833
1980
|
);
|
|
@@ -1840,16 +1987,60 @@ Be specific. No generic advice.`
|
|
|
1840
1987
|
inputSchema: {
|
|
1841
1988
|
projectId: z.string().describe("Project id"),
|
|
1842
1989
|
provider: z.enum(["anthropic", "openai", "firecrawl", "browserbase", "cursor"]).describe("Provider slug"),
|
|
1843
|
-
key: z.string().min(
|
|
1990
|
+
key: z.string().min(8).max(4096).describe("The API key value to add"),
|
|
1844
1991
|
label: z.string().optional().describe("Human-readable label for this key"),
|
|
1845
|
-
priority: z.number().int().min(
|
|
1992
|
+
priority: z.number().int().min(0).max(1e4).optional().describe("Priority for ordering (lower = higher priority)"),
|
|
1993
|
+
baseUrl: z.string().url().max(2048).optional().describe("Allow-listed OpenAI-compatible HTTPS base URL")
|
|
1846
1994
|
}
|
|
1847
1995
|
},
|
|
1848
|
-
async ({ projectId: projectId2, provider, key, label, priority }) => {
|
|
1849
|
-
const data = await apiCall(
|
|
1850
|
-
"
|
|
1851
|
-
|
|
1852
|
-
|
|
1996
|
+
async ({ projectId: projectId2, provider, key, label, priority, baseUrl }) => {
|
|
1997
|
+
const data = await apiCall("/v1/admin/byok/keys", {
|
|
1998
|
+
method: "POST",
|
|
1999
|
+
body: JSON.stringify({
|
|
2000
|
+
project_id: projectId2,
|
|
2001
|
+
provider_slug: provider,
|
|
2002
|
+
key,
|
|
2003
|
+
label,
|
|
2004
|
+
priority,
|
|
2005
|
+
base_url: baseUrl
|
|
2006
|
+
})
|
|
2007
|
+
});
|
|
2008
|
+
return { content: [{ type: "text", text: JSON.stringify(data, null, 2) }] };
|
|
2009
|
+
}
|
|
2010
|
+
);
|
|
2011
|
+
server.registerTool(
|
|
2012
|
+
"test_byok_key",
|
|
2013
|
+
{
|
|
2014
|
+
title: titleOf("test_byok_key", TDD_TOOL_CATALOG),
|
|
2015
|
+
description: descOf("test_byok_key", TDD_TOOL_CATALOG),
|
|
2016
|
+
annotations: annotationsFor("test_byok_key", TDD_TOOL_CATALOG),
|
|
2017
|
+
inputSchema: {
|
|
2018
|
+
projectId: z.string().describe("Project id"),
|
|
2019
|
+
keyId: z.string().uuid().describe("Pooled BYOK key id")
|
|
2020
|
+
}
|
|
2021
|
+
},
|
|
2022
|
+
async ({ keyId }) => {
|
|
2023
|
+
const data = await apiCall(`/v1/admin/byok/keys/${encodeURIComponent(keyId)}/test`, {
|
|
2024
|
+
method: "POST"
|
|
2025
|
+
});
|
|
2026
|
+
return { content: [{ type: "text", text: JSON.stringify(data, null, 2) }] };
|
|
2027
|
+
}
|
|
2028
|
+
);
|
|
2029
|
+
server.registerTool(
|
|
2030
|
+
"remove_byok_key",
|
|
2031
|
+
{
|
|
2032
|
+
title: titleOf("remove_byok_key", TDD_TOOL_CATALOG),
|
|
2033
|
+
description: descOf("remove_byok_key", TDD_TOOL_CATALOG),
|
|
2034
|
+
annotations: annotationsFor("remove_byok_key", TDD_TOOL_CATALOG),
|
|
2035
|
+
inputSchema: {
|
|
2036
|
+
projectId: z.string().describe("Project id"),
|
|
2037
|
+
keyId: z.string().uuid().describe("Pooled BYOK key UUID from list_byok_keys")
|
|
2038
|
+
}
|
|
2039
|
+
},
|
|
2040
|
+
async ({ keyId }) => {
|
|
2041
|
+
const data = await apiCall(`/v1/admin/byok/keys/${encodeURIComponent(keyId)}`, {
|
|
2042
|
+
method: "DELETE"
|
|
2043
|
+
});
|
|
1853
2044
|
return { content: [{ type: "text", text: JSON.stringify(data, null, 2) }] };
|
|
1854
2045
|
}
|
|
1855
2046
|
);
|
|
@@ -1864,7 +2055,9 @@ Be specific. No generic advice.`
|
|
|
1864
2055
|
}
|
|
1865
2056
|
},
|
|
1866
2057
|
async ({ projectId: projectId2 }) => {
|
|
1867
|
-
const data = await apiCall(
|
|
2058
|
+
const data = await apiCall(
|
|
2059
|
+
`/v1/admin/inventory/${projectId2}/stories/pending-review`
|
|
2060
|
+
);
|
|
1868
2061
|
return { content: [{ type: "text", text: JSON.stringify(data, null, 2) }] };
|
|
1869
2062
|
}
|
|
1870
2063
|
);
|
|
@@ -1901,13 +2094,10 @@ Be specific. No generic advice.`
|
|
|
1901
2094
|
}
|
|
1902
2095
|
},
|
|
1903
2096
|
async ({ reportId, message, authorName }) => {
|
|
1904
|
-
const data = await apiCall(
|
|
1905
|
-
|
|
1906
|
-
{
|
|
1907
|
-
|
|
1908
|
-
body: JSON.stringify({ message, author_name: authorName })
|
|
1909
|
-
}
|
|
1910
|
-
);
|
|
2097
|
+
const data = await apiCall(`/v1/sync/reports/${reportId}/reply`, {
|
|
2098
|
+
method: "POST",
|
|
2099
|
+
body: JSON.stringify({ message, author_name: authorName })
|
|
2100
|
+
});
|
|
1911
2101
|
return { content: [{ type: "text", text: JSON.stringify(data, null, 2) }] };
|
|
1912
2102
|
}
|
|
1913
2103
|
);
|
|
@@ -1986,10 +2176,10 @@ Be specific. No generic advice.`
|
|
|
1986
2176
|
async ({ project_id }) => {
|
|
1987
2177
|
const pid = project_id ?? config.projectId;
|
|
1988
2178
|
if (!pid) throw new MushiApiError(400, "MISSING_PROJECT_ID", "project_id is required");
|
|
1989
|
-
const data = await apiCall(
|
|
1990
|
-
|
|
1991
|
-
|
|
1992
|
-
);
|
|
2179
|
+
const data = await apiCall(`/v1/admin/projects/${pid}/audit`, {
|
|
2180
|
+
method: "POST",
|
|
2181
|
+
body: "{}"
|
|
2182
|
+
});
|
|
1993
2183
|
return { content: [{ type: "text", text: JSON.stringify(data, null, 2) }] };
|
|
1994
2184
|
}
|
|
1995
2185
|
);
|
|
@@ -2085,17 +2275,19 @@ Be specific. No generic advice.`
|
|
|
2085
2275
|
inputSchema: {
|
|
2086
2276
|
root_skill_slug: z.string().describe('Root skill slug to run, e.g. "workflow-fix-and-ship"'),
|
|
2087
2277
|
report_id: z.string().optional().describe("Report UUID to attach the pipeline to"),
|
|
2088
|
-
mode: z.enum(["handoff", "cloud"]).optional().describe(
|
|
2278
|
+
mode: z.enum(["handoff", "cloud"]).optional().describe(
|
|
2279
|
+
"handoff (default): get context packet for local agent. cloud: auto-dispatch via Cursor Cloud."
|
|
2280
|
+
),
|
|
2089
2281
|
project_id: z.string().optional().describe("Project UUID. Falls back to the configured project.")
|
|
2090
2282
|
}
|
|
2091
2283
|
},
|
|
2092
2284
|
async (args) => {
|
|
2093
2285
|
const resolvedProjectId = args.project_id ?? projectId;
|
|
2094
2286
|
if (!resolvedProjectId) return jsonText({ error: "No project_id provided or configured." });
|
|
2095
|
-
const data = await apiCall(
|
|
2096
|
-
"
|
|
2097
|
-
|
|
2098
|
-
);
|
|
2287
|
+
const data = await apiCall("/v1/admin/skills/pipelines", {
|
|
2288
|
+
method: "POST",
|
|
2289
|
+
body: JSON.stringify({ ...args, project_id: resolvedProjectId })
|
|
2290
|
+
});
|
|
2099
2291
|
return jsonText(data);
|
|
2100
2292
|
}
|
|
2101
2293
|
);
|
|
@@ -2131,10 +2323,10 @@ Be specific. No generic advice.`
|
|
|
2131
2323
|
},
|
|
2132
2324
|
async (args) => {
|
|
2133
2325
|
const { run_id, step_index, ...body } = args;
|
|
2134
|
-
await apiCall(
|
|
2135
|
-
|
|
2136
|
-
|
|
2137
|
-
);
|
|
2326
|
+
await apiCall(`/v1/admin/skills/pipelines/${run_id}/steps/${step_index}/checkin`, {
|
|
2327
|
+
method: "POST",
|
|
2328
|
+
body: JSON.stringify(body)
|
|
2329
|
+
});
|
|
2138
2330
|
return jsonText({ ok: true, message: `Step ${step_index} \u2192 ${args.status}` });
|
|
2139
2331
|
}
|
|
2140
2332
|
);
|
|
@@ -2302,7 +2494,11 @@ Be specific. No generic advice.`
|
|
|
2302
2494
|
if (args.compare) qs.set("compare", args.compare);
|
|
2303
2495
|
if (args.fix_id) qs.set("fix_id", args.fix_id);
|
|
2304
2496
|
if (!qs.toString()) {
|
|
2305
|
-
throw new MushiApiError(
|
|
2497
|
+
throw new MushiApiError(
|
|
2498
|
+
400,
|
|
2499
|
+
"BAD_REQUEST",
|
|
2500
|
+
"Provide paths, source=last_push, compare, or fix_id"
|
|
2501
|
+
);
|
|
2306
2502
|
}
|
|
2307
2503
|
const data = await apiCall(`/v1/admin/projects/${pid}/codebase/impact?${qs}`);
|
|
2308
2504
|
return jsonResult(data);
|
|
@@ -2354,7 +2550,7 @@ Be specific. No generic advice.`
|
|
|
2354
2550
|
"### First step",
|
|
2355
2551
|
`Call \`${cluster.tools[0]}\` to get started.`,
|
|
2356
2552
|
"",
|
|
2357
|
-
"> Tip: call any tool by name \u2014 `use_mushi` is a read-only helper that never calls other tools itself. All
|
|
2553
|
+
"> Tip: call any tool by name \u2014 `use_mushi` is a read-only helper that never calls other tools itself. All 71 tools remain available."
|
|
2358
2554
|
].join("\n");
|
|
2359
2555
|
return { content: [{ type: "text", text: orientation }] };
|
|
2360
2556
|
}
|
|
@@ -2363,11 +2559,7 @@ Be specific. No generic advice.`
|
|
|
2363
2559
|
const featureFilter = config.features ?? "all";
|
|
2364
2560
|
if (grantedScopes !== void 0 || featureFilter !== "all") {
|
|
2365
2561
|
const toolRegistry = server._registeredTools;
|
|
2366
|
-
const allSpecs = [
|
|
2367
|
-
...TOOL_CATALOG,
|
|
2368
|
-
...TDD_TOOL_CATALOG,
|
|
2369
|
-
...CODEBASE_TOOL_CATALOG
|
|
2370
|
-
];
|
|
2562
|
+
const allSpecs = [...TOOL_CATALOG, ...TDD_TOOL_CATALOG, ...CODEBASE_TOOL_CATALOG];
|
|
2371
2563
|
for (const spec of allSpecs) {
|
|
2372
2564
|
if (grantedScopes !== void 0 && !grantedScopes.includes(spec.scope)) {
|
|
2373
2565
|
toolRegistry[spec.name]?.remove();
|