@introspection-ai/recipes 0.19.3 → 0.21.0
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 +5 -4
- package/dist/agents.d.ts +17 -1
- package/dist/agents.d.ts.map +1 -1
- package/dist/agents.js +15 -1
- package/dist/agents.js.map +1 -1
- package/dist/child-agent.d.ts +5 -1
- package/dist/child-agent.d.ts.map +1 -1
- package/dist/child-agent.js +34 -1
- package/dist/child-agent.js.map +1 -1
- package/dist/mcp-chunks/{auth-command-3K7V3VCW.js → auth-command-4OEOMU2V.js} +26 -38
- package/dist/mcp-chunks/call-arguments-RPXZJOXL.js +15 -0
- package/dist/mcp-chunks/{call-command-OFPHPFM5.js → call-command-AUEKSBMD.js} +74 -40
- package/dist/mcp-chunks/{chunk-NCXEJ35U.js → chunk-3VLPWGJL.js} +4 -4
- package/dist/mcp-chunks/{chunk-2FSDGCHW.js → chunk-47N2EELW.js} +377 -527
- package/dist/mcp-chunks/{chunk-WWO5WGH5.js → chunk-4NDR45CX.js} +5 -5
- package/dist/mcp-chunks/{chunk-2MEHGB7D.js → chunk-5WGJPYOR.js} +1 -1
- package/dist/mcp-chunks/chunk-6CYJ6RN3.js +12 -0
- package/dist/mcp-chunks/{chunk-XUF6KARU.js → chunk-6DL2C6V5.js} +1 -1
- package/dist/mcp-chunks/{chunk-54EWGONA.js → chunk-6QH47GNE.js} +10 -6
- package/dist/mcp-chunks/{chunk-PKOJCYNA.js → chunk-756YH7S4.js} +2 -2
- package/dist/mcp-chunks/{chunk-C2PQFLWS.js → chunk-7CS27CWE.js} +15 -6
- package/dist/mcp-chunks/{chunk-GIF7LOYU.js → chunk-7KEDX7SE.js} +2 -2
- package/dist/mcp-chunks/{chunk-LNSUME65.js → chunk-AB7MHBEG.js} +29 -13
- package/dist/mcp-chunks/{chunk-NZOIX6XW.js → chunk-ACTRQW5L.js} +2 -2
- package/dist/mcp-chunks/{chunk-7A63PAGP.js → chunk-ADINDBOF.js} +21 -5
- package/dist/mcp-chunks/{chunk-XTL4MHFH.js → chunk-AF74TOWM.js} +11 -7
- package/dist/mcp-chunks/{chunk-KSGYBW3F.js → chunk-AFKE4BTR.js} +72 -22
- package/dist/mcp-chunks/{chunk-YTKRAHO6.js → chunk-DEYKPG4K.js} +4 -4
- package/dist/mcp-chunks/{chunk-SB2UUURE.js → chunk-E4YYMOT2.js} +10 -10
- package/dist/mcp-chunks/{chunk-HAO6PL7Z.js → chunk-HBDCHBJP.js} +7 -7
- package/dist/mcp-chunks/{chunk-QJACOI2W.js → chunk-HDUKEFBI.js} +4 -2
- package/dist/mcp-chunks/{chunk-E6RVTWJY.js → chunk-HHMWZ2FZ.js} +1 -1
- package/dist/mcp-chunks/{chunk-HTZ2URXW.js → chunk-IPH6U7SE.js} +3 -3
- package/dist/mcp-chunks/{chunk-SFREPU3D.js → chunk-J3J3NQ4X.js} +1 -1
- package/dist/mcp-chunks/{chunk-JAKI24KR.js → chunk-J6VOMOKI.js} +1 -1
- package/dist/mcp-chunks/{chunk-H7F5RZXS.js → chunk-JILBFEBD.js} +2 -1
- package/dist/mcp-chunks/{chunk-YPJ5EHXR.js → chunk-K56RW4HB.js} +4 -4
- package/dist/mcp-chunks/{chunk-YCYSQA5V.js → chunk-KMH3PHLA.js} +5 -5
- package/dist/mcp-chunks/{chunk-2JHHONW4.js → chunk-KPXFBRTG.js} +1 -1
- package/dist/mcp-chunks/{chunk-LICH4Q7A.js → chunk-L4CUJJI5.js} +4 -4
- package/dist/mcp-chunks/{chunk-XRGLP3Z2.js → chunk-LC2CCTQN.js} +1 -1
- package/dist/mcp-chunks/{chunk-P3RN22HQ.js → chunk-LJCZWKGJ.js} +3 -2
- package/dist/mcp-chunks/{chunk-F3LL4EBL.js → chunk-MFFE5QSH.js} +1 -1
- package/dist/mcp-chunks/{chunk-64EP2BVO.js → chunk-MOML5C2E.js} +1 -1
- package/dist/mcp-chunks/{chunk-CNDY7WB4.js → chunk-MRXSXBZT.js} +2 -2
- package/dist/mcp-chunks/{chunk-WXBPMFSN.js → chunk-NMFI6AUD.js} +91 -34
- package/dist/mcp-chunks/{chunk-55JIHDU3.js → chunk-NWLOPQT7.js} +1 -1
- package/dist/mcp-chunks/{chunk-DXPHJFSA.js → chunk-OGFFBNIC.js} +4 -4
- package/dist/mcp-chunks/{chunk-7RDLPFIO.js → chunk-PPIXUCYQ.js} +2 -2
- package/dist/mcp-chunks/{chunk-RBVYCKCD.js → chunk-PPOHGQKM.js} +2 -2
- package/dist/mcp-chunks/{chunk-E6T37ED6.js → chunk-PRZCYXVO.js} +2 -2
- package/dist/mcp-chunks/{chunk-ETWN4IIA.js → chunk-Q7ESBNJG.js} +6 -6
- package/dist/mcp-chunks/{chunk-CA5WFJZA.js → chunk-RE4EVQNC.js} +1 -1
- package/dist/mcp-chunks/{chunk-6D6KPSXN.js → chunk-RO2Y34XX.js} +1 -1
- package/dist/mcp-chunks/{chunk-KSMY7PXI.js → chunk-SAK5KCLR.js} +1 -1
- package/dist/mcp-chunks/{chunk-UENXT3NE.js → chunk-SCGMRUKI.js} +1 -1
- package/dist/mcp-chunks/{chunk-3IZQW4H4.js → chunk-SQTXZR56.js} +212 -18
- package/dist/mcp-chunks/{chunk-FWP4RACK.js → chunk-TGJOZDKG.js} +2 -2
- package/dist/mcp-chunks/{chunk-DEUU7WSN.js → chunk-US57PK4B.js} +2 -2
- package/dist/mcp-chunks/{chunk-UHOKCTZT.js → chunk-V4RYLZM5.js} +1 -1
- package/dist/mcp-chunks/{chunk-GFYTST6N.js → chunk-X3FOKZ5C.js} +1 -1
- package/dist/mcp-chunks/{chunk-GSZOK5TS.js → chunk-XK3LRH3Q.js} +3 -3
- package/dist/mcp-chunks/chunk-XVJAASVZ.js +1931 -0
- package/dist/mcp-chunks/{chunk-ZBFZ5UFE.js → chunk-YX2NKW6O.js} +3 -1
- package/dist/mcp-chunks/{chunk-L4VKBFYI.js → chunk-Z7O6NF7X.js} +101 -16
- package/dist/mcp-chunks/{chunk-7DH57OKF.js → chunk-ZKFG37TB.js} +2 -2
- package/dist/mcp-chunks/chunk-ZRZ7C6L3.js +823 -0
- package/dist/mcp-chunks/{chunk-YSPT6F7K.js → chunk-ZZSD2JT7.js} +1 -1
- package/dist/mcp-chunks/{cli-E4P6SZLQ.js → cli-B7WQQUME.js} +70 -69
- package/dist/mcp-chunks/client-4ZHIBB67.js +21 -0
- package/dist/mcp-chunks/{config-command-MWF3RHPQ.js → config-command-FF3JPMOP.js} +27 -27
- package/dist/mcp-chunks/daemon-command-FKW6YELL.js +35 -0
- package/dist/mcp-chunks/{dist-ZIPUENTM.js → dist-V4UB7RTR.js} +547 -402
- package/dist/mcp-chunks/{emit-ts-command-GOVJJ64A.js → emit-ts-command-4X56IZ32.js} +16 -16
- package/dist/mcp-chunks/{generate-cli-runner-L5OQIMEY.js → generate-cli-runner-MIPF73SJ.js} +49 -42
- package/dist/mcp-chunks/{inspect-cli-command-7OMMREPE.js → inspect-cli-command-GX54ZXKR.js} +9 -9
- package/dist/mcp-chunks/{launch-BWXPLPB7.js → launch-E2LWGPZS.js} +1 -1
- package/dist/mcp-chunks/{lifecycle-B5UC65PT.js → lifecycle-TONHXXXJ.js} +1 -1
- package/dist/mcp-chunks/{list-command-ZO4HVFQK.js → list-command-YUGRZO4G.js} +31 -31
- package/dist/mcp-chunks/{output-utils-M3TJ2N4M.js → output-utils-AZY6N2VQ.js} +3 -3
- package/dist/mcp-chunks/{prompt-CH6TK0bC-C7OTKGRD.js → prompt-CH6TK0bC-NSBYYJZH.js} +1 -1
- package/dist/mcp-chunks/{record-command-VD3HUQIC.js → record-command-25DLELA2.js} +5 -5
- package/dist/mcp-chunks/{replay-command-AX6IN7YD.js → replay-command-6SLDG6PC.js} +6 -6
- package/dist/mcp-chunks/{resource-command-JEZ2DW2G.js → resource-command-YVOB4JCU.js} +9 -9
- package/dist/mcp-chunks/{result-utils-3YHYGS45.js → result-utils-ZXB5DM36.js} +3 -3
- package/dist/mcp-chunks/runtime-NOWGTHZ5.js +39 -0
- package/dist/mcp-chunks/{runtime-wrapper-UREU7GC3.js → runtime-wrapper-ZZPAFQE4.js} +6 -6
- package/dist/mcp-chunks/{serve-command-M47YZ6JN.js → serve-command-QYGM2AMB.js} +35 -27
- package/dist/mcp-chunks/{timeouts-THZRYP4B.js → timeouts-P3TBB3AX.js} +5 -3
- package/dist/mcp-chunks/{vault-command-53P7MLCB.js → vault-command-VDMPATIX.js} +58 -12
- package/dist/mcp-chunks/{webapi-PHEQZQKH.js → webapi-BLTNWSB2.js} +68 -60
- package/dist/mcp-daemon.js +30 -28
- package/dist/mcp-run-worker.js +30 -28
- package/dist/mcp.d.ts.map +1 -1
- package/dist/mcp.js +24 -0
- package/dist/mcp.js.map +1 -1
- package/dist/pi-extension.d.ts +3 -0
- package/dist/pi-extension.d.ts.map +1 -1
- package/dist/pi-extension.js +30 -22
- package/dist/pi-extension.js.map +1 -1
- package/dist/run-controller.d.ts +3 -1
- package/dist/run-controller.d.ts.map +1 -1
- package/dist/run-controller.js +17 -3
- package/dist/run-controller.js.map +1 -1
- package/dist/session.d.ts +3 -1
- package/dist/session.d.ts.map +1 -1
- package/dist/session.js +4 -1
- package/dist/session.js.map +1 -1
- package/docs/host-api.md +12 -0
- package/docs/pi-extension.md +18 -5
- package/package.json +20 -16
- package/dist/mcp-chunks/call-arguments-TX3F2TEE.js +0 -15
- package/dist/mcp-chunks/chunk-SRZZQ6TL.js +0 -266
- package/dist/mcp-chunks/client-2EJC4PLL.js +0 -18
- package/dist/mcp-chunks/daemon-command-6CJ26MKI.js +0 -33
- package/dist/mcp-chunks/runtime-HSYVOME7.js +0 -37
- package/dist/recipe-check.d.ts +0 -18
- package/dist/recipe-check.d.ts.map +0 -1
- package/dist/recipe-check.js +0 -263
- package/dist/recipe-check.js.map +0 -1
- package/vendor/introspection-recipe-check/darwin-arm64/introspection-recipe-check +0 -0
- package/vendor/introspection-recipe-check/darwin-x64/introspection-recipe-check +0 -0
- package/vendor/introspection-recipe-check/linux-arm64/introspection-recipe-check +0 -0
- package/vendor/introspection-recipe-check/linux-x64/introspection-recipe-check +0 -0
- package/vendor/introspection-recipe-check/linux-x64-musl/introspection-recipe-check +0 -0
- package/vendor/introspection-recipe-check/win32-x64/introspection-recipe-check.exe +0 -0
- package/vendor/mcp-client/darwin-arm64/mcp-client +0 -0
- package/vendor/mcp-client/darwin-x64/mcp-client +0 -0
- package/vendor/mcp-client/linux-arm64/mcp-client +0 -0
- package/vendor/mcp-client/linux-x64/mcp-client +0 -0
|
@@ -3,48 +3,41 @@ import {
|
|
|
3
3
|
NON_INTERACTIVE_ELICITATION_HINT,
|
|
4
4
|
createNonInteractiveElicitationResponder,
|
|
5
5
|
registerElicitationHandler
|
|
6
|
-
} from "./chunk-
|
|
6
|
+
} from "./chunk-RE4EVQNC.js";
|
|
7
7
|
import {
|
|
8
8
|
RecordTransport,
|
|
9
9
|
resolveRecordingPath
|
|
10
|
-
} from "./chunk-
|
|
10
|
+
} from "./chunk-PRZCYXVO.js";
|
|
11
11
|
import {
|
|
12
12
|
OAuthTimeoutError,
|
|
13
13
|
connectWithAuth,
|
|
14
|
+
createOAuthSession,
|
|
14
15
|
isOAuthFlowError,
|
|
15
16
|
isPostAuthConnectError,
|
|
16
17
|
resolveOAuthTimeoutFromEnv
|
|
17
|
-
} from "./chunk-
|
|
18
|
+
} from "./chunk-ZRZ7C6L3.js";
|
|
18
19
|
import {
|
|
19
|
-
buildOAuthPersistence,
|
|
20
|
-
buildStaticClientInformation,
|
|
21
20
|
readCachedAccessToken
|
|
22
|
-
} from "./chunk-
|
|
21
|
+
} from "./chunk-SQTXZR56.js";
|
|
23
22
|
import {
|
|
24
23
|
isUnauthorizedError,
|
|
25
24
|
maybeEnableOAuth
|
|
26
|
-
} from "./chunk-
|
|
25
|
+
} from "./chunk-ZKFG37TB.js";
|
|
27
26
|
import {
|
|
28
27
|
STDIO_TRACE_ENABLED,
|
|
29
28
|
flushStdioLogs,
|
|
30
29
|
ignoreStdioEmitterError
|
|
31
|
-
} from "./chunk-
|
|
30
|
+
} from "./chunk-5WGJPYOR.js";
|
|
32
31
|
import {
|
|
33
32
|
MCPORTER_VERSION
|
|
34
|
-
} from "./chunk-
|
|
33
|
+
} from "./chunk-J3J3NQ4X.js";
|
|
35
34
|
import {
|
|
36
35
|
createPrefixedConsoleLogger,
|
|
37
36
|
resolveLogLevelFromEnv
|
|
38
|
-
} from "./chunk-
|
|
39
|
-
import {
|
|
40
|
-
normalizeTimeout,
|
|
41
|
-
raceWithTimeout,
|
|
42
|
-
resolveCommandArgument,
|
|
43
|
-
resolveCommandArguments
|
|
44
|
-
} from "./chunk-ETWN4IIA.js";
|
|
37
|
+
} from "./chunk-X3FOKZ5C.js";
|
|
45
38
|
import {
|
|
46
39
|
analyzeConnectionError
|
|
47
|
-
} from "./chunk-
|
|
40
|
+
} from "./chunk-US57PK4B.js";
|
|
48
41
|
import {
|
|
49
42
|
Client,
|
|
50
43
|
DEFAULT_REQUEST_TIMEOUT_MSEC,
|
|
@@ -56,17 +49,29 @@ import {
|
|
|
56
49
|
SdkHttpError,
|
|
57
50
|
StreamableHTTPClientTransport,
|
|
58
51
|
serializeMessage,
|
|
59
|
-
specTypeSchemas
|
|
60
|
-
|
|
61
|
-
|
|
52
|
+
specTypeSchemas
|
|
53
|
+
} from "./chunk-K56RW4HB.js";
|
|
54
|
+
import {
|
|
55
|
+
ChromeDevtoolsRelayRequiredError,
|
|
56
|
+
formatChromeDevtoolsRelayDecision,
|
|
57
|
+
recordChromeDevtoolsRelayDecision,
|
|
58
|
+
resolveChromeDevtoolsAutoConnectCommand,
|
|
59
|
+
resolveChromeDevtoolsRelayEnvironment,
|
|
60
|
+
rewriteChromeDevtoolsArgsForRelay
|
|
61
|
+
} from "./chunk-XVJAASVZ.js";
|
|
62
|
+
import {
|
|
63
|
+
normalizeTimeout,
|
|
64
|
+
raceWithTimeout,
|
|
65
|
+
resolveCommandArgument,
|
|
66
|
+
resolveCommandArguments
|
|
67
|
+
} from "./chunk-Q7ESBNJG.js";
|
|
62
68
|
import {
|
|
63
69
|
loadServerDefinitions
|
|
64
|
-
} from "./chunk-
|
|
70
|
+
} from "./chunk-Z7O6NF7X.js";
|
|
65
71
|
import {
|
|
66
72
|
resolveEnvPlaceholders,
|
|
67
|
-
resolveEnvValue,
|
|
68
73
|
withEnvOverrides
|
|
69
|
-
} from "./chunk-
|
|
74
|
+
} from "./chunk-HBDCHBJP.js";
|
|
70
75
|
import {
|
|
71
76
|
__commonJS,
|
|
72
77
|
__require,
|
|
@@ -550,27 +555,27 @@ var require_cross_spawn = __commonJS({
|
|
|
550
555
|
var cp = __require("child_process");
|
|
551
556
|
var parse = require_parse();
|
|
552
557
|
var enoent = require_enoent();
|
|
553
|
-
function
|
|
558
|
+
function spawn2(command, args, options) {
|
|
554
559
|
const parsed = parse(command, args, options);
|
|
555
560
|
const spawned = cp.spawn(parsed.command, parsed.args, parsed.options);
|
|
556
561
|
enoent.hookChildProcess(spawned, parsed);
|
|
557
562
|
return spawned;
|
|
558
563
|
}
|
|
559
|
-
function
|
|
564
|
+
function spawnSync2(command, args, options) {
|
|
560
565
|
const parsed = parse(command, args, options);
|
|
561
566
|
const result = cp.spawnSync(parsed.command, parsed.args, parsed.options);
|
|
562
567
|
result.error = result.error || enoent.verifyENOENTSync(result.status, parsed);
|
|
563
568
|
return result;
|
|
564
569
|
}
|
|
565
|
-
module.exports =
|
|
566
|
-
module.exports.spawn =
|
|
567
|
-
module.exports.sync =
|
|
570
|
+
module.exports = spawn2;
|
|
571
|
+
module.exports.spawn = spawn2;
|
|
572
|
+
module.exports.sync = spawnSync2;
|
|
568
573
|
module.exports._parse = parse;
|
|
569
574
|
module.exports._enoent = enoent;
|
|
570
575
|
}
|
|
571
576
|
});
|
|
572
577
|
|
|
573
|
-
// node_modules/.pnpm/mcporter@0.13.
|
|
578
|
+
// node_modules/.pnpm/mcporter@0.13.7/node_modules/mcporter/dist/runtime-process-utils.js
|
|
574
579
|
import { execFile } from "node:child_process";
|
|
575
580
|
async function closeTransportAndWait(logger, transport, options = {}) {
|
|
576
581
|
const pidBeforeClose = getTransportPid(transport);
|
|
@@ -777,7 +782,7 @@ function delay(ms) {
|
|
|
777
782
|
return new Promise((resolve) => setTimeout(resolve, ms));
|
|
778
783
|
}
|
|
779
784
|
|
|
780
|
-
// node_modules/.pnpm/mcporter@0.13.
|
|
785
|
+
// node_modules/.pnpm/mcporter@0.13.7/node_modules/mcporter/dist/runtime/errors.js
|
|
781
786
|
var NON_FATAL_MCP_ERROR_CODES = /* @__PURE__ */ new Set([
|
|
782
787
|
ProtocolErrorCode.InvalidRequest,
|
|
783
788
|
ProtocolErrorCode.MethodNotFound,
|
|
@@ -799,7 +804,7 @@ function protocolErrorCode(error) {
|
|
|
799
804
|
return typeof error.code === "number" ? error.code : void 0;
|
|
800
805
|
}
|
|
801
806
|
|
|
802
|
-
// node_modules/.pnpm/mcporter@0.13.
|
|
807
|
+
// node_modules/.pnpm/mcporter@0.13.7/node_modules/mcporter/dist/runtime/replay-transport.js
|
|
803
808
|
import fs from "node:fs";
|
|
804
809
|
import { isDeepStrictEqual } from "node:util";
|
|
805
810
|
var CLIENT_IDENTITY_META_KEYS = [
|
|
@@ -1021,13 +1026,13 @@ function formatReplayRemainder(server, expectedSends) {
|
|
|
1021
1026
|
return `Replay ended for server '${server}' with ${count} recorded ${requestText} still unused; next expected recv ${expectedText}.`;
|
|
1022
1027
|
}
|
|
1023
1028
|
|
|
1024
|
-
// node_modules/.pnpm/mcporter@0.13.
|
|
1029
|
+
// node_modules/.pnpm/mcporter@0.13.7/node_modules/mcporter/dist/chrome-devtools-compat.js
|
|
1025
1030
|
import fs3 from "node:fs";
|
|
1026
1031
|
import os from "node:os";
|
|
1027
1032
|
import path2 from "node:path";
|
|
1028
1033
|
import { fileURLToPath, pathToFileURL } from "node:url";
|
|
1029
1034
|
|
|
1030
|
-
// node_modules/.pnpm/mcporter@0.13.
|
|
1035
|
+
// node_modules/.pnpm/mcporter@0.13.7/node_modules/mcporter/dist/chrome-devtools-auto-connect-patch.js
|
|
1031
1036
|
import fs2 from "node:fs";
|
|
1032
1037
|
import path from "node:path";
|
|
1033
1038
|
var MARKER = "MCPORTER_DEVTOOLS_TIMEOUT_PATCH";
|
|
@@ -1114,8 +1119,7 @@ ${helper}`);
|
|
|
1114
1119
|
}
|
|
1115
1120
|
}
|
|
1116
1121
|
|
|
1117
|
-
// node_modules/.pnpm/mcporter@0.13.
|
|
1118
|
-
var AUTO_CONNECT_FLAGS = /* @__PURE__ */ new Set(["--autoConnect", "--auto-connect"]);
|
|
1122
|
+
// node_modules/.pnpm/mcporter@0.13.7/node_modules/mcporter/dist/chrome-devtools-compat.js
|
|
1119
1123
|
var FALLBACK_PATCH_FILENAME = "mcporter-chrome-devtools-auto-connect-patch.js";
|
|
1120
1124
|
function applyChromeDevtoolsCompat(env, command, args) {
|
|
1121
1125
|
if (!shouldApplyChromeDevtoolsCompat(command, args, env)) {
|
|
@@ -1143,11 +1147,7 @@ function shouldApplyChromeDevtoolsCompat(command, args, env = process.env) {
|
|
|
1143
1147
|
if (env.MCPORTER_DISABLE_CHROME_DEVTOOLS_COMPAT === "1") {
|
|
1144
1148
|
return false;
|
|
1145
1149
|
}
|
|
1146
|
-
|
|
1147
|
-
return tokens.some(isChromeDevtoolsToken) && args.some((arg) => AUTO_CONNECT_FLAGS.has(arg));
|
|
1148
|
-
}
|
|
1149
|
-
function isChromeDevtoolsToken(token) {
|
|
1150
|
-
return token === "chrome-devtools-mcp" || token.startsWith("chrome-devtools-mcp@") || token.includes("/chrome-devtools-mcp");
|
|
1150
|
+
return resolveChromeDevtoolsAutoConnectCommand(command, args).enabled;
|
|
1151
1151
|
}
|
|
1152
1152
|
function resolveChromeDevtoolsCompatPatchPath(candidates = defaultChromeDevtoolsPatchCandidates(), fallbackDir = os.tmpdir()) {
|
|
1153
1153
|
const existing = candidates.find((candidate) => fs3.existsSync(candidate));
|
|
@@ -1173,88 +1173,232 @@ function writeFallbackPatch(fallbackDir) {
|
|
|
1173
1173
|
}
|
|
1174
1174
|
}
|
|
1175
1175
|
|
|
1176
|
-
// node_modules/.pnpm/mcporter@0.13.
|
|
1176
|
+
// node_modules/.pnpm/mcporter@0.13.7/node_modules/mcporter/dist/chrome-devtools-relay-handoff.js
|
|
1177
|
+
import { spawnSync } from "node:child_process";
|
|
1178
|
+
import { randomBytes } from "node:crypto";
|
|
1177
1179
|
import fs4 from "node:fs";
|
|
1178
1180
|
import os2 from "node:os";
|
|
1179
1181
|
import path3 from "node:path";
|
|
1180
|
-
|
|
1181
|
-
var
|
|
1182
|
-
var
|
|
1183
|
-
|
|
1184
|
-
|
|
1185
|
-
|
|
1186
|
-
function
|
|
1187
|
-
|
|
1188
|
-
let url;
|
|
1182
|
+
import { pathToFileURL as pathToFileURL2 } from "node:url";
|
|
1183
|
+
var CHROME_RELAY_HANDOFF_ENV = "MCPORTER_CHROME_RELAY_HANDOFF_PATH";
|
|
1184
|
+
var HANDOFF_DIR_PREFIX = "mcporter-chrome-relay-";
|
|
1185
|
+
var HANDOFF_FILENAME = "headers.json";
|
|
1186
|
+
var PRELOAD_FILENAME = "preload.mjs";
|
|
1187
|
+
var WINDOWS_ACL_PATH_ENV = "MCPORTER_CHROME_RELAY_ACL_PATH";
|
|
1188
|
+
function createChromeDevtoolsRelayHandoff(env, clientAuthorization) {
|
|
1189
|
+
let directory;
|
|
1189
1190
|
try {
|
|
1190
|
-
|
|
1191
|
-
|
|
1192
|
-
|
|
1193
|
-
|
|
1194
|
-
|
|
1195
|
-
|
|
1196
|
-
|
|
1197
|
-
|
|
1191
|
+
if (process.platform === "win32")
|
|
1192
|
+
directory = createWindowsHandoffDirectory();
|
|
1193
|
+
else {
|
|
1194
|
+
directory = fs4.mkdtempSync(path3.join(os2.tmpdir(), HANDOFF_DIR_PREFIX));
|
|
1195
|
+
fs4.chmodSync(directory, 448);
|
|
1196
|
+
}
|
|
1197
|
+
assertSecurePath(directory, "directory");
|
|
1198
|
+
const handoffPath = path3.join(directory, HANDOFF_FILENAME);
|
|
1199
|
+
const preloadPath = path3.join(directory, PRELOAD_FILENAME);
|
|
1200
|
+
writeExclusiveFile(preloadPath, renderChromeDevtoolsRelayPreloadSource());
|
|
1201
|
+
writeExclusiveFile(handoffPath, JSON.stringify({ Authorization: clientAuthorization }));
|
|
1202
|
+
const importFlag = `--import=${pathToFileURL2(preloadPath).href}`;
|
|
1203
|
+
const existingOptions = env.NODE_OPTIONS?.trim();
|
|
1204
|
+
let closed = false;
|
|
1205
|
+
return {
|
|
1206
|
+
env: {
|
|
1207
|
+
...env,
|
|
1208
|
+
NODE_OPTIONS: existingOptions ? `${existingOptions} ${importFlag}` : importFlag,
|
|
1209
|
+
[CHROME_RELAY_HANDOFF_ENV]: handoffPath
|
|
1210
|
+
},
|
|
1211
|
+
handoffPath,
|
|
1212
|
+
preloadPath,
|
|
1213
|
+
async close() {
|
|
1214
|
+
if (closed)
|
|
1215
|
+
return;
|
|
1216
|
+
closed = true;
|
|
1217
|
+
cleanupHandoff(directory, handoffPath, preloadPath);
|
|
1218
|
+
}
|
|
1219
|
+
};
|
|
1220
|
+
} catch (error) {
|
|
1221
|
+
if (directory)
|
|
1222
|
+
cleanupHandoff(directory, path3.join(directory, HANDOFF_FILENAME), path3.join(directory, PRELOAD_FILENAME));
|
|
1223
|
+
const diagnostic = error instanceof Error && error.message.startsWith("Windows ACL setup failed:") ? ` ${error.message}` : "";
|
|
1224
|
+
throw new Error(`Unable to install secure Chrome relay authorization handoff.${diagnostic}`, { cause: error });
|
|
1225
|
+
}
|
|
1226
|
+
}
|
|
1227
|
+
function createWindowsHandoffDirectory() {
|
|
1228
|
+
const directory = path3.join(os2.tmpdir(), `${HANDOFF_DIR_PREFIX}${randomBytes(16).toString("hex")}`);
|
|
1229
|
+
const script = String.raw`
|
|
1230
|
+
$ErrorActionPreference = 'Stop'
|
|
1231
|
+
$stage = 'identity'
|
|
1232
|
+
try {
|
|
1233
|
+
$target = $env:${WINDOWS_ACL_PATH_ENV}
|
|
1234
|
+
if ([System.IO.Directory]::Exists($target)) { throw 'handoff path already exists' }
|
|
1235
|
+
$sid = [System.Security.Principal.WindowsIdentity]::GetCurrent().User
|
|
1236
|
+
$stage = 'descriptor'
|
|
1237
|
+
$security = New-Object System.Security.AccessControl.DirectorySecurity
|
|
1238
|
+
$sidValue = $sid.Value
|
|
1239
|
+
$security.SetSecurityDescriptorSddlForm("O:$($sidValue)G:$($sidValue)D:P(A;OICI;FA;;;$($sidValue))")
|
|
1240
|
+
$directory = New-Object System.IO.DirectoryInfo -ArgumentList @($target)
|
|
1241
|
+
$stage = 'create'
|
|
1242
|
+
$directory.Create($security)
|
|
1243
|
+
$stage = 'acl-read'
|
|
1244
|
+
$check = $directory.GetAccessControl([System.Security.AccessControl.AccessControlSections]::All)
|
|
1245
|
+
$rules = @($check.GetAccessRules($true, $true, [System.Security.Principal.SecurityIdentifier]))
|
|
1246
|
+
$ownerSid = $check.GetOwner([System.Security.Principal.SecurityIdentifier]).Value
|
|
1247
|
+
$stage = 'acl-verify'
|
|
1248
|
+
if (-not $check.AreAccessRulesProtected -or $ownerSid -ne $sid.Value -or $rules.Count -ne 1) { throw 'unsafe ACL' }
|
|
1249
|
+
$ruleSid = $rules[0].IdentityReference.Value
|
|
1250
|
+
$hasFullControl = ($rules[0].FileSystemRights -band [System.Security.AccessControl.FileSystemRights]::FullControl) -eq [System.Security.AccessControl.FileSystemRights]::FullControl
|
|
1251
|
+
if ($ruleSid -ne $sid.Value -or $rules[0].IsInherited -or -not $hasFullControl -or $rules[0].AccessControlType -ne [System.Security.AccessControl.AccessControlType]::Allow) { throw 'unsafe ACL' }
|
|
1252
|
+
} catch {
|
|
1253
|
+
$type = $_.Exception.GetType().FullName
|
|
1254
|
+
$hresult = ('0x{0:X8}' -f ($_.Exception.HResult -band 0xffffffffL))
|
|
1255
|
+
[Console]::Error.WriteLine("stage=$stage type=$type hresult=$hresult")
|
|
1256
|
+
exit 1
|
|
1198
1257
|
}
|
|
1199
|
-
|
|
1200
|
-
const
|
|
1201
|
-
|
|
1202
|
-
|
|
1203
|
-
|
|
1204
|
-
|
|
1205
|
-
}
|
|
1206
|
-
|
|
1258
|
+
`;
|
|
1259
|
+
const result = spawnSync(resolveSystemPowerShellPath(), ["-NoLogo", "-NoProfile", "-NonInteractive", "-Command", script], {
|
|
1260
|
+
encoding: "utf8",
|
|
1261
|
+
env: { ...process.env, [WINDOWS_ACL_PATH_ENV]: directory },
|
|
1262
|
+
stdio: ["ignore", "ignore", "pipe"],
|
|
1263
|
+
windowsHide: true
|
|
1264
|
+
});
|
|
1265
|
+
if (result.status !== 0) {
|
|
1266
|
+
try {
|
|
1267
|
+
fs4.rmdirSync(directory);
|
|
1268
|
+
} catch {
|
|
1269
|
+
}
|
|
1270
|
+
const stderr = typeof result.stderr === "string" ? result.stderr.trim() : "";
|
|
1271
|
+
const safeDetail = /^[A-Za-z0-9_.:=\- ]{1,240}$/u.test(stderr) ? stderr : `stage=spawn type=${result.error?.code ?? "unknown"} hresult=unknown`;
|
|
1272
|
+
throw new Error(`Windows ACL setup failed: ${safeDetail}`);
|
|
1207
1273
|
}
|
|
1208
|
-
|
|
1209
|
-
return /^[0-9a-f]{64}$/.test(token) ? token : void 0;
|
|
1274
|
+
return directory;
|
|
1210
1275
|
}
|
|
1211
|
-
|
|
1212
|
-
const
|
|
1213
|
-
|
|
1214
|
-
|
|
1276
|
+
function resolveSystemPowerShellPath() {
|
|
1277
|
+
const systemRoot = process.env.SystemRoot?.trim() || process.env.WINDIR?.trim();
|
|
1278
|
+
if (!systemRoot || !path3.win32.isAbsolute(systemRoot))
|
|
1279
|
+
throw new Error("unsafe Windows system root");
|
|
1280
|
+
const executable = path3.win32.join(systemRoot, "System32", "WindowsPowerShell", "v1.0", "powershell.exe");
|
|
1281
|
+
const stat = fs4.lstatSync(executable);
|
|
1282
|
+
if (!stat.isFile() || stat.isSymbolicLink())
|
|
1283
|
+
throw new Error("unsafe Windows PowerShell path");
|
|
1284
|
+
return executable;
|
|
1285
|
+
}
|
|
1286
|
+
function writeExclusiveFile(filePath, contents) {
|
|
1287
|
+
const descriptor = fs4.openSync(filePath, fs4.constants.O_WRONLY | fs4.constants.O_CREAT | fs4.constants.O_EXCL | (fs4.constants.O_NOFOLLOW ?? 0), 384);
|
|
1215
1288
|
try {
|
|
1216
|
-
|
|
1217
|
-
|
|
1218
|
-
|
|
1219
|
-
});
|
|
1220
|
-
return response.status === 200;
|
|
1221
|
-
} catch {
|
|
1222
|
-
return false;
|
|
1289
|
+
if (process.platform !== "win32")
|
|
1290
|
+
fs4.fchmodSync(descriptor, 384);
|
|
1291
|
+
fs4.writeFileSync(descriptor, contents, "utf8");
|
|
1223
1292
|
} finally {
|
|
1224
|
-
|
|
1293
|
+
fs4.closeSync(descriptor);
|
|
1225
1294
|
}
|
|
1295
|
+
assertSecurePath(filePath, "file");
|
|
1226
1296
|
}
|
|
1227
|
-
function
|
|
1228
|
-
|
|
1229
|
-
|
|
1230
|
-
|
|
1231
|
-
|
|
1232
|
-
|
|
1297
|
+
function assertSecurePath(filePath, kind) {
|
|
1298
|
+
const stat = fs4.lstatSync(filePath);
|
|
1299
|
+
if ((kind === "directory" ? !stat.isDirectory() : !stat.isFile()) || stat.isSymbolicLink())
|
|
1300
|
+
throw new Error("unsafe");
|
|
1301
|
+
if (process.platform === "win32")
|
|
1302
|
+
return;
|
|
1303
|
+
if ((stat.mode & 63) !== 0)
|
|
1304
|
+
throw new Error("unsafe");
|
|
1305
|
+
if (typeof process.getuid === "function" && stat.uid !== process.getuid())
|
|
1306
|
+
throw new Error("unsafe");
|
|
1233
1307
|
}
|
|
1234
|
-
|
|
1235
|
-
|
|
1236
|
-
|
|
1308
|
+
function cleanupHandoff(directory, handoffPath, preloadPath) {
|
|
1309
|
+
for (const filePath of [handoffPath, preloadPath]) {
|
|
1310
|
+
try {
|
|
1311
|
+
fs4.unlinkSync(filePath);
|
|
1312
|
+
} catch {
|
|
1313
|
+
}
|
|
1237
1314
|
}
|
|
1238
|
-
|
|
1239
|
-
|
|
1240
|
-
|
|
1315
|
+
try {
|
|
1316
|
+
fs4.rmdirSync(directory);
|
|
1317
|
+
} catch {
|
|
1241
1318
|
}
|
|
1242
|
-
|
|
1243
|
-
|
|
1244
|
-
|
|
1319
|
+
}
|
|
1320
|
+
function renderChromeDevtoolsRelayPreloadSource() {
|
|
1321
|
+
return `import fs from 'node:fs';
|
|
1322
|
+
import path from 'node:path';
|
|
1323
|
+
|
|
1324
|
+
const targetPath = process.argv[1]?.replaceAll('\\\\', '/').toLowerCase();
|
|
1325
|
+
if (targetPath?.includes('chrome-devtools-mcp')) {
|
|
1326
|
+
const failureMessage = 'MCPorter Chrome relay authorization handoff unavailable.';
|
|
1327
|
+
const fail = () => {
|
|
1328
|
+
throw new Error(failureMessage);
|
|
1329
|
+
};
|
|
1330
|
+
const envName = ${JSON.stringify(CHROME_RELAY_HANDOFF_ENV)};
|
|
1331
|
+
const handoffPath = process.env[envName];
|
|
1332
|
+
delete process.env[envName];
|
|
1333
|
+
if (!handoffPath || !path.isAbsolute(handoffPath)) fail();
|
|
1334
|
+
|
|
1335
|
+
const directoryStat = (() => {
|
|
1336
|
+
try {
|
|
1337
|
+
return fs.lstatSync(path.dirname(handoffPath));
|
|
1338
|
+
} catch {
|
|
1339
|
+
return fail();
|
|
1340
|
+
}
|
|
1341
|
+
})();
|
|
1342
|
+
if (!directoryStat.isDirectory() || directoryStat.isSymbolicLink()) fail();
|
|
1343
|
+
if (process.platform !== 'win32') {
|
|
1344
|
+
if ((directoryStat.mode & 0o077) !== 0) fail();
|
|
1345
|
+
if (typeof process.getuid === 'function' && directoryStat.uid !== process.getuid()) fail();
|
|
1245
1346
|
}
|
|
1246
|
-
|
|
1247
|
-
const
|
|
1248
|
-
|
|
1249
|
-
|
|
1347
|
+
|
|
1348
|
+
const descriptor = (() => {
|
|
1349
|
+
try {
|
|
1350
|
+
return fs.openSync(handoffPath, fs.constants.O_RDONLY | (fs.constants.O_NOFOLLOW ?? 0));
|
|
1351
|
+
} catch {
|
|
1352
|
+
return fail();
|
|
1353
|
+
}
|
|
1354
|
+
})();
|
|
1355
|
+
|
|
1356
|
+
let raw = '';
|
|
1357
|
+
let consumed = false;
|
|
1358
|
+
try {
|
|
1359
|
+
const stat = fs.fstatSync(descriptor);
|
|
1360
|
+
if (!stat.isFile() || stat.size <= 0 || stat.size > 4_096) fail();
|
|
1361
|
+
if (process.platform !== 'win32') {
|
|
1362
|
+
if ((stat.mode & 0o077) !== 0) fail();
|
|
1363
|
+
if (typeof process.getuid === 'function' && stat.uid !== process.getuid()) fail();
|
|
1364
|
+
}
|
|
1365
|
+
raw = fs.readFileSync(descriptor, 'utf8');
|
|
1366
|
+
try {
|
|
1367
|
+
fs.unlinkSync(handoffPath);
|
|
1368
|
+
consumed = true;
|
|
1369
|
+
} catch {
|
|
1370
|
+
try {
|
|
1371
|
+
fs.ftruncateSync(descriptor, 0);
|
|
1372
|
+
consumed = true;
|
|
1373
|
+
} catch {
|
|
1374
|
+
fail();
|
|
1375
|
+
}
|
|
1376
|
+
}
|
|
1377
|
+
} finally {
|
|
1378
|
+
fs.closeSync(descriptor);
|
|
1250
1379
|
}
|
|
1251
|
-
|
|
1252
|
-
|
|
1253
|
-
|
|
1254
|
-
|
|
1380
|
+
if (!consumed) fail();
|
|
1381
|
+
|
|
1382
|
+
let parsed;
|
|
1383
|
+
try {
|
|
1384
|
+
parsed = JSON.parse(raw);
|
|
1385
|
+
} catch {
|
|
1386
|
+
fail();
|
|
1387
|
+
}
|
|
1388
|
+
if (!parsed || typeof parsed !== 'object' || Array.isArray(parsed)) fail();
|
|
1389
|
+
const entries = Object.entries(parsed);
|
|
1390
|
+
if (entries.length !== 1 || entries[0]?.[0] !== 'Authorization') fail();
|
|
1391
|
+
const authorization = entries[0]?.[1];
|
|
1392
|
+
if (typeof authorization !== 'string' || !/^Bearer [A-Za-z0-9_-]{43}$/u.test(authorization)) fail();
|
|
1393
|
+
|
|
1394
|
+
const terminatorIndex = process.argv.indexOf('--', 2);
|
|
1395
|
+
const insertionIndex = terminatorIndex >= 0 ? terminatorIndex : process.argv.length;
|
|
1396
|
+
process.argv.splice(insertionIndex, 0, '--wsHeaders', JSON.stringify({ Authorization: authorization }));
|
|
1397
|
+
}
|
|
1398
|
+
`;
|
|
1255
1399
|
}
|
|
1256
1400
|
|
|
1257
|
-
// node_modules/.pnpm/mcporter@0.13.
|
|
1401
|
+
// node_modules/.pnpm/mcporter@0.13.7/node_modules/mcporter/dist/runtime/cached-auth.js
|
|
1258
1402
|
function hasAuthorizationHeader(headers) {
|
|
1259
1403
|
return Boolean(headers && Object.keys(headers).some((key) => key.toLowerCase() === "authorization"));
|
|
1260
1404
|
}
|
|
@@ -1317,392 +1461,7 @@ async function applyCachedAuthIfAvailable(definition, logger, allowCachedAuth) {
|
|
|
1317
1461
|
}
|
|
1318
1462
|
}
|
|
1319
1463
|
|
|
1320
|
-
// node_modules/.pnpm/mcporter@0.13.
|
|
1321
|
-
import { spawn } from "node:child_process";
|
|
1322
|
-
import { createHash, randomUUID } from "node:crypto";
|
|
1323
|
-
import http from "node:http";
|
|
1324
|
-
import { URL as URL2 } from "node:url";
|
|
1325
|
-
var CALLBACK_HOST = "127.0.0.1";
|
|
1326
|
-
var CALLBACK_PATH = "/callback";
|
|
1327
|
-
var INTERACTIVE_AUTHORIZATION_TTL_MS = 3e5;
|
|
1328
|
-
function createDeferred() {
|
|
1329
|
-
let resolve;
|
|
1330
|
-
let reject;
|
|
1331
|
-
const promise = new Promise((res, rej) => {
|
|
1332
|
-
resolve = res;
|
|
1333
|
-
reject = rej;
|
|
1334
|
-
});
|
|
1335
|
-
return { promise, resolve, reject };
|
|
1336
|
-
}
|
|
1337
|
-
function openExternal(url, platform = process.platform, launch = spawn) {
|
|
1338
|
-
const stdio = "ignore";
|
|
1339
|
-
try {
|
|
1340
|
-
if (platform === "darwin") {
|
|
1341
|
-
const child = launch("open", [url], { stdio, detached: true });
|
|
1342
|
-
child.unref();
|
|
1343
|
-
} else if (platform === "win32") {
|
|
1344
|
-
const child = launch("rundll32", ["url.dll,FileProtocolHandler", url], {
|
|
1345
|
-
stdio,
|
|
1346
|
-
detached: true,
|
|
1347
|
-
windowsHide: true
|
|
1348
|
-
});
|
|
1349
|
-
child.unref();
|
|
1350
|
-
} else {
|
|
1351
|
-
try {
|
|
1352
|
-
const child = launch("xdg-open", [url], { stdio, detached: true });
|
|
1353
|
-
child.on("error", () => {
|
|
1354
|
-
});
|
|
1355
|
-
child.unref();
|
|
1356
|
-
} catch {
|
|
1357
|
-
}
|
|
1358
|
-
}
|
|
1359
|
-
} catch {
|
|
1360
|
-
}
|
|
1361
|
-
}
|
|
1362
|
-
var PersistentOAuthClientProvider = class _PersistentOAuthClientProvider {
|
|
1363
|
-
definition;
|
|
1364
|
-
options;
|
|
1365
|
-
metadata;
|
|
1366
|
-
logger;
|
|
1367
|
-
persistence;
|
|
1368
|
-
redirectUrlValue;
|
|
1369
|
-
authorizationDeferred = null;
|
|
1370
|
-
authorizationRedirectStarted = false;
|
|
1371
|
-
// One interactive authorization transaction per provider: concurrent SDK auth() flows
|
|
1372
|
-
// (background GET reconnect + bridged POST both hitting 401) must not each open a
|
|
1373
|
-
// prompt, because only one persisted PKCE verifier can complete (issue #247).
|
|
1374
|
-
interactiveAuthorization = null;
|
|
1375
|
-
pendingVerifiersByChallenge = /* @__PURE__ */ new Map();
|
|
1376
|
-
server;
|
|
1377
|
-
constructor(definition, persistence, redirectUrl, logger, options = {}) {
|
|
1378
|
-
this.definition = definition;
|
|
1379
|
-
this.options = options;
|
|
1380
|
-
this.redirectUrlValue = redirectUrl;
|
|
1381
|
-
this.logger = logger;
|
|
1382
|
-
this.persistence = persistence;
|
|
1383
|
-
this.metadata = {
|
|
1384
|
-
client_name: definition.clientName ?? `mcporter (${definition.name})`,
|
|
1385
|
-
redirect_uris: [this.redirectUrlValue.toString()],
|
|
1386
|
-
grant_types: ["authorization_code", "refresh_token"],
|
|
1387
|
-
response_types: ["code"],
|
|
1388
|
-
token_endpoint_auth_method: "none",
|
|
1389
|
-
// Omit scope so the MCP SDK can derive it from the server's metadata
|
|
1390
|
-
// (resource metadata scopes_supported or auth server scopes_supported).
|
|
1391
|
-
// Hardcoding 'mcp:tools' breaks providers like Granola whose auth server
|
|
1392
|
-
// does not recognise that scope value.
|
|
1393
|
-
// If oauthScope is explicitly configured, prefer that exact value.
|
|
1394
|
-
...definition.oauthScope !== void 0 ? { scope: definition.oauthScope || void 0 } : {}
|
|
1395
|
-
};
|
|
1396
|
-
}
|
|
1397
|
-
static async create(definition, logger, options = {}) {
|
|
1398
|
-
validateClientMetadataUrl(definition.oauthClientMetadataUrl);
|
|
1399
|
-
const persistence = await buildOAuthPersistence(definition, logger);
|
|
1400
|
-
const server = http.createServer();
|
|
1401
|
-
const overrideRedirect = definition.oauthRedirectUrl ? new URL2(definition.oauthRedirectUrl) : null;
|
|
1402
|
-
const listenHost = overrideRedirect?.hostname ?? CALLBACK_HOST;
|
|
1403
|
-
const overridePort = overrideRedirect?.port ?? "";
|
|
1404
|
-
const usesDynamicPort = !overrideRedirect || overridePort === "" || overridePort === "0";
|
|
1405
|
-
const desiredPort = usesDynamicPort ? void 0 : Number.parseInt(overridePort, 10);
|
|
1406
|
-
const callbackPath = overrideRedirect?.pathname && overrideRedirect.pathname !== "/" ? overrideRedirect.pathname : CALLBACK_PATH;
|
|
1407
|
-
const port = await new Promise((resolve, reject) => {
|
|
1408
|
-
server.listen(desiredPort ?? 0, listenHost, () => {
|
|
1409
|
-
const address = server.address();
|
|
1410
|
-
if (typeof address === "object" && address && "port" in address) {
|
|
1411
|
-
resolve(address.port);
|
|
1412
|
-
} else {
|
|
1413
|
-
reject(new Error("Failed to determine callback port"));
|
|
1414
|
-
}
|
|
1415
|
-
});
|
|
1416
|
-
server.once("error", (error) => reject(error));
|
|
1417
|
-
});
|
|
1418
|
-
const redirectUrl = overrideRedirect ? new URL2(overrideRedirect.toString()) : new URL2(`http://${listenHost}:${port}${callbackPath}`);
|
|
1419
|
-
if (usesDynamicPort) {
|
|
1420
|
-
redirectUrl.port = String(port);
|
|
1421
|
-
}
|
|
1422
|
-
if (!overrideRedirect || overrideRedirect.pathname === "/" || overrideRedirect.pathname === "") {
|
|
1423
|
-
redirectUrl.pathname = callbackPath;
|
|
1424
|
-
}
|
|
1425
|
-
if (usesDynamicPort) {
|
|
1426
|
-
try {
|
|
1427
|
-
const cachedClient = await persistence.readClientInfo();
|
|
1428
|
-
const cachedRedirect = firstRedirectUri(cachedClient);
|
|
1429
|
-
if (cachedRedirect && cachedRedirect !== redirectUrl.toString()) {
|
|
1430
|
-
logger.info(`Redirect URI changed (${cachedRedirect} \u2192 ${redirectUrl.toString()}); clearing stale client registration.`);
|
|
1431
|
-
await persistence.clear("client");
|
|
1432
|
-
}
|
|
1433
|
-
} catch (error) {
|
|
1434
|
-
await new Promise((resolve) => {
|
|
1435
|
-
server.close(() => resolve());
|
|
1436
|
-
});
|
|
1437
|
-
throw error;
|
|
1438
|
-
}
|
|
1439
|
-
}
|
|
1440
|
-
const provider = new _PersistentOAuthClientProvider(definition, persistence, redirectUrl, logger, options);
|
|
1441
|
-
provider.attachServer(server);
|
|
1442
|
-
return {
|
|
1443
|
-
provider,
|
|
1444
|
-
close: async () => {
|
|
1445
|
-
await provider.close();
|
|
1446
|
-
}
|
|
1447
|
-
};
|
|
1448
|
-
}
|
|
1449
|
-
// attachServer listens for the OAuth redirect and resolves/rejects the deferred code promise.
|
|
1450
|
-
attachServer(server) {
|
|
1451
|
-
this.server = server;
|
|
1452
|
-
server.on("request", async (req, res) => {
|
|
1453
|
-
try {
|
|
1454
|
-
const url = req.url ?? "";
|
|
1455
|
-
const parsed = new URL2(url, this.redirectUrlValue);
|
|
1456
|
-
const expectedPath = this.redirectUrlValue.pathname || "/callback";
|
|
1457
|
-
if (parsed.pathname !== expectedPath) {
|
|
1458
|
-
res.statusCode = 404;
|
|
1459
|
-
res.end("Not found");
|
|
1460
|
-
return;
|
|
1461
|
-
}
|
|
1462
|
-
const code = parsed.searchParams.get("code");
|
|
1463
|
-
const error = parsed.searchParams.get("error");
|
|
1464
|
-
const receivedState = parsed.searchParams.get("state");
|
|
1465
|
-
const iss = parsed.searchParams.get("iss") ?? void 0;
|
|
1466
|
-
const expectedState = await this.persistence.readState();
|
|
1467
|
-
if (expectedState && receivedState !== expectedState) {
|
|
1468
|
-
res.statusCode = 400;
|
|
1469
|
-
res.setHeader("Content-Type", "text/html");
|
|
1470
|
-
res.end("<html><body><h1>Authorization failed</h1><p>Invalid OAuth state</p></body></html>");
|
|
1471
|
-
this.authorizationDeferred?.reject(new Error("Invalid OAuth state"));
|
|
1472
|
-
this.authorizationDeferred = null;
|
|
1473
|
-
this.clearInteractiveAuthorization();
|
|
1474
|
-
return;
|
|
1475
|
-
}
|
|
1476
|
-
if (code) {
|
|
1477
|
-
this.logger.info(`Received OAuth authorization code for ${this.definition.name}`);
|
|
1478
|
-
res.statusCode = 200;
|
|
1479
|
-
res.setHeader("Content-Type", "text/html");
|
|
1480
|
-
res.end("<html><body><h1>Authorization successful</h1><p>You can return to the CLI.</p></body></html>");
|
|
1481
|
-
this.authorizationDeferred?.resolve({ code, iss });
|
|
1482
|
-
this.authorizationDeferred = null;
|
|
1483
|
-
this.clearInteractiveAuthorization();
|
|
1484
|
-
} else if (error) {
|
|
1485
|
-
res.statusCode = 400;
|
|
1486
|
-
res.setHeader("Content-Type", "text/html");
|
|
1487
|
-
res.end("<html><body><h1>Authorization failed</h1><p>Return to the CLI for details.</p></body></html>");
|
|
1488
|
-
this.authorizationDeferred?.reject(new Error("OAuth authorization failed."));
|
|
1489
|
-
this.authorizationDeferred = null;
|
|
1490
|
-
this.clearInteractiveAuthorization();
|
|
1491
|
-
} else {
|
|
1492
|
-
res.statusCode = 400;
|
|
1493
|
-
res.end("Missing authorization code");
|
|
1494
|
-
this.authorizationDeferred?.reject(new Error("Missing authorization code"));
|
|
1495
|
-
this.authorizationDeferred = null;
|
|
1496
|
-
this.clearInteractiveAuthorization();
|
|
1497
|
-
}
|
|
1498
|
-
} catch (error) {
|
|
1499
|
-
this.authorizationDeferred?.reject(error);
|
|
1500
|
-
this.authorizationDeferred = null;
|
|
1501
|
-
this.clearInteractiveAuthorization();
|
|
1502
|
-
}
|
|
1503
|
-
});
|
|
1504
|
-
}
|
|
1505
|
-
get redirectUrl() {
|
|
1506
|
-
return this.redirectUrlValue;
|
|
1507
|
-
}
|
|
1508
|
-
get clientMetadata() {
|
|
1509
|
-
return this.metadata;
|
|
1510
|
-
}
|
|
1511
|
-
get clientMetadataUrl() {
|
|
1512
|
-
return this.definition.oauthClientMetadataUrl;
|
|
1513
|
-
}
|
|
1514
|
-
async state() {
|
|
1515
|
-
const existing = await this.persistence.readState();
|
|
1516
|
-
if (existing) {
|
|
1517
|
-
return existing;
|
|
1518
|
-
}
|
|
1519
|
-
const state = randomUUID();
|
|
1520
|
-
await this.persistence.saveState(state);
|
|
1521
|
-
return state;
|
|
1522
|
-
}
|
|
1523
|
-
async clientInformation(ctx) {
|
|
1524
|
-
const staticClient = buildStaticClientInformation(this.definition, { redirectUrl: this.redirectUrlValue });
|
|
1525
|
-
if (staticClient) {
|
|
1526
|
-
return { ...staticClient, ...ctx ? { issuer: ctx.issuer } : {} };
|
|
1527
|
-
}
|
|
1528
|
-
const stored = await this.persistence.readClientInfo();
|
|
1529
|
-
if (ctx && stored?.issuer && !issuersMatch(stored.issuer, ctx.issuer)) {
|
|
1530
|
-
await this.persistence.clear("client");
|
|
1531
|
-
this.logger.info(`Discarded OAuth client registration for ${this.definition.name} after issuer changed.`);
|
|
1532
|
-
return void 0;
|
|
1533
|
-
}
|
|
1534
|
-
return stored;
|
|
1535
|
-
}
|
|
1536
|
-
async saveClientInformation(clientInformation) {
|
|
1537
|
-
await this.persistence.saveClientInfo(clientInformation);
|
|
1538
|
-
}
|
|
1539
|
-
async tokens(ctx) {
|
|
1540
|
-
const stored = await this.persistence.readTokens();
|
|
1541
|
-
if (ctx && stored?.issuer && !issuersMatch(stored.issuer, ctx.issuer)) {
|
|
1542
|
-
await this.persistence.clear("tokens");
|
|
1543
|
-
this.logger.info(`Discarded OAuth tokens for ${this.definition.name} after issuer changed.`);
|
|
1544
|
-
return void 0;
|
|
1545
|
-
}
|
|
1546
|
-
return stored;
|
|
1547
|
-
}
|
|
1548
|
-
async saveTokens(tokens) {
|
|
1549
|
-
await this.persistence.saveTokens(tokens);
|
|
1550
|
-
this.logger.info(`Saved OAuth tokens for ${this.definition.name} (${this.persistence.describe()})`);
|
|
1551
|
-
}
|
|
1552
|
-
async redirectToAuthorization(authorizationUrl) {
|
|
1553
|
-
this.authorizationRedirectStarted = true;
|
|
1554
|
-
this.ensureAuthorizationDeferred();
|
|
1555
|
-
const challenge = authorizationUrl.searchParams.get("code_challenge");
|
|
1556
|
-
if (this.hasActiveInteractiveAuthorization()) {
|
|
1557
|
-
if (challenge) {
|
|
1558
|
-
this.pendingVerifiersByChallenge.delete(challenge);
|
|
1559
|
-
}
|
|
1560
|
-
this.logger.info(`Authorization already pending for ${this.definition.name}; suppressing duplicate prompt.`);
|
|
1561
|
-
return;
|
|
1562
|
-
}
|
|
1563
|
-
this.interactiveAuthorization = { challenge, claimedAt: Date.now() };
|
|
1564
|
-
const claimedVerifier = challenge ? this.pendingVerifiersByChallenge.get(challenge) : void 0;
|
|
1565
|
-
if (challenge) {
|
|
1566
|
-
this.pendingVerifiersByChallenge.delete(challenge);
|
|
1567
|
-
}
|
|
1568
|
-
if (claimedVerifier) {
|
|
1569
|
-
await this.persistence.saveCodeVerifier(claimedVerifier);
|
|
1570
|
-
}
|
|
1571
|
-
const request = {
|
|
1572
|
-
authorizationUrl: authorizationUrl.toString(),
|
|
1573
|
-
redirectUrl: this.redirectUrlValue.toString()
|
|
1574
|
-
};
|
|
1575
|
-
if (this.options.suppressBrowserLaunch) {
|
|
1576
|
-
await this.options.onAuthorizationUrl?.(request);
|
|
1577
|
-
return;
|
|
1578
|
-
}
|
|
1579
|
-
this.logger.info(`Authorization required for ${this.definition.name}. Opening browser...`);
|
|
1580
|
-
__oauthInternals.openExternal(request.authorizationUrl);
|
|
1581
|
-
this.logger.warn(`If the browser did not open, visit ${request.authorizationUrl} manually.`);
|
|
1582
|
-
}
|
|
1583
|
-
hasAuthorizationRedirectStarted() {
|
|
1584
|
-
return this.authorizationRedirectStarted;
|
|
1585
|
-
}
|
|
1586
|
-
async saveCodeVerifier(codeVerifier) {
|
|
1587
|
-
this.pendingVerifiersByChallenge.set(challengeForVerifier(codeVerifier), codeVerifier);
|
|
1588
|
-
if (this.hasActiveInteractiveAuthorization()) {
|
|
1589
|
-
return;
|
|
1590
|
-
}
|
|
1591
|
-
await this.persistence.saveCodeVerifier(codeVerifier);
|
|
1592
|
-
}
|
|
1593
|
-
async codeVerifier() {
|
|
1594
|
-
const value = await this.persistence.readCodeVerifier();
|
|
1595
|
-
if (!value) {
|
|
1596
|
-
throw new Error(`Missing PKCE code verifier for ${this.definition.name}`);
|
|
1597
|
-
}
|
|
1598
|
-
return value.trim();
|
|
1599
|
-
}
|
|
1600
|
-
// invalidateCredentials removes cached files to force the next OAuth flow.
|
|
1601
|
-
async invalidateCredentials(scope) {
|
|
1602
|
-
if (scope === "all" || scope === "verifier") {
|
|
1603
|
-
this.clearInteractiveAuthorization();
|
|
1604
|
-
}
|
|
1605
|
-
await this.persistence.clear(scope);
|
|
1606
|
-
}
|
|
1607
|
-
async saveDiscoveryState(state) {
|
|
1608
|
-
await this.persistence.saveDiscoveryState(state);
|
|
1609
|
-
}
|
|
1610
|
-
async discoveryState() {
|
|
1611
|
-
return this.persistence.readDiscoveryState();
|
|
1612
|
-
}
|
|
1613
|
-
async saveAuthorizationServerUrl(url) {
|
|
1614
|
-
await this.persistence.saveAuthorizationServerUrl(url);
|
|
1615
|
-
}
|
|
1616
|
-
async authorizationServerUrl() {
|
|
1617
|
-
return this.persistence.readAuthorizationServerUrl();
|
|
1618
|
-
}
|
|
1619
|
-
async saveResourceUrl(url) {
|
|
1620
|
-
await this.persistence.saveResourceUrl(url);
|
|
1621
|
-
}
|
|
1622
|
-
async resourceUrl() {
|
|
1623
|
-
return this.persistence.readResourceUrl();
|
|
1624
|
-
}
|
|
1625
|
-
// waitForAuthorizationCode resolves once the local callback server captures a redirect.
|
|
1626
|
-
// The same deferred is shared with redirectToAuthorization so callback resolution is stable.
|
|
1627
|
-
async waitForAuthorizationCode() {
|
|
1628
|
-
return (await this.waitForAuthorizationResponse()).code;
|
|
1629
|
-
}
|
|
1630
|
-
async waitForAuthorizationResponse() {
|
|
1631
|
-
return this.ensureAuthorizationDeferred().promise;
|
|
1632
|
-
}
|
|
1633
|
-
// close stops the temporary callback server created for the OAuth session.
|
|
1634
|
-
async close() {
|
|
1635
|
-
if (this.authorizationDeferred) {
|
|
1636
|
-
this.authorizationDeferred.reject(new Error("OAuth session closed before receiving authorization code."));
|
|
1637
|
-
this.authorizationDeferred = null;
|
|
1638
|
-
this.clearInteractiveAuthorization();
|
|
1639
|
-
}
|
|
1640
|
-
if (!this.server) {
|
|
1641
|
-
return;
|
|
1642
|
-
}
|
|
1643
|
-
this.server.closeAllConnections?.();
|
|
1644
|
-
const server = this.server;
|
|
1645
|
-
this.server = void 0;
|
|
1646
|
-
await new Promise((resolve) => {
|
|
1647
|
-
server.close(() => resolve());
|
|
1648
|
-
});
|
|
1649
|
-
}
|
|
1650
|
-
ensureAuthorizationDeferred() {
|
|
1651
|
-
if (!this.authorizationDeferred) {
|
|
1652
|
-
this.authorizationDeferred = createDeferred();
|
|
1653
|
-
}
|
|
1654
|
-
return this.authorizationDeferred;
|
|
1655
|
-
}
|
|
1656
|
-
hasActiveInteractiveAuthorization() {
|
|
1657
|
-
if (!this.interactiveAuthorization) {
|
|
1658
|
-
return false;
|
|
1659
|
-
}
|
|
1660
|
-
if (Date.now() - this.interactiveAuthorization.claimedAt > INTERACTIVE_AUTHORIZATION_TTL_MS) {
|
|
1661
|
-
this.interactiveAuthorization = null;
|
|
1662
|
-
return false;
|
|
1663
|
-
}
|
|
1664
|
-
return true;
|
|
1665
|
-
}
|
|
1666
|
-
clearInteractiveAuthorization() {
|
|
1667
|
-
this.interactiveAuthorization = null;
|
|
1668
|
-
this.pendingVerifiersByChallenge.clear();
|
|
1669
|
-
}
|
|
1670
|
-
};
|
|
1671
|
-
async function createOAuthSession(definition, logger, options = {}) {
|
|
1672
|
-
const { provider, close } = await PersistentOAuthClientProvider.create(definition, logger, options);
|
|
1673
|
-
const waitForAuthorizationCode = () => provider.waitForAuthorizationCode();
|
|
1674
|
-
const waitForAuthorizationResponse = () => provider.waitForAuthorizationResponse();
|
|
1675
|
-
const hasAuthorizationRedirectStarted = () => provider.hasAuthorizationRedirectStarted();
|
|
1676
|
-
return {
|
|
1677
|
-
provider,
|
|
1678
|
-
waitForAuthorizationCode,
|
|
1679
|
-
waitForAuthorizationResponse,
|
|
1680
|
-
hasAuthorizationRedirectStarted,
|
|
1681
|
-
close
|
|
1682
|
-
};
|
|
1683
|
-
}
|
|
1684
|
-
function challengeForVerifier(verifier) {
|
|
1685
|
-
return createHash("sha256").update(verifier).digest("base64url");
|
|
1686
|
-
}
|
|
1687
|
-
function firstRedirectUri(client) {
|
|
1688
|
-
if (!client || typeof client !== "object") {
|
|
1689
|
-
return void 0;
|
|
1690
|
-
}
|
|
1691
|
-
const redirectUris = client.redirect_uris;
|
|
1692
|
-
if (!Array.isArray(redirectUris)) {
|
|
1693
|
-
return void 0;
|
|
1694
|
-
}
|
|
1695
|
-
const [first] = redirectUris;
|
|
1696
|
-
return typeof first === "string" ? first : void 0;
|
|
1697
|
-
}
|
|
1698
|
-
function issuersMatch(first, second) {
|
|
1699
|
-
return first === second || first.endsWith("/") && first.slice(0, -1) === second || second.endsWith("/") && second.slice(0, -1) === first;
|
|
1700
|
-
}
|
|
1701
|
-
var __oauthInternals = {
|
|
1702
|
-
openExternal
|
|
1703
|
-
};
|
|
1704
|
-
|
|
1705
|
-
// node_modules/.pnpm/mcporter@0.13.0/node_modules/mcporter/dist/runtime-header-utils.js
|
|
1464
|
+
// node_modules/.pnpm/mcporter@0.13.7/node_modules/mcporter/dist/runtime-header-utils.js
|
|
1706
1465
|
function materializeHeaders(headers, serverName) {
|
|
1707
1466
|
if (!headers) {
|
|
1708
1467
|
return void 0;
|
|
@@ -1719,8 +1478,8 @@ function materializeHeaders(headers, serverName) {
|
|
|
1719
1478
|
return resolved;
|
|
1720
1479
|
}
|
|
1721
1480
|
|
|
1722
|
-
// node_modules/.pnpm/mcporter@0.13.
|
|
1723
|
-
import
|
|
1481
|
+
// node_modules/.pnpm/mcporter@0.13.7/node_modules/mcporter/dist/runtime/node-http-fetch.js
|
|
1482
|
+
import http from "node:http";
|
|
1724
1483
|
import https from "node:https";
|
|
1725
1484
|
import { Buffer as Buffer2 } from "node:buffer";
|
|
1726
1485
|
import { Readable } from "node:stream";
|
|
@@ -1750,12 +1509,15 @@ async function nodeHttp1FetchWithRedirects(input, init, redirectCount) {
|
|
|
1750
1509
|
throw new DOMException("The operation was aborted.", "AbortError");
|
|
1751
1510
|
}
|
|
1752
1511
|
const headers = normalizeRequestHeaders(init.headers);
|
|
1512
|
+
if (!hasHeader(headers, "user-agent")) {
|
|
1513
|
+
headers["user-agent"] = `mcporter/${MCPORTER_VERSION}`;
|
|
1514
|
+
}
|
|
1753
1515
|
const body = await materializeRequestBody(init.body);
|
|
1754
1516
|
if (body !== void 0 && !hasHeader(headers, "content-length") && !hasHeader(headers, "transfer-encoding")) {
|
|
1755
1517
|
headers["content-length"] = String(Buffer2.byteLength(body));
|
|
1756
1518
|
}
|
|
1757
1519
|
return new Promise((resolve, reject) => {
|
|
1758
|
-
const client = url.protocol === "https:" ? https :
|
|
1520
|
+
const client = url.protocol === "https:" ? https : http;
|
|
1759
1521
|
const request = client.request(url, {
|
|
1760
1522
|
method: init.method ?? "GET",
|
|
1761
1523
|
headers
|
|
@@ -1875,7 +1637,7 @@ async function materializeRequestBody(body) {
|
|
|
1875
1637
|
throw new TypeError("node-http1 fetch does not support streaming request bodies.");
|
|
1876
1638
|
}
|
|
1877
1639
|
|
|
1878
|
-
// node_modules/.pnpm/mcporter@0.13.
|
|
1640
|
+
// node_modules/.pnpm/mcporter@0.13.7/node_modules/mcporter/dist/runtime/http-transport.js
|
|
1879
1641
|
function extractTransportStatusCode(error) {
|
|
1880
1642
|
if (!error || typeof error !== "object")
|
|
1881
1643
|
return void 0;
|
|
@@ -1910,6 +1672,7 @@ function removeAuthorizationHeader(headers) {
|
|
|
1910
1672
|
return Object.keys(headers).length > 0 ? headers : void 0;
|
|
1911
1673
|
}
|
|
1912
1674
|
var NODE_HTTP1_FETCH_HOSTS = /* @__PURE__ */ new Set(["api.sunsama.com"]);
|
|
1675
|
+
var STANDALONE_SSE_START_GRACE_MS = 250;
|
|
1913
1676
|
function resolveHttpFetchOverride(definition) {
|
|
1914
1677
|
if (definition.command.kind !== "http" || definition.httpFetch === "default")
|
|
1915
1678
|
return void 0;
|
|
@@ -1954,6 +1717,26 @@ function trackStandaloneSseFetch(fetchOverride) {
|
|
|
1954
1717
|
}
|
|
1955
1718
|
};
|
|
1956
1719
|
}
|
|
1720
|
+
function waitForStandaloneSseStart(started, signal) {
|
|
1721
|
+
if (signal?.aborted)
|
|
1722
|
+
return Promise.resolve();
|
|
1723
|
+
return new Promise((resolve) => {
|
|
1724
|
+
let settled = false;
|
|
1725
|
+
const finish = () => {
|
|
1726
|
+
if (settled)
|
|
1727
|
+
return;
|
|
1728
|
+
settled = true;
|
|
1729
|
+
clearTimeout(timer);
|
|
1730
|
+
signal?.removeEventListener("abort", finish);
|
|
1731
|
+
resolve();
|
|
1732
|
+
};
|
|
1733
|
+
const timer = setTimeout(finish, STANDALONE_SSE_START_GRACE_MS);
|
|
1734
|
+
signal?.addEventListener("abort", finish, { once: true });
|
|
1735
|
+
if (signal?.aborted)
|
|
1736
|
+
finish();
|
|
1737
|
+
void started.then(finish);
|
|
1738
|
+
});
|
|
1739
|
+
}
|
|
1957
1740
|
async function closeOAuthSession(oauthSession) {
|
|
1958
1741
|
await oauthSession?.close().catch(() => {
|
|
1959
1742
|
});
|
|
@@ -1961,7 +1744,11 @@ async function closeOAuthSession(oauthSession) {
|
|
|
1961
1744
|
function shouldAbortSseFallback(error) {
|
|
1962
1745
|
if (isPostAuthConnectError(error))
|
|
1963
1746
|
return !isLegacySseTransportMismatch(error);
|
|
1964
|
-
|
|
1747
|
+
if (isOAuthFlowError(error) || error instanceof OAuthTimeoutError)
|
|
1748
|
+
return true;
|
|
1749
|
+
if (isUnauthorizedError(error))
|
|
1750
|
+
return false;
|
|
1751
|
+
return !isLegacySseTransportMismatch(error);
|
|
1965
1752
|
}
|
|
1966
1753
|
function isEraNegotiationFailure(error) {
|
|
1967
1754
|
return !!error && typeof error === "object" && "code" in error && error.code === SdkErrorCode.EraNegotiationFailed;
|
|
@@ -2042,18 +1829,20 @@ async function connectPrimaryHttpTransport(client, definition, command, transpor
|
|
|
2042
1829
|
recreateTransport: async () => createStreamableTransport()
|
|
2043
1830
|
});
|
|
2044
1831
|
if (typeof client.getProtocolEra === "function" && client.getProtocolEra() === "legacy") {
|
|
2045
|
-
await transportOptions.standaloneSseStarted;
|
|
1832
|
+
await waitForStandaloneSseStart(transportOptions.standaloneSseStarted, options.signal);
|
|
2046
1833
|
}
|
|
2047
1834
|
return { client, transport, definition, oauthSession };
|
|
2048
1835
|
}
|
|
2049
1836
|
async function connectSseFallbackTransport(client, definition, command, transportOptions, oauthSession, logger, options, wrapRecordTransport2, clientFactory) {
|
|
1837
|
+
const createSseTransport = () => wrapRecordTransport2(new SSEClientTransport(command.url, transportOptions), definition, options);
|
|
2050
1838
|
try {
|
|
2051
|
-
const transport = await connectHttpTransport(client,
|
|
1839
|
+
const transport = await connectHttpTransport(client, createSseTransport(), oauthSession, logger, {
|
|
2052
1840
|
serverName: definition.name,
|
|
2053
1841
|
serverUrl: command.url,
|
|
2054
1842
|
maxAttempts: options.maxOAuthAttempts,
|
|
2055
1843
|
oauthTimeoutMs: options.oauthTimeoutMs,
|
|
2056
|
-
signal: options.signal
|
|
1844
|
+
signal: options.signal,
|
|
1845
|
+
recreateTransport: async () => createSseTransport()
|
|
2057
1846
|
});
|
|
2058
1847
|
return { client, transport, definition, oauthSession };
|
|
2059
1848
|
} catch (sseError) {
|
|
@@ -2066,8 +1855,7 @@ async function connectSseFallbackTransport(client, definition, command, transpor
|
|
|
2066
1855
|
options.onDefinitionPromoted?.(promoted);
|
|
2067
1856
|
return createHttpClientContext(promoted, logger, options, wrapRecordTransport2, clientFactory);
|
|
2068
1857
|
}
|
|
2069
|
-
|
|
2070
|
-
throw sseError;
|
|
1858
|
+
throw sseError;
|
|
2071
1859
|
}
|
|
2072
1860
|
throw sseError;
|
|
2073
1861
|
}
|
|
@@ -2279,8 +2067,9 @@ var StdioClientTransport = class {
|
|
|
2279
2067
|
}
|
|
2280
2068
|
};
|
|
2281
2069
|
|
|
2282
|
-
// node_modules/.pnpm/mcporter@0.13.
|
|
2070
|
+
// node_modules/.pnpm/mcporter@0.13.7/node_modules/mcporter/dist/runtime/stdio-transport.js
|
|
2283
2071
|
var McporterStdioTransport = class extends StdioClientTransport {
|
|
2072
|
+
parameters;
|
|
2284
2073
|
meta;
|
|
2285
2074
|
closing = false;
|
|
2286
2075
|
closeDelegate;
|
|
@@ -2288,6 +2077,7 @@ var McporterStdioTransport = class extends StdioClientTransport {
|
|
|
2288
2077
|
closeInterceptor = () => {
|
|
2289
2078
|
this.meta.code = this.closing ? 0 : 1;
|
|
2290
2079
|
flushStdioLogs(this.meta);
|
|
2080
|
+
void this.cleanup();
|
|
2291
2081
|
this.closeDelegate?.();
|
|
2292
2082
|
};
|
|
2293
2083
|
messageInterceptor = (message) => {
|
|
@@ -2295,8 +2085,10 @@ var McporterStdioTransport = class extends StdioClientTransport {
|
|
|
2295
2085
|
this.meta.stdoutChunks?.push(JSON.stringify(message));
|
|
2296
2086
|
this.messageDelegate?.(message);
|
|
2297
2087
|
};
|
|
2088
|
+
cleanupPromise;
|
|
2298
2089
|
constructor(parameters) {
|
|
2299
2090
|
super({ ...parameters, stderr: "pipe" });
|
|
2091
|
+
this.parameters = parameters;
|
|
2300
2092
|
this.meta = {
|
|
2301
2093
|
stderrChunks: [],
|
|
2302
2094
|
stdoutChunks: STDIO_TRACE_ENABLED ? [] : void 0,
|
|
@@ -2339,8 +2131,14 @@ var McporterStdioTransport = class extends StdioClientTransport {
|
|
|
2339
2131
|
} finally {
|
|
2340
2132
|
this.meta.code ??= 0;
|
|
2341
2133
|
flushStdioLogs(this.meta);
|
|
2134
|
+
await this.cleanup();
|
|
2342
2135
|
}
|
|
2343
2136
|
}
|
|
2137
|
+
cleanup() {
|
|
2138
|
+
this.cleanupPromise ??= Promise.resolve(this.parameters.cleanup?.()).catch(() => {
|
|
2139
|
+
});
|
|
2140
|
+
return this.cleanupPromise;
|
|
2141
|
+
}
|
|
2344
2142
|
installInterceptors() {
|
|
2345
2143
|
if (this.onclose !== this.closeInterceptor) {
|
|
2346
2144
|
this.closeDelegate = this.onclose;
|
|
@@ -2353,7 +2151,7 @@ var McporterStdioTransport = class extends StdioClientTransport {
|
|
|
2353
2151
|
}
|
|
2354
2152
|
};
|
|
2355
2153
|
|
|
2356
|
-
// node_modules/.pnpm/mcporter@0.13.
|
|
2154
|
+
// node_modules/.pnpm/mcporter@0.13.7/node_modules/mcporter/dist/runtime/transport.js
|
|
2357
2155
|
function shouldUseModeForServer(definition, serverFilter) {
|
|
2358
2156
|
return !serverFilter || serverFilter === definition.name;
|
|
2359
2157
|
}
|
|
@@ -2414,33 +2212,85 @@ async function createReplayClientContext(definition, replayPath, clientInfo, opt
|
|
|
2414
2212
|
return { client, transport, definition, oauthSession: void 0 };
|
|
2415
2213
|
}
|
|
2416
2214
|
async function createStdioClientContext(client, definition, logger, options) {
|
|
2417
|
-
const
|
|
2418
|
-
const mergedEnv = resolvedEnvOverrides && Object.keys(resolvedEnvOverrides).length > 0 ? { ...process.env, ...resolvedEnvOverrides } : { ...process.env };
|
|
2215
|
+
const mergedEnv = resolveChromeDevtoolsRelayEnvironment(definition.env);
|
|
2419
2216
|
const command = resolveCommandArgument(definition.command.command);
|
|
2420
2217
|
const resolvedArgs = resolveCommandArguments(definition.command.args);
|
|
2421
|
-
const
|
|
2422
|
-
|
|
2423
|
-
|
|
2424
|
-
|
|
2425
|
-
|
|
2426
|
-
|
|
2427
|
-
|
|
2428
|
-
|
|
2429
|
-
|
|
2430
|
-
|
|
2431
|
-
|
|
2432
|
-
|
|
2433
|
-
|
|
2434
|
-
|
|
2435
|
-
}
|
|
2436
|
-
|
|
2218
|
+
const publishRelayDecision = (decision) => {
|
|
2219
|
+
if (decision.reason === "not-eligible")
|
|
2220
|
+
return;
|
|
2221
|
+
recordChromeDevtoolsRelayDecision(definition.name, decision);
|
|
2222
|
+
logger.info(`Chrome DevTools relay decision ${formatChromeDevtoolsRelayDecision(decision)}`);
|
|
2223
|
+
};
|
|
2224
|
+
let relayDecision;
|
|
2225
|
+
let relay;
|
|
2226
|
+
try {
|
|
2227
|
+
relay = await rewriteChromeDevtoolsArgsForRelay(command, resolvedArgs, mergedEnv, { onDecision: (decision) => relayDecision = decision }, definition.chromeDevtoolsRelay);
|
|
2228
|
+
} catch (error) {
|
|
2229
|
+
if (relayDecision)
|
|
2230
|
+
publishRelayDecision(relayDecision);
|
|
2231
|
+
throw error;
|
|
2232
|
+
}
|
|
2233
|
+
let commandArgs = [...relay.args];
|
|
2234
|
+
let activeProxy = relay.proxy;
|
|
2235
|
+
let handoff;
|
|
2236
|
+
let rawTransport;
|
|
2237
|
+
try {
|
|
2238
|
+
if (activeProxy) {
|
|
2239
|
+
try {
|
|
2240
|
+
handoff = createChromeDevtoolsRelayHandoff(mergedEnv, activeProxy.consumeClientAuthorization());
|
|
2241
|
+
} catch {
|
|
2242
|
+
await activeProxy.close().catch(() => {
|
|
2243
|
+
});
|
|
2244
|
+
activeProxy = void 0;
|
|
2245
|
+
relayDecision = {
|
|
2246
|
+
...relay.decision,
|
|
2247
|
+
route: relay.decision.policy === "require" ? "unavailable" : "legacy",
|
|
2248
|
+
reason: "handoff-error"
|
|
2249
|
+
};
|
|
2250
|
+
if (relay.decision.policy === "require") {
|
|
2251
|
+
publishRelayDecision(relayDecision);
|
|
2252
|
+
throw new ChromeDevtoolsRelayRequiredError(relayDecision);
|
|
2253
|
+
}
|
|
2254
|
+
commandArgs = [...resolvedArgs];
|
|
2255
|
+
}
|
|
2256
|
+
}
|
|
2257
|
+
const transportEnv = handoff?.env ?? mergedEnv;
|
|
2258
|
+
const compat = applyChromeDevtoolsCompat(transportEnv, command, commandArgs);
|
|
2259
|
+
if (compat.applied) {
|
|
2260
|
+
logger.info(`Injecting chrome-devtools-mcp --autoConnect compatibility patch from ${compat.patchPath}.`);
|
|
2261
|
+
}
|
|
2262
|
+
if (relayDecision)
|
|
2263
|
+
publishRelayDecision(relayDecision);
|
|
2264
|
+
rawTransport = new McporterStdioTransport({
|
|
2265
|
+
command,
|
|
2266
|
+
args: commandArgs,
|
|
2267
|
+
cwd: definition.command.cwd,
|
|
2268
|
+
env: compat.env,
|
|
2269
|
+
cleanup: activeProxy ? async () => {
|
|
2270
|
+
await handoff?.close();
|
|
2271
|
+
await activeProxy?.close();
|
|
2272
|
+
} : void 0
|
|
2273
|
+
});
|
|
2274
|
+
} catch (error) {
|
|
2275
|
+
await handoff?.close().catch(() => {
|
|
2276
|
+
});
|
|
2277
|
+
await activeProxy?.close().catch(() => {
|
|
2278
|
+
});
|
|
2279
|
+
throw error;
|
|
2280
|
+
}
|
|
2281
|
+
let transport;
|
|
2282
|
+
try {
|
|
2283
|
+
transport = wrapRecordTransport(rawTransport, definition, options);
|
|
2284
|
+
} catch (error) {
|
|
2285
|
+
await closeTransportAndWait(logger, rawTransport).catch(() => {
|
|
2286
|
+
});
|
|
2287
|
+
throw error;
|
|
2288
|
+
}
|
|
2437
2289
|
try {
|
|
2438
2290
|
await client.connect(transport, { signal: options.signal });
|
|
2439
2291
|
} catch (error) {
|
|
2440
|
-
|
|
2441
|
-
|
|
2442
|
-
});
|
|
2443
|
-
}
|
|
2292
|
+
await closeTransportAndWait(logger, transport).catch(() => {
|
|
2293
|
+
});
|
|
2444
2294
|
throw error;
|
|
2445
2295
|
}
|
|
2446
2296
|
return { client, transport, definition, oauthSession: void 0 };
|
|
@@ -2477,7 +2327,7 @@ async function createClientContext(definition, logger, clientInfo, options = {})
|
|
|
2477
2327
|
});
|
|
2478
2328
|
}
|
|
2479
2329
|
|
|
2480
|
-
// node_modules/.pnpm/mcporter@0.13.
|
|
2330
|
+
// node_modules/.pnpm/mcporter@0.13.7/node_modules/mcporter/dist/runtime/connection-cache.js
|
|
2481
2331
|
var RuntimeConnectionCache = class {
|
|
2482
2332
|
definitions;
|
|
2483
2333
|
options;
|
|
@@ -3030,7 +2880,7 @@ function connectionInfoFromClient(client) {
|
|
|
3030
2880
|
};
|
|
3031
2881
|
}
|
|
3032
2882
|
|
|
3033
|
-
// node_modules/.pnpm/mcporter@0.13.
|
|
2883
|
+
// node_modules/.pnpm/mcporter@0.13.7/node_modules/mcporter/dist/tool-filters.js
|
|
3034
2884
|
function validateToolFilters(name, filter) {
|
|
3035
2885
|
if (filter.allowedTools !== void 0 && filter.blockedTools !== void 0) {
|
|
3036
2886
|
throw new Error(`Server '${name}' cannot specify both allowedTools and blockedTools.`);
|
|
@@ -3052,7 +2902,7 @@ function filterTools(tools, filter) {
|
|
|
3052
2902
|
return tools.filter((tool) => isToolAllowed(tool.name, filter));
|
|
3053
2903
|
}
|
|
3054
2904
|
|
|
3055
|
-
// node_modules/.pnpm/mcporter@0.13.
|
|
2905
|
+
// node_modules/.pnpm/mcporter@0.13.7/node_modules/mcporter/dist/runtime.js
|
|
3056
2906
|
var PACKAGE_NAME = "mcporter";
|
|
3057
2907
|
var OAUTH_CODE_TIMEOUT_MS = resolveOAuthTimeoutFromEnv();
|
|
3058
2908
|
var MAX_RESOURCE_LIST_PAGES = 100;
|