@mushi-mushi/mcp 0.24.4 → 0.24.5

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 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.4";
49
+ declare const MCP_PIN_SPEC = "@mushi-mushi/mcp@0.24.5";
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.4";
11
+ var MCP_PIN_SPEC = "@mushi-mushi/mcp@0.24.5";
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
@@ -7541,7 +7541,7 @@ function createSetupModeServer(config) {
7541
7541
  features: "all",
7542
7542
  ...config.fetch ? { fetch: config.fetch } : {},
7543
7543
  ...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."
7544
+ 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
7545
  });
7546
7546
  const internals = server;
7547
7547
  for (const [name, tool] of Object.entries(internals._registeredTools)) {
@@ -7556,7 +7556,8 @@ function createSetupModeServer(config) {
7556
7556
  }
7557
7557
  const spec = TOOL_CATALOG.find((t) => t.name === "diagnose_setup");
7558
7558
  if (!spec) throw new Error("[mushi-mcp] diagnose_setup is missing from TOOL_CATALOG");
7559
- const nextAction = "Run `npx mushi-mushi` in your project (signs you in and writes the key) or `mushi login`, then restart this MCP server.";
7559
+ const sdkKey = config.reason === "sdk-key";
7560
+ 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
7561
  server.registerTool(
7561
7562
  "diagnose_setup",
7562
7563
  {
@@ -7578,7 +7579,12 @@ function createSetupModeServer(config) {
7578
7579
  ready: false,
7579
7580
  mode: "setup",
7580
7581
  steps: [
7581
- {
7582
+ sdkKey ? {
7583
+ label: "MCP server key can read reports (mcp:read)",
7584
+ complete: false,
7585
+ required: true,
7586
+ 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.`
7587
+ } : {
7582
7588
  label: "MCP server has an API key",
7583
7589
  complete: false,
7584
7590
  required: true,
@@ -7595,6 +7601,50 @@ function createSetupModeServer(config) {
7595
7601
  return server;
7596
7602
  }
7597
7603
 
7604
+ // src/key-scopes.ts
7605
+ async function fetchKeyScopes(opts) {
7606
+ const doFetch = opts.fetch ?? fetch;
7607
+ try {
7608
+ const res = await doFetch(`${opts.apiEndpoint.replace(/\/+$/, "")}/v1/sync/whoami`, {
7609
+ headers: {
7610
+ "X-Mushi-Api-Key": opts.apiKey,
7611
+ ...opts.projectId ? { "X-Mushi-Project-Id": opts.projectId } : {}
7612
+ },
7613
+ signal: AbortSignal.timeout(opts.timeoutMs ?? 5e3)
7614
+ });
7615
+ if (!res.ok) return null;
7616
+ const body = await res.json();
7617
+ const scopes = body?.data?.scopes;
7618
+ if (!Array.isArray(scopes)) return null;
7619
+ return scopes.filter((s) => typeof s === "string");
7620
+ } catch {
7621
+ return null;
7622
+ }
7623
+ }
7624
+ function decideScopes(keyScopes, configured) {
7625
+ if (keyScopes === null) return { kind: "serve", scopes: configured };
7626
+ const granted = /* @__PURE__ */ new Set();
7627
+ if (keyScopes.includes("mcp:write")) {
7628
+ granted.add("mcp:read");
7629
+ granted.add("mcp:write");
7630
+ } else if (keyScopes.includes("mcp:read")) {
7631
+ granted.add("mcp:read");
7632
+ }
7633
+ if (granted.size === 0) return { kind: "sdk-key", keyScopes };
7634
+ return { kind: "serve", scopes: configured.filter((s) => granted.has(s)) };
7635
+ }
7636
+ function sdkKeyReport(keyScopes, consoleUrl) {
7637
+ const held = keyScopes.length > 0 ? keyScopes.join(", ") : "none";
7638
+ return [
7639
+ "",
7640
+ `[mushi-mcp] This API key has scopes: ${held}. It can send bug reports (the SDK key) but not read them,`,
7641
+ " so the MCP tools would all be refused. Serving setup mode.",
7642
+ ` Fix: mint an MCP key in the console (${consoleUrl}/mcp \u2192 "Mint mcp:read key"),`,
7643
+ " or run `mushi login`, then put it in MUSHI_API_KEY for this server and restart it.",
7644
+ ""
7645
+ ].join("\n");
7646
+ }
7647
+
7598
7648
  // src/inventory-poll.ts
7599
7649
  function startInventoryPoll(options) {
7600
7650
  const doFetch = options.fetch ?? globalThis.fetch;
@@ -7854,6 +7904,23 @@ async function main() {
7854
7904
  );
7855
7905
  }
7856
7906
  }
7907
+ let scopes = SCOPES;
7908
+ if (!SCOPES_RAW) {
7909
+ const keyScopes = await fetchKeyScopes({ apiEndpoint: API_ENDPOINT, apiKey: API_KEY, projectId: PROJECT_ID || void 0 });
7910
+ const decision = decideScopes(keyScopes, SCOPES);
7911
+ if (decision.kind === "sdk-key") {
7912
+ const report = sdkKeyReport(decision.keyScopes, MUSHI_CONSOLE_URL);
7913
+ process.stderr.write(report);
7914
+ log.warn("The API key has no MCP scope (mcp:read / mcp:write) \u2014 serving setup mode.", {
7915
+ keyScopes: decision.keyScopes.join(",")
7916
+ });
7917
+ serveUntilClosed(serveStdio(() => createSetupModeServer({ version: VERSION, missingKeyReport: report, reason: "sdk-key" }), {
7918
+ onerror: (err) => log.error("stdio transport error", { err: String(err) })
7919
+ }));
7920
+ return;
7921
+ }
7922
+ scopes = decision.scopes;
7923
+ }
7857
7924
  const mode = PROJECT_ID ? "single-project" : "account";
7858
7925
  if (!PROJECT_ID) {
7859
7926
  log.info(
@@ -7865,7 +7932,7 @@ async function main() {
7865
7932
  mode,
7866
7933
  endpoint: API_ENDPOINT,
7867
7934
  hasProjectId: !!PROJECT_ID,
7868
- scopes: SCOPES.join(",")
7935
+ scopes: scopes.join(",")
7869
7936
  });
7870
7937
  let server;
7871
7938
  const handle = serveStdio(
@@ -7875,7 +7942,7 @@ async function main() {
7875
7942
  apiEndpoint: API_ENDPOINT,
7876
7943
  apiKey: API_KEY,
7877
7944
  projectId: PROJECT_ID || void 0,
7878
- scopes: SCOPES,
7945
+ scopes,
7879
7946
  features: FEATURES
7880
7947
  });
7881
7948
  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
@@ -6217,7 +6217,7 @@ function createSetupModeServer(config) {
6217
6217
  features: "all",
6218
6218
  ...config.fetch ? { fetch: config.fetch } : {},
6219
6219
  ...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."
6220
+ 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
6221
  });
6222
6222
  const internals = server;
6223
6223
  for (const [name, tool] of Object.entries(internals._registeredTools)) {
@@ -6232,7 +6232,8 @@ function createSetupModeServer(config) {
6232
6232
  }
6233
6233
  const spec = TOOL_CATALOG.find((t) => t.name === "diagnose_setup");
6234
6234
  if (!spec) throw new Error("[mushi-mcp] diagnose_setup is missing from TOOL_CATALOG");
6235
- const nextAction = "Run `npx mushi-mushi` in your project (signs you in and writes the key) or `mushi login`, then restart this MCP server.";
6235
+ const sdkKey = config.reason === "sdk-key";
6236
+ 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
6237
  server.registerTool(
6237
6238
  "diagnose_setup",
6238
6239
  {
@@ -6254,7 +6255,12 @@ function createSetupModeServer(config) {
6254
6255
  ready: false,
6255
6256
  mode: "setup",
6256
6257
  steps: [
6257
- {
6258
+ sdkKey ? {
6259
+ label: "MCP server key can read reports (mcp:read)",
6260
+ complete: false,
6261
+ required: true,
6262
+ 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.`
6263
+ } : {
6258
6264
  label: "MCP server has an API key",
6259
6265
  complete: false,
6260
6266
  required: true,
@@ -6271,6 +6277,7 @@ function createSetupModeServer(config) {
6271
6277
  return server;
6272
6278
  }
6273
6279
  export {
6280
+ MUSHI_CONSOLE_URL,
6274
6281
  MushiApiError,
6275
6282
  SETUP_MODE_TOOLS,
6276
6283
  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",
4
+ "version": "0.24.5",
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.31.2"
48
+ "@mushi-mushi/core": "^1.32.0"
49
49
  },
50
50
  "peerDependencies": {
51
51
  "@sentry/node": "^10.57.0"