@ai-ecoverse/mcpcat 0.31.15 → 0.31.17

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.
@@ -14287,10 +14287,30 @@ var HOLDER_RESTART_MAX_MS = 3e4;
14287
14287
  var HOLDER_STABLE_MS = 3e4;
14288
14288
  var HOLDER_STOP_GRACE_MS = 2e3;
14289
14289
  var HOLDER_READY_MS = 2e4;
14290
+ var FALLBACK_UNVERIFIED = "webmcp: other-extension fallback could not verify the reloaded document; tools are unavailable";
14290
14291
  var LABEL = "mcpcat serve --webmcp";
14291
- var GUARD_REFUSAL_RE = /^(?:(?:playwright-cli )?webmcp-polyfill: )?[A-Z][A-Za-z]*\.[a-z][A-Za-z]*: slicc: refused: \S/;
14292
+ var TERMINAL_REFUSALS = /* @__PURE__ */ new Set([
14293
+ "slicc: refused: target is on seven's origin",
14294
+ "slicc: refused: seven\u2019s own pages and the vault are out of reach of browser automation",
14295
+ "slicc: refused: breakpoints could run in seven\u2019s pages or the vault, so the guard doesn\u2019t offer the Debugger domains",
14296
+ "slicc: refused: update the browser guard and client",
14297
+ "slicc: refused: WebMCP installation could not verify the document; update the browser guard and client",
14298
+ "slicc: refused: WebMCP installation could not verify a usable guard and document; update the browser guard and client",
14299
+ "slicc: refused: WebMCP instrumentation is unavailable; update the browser guard and client",
14300
+ "webmcp: no tools are available through the other-extension fallback; page startup or parse-time checks may have happened before installation"
14301
+ ]);
14302
+ var FALLBACK_REFUSALS = /* @__PURE__ */ new Set([
14303
+ "other-extension fallback could not verify the reloaded document; tools are unavailable",
14304
+ "other-extension fallback could not verify the document"
14305
+ ]);
14306
+ function holderReason(line) {
14307
+ return line.trim().replace(/^playwright-cli webmcp-polyfill: /, "").replace(/^webmcp-polyfill: /, "").replace(/^[A-Z][A-Za-z]*\.[a-z][A-Za-z]*: /, "");
14308
+ }
14309
+ function isFallbackUnavailable(line) {
14310
+ return FALLBACK_REFUSALS.has(holderReason(line));
14311
+ }
14292
14312
  function isGuardRefusal(line) {
14293
- return GUARD_REFUSAL_RE.test(line.trim());
14313
+ return TERMINAL_REFUSALS.has(holderReason(line)) || isFallbackUnavailable(line);
14294
14314
  }
14295
14315
  function compareVersions(a, b) {
14296
14316
  const pa = a.split(".").map(Number);
@@ -14418,6 +14438,9 @@ function startHolder(platform2, options) {
14418
14438
  return;
14419
14439
  }
14420
14440
  proc = child;
14441
+ state.fallbackUnavailable = false;
14442
+ if (Number.isSafeInteger(child.pid) && child.pid > 0)
14443
+ report(`holder-pid ${child.pid} tab ${options.tab}`);
14421
14444
  writer = child.stdin.getWriter();
14422
14445
  let lastError;
14423
14446
  const out = drain(child.stdout, onEvent);
@@ -14425,7 +14448,8 @@ function startHolder(platform2, options) {
14425
14448
  const text = line.trim();
14426
14449
  if (!text) return;
14427
14450
  lastError = text;
14428
- if (readyAt === void 0 && isGuardRefusal(text)) refusal ??= text;
14451
+ if (isFallbackUnavailable(text)) state.fallbackUnavailable = true;
14452
+ if (isGuardRefusal(text)) refusal ??= text;
14429
14453
  else relay(text);
14430
14454
  });
