@mushi-mushi/mcp 0.24.4 → 0.24.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.
- package/dist/clients.d.ts +1 -1
- package/dist/clients.js +1 -1
- package/dist/index.js +77 -9
- package/dist/server.d.ts +7 -1
- package/dist/server.js +15 -7
- package/package.json +2 -2
package/dist/clients.d.ts
CHANGED
|
@@ -46,7 +46,7 @@ import { FeatureGroup } from './feature-groups.js';
|
|
|
46
46
|
* editor launch. Synced to package.json by `scripts/sync-mcp-pin.mjs` — never
|
|
47
47
|
* hand-edit the version.
|
|
48
48
|
*/
|
|
49
|
-
declare const MCP_PIN_SPEC = "@mushi-mushi/mcp@0.24.
|
|
49
|
+
declare const MCP_PIN_SPEC = "@mushi-mushi/mcp@0.24.6";
|
|
50
50
|
interface StdioConfig {
|
|
51
51
|
command: string;
|
|
52
52
|
args: string[];
|
package/dist/clients.js
CHANGED
|
@@ -8,7 +8,7 @@ import {
|
|
|
8
8
|
} from "./chunk-F65T4IGT.js";
|
|
9
9
|
|
|
10
10
|
// src/clients.ts
|
|
11
|
-
var MCP_PIN_SPEC = "@mushi-mushi/mcp@0.24.
|
|
11
|
+
var MCP_PIN_SPEC = "@mushi-mushi/mcp@0.24.6";
|
|
12
12
|
var PIN_SPEC_RE = /^@mushi-mushi\/mcp@\d+\.\d+\.\d+$/;
|
|
13
13
|
function pinOf(pinSpec) {
|
|
14
14
|
return pinSpec && PIN_SPEC_RE.test(pinSpec) ? pinSpec : MCP_PIN_SPEC;
|
package/dist/index.js
CHANGED
|
@@ -1476,7 +1476,7 @@ var MUSHI_DOCS_INDEX = [
|
|
|
1476
1476
|
route: "/admin/billing",
|
|
1477
1477
|
markdown: "admin/billing.md",
|
|
1478
1478
|
keywords: ["admin", "billing"],
|
|
1479
|
-
headings: ["Reading your usage card", "Usage breakdown", "Predictability controls", "Upgrading your plan", "Managing payment and invoices", "CLI parity", "Related docs"],
|
|
1479
|
+
headings: ["Reading your usage card", "Usage breakdown", "Predictability controls", "Upgrading your plan", "Changing plan", "Managing payment and invoices", "CLI parity", "Related docs"],
|
|
1480
1480
|
excerpt: "The Billing page shows your diagnosis quota, usage alerts at 50% and 80%, your projected bill, and spend caps for your Mushi plan."
|
|
1481
1481
|
},
|
|
1482
1482
|
{
|
|
@@ -1854,7 +1854,7 @@ var MUSHI_DOCS_INDEX = [
|
|
|
1854
1854
|
route: "/admin/research",
|
|
1855
1855
|
markdown: "admin/research.md",
|
|
1856
1856
|
keywords: ["admin", "research"],
|
|
1857
|
-
headings: ["What it's for", "Running a search", "Saving results", "Prerequisites", "Related pages"],
|
|
1857
|
+
headings: ["What it's for", "Running a search", "Saving results", "Automatic results on error reports", "Prerequisites", "Related pages"],
|
|
1858
1858
|
excerpt: "The Research page runs a Firecrawl web search scoped to your tech stack and returns summarised answers with links to their sources."
|
|
1859
1859
|
},
|
|
1860
1860
|
{
|
|
@@ -3141,7 +3141,7 @@ var MUSHI_DOCS_INDEX = [
|
|
|
3141
3141
|
route: "/security/byok",
|
|
3142
3142
|
markdown: "security/byok.md",
|
|
3143
3143
|
keywords: ["security", "byok", "bring-your-own-key"],
|
|
3144
|
-
headings: ["Setup", "What uses the key", "OpenRouter", "Audit trail", "Rotation", "Langfuse trace attribution"],
|
|
3144
|
+
headings: ["Setup", "One key for every app", "What uses the key", "OpenRouter", "Audit trail", "Rotation", "Langfuse trace attribution"],
|
|
3145
3145
|
excerpt: "Use your own Anthropic, OpenAI or OpenRouter key for a Mushi project, so every diagnosis, fix and grading run bills to your provider account."
|
|
3146
3146
|
},
|
|
3147
3147
|
{
|
|
@@ -5305,7 +5305,8 @@ function createMushiServer(config) {
|
|
|
5305
5305
|
);
|
|
5306
5306
|
const latest = data.latest ?? data.version;
|
|
5307
5307
|
const current = args.current;
|
|
5308
|
-
const
|
|
5308
|
+
const pinned = current?.trim().replace(/^[\^~>=<v\s]+/, "");
|
|
5309
|
+
const outdated = pinned && latest ? pinned !== latest : void 0;
|
|
5309
5310
|
return jsonResult({
|
|
5310
5311
|
package: data.package ?? pkg,
|
|
5311
5312
|
latest,
|
|
@@ -7541,7 +7542,7 @@ function createSetupModeServer(config) {
|
|
|
7541
7542
|
features: "all",
|
|
7542
7543
|
...config.fetch ? { fetch: config.fetch } : {},
|
|
7543
7544
|
...config.timeoutMs ? { timeoutMs: config.timeoutMs } : {},
|
|
7544
|
-
instructions: "Mushi is running in setup mode: no API key is configured, so only search_mushi_docs, get_mushi_doc and diagnose_setup work. Call diagnose_setup for the exact steps to connect (run `npx mushi-mushi` or `mushi login`, or put MUSHI_API_KEY in this server's env block), then restart the MCP server."
|
|
7545
|
+
instructions: config.reason === "sdk-key" ? "Mushi is running in setup mode: the configured API key is an SDK key (report:write). It can send bug reports but not read them, so only search_mushi_docs, get_mushi_doc and diagnose_setup work. Call diagnose_setup for how to mint an MCP key (mcp:read), then restart the MCP server." : "Mushi is running in setup mode: no API key is configured, so only search_mushi_docs, get_mushi_doc and diagnose_setup work. Call diagnose_setup for the exact steps to connect (run `npx mushi-mushi` or `mushi login`, or put MUSHI_API_KEY in this server's env block), then restart the MCP server."
|
|
7545
7546
|
});
|
|
7546
7547
|
const internals = server;
|
|
7547
7548
|
for (const [name, tool] of Object.entries(internals._registeredTools)) {
|
|
@@ -7556,7 +7557,8 @@ function createSetupModeServer(config) {
|
|
|
7556
7557
|
}
|
|
7557
7558
|
const spec = TOOL_CATALOG.find((t) => t.name === "diagnose_setup");
|
|
7558
7559
|
if (!spec) throw new Error("[mushi-mcp] diagnose_setup is missing from TOOL_CATALOG");
|
|
7559
|
-
const
|
|
7560
|
+
const sdkKey = config.reason === "sdk-key";
|
|
7561
|
+
const nextAction = sdkKey ? `Mint an MCP key in the console (${MUSHI_CONSOLE_URL}/mcp \u2192 "Mint mcp:read key") or run \`mushi login\`, put it in MUSHI_API_KEY for this server, then restart it.` : "Run `npx mushi-mushi` in your project (signs you in and writes the key) or `mushi login`, then restart this MCP server.";
|
|
7560
7562
|
server.registerTool(
|
|
7561
7563
|
"diagnose_setup",
|
|
7562
7564
|
{
|
|
@@ -7578,7 +7580,12 @@ function createSetupModeServer(config) {
|
|
|
7578
7580
|
ready: false,
|
|
7579
7581
|
mode: "setup",
|
|
7580
7582
|
steps: [
|
|
7581
|
-
{
|
|
7583
|
+
sdkKey ? {
|
|
7584
|
+
label: "MCP server key can read reports (mcp:read)",
|
|
7585
|
+
complete: false,
|
|
7586
|
+
required: true,
|
|
7587
|
+
hint: `${nextAction} The SDK key (report:write) belongs in your app; MCP and the CLI need a key with mcp:read, or mcp:write to also triage and dispatch fixes.`
|
|
7588
|
+
} : {
|
|
7582
7589
|
label: "MCP server has an API key",
|
|
7583
7590
|
complete: false,
|
|
7584
7591
|
required: true,
|
|
@@ -7595,6 +7602,50 @@ function createSetupModeServer(config) {
|
|
|
7595
7602
|
return server;
|
|
7596
7603
|
}
|
|
7597
7604
|
|
|
7605
|
+
// src/key-scopes.ts
|
|
7606
|
+
async function fetchKeyScopes(opts) {
|
|
7607
|
+
const doFetch = opts.fetch ?? fetch;
|
|
7608
|
+
try {
|
|
7609
|
+
const res = await doFetch(`${opts.apiEndpoint.replace(/\/+$/, "")}/v1/sync/whoami`, {
|
|
7610
|
+
headers: {
|
|
7611
|
+
"X-Mushi-Api-Key": opts.apiKey,
|
|
7612
|
+
...opts.projectId ? { "X-Mushi-Project-Id": opts.projectId } : {}
|
|
7613
|
+
},
|
|
7614
|
+
signal: AbortSignal.timeout(opts.timeoutMs ?? 5e3)
|
|
7615
|
+
});
|
|
7616
|
+
if (!res.ok) return null;
|
|
7617
|
+
const body = await res.json();
|
|
7618
|
+
const scopes = body?.data?.scopes;
|
|
7619
|
+
if (!Array.isArray(scopes)) return null;
|
|
7620
|
+
return scopes.filter((s) => typeof s === "string");
|
|
7621
|
+
} catch {
|
|
7622
|
+
return null;
|
|
7623
|
+
}
|
|
7624
|
+
}
|
|
7625
|
+
function decideScopes(keyScopes, configured) {
|
|
7626
|
+
if (keyScopes === null) return { kind: "serve", scopes: configured };
|
|
7627
|
+
const granted = /* @__PURE__ */ new Set();
|
|
7628
|
+
if (keyScopes.includes("mcp:write")) {
|
|
7629
|
+
granted.add("mcp:read");
|
|
7630
|
+
granted.add("mcp:write");
|
|
7631
|
+
} else if (keyScopes.includes("mcp:read")) {
|
|
7632
|
+
granted.add("mcp:read");
|
|
7633
|
+
}
|
|
7634
|
+
if (granted.size === 0) return { kind: "sdk-key", keyScopes };
|
|
7635
|
+
return { kind: "serve", scopes: configured.filter((s) => granted.has(s)) };
|
|
7636
|
+
}
|
|
7637
|
+
function sdkKeyReport(keyScopes, consoleUrl) {
|
|
7638
|
+
const held = keyScopes.length > 0 ? keyScopes.join(", ") : "none";
|
|
7639
|
+
return [
|
|
7640
|
+
"",
|
|
7641
|
+
`[mushi-mcp] This API key has scopes: ${held}. It can send bug reports (the SDK key) but not read them,`,
|
|
7642
|
+
" so the MCP tools would all be refused. Serving setup mode.",
|
|
7643
|
+
` Fix: mint an MCP key in the console (${consoleUrl}/mcp \u2192 "Mint mcp:read key"),`,
|
|
7644
|
+
" or run `mushi login`, then put it in MUSHI_API_KEY for this server and restart it.",
|
|
7645
|
+
""
|
|
7646
|
+
].join("\n");
|
|
7647
|
+
}
|
|
7648
|
+
|
|
7598
7649
|
// src/inventory-poll.ts
|
|
7599
7650
|
function startInventoryPoll(options) {
|
|
7600
7651
|
const doFetch = options.fetch ?? globalThis.fetch;
|
|
@@ -7854,6 +7905,23 @@ async function main() {
|
|
|
7854
7905
|
);
|
|
7855
7906
|
}
|
|
7856
7907
|
}
|
|
7908
|
+
let scopes = SCOPES;
|
|
7909
|
+
if (!SCOPES_RAW) {
|
|
7910
|
+
const keyScopes = await fetchKeyScopes({ apiEndpoint: API_ENDPOINT, apiKey: API_KEY, projectId: PROJECT_ID || void 0 });
|
|
7911
|
+
const decision = decideScopes(keyScopes, SCOPES);
|
|
7912
|
+
if (decision.kind === "sdk-key") {
|
|
7913
|
+
const report = sdkKeyReport(decision.keyScopes, MUSHI_CONSOLE_URL);
|
|
7914
|
+
process.stderr.write(report);
|
|
7915
|
+
log.warn("The API key has no MCP scope (mcp:read / mcp:write) \u2014 serving setup mode.", {
|
|
7916
|
+
keyScopes: decision.keyScopes.join(",")
|
|
7917
|
+
});
|
|
7918
|
+
serveUntilClosed(serveStdio(() => createSetupModeServer({ version: VERSION, missingKeyReport: report, reason: "sdk-key" }), {
|
|
7919
|
+
onerror: (err) => log.error("stdio transport error", { err: String(err) })
|
|
7920
|
+
}));
|
|
7921
|
+
return;
|
|
7922
|
+
}
|
|
7923
|
+
scopes = decision.scopes;
|
|
7924
|
+
}
|
|
7857
7925
|
const mode = PROJECT_ID ? "single-project" : "account";
|
|
7858
7926
|
if (!PROJECT_ID) {
|
|
7859
7927
|
log.info(
|
|
@@ -7865,7 +7933,7 @@ async function main() {
|
|
|
7865
7933
|
mode,
|
|
7866
7934
|
endpoint: API_ENDPOINT,
|
|
7867
7935
|
hasProjectId: !!PROJECT_ID,
|
|
7868
|
-
scopes:
|
|
7936
|
+
scopes: scopes.join(",")
|
|
7869
7937
|
});
|
|
7870
7938
|
let server;
|
|
7871
7939
|
const handle = serveStdio(
|
|
@@ -7875,7 +7943,7 @@ async function main() {
|
|
|
7875
7943
|
apiEndpoint: API_ENDPOINT,
|
|
7876
7944
|
apiKey: API_KEY,
|
|
7877
7945
|
projectId: PROJECT_ID || void 0,
|
|
7878
|
-
scopes
|
|
7946
|
+
scopes,
|
|
7879
7947
|
features: FEATURES
|
|
7880
7948
|
});
|
|
7881
7949
|
log.debug("[mushi-mcp] server instance created", { era: ctx.era });
|
package/dist/server.d.ts
CHANGED
|
@@ -63,10 +63,16 @@ interface MushiServerConfig {
|
|
|
63
63
|
declare function createMushiServer(config: MushiServerConfig): McpServer;
|
|
64
64
|
/** Tools that work before an API key exists: they read only the public docs. */
|
|
65
65
|
declare const SETUP_MODE_TOOLS: readonly ["search_mushi_docs", "get_mushi_doc", "diagnose_setup"];
|
|
66
|
+
declare const MUSHI_CONSOLE_URL = "https://kensaur.us/mushi-mushi/admin";
|
|
66
67
|
interface SetupModeServerConfig {
|
|
67
68
|
version: string;
|
|
68
69
|
/** Why there is no key, as printed to stderr (sources checked, config path). */
|
|
69
70
|
missingKeyReport: string;
|
|
71
|
+
/**
|
|
72
|
+
* `missing-key` (default): no key reached the server. `sdk-key`: a valid
|
|
73
|
+
* key without mcp:read or mcp:write, such as the report:write SDK key.
|
|
74
|
+
*/
|
|
75
|
+
reason?: 'missing-key' | 'sdk-key';
|
|
70
76
|
fetch?: typeof fetch;
|
|
71
77
|
timeoutMs?: number;
|
|
72
78
|
}
|
|
@@ -78,4 +84,4 @@ interface SetupModeServerConfig {
|
|
|
78
84
|
*/
|
|
79
85
|
declare function createSetupModeServer(config: SetupModeServerConfig): McpServer;
|
|
80
86
|
|
|
81
|
-
export { MushiApiError, type MushiServerConfig, SETUP_MODE_TOOLS, type SetupModeServerConfig, createMushiServer, createSetupModeServer, resolveTimeoutMsFromEnv };
|
|
87
|
+
export { MUSHI_CONSOLE_URL, MushiApiError, type MushiServerConfig, SETUP_MODE_TOOLS, type SetupModeServerConfig, createMushiServer, createSetupModeServer, resolveTimeoutMsFromEnv };
|
package/dist/server.js
CHANGED
|
@@ -86,7 +86,7 @@ var MUSHI_DOCS_INDEX = [
|
|
|
86
86
|
route: "/admin/billing",
|
|
87
87
|
markdown: "admin/billing.md",
|
|
88
88
|
keywords: ["admin", "billing"],
|
|
89
|
-
headings: ["Reading your usage card", "Usage breakdown", "Predictability controls", "Upgrading your plan", "Managing payment and invoices", "CLI parity", "Related docs"],
|
|
89
|
+
headings: ["Reading your usage card", "Usage breakdown", "Predictability controls", "Upgrading your plan", "Changing plan", "Managing payment and invoices", "CLI parity", "Related docs"],
|
|
90
90
|
excerpt: "The Billing page shows your diagnosis quota, usage alerts at 50% and 80%, your projected bill, and spend caps for your Mushi plan."
|
|
91
91
|
},
|
|
92
92
|
{
|
|
@@ -464,7 +464,7 @@ var MUSHI_DOCS_INDEX = [
|
|
|
464
464
|
route: "/admin/research",
|
|
465
465
|
markdown: "admin/research.md",
|
|
466
466
|
keywords: ["admin", "research"],
|
|
467
|
-
headings: ["What it's for", "Running a search", "Saving results", "Prerequisites", "Related pages"],
|
|
467
|
+
headings: ["What it's for", "Running a search", "Saving results", "Automatic results on error reports", "Prerequisites", "Related pages"],
|
|
468
468
|
excerpt: "The Research page runs a Firecrawl web search scoped to your tech stack and returns summarised answers with links to their sources."
|
|
469
469
|
},
|
|
470
470
|
{
|
|
@@ -1751,7 +1751,7 @@ var MUSHI_DOCS_INDEX = [
|
|
|
1751
1751
|
route: "/security/byok",
|
|
1752
1752
|
markdown: "security/byok.md",
|
|
1753
1753
|
keywords: ["security", "byok", "bring-your-own-key"],
|
|
1754
|
-
headings: ["Setup", "What uses the key", "OpenRouter", "Audit trail", "Rotation", "Langfuse trace attribution"],
|
|
1754
|
+
headings: ["Setup", "One key for every app", "What uses the key", "OpenRouter", "Audit trail", "Rotation", "Langfuse trace attribution"],
|
|
1755
1755
|
excerpt: "Use your own Anthropic, OpenAI or OpenRouter key for a Mushi project, so every diagnosis, fix and grading run bills to your provider account."
|
|
1756
1756
|
},
|
|
1757
1757
|
{
|
|
@@ -3981,7 +3981,8 @@ function createMushiServer(config) {
|
|
|
3981
3981
|
);
|
|
3982
3982
|
const latest = data.latest ?? data.version;
|
|
3983
3983
|
const current = args.current;
|
|
3984
|
-
const
|
|
3984
|
+
const pinned = current?.trim().replace(/^[\^~>=<v\s]+/, "");
|
|
3985
|
+
const outdated = pinned && latest ? pinned !== latest : void 0;
|
|
3985
3986
|
return jsonResult({
|
|
3986
3987
|
package: data.package ?? pkg,
|
|
3987
3988
|
latest,
|
|
@@ -6217,7 +6218,7 @@ function createSetupModeServer(config) {
|
|
|
6217
6218
|
features: "all",
|
|
6218
6219
|
...config.fetch ? { fetch: config.fetch } : {},
|
|
6219
6220
|
...config.timeoutMs ? { timeoutMs: config.timeoutMs } : {},
|
|
6220
|
-
instructions: "Mushi is running in setup mode: no API key is configured, so only search_mushi_docs, get_mushi_doc and diagnose_setup work. Call diagnose_setup for the exact steps to connect (run `npx mushi-mushi` or `mushi login`, or put MUSHI_API_KEY in this server's env block), then restart the MCP server."
|
|
6221
|
+
instructions: config.reason === "sdk-key" ? "Mushi is running in setup mode: the configured API key is an SDK key (report:write). It can send bug reports but not read them, so only search_mushi_docs, get_mushi_doc and diagnose_setup work. Call diagnose_setup for how to mint an MCP key (mcp:read), then restart the MCP server." : "Mushi is running in setup mode: no API key is configured, so only search_mushi_docs, get_mushi_doc and diagnose_setup work. Call diagnose_setup for the exact steps to connect (run `npx mushi-mushi` or `mushi login`, or put MUSHI_API_KEY in this server's env block), then restart the MCP server."
|
|
6221
6222
|
});
|
|
6222
6223
|
const internals = server;
|
|
6223
6224
|
for (const [name, tool] of Object.entries(internals._registeredTools)) {
|
|
@@ -6232,7 +6233,8 @@ function createSetupModeServer(config) {
|
|
|
6232
6233
|
}
|
|
6233
6234
|
const spec = TOOL_CATALOG.find((t) => t.name === "diagnose_setup");
|
|
6234
6235
|
if (!spec) throw new Error("[mushi-mcp] diagnose_setup is missing from TOOL_CATALOG");
|
|
6235
|
-
const
|
|
6236
|
+
const sdkKey = config.reason === "sdk-key";
|
|
6237
|
+
const nextAction = sdkKey ? `Mint an MCP key in the console (${MUSHI_CONSOLE_URL}/mcp \u2192 "Mint mcp:read key") or run \`mushi login\`, put it in MUSHI_API_KEY for this server, then restart it.` : "Run `npx mushi-mushi` in your project (signs you in and writes the key) or `mushi login`, then restart this MCP server.";
|
|
6236
6238
|
server.registerTool(
|
|
6237
6239
|
"diagnose_setup",
|
|
6238
6240
|
{
|
|
@@ -6254,7 +6256,12 @@ function createSetupModeServer(config) {
|
|
|
6254
6256
|
ready: false,
|
|
6255
6257
|
mode: "setup",
|
|
6256
6258
|
steps: [
|
|
6257
|
-
{
|
|
6259
|
+
sdkKey ? {
|
|
6260
|
+
label: "MCP server key can read reports (mcp:read)",
|
|
6261
|
+
complete: false,
|
|
6262
|
+
required: true,
|
|
6263
|
+
hint: `${nextAction} The SDK key (report:write) belongs in your app; MCP and the CLI need a key with mcp:read, or mcp:write to also triage and dispatch fixes.`
|
|
6264
|
+
} : {
|
|
6258
6265
|
label: "MCP server has an API key",
|
|
6259
6266
|
complete: false,
|
|
6260
6267
|
required: true,
|
|
@@ -6271,6 +6278,7 @@ function createSetupModeServer(config) {
|
|
|
6271
6278
|
return server;
|
|
6272
6279
|
}
|
|
6273
6280
|
export {
|
|
6281
|
+
MUSHI_CONSOLE_URL,
|
|
6274
6282
|
MushiApiError,
|
|
6275
6283
|
SETUP_MODE_TOOLS,
|
|
6276
6284
|
createMushiServer,
|
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.24.
|
|
4
|
+
"version": "0.24.6",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"description": "MCP server for Cursor, Claude Code and Copilot. The bug mediator for AI-built apps: plain-English diagnosis + a ready fix, in your editor.",
|
|
7
7
|
"type": "module",
|
|
@@ -45,7 +45,7 @@
|
|
|
45
45
|
"@modelcontextprotocol/core": "^2.0.0",
|
|
46
46
|
"@modelcontextprotocol/server": "^2.0.0",
|
|
47
47
|
"zod": "^4.4.3",
|
|
48
|
-
"@mushi-mushi/core": "^1.
|
|
48
|
+
"@mushi-mushi/core": "^1.32.2"
|
|
49
49
|
},
|
|
50
50
|
"peerDependencies": {
|
|
51
51
|
"@sentry/node": "^10.57.0"
|