@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.
- package/dist/host/mcpcat.mjs +36 -5
- package/dist/kernel/mcpcat.mjs +53 -6
- package/package.json +6 -5
package/dist/host/mcpcat.mjs
CHANGED
|
@@ -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
|
|
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
|
|
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 (
|
|
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
|
|
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.
|
|
22318
|
+
var code = await run(platform, "0.31.17", args);
|
|
22288
22319
|
process.exit(code);
|
package/dist/kernel/mcpcat.mjs
CHANGED
|
@@ -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
|
|
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
|
|
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 (
|
|
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
|
|
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.
|
|
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.
|
|
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.
|
|
62
|
-
"@ai-ecoverse/slicc-shared-web": "2.13.
|
|
63
|
-
"@
|
|
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": "
|
|
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",
|