14431
14455
  exited = Promise.all([out, err, child.wait()]).then(([, , result]) => {
@@ -14749,6 +14773,12 @@ function startDialogHolder(platform2, options) {
14749
14773
 
14750
14774
  // src/serve/webmcp.ts
14751
14775
  var UNAVAILABLE_RE = /WebMCP is unavailable on this page/;
14776
+ function emptyFallbackOrError(error, holderHint) {
14777
+ const hint = error.trim();
14778
+ if (hint === "webmcp: unverified isolated context" && holderHint === FALLBACK_UNVERIFIED)
14779
+ return { tools: [], hint: holderHint };
14780
+ return hint === "webmcp: no tools are available through the other-extension fallback; page startup or parse-time checks may have happened before installation" ? { tools: [], hint } : { tools: [], error };
14781
+ }
14752
14782
  function buildBaseArgs(options) {
14753
14783
  const args2 = [];
14754
14784
  if (options.cdp) {
@@ -15317,7 +15347,7 @@ function createWebMcpHandler(platform2, options) {
15317
15347
  async function getRpcTools() {
15318
15348
  const { tools, error, notFound, unavailable } = await listRaw();
15319
15349
  if (notFound) return null;
15320
- if (error) return { tools: [], error };
15350
+ if (error) return emptyFallbackOrError(error, options.emptyHint?.(false));
15321
15351
  const late = options.late?.() ?? false;
15322
15352
  const rpcTools = [];
15323
15353
  const hidden = {};
@@ -16479,6 +16509,7 @@ function emptyToolsHint(options, polyfill, unavailable) {
16479
16509
  return `the page shows no WebMCP tools, and the WebMCP polyfill needs playwright-cli ${POLYFILL_MIN_VERSION} or newer (found ${polyfill.oldVersion})`;
16480
16510
  }
16481
16511
  const status = polyfill.holder?.status();
16512
+ if (status?.refused && status.fallbackUnavailable) return FALLBACK_UNVERIFIED;
16482
16513
  if (isLate(polyfill.holder)) {
16483
16514
  return "the page may check for WebMCP only when it loads, before the polyfill was injected; reload the tab, or restart with --webmcp-reload (it reloads the tab)";
16484
16515
  }
@@ -22284,5 +22315,5 @@ try {
22284
22315
  });
22285
22316
  } catch {
22286
22317
  }
22287
- var code = await run(platform, "0.31.15", args);
22318
+ var code = await run(platform, "0.31.17", args);
22288
22319
  process.exit(code);
@@ -6571,7 +6571,17 @@ var SETTINGS_SIGN_IN = "Sign in under Settings \u203A MCP servers.";
6571
6571
  var HEADER_REJECTED = "The server rejected the explicit Authorization header.";
6572
6572
  var PLACEHOLDER_NOT_ACCEPTED = "The request carried the signed-in credential's placeholder and the server still answered 401. Seven's vault fills the placeholder in when the request is forwarded, so either that forwarding is not active in this seven yet or the server rejected the credential. Try again from the Settings page's Connect, or ask whoever runs seven.";
6573
6573
  var VAULT_NO_ANSWER = "Seven's vault did not answer, so the request carried no credential. Try again, or ask whoever runs seven.";
6574
+ var PLACEHOLDER_REFUSED = "Seven's vault fills a placeholder in when the request is forwarded, so either that forwarding is not active in this seven yet or it failed. Try again, or ask whoever runs seven.";
6575
+ var CAUSED = /\brefused \([a-z][a-z-]*\): \S/;
6574
6576
  var NO_PLACEHOLDER = `This user gets no placeholder for this server. With no sign-in yet: ${SETTINGS_SIGN_IN} After a sign-in, the agent already has this server's tools, because a Settings sign-in gives it the server as native tools, and a human can use the server from a panel terminal as root.`;
6577
+ function placeholderRefusal(err) {
6578
+ if (!(err instanceof TypeError)) return void 0;
6579
+ const { code, detail } = err.cause ?? {};
6580
+ if (code !== "EACCES" || typeof detail !== "string") return void 0;
6581
+ if (!detail.includes("sealed placeholder")) return void 0;
6582
+ const reason = detail.replace(/fnox_proxy_[0-9a-f]{24}/g, "[placeholder]");
6583
+ return authError(CAUSED.test(reason) ? `${reason}.` : `${reason}. ${PLACEHOLDER_REFUSED}`);
6584
+ }
6575
6585
  var SettingsSignInError = class extends McpcatError {
6576
6586
  advice;
6577
6587
  constructor(status, advice = SETTINGS_SIGN_IN) {
@@ -13908,10 +13918,30 @@ var HOLDER_RESTART_MAX_MS = 3e4;
13908
13918
  var HOLDER_STABLE_MS = 3e4;
13909
13919
  var HOLDER_STOP_GRACE_MS = 2e3;
13910
13920
  var HOLDER_READY_MS = 2e4;
13921
+ var FALLBACK_UNVERIFIED = "webmcp: other-extension fallback could not verify the reloaded document; tools are unavailable";
13911
13922
  var LABEL = "mcpcat serve --webmcp";
13912
- var GUARD_REFUSAL_RE = /^(?:(?:playwright-cli )?webmcp-polyfill: )?[A-Z][A-Za-z]*\.[a-z][A-Za-z]*: slicc: refused: \S/;
13923
+ var TERMINAL_REFUSALS = /* @__PURE__ */ new Set([
13924
+ "slicc: refused: target is on seven's origin",
13925
+ "slicc: refused: seven\u2019s own pages and the vault are out of reach of browser automation",
13926
+ "slicc: refused: breakpoints could run in seven\u2019s pages or the vault, so the guard doesn\u2019t offer the Debugger domains",
13927
+ "slicc: refused: update the browser guard and client",
13928
+ "slicc: refused: WebMCP installation could not verify the document; update the browser guard and client",
13929
+ "slicc: refused: WebMCP installation could not verify a usable guard and document; update the browser guard and client",
13930
+ "slicc: refused: WebMCP instrumentation is unavailable; update the browser guard and client",
13931
+ "webmcp: no tools are available through the other-extension fallback; page startup or parse-time checks may have happened before installation"
13932
+ ]);
13933
+ var FALLBACK_REFUSALS = /* @__PURE__ */ new Set([
13934
+ "other-extension fallback could not verify the reloaded document; tools are unavailable",
13935
+ "other-extension fallback could not verify the document"
13936
+ ]);
13937
+ function holderReason(line) {
13938
+ return line.trim().replace(/^playwright-cli webmcp-polyfill: /, "").replace(/^webmcp-polyfill: /, "").replace(/^[A-Z][A-Za-z]*\.[a-z][A-Za-z]*: /, "");
13939
+ }
13940
+ function isFallbackUnavailable(line) {
13941
+ return FALLBACK_REFUSALS.has(holderReason(line));
13942
+ }
13913
13943
  function isGuardRefusal(line) {
13914
- return GUARD_REFUSAL_RE.test(line.trim());
13944
+ return TERMINAL_REFUSALS.has(holderReason(line)) || isFallbackUnavailable(line);
13915
13945
  }
13916
13946
  function compareVersions(a, b) {
13917
13947
  const pa = a.split(".").map(Number);
@@ -14039,6 +14069,9 @@ function startHolder(platform2, options) {
14039
14069
  return;
14040
14070
  }
14041
14071
  proc = child;
14072
+ state.fallbackUnavailable = false;
14073
+ if (Number.isSafeInteger(child.pid) && child.pid > 0)
14074
+ report(`holder-pid ${child.pid} tab ${options.tab}`);
14042
14075
  writer = child.stdin.getWriter();
14043
14076
  let lastError;
14044
14077
  const out = drain(child.stdout, onEvent);
@@ -14046,7 +14079,8 @@ function startHolder(platform2, options) {
14046
14079
  const text = line.trim();
14047
14080
  if (!text) return;
14048
14081
  lastError = text;
14049
- if (readyAt === void 0 && isGuardRefusal(text)) refusal ??= text;
14082
+ if (isFallbackUnavailable(text)) state.fallbackUnavailable = true;
14083
+ if (isGuardRefusal(text)) refusal ??= text;
14050
14084
  else relay(text);
14051
14085
  });
14052
14086
  exited = Promise.all([out, err, child.wait()]).then(([, , result]) => {
@@ -14370,6 +14404,12 @@ function startDialogHolder(platform2, options) {
14370
14404
 
14371
14405
  // src/serve/webmcp.ts
14372
14406
  var UNAVAILABLE_RE = /WebMCP is unavailable on this page/;
14407
+ function emptyFallbackOrError(error, holderHint) {
14408
+ const hint = error.trim();
14409
+ if (hint === "webmcp: unverified isolated context" && holderHint === FALLBACK_UNVERIFIED)
14410
+ return { tools: [], hint: holderHint };
14411
+ return hint === "webmcp: no tools are available through the other-extension fallback; page startup or parse-time checks may have happened before installation" ? { tools: [], hint } : { tools: [], error };
14412
+ }
14373
14413
  function buildBaseArgs(options) {
14374
14414
  const args = [];
14375
14415
  if (options.cdp) {
@@ -14938,7 +14978,7 @@ function createWebMcpHandler(platform2, options) {
14938
14978
  async function getRpcTools() {
14939
14979
  const { tools, error, notFound, unavailable } = await listRaw();
14940
14980
  if (notFound) return null;
14941
- if (error) return { tools: [], error };
14981
+ if (error) return emptyFallbackOrError(error, options.emptyHint?.(false));
14942
14982
  const late = options.late?.() ?? false;
14943
14983
  const rpcTools = [];
14944
14984
  const hidden = {};
@@ -16100,6 +16140,7 @@ function emptyToolsHint(options, polyfill, unavailable) {
16100
16140
  return `the page shows no WebMCP tools, and the WebMCP polyfill needs playwright-cli ${POLYFILL_MIN_VERSION} or newer (found ${polyfill.oldVersion})`;
16101
16141
  }
16102
16142
  const status = polyfill.holder?.status();
16143
+ if (status?.refused && status.fallbackUnavailable) return FALLBACK_UNVERIFIED;
16103
16144
  if (isLate(polyfill.holder)) {
16104
16145
  return "the page may check for WebMCP only when it loads, before the polyfill was injected; reload the tab, or restart with --webmcp-reload (it reloads the tab)";
16105
16146
  }
@@ -21229,6 +21270,7 @@ async function kernelSpawn(ctx, options) {
21229
21270
  const useGroupKill = groupSpawnSupported;
21230
21271
  let waited;
21231
21272
  return {
21273
+ pid: childPid,
21232
21274
  stdin: result.stdin ?? new WritableStream(),
21233
21275
  stdout: result.stdout,
21234
21276
  stderr: result.stderr,
@@ -21577,6 +21619,11 @@ function createKernelFetch(ctx) {
21577
21619
  return ctx.fetch(input, init);
21578
21620
  };
21579
21621
  }
21622
+ function reportingRefusals(fetch) {
21623
+ return (input, init) => fetch(input, init).catch((err) => {
21624
+ throw placeholderRefusal(err) ?? err;
21625
+ });
21626
+ }
21580
21627
  async function kernelSeal(ctx, request) {
21581
21628
  const f = await ctx.open("/dev/sealed", { read: true, write: true });
21582
21629
  try {
@@ -21597,7 +21644,7 @@ function createKernelPlatform(ctx, options) {
21597
21644
  return {
21598
21645
  kind: "kernel",
21599
21646
  uid: ctx.sync?.cred?.().euid,
21600
- fetch: createKernelFetch(ctx),
21647
+ fetch: reportingRefusals(createKernelFetch(ctx)),
21601
21648
  spawn: (options2) => kernelSpawn(ctx, options2),
21602
21649
  listen: (options2) => kernelListen(ctx, options2),
21603
21650
  ...ctx.websocket ? { websocket: (url) => ctx.websocket(url) } : {},
@@ -21637,7 +21684,7 @@ async function main(ctx) {
21637
21684
  packageDir: "/node_modules/@ai-ecoverse/mcpcat"
21638
21685
  });
21639
21686
  const args = ctx.argv.slice(1);
21640
- return run(platform2, "0.31.15", args);
21687
+ return run(platform2, "0.31.17", args);
21641
21688
  }
21642
21689
  export {
21643
21690
  main as default
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ai-ecoverse/mcpcat",
3
- "version": "0.31.15",
3
+ "version": "0.31.17",
4
4
  "description": "A curl for the Model Context Protocol",
5
5
  "type": "module",
6
6
  "license": "Apache-2.0",
@@ -58,15 +58,16 @@
58
58
  "trust:dry": "npx fledgling sync --dry-run -y --skip-publish"
59
59
  },
60
60
  "devDependencies": {
61
- "@ai-ecoverse/slicc-kernel": "1.170.3",
62
- "@ai-ecoverse/slicc-shared-web": "2.13.7",
63
- "@biomejs/biome": "2.6.2",
61
+ "@ai-ecoverse/slicc-kernel": "1.173.0",
62
+ "@ai-ecoverse/slicc-shared-web": "2.13.10",
63
+ "@ai-ecoverse/slicc-vault": "1.21.2",
64
+ "@biomejs/biome": "2.6.3",
64
65
  "@earendil-works/pi-codemode": "1.4.0",
65
66
  "@earendil-works/pi-mcp": "1.4.0",
66
67
  "@types/node": "26.6.5",
67
68
  "esbuild": "0.28.2",
68
69
  "lefthook": "2.2.2",
69
- "monocart-coverage-reports": "2.13.2",
70
+ "monocart-coverage-reports": "3.1.0",
70
71
  "proper-lockfile": "4.1.2",
71
72
  "quickjs-wasi": "3.6.3",
72
73
  "semantic-release": "25.0.9",