@introspection-ai/recipes 0.18.0 → 0.19.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.
Files changed (146) hide show
  1. package/dist/inspect.d.ts +1 -0
  2. package/dist/inspect.d.ts.map +1 -1
  3. package/dist/inspect.js +3 -0
  4. package/dist/inspect.js.map +1 -1
  5. package/dist/mcp-chunks/{auth-command-ZLGYIEUY.js → auth-command-3K7V3VCW.js} +31 -35
  6. package/dist/mcp-chunks/call-arguments-TX3F2TEE.js +15 -0
  7. package/dist/mcp-chunks/{call-command-LKTKSYTH.js → call-command-OFPHPFM5.js} +36 -34
  8. package/dist/mcp-chunks/chunk-2FSDGCHW.js +3299 -0
  9. package/dist/mcp-chunks/{chunk-BV56DXPW.js → chunk-2JHHONW4.js} +1 -1
  10. package/dist/mcp-chunks/chunk-2MEHGB7D.js +63 -0
  11. package/dist/mcp-chunks/chunk-3IZQW4H4.js +929 -0
  12. package/dist/mcp-chunks/{chunk-MZ2NARG7.js → chunk-54EWGONA.js} +5 -5
  13. package/dist/mcp-chunks/{chunk-LQQEYD76.js → chunk-55JIHDU3.js} +1 -1
  14. package/dist/mcp-chunks/chunk-64EP2BVO.js +39 -0
  15. package/dist/mcp-chunks/{chunk-LS7PMWSR.js → chunk-6D6KPSXN.js} +1 -1
  16. package/dist/mcp-chunks/{chunk-2XL7MG7R.js → chunk-7A63PAGP.js} +15 -9
  17. package/dist/mcp-chunks/chunk-7DH57OKF.js +28 -0
  18. package/dist/mcp-chunks/{chunk-BTLAWHTA.js → chunk-7RDLPFIO.js} +2 -2
  19. package/dist/mcp-chunks/chunk-C2PQFLWS.js +422 -0
  20. package/dist/mcp-chunks/chunk-CA5WFJZA.js +197 -0
  21. package/dist/mcp-chunks/{chunk-LNH5LAJD.js → chunk-CNDY7WB4.js} +2 -2
  22. package/dist/mcp-chunks/{chunk-UKYNQGNE.js → chunk-DEUU7WSN.js} +34 -8
  23. package/dist/mcp-chunks/{chunk-LKIBAYKU.js → chunk-DXPHJFSA.js} +25 -35
  24. package/dist/mcp-chunks/{chunk-J6LYIZXN.js → chunk-E6RVTWJY.js} +1 -1
  25. package/dist/mcp-chunks/{chunk-7FHEBT5G.js → chunk-E6T37ED6.js} +18 -13
  26. package/dist/mcp-chunks/chunk-ETWN4IIA.js +57 -0
  27. package/dist/mcp-chunks/{chunk-YVZKMV5H.js → chunk-F3LL4EBL.js} +1 -1
  28. package/dist/mcp-chunks/chunk-FWP4RACK.js +42 -0
  29. package/dist/mcp-chunks/{chunk-6W5QFASN.js → chunk-GFYTST6N.js} +1 -1
  30. package/dist/mcp-chunks/{chunk-TEUKFFQL.js → chunk-GIF7LOYU.js} +2 -2
  31. package/dist/mcp-chunks/{chunk-QXJUA3ND.js → chunk-GSZOK5TS.js} +828 -7
  32. package/dist/mcp-chunks/chunk-H7F5RZXS.js +26 -0
  33. package/dist/mcp-chunks/{chunk-ECIVB7P4.js → chunk-HAO6PL7Z.js} +2 -37
  34. package/dist/mcp-chunks/{chunk-WQJZMCJN.js → chunk-HTZ2URXW.js} +5 -3
  35. package/dist/mcp-chunks/{chunk-BWHIA4PC.js → chunk-JAKI24KR.js} +1 -1
  36. package/dist/mcp-chunks/{chunk-PWYFKGKG.js → chunk-KSGYBW3F.js} +180 -89
  37. package/dist/mcp-chunks/{chunk-SJCCBNZ4.js → chunk-KSMY7PXI.js} +1 -1
  38. package/dist/mcp-chunks/{chunk-2U4BSDC4.js → chunk-L4VKBFYI.js} +48 -29
  39. package/dist/mcp-chunks/{chunk-LEZSACDE.js → chunk-LICH4Q7A.js} +4 -4
  40. package/dist/mcp-chunks/{chunk-PIIYJR44.js → chunk-LNSUME65.js} +29 -33
  41. package/dist/mcp-chunks/{chunk-D3MRAZ6H.js → chunk-LWVFSQYX.js} +13974 -15562
  42. package/dist/mcp-chunks/{chunk-7KA2VJVZ.js → chunk-NCXEJ35U.js} +10 -5
  43. package/dist/mcp-chunks/{chunk-5QOSCSQB.js → chunk-NZOIX6XW.js} +2 -2
  44. package/dist/mcp-chunks/{chunk-XANPGTLI.js → chunk-P3RN22HQ.js} +11 -4
  45. package/dist/mcp-chunks/{chunk-IABRYROW.js → chunk-PKOJCYNA.js} +3 -3
  46. package/dist/mcp-chunks/{chunk-BNV3TPE4.js → chunk-QJACOI2W.js} +5 -13
  47. package/dist/mcp-chunks/{chunk-UNKB4SBV.js → chunk-RBVYCKCD.js} +2 -2
  48. package/dist/mcp-chunks/{chunk-DHBE7UBH.js → chunk-SB2UUURE.js} +12 -42
  49. package/dist/mcp-chunks/{chunk-4SQKWYFF.js → chunk-SFREPU3D.js} +1 -1
  50. package/dist/mcp-chunks/{chunk-BZIQOWE6.js → chunk-SRZZQ6TL.js} +35 -36
  51. package/dist/mcp-chunks/{chunk-M3TPODXI.js → chunk-UENXT3NE.js} +1 -1
  52. package/dist/mcp-chunks/chunk-UHOKCTZT.js +37 -0
  53. package/dist/mcp-chunks/{chunk-E22DYOW5.js → chunk-WWO5WGH5.js} +5 -5
  54. package/dist/mcp-chunks/{chunk-6XCZGU3G.js → chunk-WXBPMFSN.js} +149 -192
  55. package/dist/mcp-chunks/{chunk-XQK2JSW4.js → chunk-XRGLP3Z2.js} +14 -2
  56. package/dist/mcp-chunks/{chunk-L7NTQVYN.js → chunk-XTL4MHFH.js} +28 -10
  57. package/dist/mcp-chunks/{chunk-N46NEFAF.js → chunk-XUF6KARU.js} +1 -1
  58. package/dist/mcp-chunks/{chunk-WD6BOD24.js → chunk-YCYSQA5V.js} +23 -4
  59. package/dist/mcp-chunks/chunk-YPJ5EHXR.js +17394 -0
  60. package/dist/mcp-chunks/{chunk-NRAJX5E4.js → chunk-YSPT6F7K.js} +3 -3
  61. package/dist/mcp-chunks/{chunk-7UDVSOOF.js → chunk-YTKRAHO6.js} +54 -46
  62. package/dist/mcp-chunks/chunk-ZBFZ5UFE.js +67 -0
  63. package/dist/mcp-chunks/{cli-UV4QJZZM.js → cli-E4P6SZLQ.js} +89 -76
  64. package/dist/mcp-chunks/client-2EJC4PLL.js +18 -0
  65. package/dist/mcp-chunks/{config-command-NLAGKID5.js → config-command-MWF3RHPQ.js} +38 -59
  66. package/dist/mcp-chunks/daemon-command-6CJ26MKI.js +33 -0
  67. package/dist/mcp-chunks/{dist-LK3SHAMX.js → dist-ZIPUENTM.js} +527 -469
  68. package/dist/mcp-chunks/{emit-ts-command-VBXVXO6V.js → emit-ts-command-GOVJJ64A.js} +16 -13
  69. package/dist/mcp-chunks/{generate-cli-runner-6CAZZA3P.js → generate-cli-runner-L5OQIMEY.js} +242 -247
  70. package/dist/mcp-chunks/{inspect-cli-command-3ZORTOR7.js → inspect-cli-command-7OMMREPE.js} +10 -9
  71. package/dist/mcp-chunks/{launch-YKRXHXJI.js → launch-BWXPLPB7.js} +1 -1
  72. package/dist/mcp-chunks/{lifecycle-XVKRHPH3.js → lifecycle-B5UC65PT.js} +1 -1
  73. package/dist/mcp-chunks/{list-command-2MEGGNFQ.js → list-command-ZO4HVFQK.js} +74 -43
  74. package/dist/mcp-chunks/{output-utils-NKESLAJ6.js → output-utils-M3TJ2N4M.js} +3 -3
  75. package/dist/mcp-chunks/{prompt-B1Yc1NPt-VGOTWJMN.js → prompt-CH6TK0bC-C7OTKGRD.js} +1 -3
  76. package/dist/mcp-chunks/{record-command-YXHTTTT5.js → record-command-VD3HUQIC.js} +5 -4
  77. package/dist/mcp-chunks/replay-command-AX6IN7YD.js +42 -0
  78. package/dist/mcp-chunks/{resource-command-OO4NYF5C.js → resource-command-JEZ2DW2G.js} +10 -10
  79. package/dist/mcp-chunks/{result-utils-MOHHLNM7.js → result-utils-3YHYGS45.js} +4 -4
  80. package/dist/mcp-chunks/runtime-HSYVOME7.js +37 -0
  81. package/dist/mcp-chunks/{runtime-wrapper-RPWDIDBF.js → runtime-wrapper-UREU7GC3.js} +7 -3
  82. package/dist/mcp-chunks/serve-command-M47YZ6JN.js +16018 -0
  83. package/dist/mcp-chunks/{timeouts-W2XWCCXR.js → timeouts-THZRYP4B.js} +3 -1
  84. package/dist/mcp-chunks/{vault-command-PIYIUEZL.js → vault-command-53P7MLCB.js} +7 -6
  85. package/dist/mcp-chunks/webapi-PHEQZQKH.js +3316 -0
  86. package/dist/mcp-client.js +11 -1
  87. package/dist/mcp-client.js.map +1 -1
  88. package/dist/mcp-daemon-client.d.ts.map +1 -1
  89. package/dist/mcp-daemon-client.js +3 -0
  90. package/dist/mcp-daemon-client.js.map +1 -1
  91. package/dist/mcp-daemon-protocol.d.ts +6 -0
  92. package/dist/mcp-daemon-protocol.d.ts.map +1 -1
  93. package/dist/mcp-daemon-protocol.js.map +1 -1
  94. package/dist/mcp-daemon.js +43 -22
  95. package/dist/mcp-daemon.js.map +1 -1
  96. package/dist/mcp-run-worker.js +29 -22
  97. package/dist/mcp-trace-context.d.ts +6 -0
  98. package/dist/mcp-trace-context.d.ts.map +1 -0
  99. package/dist/mcp-trace-context.js +31 -0
  100. package/dist/mcp-trace-context.js.map +1 -0
  101. package/dist/model-binding.d.ts.map +1 -1
  102. package/dist/model-binding.js +8 -4
  103. package/dist/model-binding.js.map +1 -1
  104. package/dist/pi-extension.d.ts.map +1 -1
  105. package/dist/pi-extension.js +12 -0
  106. package/dist/pi-extension.js.map +1 -1
  107. package/dist/recipe/resolve.d.ts +2 -0
  108. package/dist/recipe/resolve.d.ts.map +1 -1
  109. package/dist/recipe/resolve.js +2 -1
  110. package/dist/recipe/resolve.js.map +1 -1
  111. package/dist/recipe-agent.d.ts +5 -2
  112. package/dist/recipe-agent.d.ts.map +1 -1
  113. package/dist/recipe-agent.js +20 -4
  114. package/dist/recipe-agent.js.map +1 -1
  115. package/dist/recipe-model.d.ts +7 -1
  116. package/dist/recipe-model.d.ts.map +1 -1
  117. package/dist/recipe-model.js +89 -20
  118. package/dist/recipe-model.js.map +1 -1
  119. package/dist/recipe-session.d.ts +14 -0
  120. package/dist/recipe-session.d.ts.map +1 -0
  121. package/dist/recipe-session.js +181 -0
  122. package/dist/recipe-session.js.map +1 -0
  123. package/dist/session.d.ts.map +1 -1
  124. package/dist/session.js +23 -1
  125. package/dist/session.js.map +1 -1
  126. package/docs/agent-composition.md +46 -22
  127. package/docs/pi-extension.md +9 -3
  128. package/docs/recipe-format.md +41 -5
  129. package/package.json +7 -7
  130. package/vendor/introspection-recipe-check/darwin-arm64/introspection-recipe-check +0 -0
  131. package/vendor/introspection-recipe-check/darwin-x64/introspection-recipe-check +0 -0
  132. package/vendor/introspection-recipe-check/linux-arm64/introspection-recipe-check +0 -0
  133. package/vendor/introspection-recipe-check/linux-x64/introspection-recipe-check +0 -0
  134. package/vendor/introspection-recipe-check/linux-x64-musl/introspection-recipe-check +0 -0
  135. package/vendor/introspection-recipe-check/win32-x64/introspection-recipe-check.exe +0 -0
  136. package/dist/mcp-chunks/call-arguments-LU3W6D3K.js +0 -13
  137. package/dist/mcp-chunks/chunk-HKRJ6O36.js +0 -1076
  138. package/dist/mcp-chunks/chunk-NNOEGEUZ.js +0 -17273
  139. package/dist/mcp-chunks/chunk-P3PSC54P.js +0 -869
  140. package/dist/mcp-chunks/chunk-TATVT5IT.js +0 -194
  141. package/dist/mcp-chunks/chunk-YHQUTU6L.js +0 -571
  142. package/dist/mcp-chunks/client-S7RQUG5U.js +0 -13
  143. package/dist/mcp-chunks/daemon-command-U242Z6VY.js +0 -26
  144. package/dist/mcp-chunks/replay-command-25HJ6AQU.js +0 -85
  145. package/dist/mcp-chunks/runtime-5WJ3G25Y.js +0 -33
  146. package/dist/mcp-chunks/serve-command-DHXJZMMN.js +0 -3302
@@ -0,0 +1,3299 @@
1
+ import { createRequire as __createRequire } from "node:module"; const require = __createRequire(import.meta.url);
2
+ import {
3
+ NON_INTERACTIVE_ELICITATION_HINT,
4
+ createNonInteractiveElicitationResponder,
5
+ registerElicitationHandler
6
+ } from "./chunk-CA5WFJZA.js";
7
+ import {
8
+ RecordTransport,
9
+ resolveRecordingPath
10
+ } from "./chunk-E6T37ED6.js";
11
+ import {
12
+ OAuthTimeoutError,
13
+ connectWithAuth,
14
+ isOAuthFlowError,
15
+ isPostAuthConnectError,
16
+ resolveOAuthTimeoutFromEnv
17
+ } from "./chunk-SRZZQ6TL.js";
18
+ import {
19
+ buildOAuthPersistence,
20
+ buildStaticClientInformation,
21
+ readCachedAccessToken
22
+ } from "./chunk-3IZQW4H4.js";
23
+ import {
24
+ isUnauthorizedError,
25
+ maybeEnableOAuth
26
+ } from "./chunk-7DH57OKF.js";
27
+ import {
28
+ STDIO_TRACE_ENABLED,
29
+ flushStdioLogs,
30
+ ignoreStdioEmitterError
31
+ } from "./chunk-2MEHGB7D.js";
32
+ import {
33
+ MCPORTER_VERSION
34
+ } from "./chunk-SFREPU3D.js";
35
+ import {
36
+ createPrefixedConsoleLogger,
37
+ resolveLogLevelFromEnv
38
+ } from "./chunk-GFYTST6N.js";
39
+ import {
40
+ normalizeTimeout,
41
+ raceWithTimeout,
42
+ resolveCommandArgument,
43
+ resolveCommandArguments
44
+ } from "./chunk-ETWN4IIA.js";
45
+ import {
46
+ analyzeConnectionError
47
+ } from "./chunk-DEUU7WSN.js";
48
+ import {
49
+ Client,
50
+ DEFAULT_REQUEST_TIMEOUT_MSEC,
51
+ ProtocolErrorCode,
52
+ ReadBuffer,
53
+ SSEClientTransport,
54
+ SdkError,
55
+ SdkErrorCode,
56
+ SdkHttpError,
57
+ StreamableHTTPClientTransport,
58
+ serializeMessage,
59
+ specTypeSchemas,
60
+ validateClientMetadataUrl
61
+ } from "./chunk-YPJ5EHXR.js";
62
+ import {
63
+ loadServerDefinitions
64
+ } from "./chunk-L4VKBFYI.js";
65
+ import {
66
+ resolveEnvPlaceholders,
67
+ resolveEnvValue,
68
+ withEnvOverrides
69
+ } from "./chunk-HAO6PL7Z.js";
70
+ import {
71
+ __commonJS,
72
+ __require,
73
+ __toESM
74
+ } from "./chunk-LRKZP7DJ.js";
75
+
76
+ // node_modules/.pnpm/isexe@2.0.0/node_modules/isexe/windows.js
77
+ var require_windows = __commonJS({
78
+ "node_modules/.pnpm/isexe@2.0.0/node_modules/isexe/windows.js"(exports, module) {
79
+ module.exports = isexe;
80
+ isexe.sync = sync;
81
+ var fs5 = __require("fs");
82
+ function checkPathExt(path4, options) {
83
+ var pathext = options.pathExt !== void 0 ? options.pathExt : process.env.PATHEXT;
84
+ if (!pathext) {
85
+ return true;
86
+ }
87
+ pathext = pathext.split(";");
88
+ if (pathext.indexOf("") !== -1) {
89
+ return true;
90
+ }
91
+ for (var i = 0; i < pathext.length; i++) {
92
+ var p = pathext[i].toLowerCase();
93
+ if (p && path4.substr(-p.length).toLowerCase() === p) {
94
+ return true;
95
+ }
96
+ }
97
+ return false;
98
+ }
99
+ function checkStat(stat, path4, options) {
100
+ if (!stat.isSymbolicLink() && !stat.isFile()) {
101
+ return false;
102
+ }
103
+ return checkPathExt(path4, options);
104
+ }
105
+ function isexe(path4, options, cb) {
106
+ fs5.stat(path4, function(er, stat) {
107
+ cb(er, er ? false : checkStat(stat, path4, options));
108
+ });
109
+ }
110
+ function sync(path4, options) {
111
+ return checkStat(fs5.statSync(path4), path4, options);
112
+ }
113
+ }
114
+ });
115
+
116
+ // node_modules/.pnpm/isexe@2.0.0/node_modules/isexe/mode.js
117
+ var require_mode = __commonJS({
118
+ "node_modules/.pnpm/isexe@2.0.0/node_modules/isexe/mode.js"(exports, module) {
119
+ module.exports = isexe;
120
+ isexe.sync = sync;
121
+ var fs5 = __require("fs");
122
+ function isexe(path4, options, cb) {
123
+ fs5.stat(path4, function(er, stat) {
124
+ cb(er, er ? false : checkStat(stat, options));
125
+ });
126
+ }
127
+ function sync(path4, options) {
128
+ return checkStat(fs5.statSync(path4), options);
129
+ }
130
+ function checkStat(stat, options) {
131
+ return stat.isFile() && checkMode(stat, options);
132
+ }
133
+ function checkMode(stat, options) {
134
+ var mod = stat.mode;
135
+ var uid = stat.uid;
136
+ var gid = stat.gid;
137
+ var myUid = options.uid !== void 0 ? options.uid : process.getuid && process.getuid();
138
+ var myGid = options.gid !== void 0 ? options.gid : process.getgid && process.getgid();
139
+ var u = parseInt("100", 8);
140
+ var g = parseInt("010", 8);
141
+ var o = parseInt("001", 8);
142
+ var ug = u | g;
143
+ var ret = mod & o || mod & g && gid === myGid || mod & u && uid === myUid || mod & ug && myUid === 0;
144
+ return ret;
145
+ }
146
+ }
147
+ });
148
+
149
+ // node_modules/.pnpm/isexe@2.0.0/node_modules/isexe/index.js
150
+ var require_isexe = __commonJS({
151
+ "node_modules/.pnpm/isexe@2.0.0/node_modules/isexe/index.js"(exports, module) {
152
+ var fs5 = __require("fs");
153
+ var core;
154
+ if (process.platform === "win32" || global.TESTING_WINDOWS) {
155
+ core = require_windows();
156
+ } else {
157
+ core = require_mode();
158
+ }
159
+ module.exports = isexe;
160
+ isexe.sync = sync;
161
+ function isexe(path4, options, cb) {
162
+ if (typeof options === "function") {
163
+ cb = options;
164
+ options = {};
165
+ }
166
+ if (!cb) {
167
+ if (typeof Promise !== "function") {
168
+ throw new TypeError("callback not provided");
169
+ }
170
+ return new Promise(function(resolve, reject) {
171
+ isexe(path4, options || {}, function(er, is) {
172
+ if (er) {
173
+ reject(er);
174
+ } else {
175
+ resolve(is);
176
+ }
177
+ });
178
+ });
179
+ }
180
+ core(path4, options || {}, function(er, is) {
181
+ if (er) {
182
+ if (er.code === "EACCES" || options && options.ignoreErrors) {
183
+ er = null;
184
+ is = false;
185
+ }
186
+ }
187
+ cb(er, is);
188
+ });
189
+ }
190
+ function sync(path4, options) {
191
+ try {
192
+ return core.sync(path4, options || {});
193
+ } catch (er) {
194
+ if (options && options.ignoreErrors || er.code === "EACCES") {
195
+ return false;
196
+ } else {
197
+ throw er;
198
+ }
199
+ }
200
+ }
201
+ }
202
+ });
203
+
204
+ // node_modules/.pnpm/which@2.0.2/node_modules/which/which.js
205
+ var require_which = __commonJS({
206
+ "node_modules/.pnpm/which@2.0.2/node_modules/which/which.js"(exports, module) {
207
+ var isWindows = process.platform === "win32" || process.env.OSTYPE === "cygwin" || process.env.OSTYPE === "msys";
208
+ var path4 = __require("path");
209
+ var COLON = isWindows ? ";" : ":";
210
+ var isexe = require_isexe();
211
+ var getNotFoundError = (cmd) => Object.assign(new Error(`not found: ${cmd}`), { code: "ENOENT" });
212
+ var getPathInfo = (cmd, opt) => {
213
+ const colon = opt.colon || COLON;
214
+ const pathEnv = cmd.match(/\//) || isWindows && cmd.match(/\\/) ? [""] : [
215
+ // windows always checks the cwd first
216
+ ...isWindows ? [process.cwd()] : [],
217
+ ...(opt.path || process.env.PATH || /* istanbul ignore next: very unusual */
218
+ "").split(colon)
219
+ ];
220
+ const pathExtExe = isWindows ? opt.pathExt || process.env.PATHEXT || ".EXE;.CMD;.BAT;.COM" : "";
221
+ const pathExt = isWindows ? pathExtExe.split(colon) : [""];
222
+ if (isWindows) {
223
+ if (cmd.indexOf(".") !== -1 && pathExt[0] !== "")
224
+ pathExt.unshift("");
225
+ }
226
+ return {
227
+ pathEnv,
228
+ pathExt,
229
+ pathExtExe
230
+ };
231
+ };
232
+ var which = (cmd, opt, cb) => {
233
+ if (typeof opt === "function") {
234
+ cb = opt;
235
+ opt = {};
236
+ }
237
+ if (!opt)
238
+ opt = {};
239
+ const { pathEnv, pathExt, pathExtExe } = getPathInfo(cmd, opt);
240
+ const found = [];
241
+ const step = (i) => new Promise((resolve, reject) => {
242
+ if (i === pathEnv.length)
243
+ return opt.all && found.length ? resolve(found) : reject(getNotFoundError(cmd));
244
+ const ppRaw = pathEnv[i];
245
+ const pathPart = /^".*"$/.test(ppRaw) ? ppRaw.slice(1, -1) : ppRaw;
246
+ const pCmd = path4.join(pathPart, cmd);
247
+ const p = !pathPart && /^\.[\\\/]/.test(cmd) ? cmd.slice(0, 2) + pCmd : pCmd;
248
+ resolve(subStep(p, i, 0));
249
+ });
250
+ const subStep = (p, i, ii) => new Promise((resolve, reject) => {
251
+ if (ii === pathExt.length)
252
+ return resolve(step(i + 1));
253
+ const ext = pathExt[ii];
254
+ isexe(p + ext, { pathExt: pathExtExe }, (er, is) => {
255
+ if (!er && is) {
256
+ if (opt.all)
257
+ found.push(p + ext);
258
+ else
259
+ return resolve(p + ext);
260
+ }
261
+ return resolve(subStep(p, i, ii + 1));
262
+ });
263
+ });
264
+ return cb ? step(0).then((res) => cb(null, res), cb) : step(0);
265
+ };
266
+ var whichSync = (cmd, opt) => {
267
+ opt = opt || {};
268
+ const { pathEnv, pathExt, pathExtExe } = getPathInfo(cmd, opt);
269
+ const found = [];
270
+ for (let i = 0; i < pathEnv.length; i++) {
271
+ const ppRaw = pathEnv[i];
272
+ const pathPart = /^".*"$/.test(ppRaw) ? ppRaw.slice(1, -1) : ppRaw;
273
+ const pCmd = path4.join(pathPart, cmd);
274
+ const p = !pathPart && /^\.[\\\/]/.test(cmd) ? cmd.slice(0, 2) + pCmd : pCmd;
275
+ for (let j = 0; j < pathExt.length; j++) {
276
+ const cur = p + pathExt[j];
277
+ try {
278
+ const is = isexe.sync(cur, { pathExt: pathExtExe });
279
+ if (is) {
280
+ if (opt.all)
281
+ found.push(cur);
282
+ else
283
+ return cur;
284
+ }
285
+ } catch (ex) {
286
+ }
287
+ }
288
+ }
289
+ if (opt.all && found.length)
290
+ return found;
291
+ if (opt.nothrow)
292
+ return null;
293
+ throw getNotFoundError(cmd);
294
+ };
295
+ module.exports = which;
296
+ which.sync = whichSync;
297
+ }
298
+ });
299
+
300
+ // node_modules/.pnpm/path-key@3.1.1/node_modules/path-key/index.js
301
+ var require_path_key = __commonJS({
302
+ "node_modules/.pnpm/path-key@3.1.1/node_modules/path-key/index.js"(exports, module) {
303
+ "use strict";
304
+ var pathKey = (options = {}) => {
305
+ const environment = options.env || process.env;
306
+ const platform = options.platform || process.platform;
307
+ if (platform !== "win32") {
308
+ return "PATH";
309
+ }
310
+ return Object.keys(environment).reverse().find((key) => key.toUpperCase() === "PATH") || "Path";
311
+ };
312
+ module.exports = pathKey;
313
+ module.exports.default = pathKey;
314
+ }
315
+ });
316
+
317
+ // node_modules/.pnpm/cross-spawn@7.0.6/node_modules/cross-spawn/lib/util/resolveCommand.js
318
+ var require_resolveCommand = __commonJS({
319
+ "node_modules/.pnpm/cross-spawn@7.0.6/node_modules/cross-spawn/lib/util/resolveCommand.js"(exports, module) {
320
+ "use strict";
321
+ var path4 = __require("path");
322
+ var which = require_which();
323
+ var getPathKey = require_path_key();
324
+ function resolveCommandAttempt(parsed, withoutPathExt) {
325
+ const env = parsed.options.env || process.env;
326
+ const cwd = process.cwd();
327
+ const hasCustomCwd = parsed.options.cwd != null;
328
+ const shouldSwitchCwd = hasCustomCwd && process.chdir !== void 0 && !process.chdir.disabled;
329
+ if (shouldSwitchCwd) {
330
+ try {
331
+ process.chdir(parsed.options.cwd);
332
+ } catch (err) {
333
+ }
334
+ }
335
+ let resolved;
336
+ try {
337
+ resolved = which.sync(parsed.command, {
338
+ path: env[getPathKey({ env })],
339
+ pathExt: withoutPathExt ? path4.delimiter : void 0
340
+ });
341
+ } catch (e) {
342
+ } finally {
343
+ if (shouldSwitchCwd) {
344
+ process.chdir(cwd);
345
+ }
346
+ }
347
+ if (resolved) {
348
+ resolved = path4.resolve(hasCustomCwd ? parsed.options.cwd : "", resolved);
349
+ }
350
+ return resolved;
351
+ }
352
+ function resolveCommand(parsed) {
353
+ return resolveCommandAttempt(parsed) || resolveCommandAttempt(parsed, true);
354
+ }
355
+ module.exports = resolveCommand;
356
+ }
357
+ });
358
+
359
+ // node_modules/.pnpm/cross-spawn@7.0.6/node_modules/cross-spawn/lib/util/escape.js
360
+ var require_escape = __commonJS({
361
+ "node_modules/.pnpm/cross-spawn@7.0.6/node_modules/cross-spawn/lib/util/escape.js"(exports, module) {
362
+ "use strict";
363
+ var metaCharsRegExp = /([()\][%!^"`<>&|;, *?])/g;
364
+ function escapeCommand(arg) {
365
+ arg = arg.replace(metaCharsRegExp, "^$1");
366
+ return arg;
367
+ }
368
+ function escapeArgument(arg, doubleEscapeMetaChars) {
369
+ arg = `${arg}`;
370
+ arg = arg.replace(/(?=(\\+?)?)\1"/g, '$1$1\\"');
371
+ arg = arg.replace(/(?=(\\+?)?)\1$/, "$1$1");
372
+ arg = `"${arg}"`;
373
+ arg = arg.replace(metaCharsRegExp, "^$1");
374
+ if (doubleEscapeMetaChars) {
375
+ arg = arg.replace(metaCharsRegExp, "^$1");
376
+ }
377
+ return arg;
378
+ }
379
+ module.exports.command = escapeCommand;
380
+ module.exports.argument = escapeArgument;
381
+ }
382
+ });
383
+
384
+ // node_modules/.pnpm/shebang-regex@3.0.0/node_modules/shebang-regex/index.js
385
+ var require_shebang_regex = __commonJS({
386
+ "node_modules/.pnpm/shebang-regex@3.0.0/node_modules/shebang-regex/index.js"(exports, module) {
387
+ "use strict";
388
+ module.exports = /^#!(.*)/;
389
+ }
390
+ });
391
+
392
+ // node_modules/.pnpm/shebang-command@2.0.0/node_modules/shebang-command/index.js
393
+ var require_shebang_command = __commonJS({
394
+ "node_modules/.pnpm/shebang-command@2.0.0/node_modules/shebang-command/index.js"(exports, module) {
395
+ "use strict";
396
+ var shebangRegex = require_shebang_regex();
397
+ module.exports = (string = "") => {
398
+ const match = string.match(shebangRegex);
399
+ if (!match) {
400
+ return null;
401
+ }
402
+ const [path4, argument] = match[0].replace(/#! ?/, "").split(" ");
403
+ const binary = path4.split("/").pop();
404
+ if (binary === "env") {
405
+ return argument;
406
+ }
407
+ return argument ? `${binary} ${argument}` : binary;
408
+ };
409
+ }
410
+ });
411
+
412
+ // node_modules/.pnpm/cross-spawn@7.0.6/node_modules/cross-spawn/lib/util/readShebang.js
413
+ var require_readShebang = __commonJS({
414
+ "node_modules/.pnpm/cross-spawn@7.0.6/node_modules/cross-spawn/lib/util/readShebang.js"(exports, module) {
415
+ "use strict";
416
+ var fs5 = __require("fs");
417
+ var shebangCommand = require_shebang_command();
418
+ function readShebang(command) {
419
+ const size = 150;
420
+ const buffer = Buffer.alloc(size);
421
+ let fd;
422
+ try {
423
+ fd = fs5.openSync(command, "r");
424
+ fs5.readSync(fd, buffer, 0, size, 0);
425
+ fs5.closeSync(fd);
426
+ } catch (e) {
427
+ }
428
+ return shebangCommand(buffer.toString());
429
+ }
430
+ module.exports = readShebang;
431
+ }
432
+ });
433
+
434
+ // node_modules/.pnpm/cross-spawn@7.0.6/node_modules/cross-spawn/lib/parse.js
435
+ var require_parse = __commonJS({
436
+ "node_modules/.pnpm/cross-spawn@7.0.6/node_modules/cross-spawn/lib/parse.js"(exports, module) {
437
+ "use strict";
438
+ var path4 = __require("path");
439
+ var resolveCommand = require_resolveCommand();
440
+ var escape = require_escape();
441
+ var readShebang = require_readShebang();
442
+ var isWin = process.platform === "win32";
443
+ var isExecutableRegExp = /\.(?:com|exe)$/i;
444
+ var isCmdShimRegExp = /node_modules[\\/].bin[\\/][^\\/]+\.cmd$/i;
445
+ function detectShebang(parsed) {
446
+ parsed.file = resolveCommand(parsed);
447
+ const shebang = parsed.file && readShebang(parsed.file);
448
+ if (shebang) {
449
+ parsed.args.unshift(parsed.file);
450
+ parsed.command = shebang;
451
+ return resolveCommand(parsed);
452
+ }
453
+ return parsed.file;
454
+ }
455
+ function parseNonShell(parsed) {
456
+ if (!isWin) {
457
+ return parsed;
458
+ }
459
+ const commandFile = detectShebang(parsed);
460
+ const needsShell = !isExecutableRegExp.test(commandFile);
461
+ if (parsed.options.forceShell || needsShell) {
462
+ const needsDoubleEscapeMetaChars = isCmdShimRegExp.test(commandFile);
463
+ parsed.command = path4.normalize(parsed.command);
464
+ parsed.command = escape.command(parsed.command);
465
+ parsed.args = parsed.args.map((arg) => escape.argument(arg, needsDoubleEscapeMetaChars));
466
+ const shellCommand = [parsed.command].concat(parsed.args).join(" ");
467
+ parsed.args = ["/d", "/s", "/c", `"${shellCommand}"`];
468
+ parsed.command = process.env.comspec || "cmd.exe";
469
+ parsed.options.windowsVerbatimArguments = true;
470
+ }
471
+ return parsed;
472
+ }
473
+ function parse(command, args, options) {
474
+ if (args && !Array.isArray(args)) {
475
+ options = args;
476
+ args = null;
477
+ }
478
+ args = args ? args.slice(0) : [];
479
+ options = Object.assign({}, options);
480
+ const parsed = {
481
+ command,
482
+ args,
483
+ options,
484
+ file: void 0,
485
+ original: {
486
+ command,
487
+ args
488
+ }
489
+ };
490
+ return options.shell ? parsed : parseNonShell(parsed);
491
+ }
492
+ module.exports = parse;
493
+ }
494
+ });
495
+
496
+ // node_modules/.pnpm/cross-spawn@7.0.6/node_modules/cross-spawn/lib/enoent.js
497
+ var require_enoent = __commonJS({
498
+ "node_modules/.pnpm/cross-spawn@7.0.6/node_modules/cross-spawn/lib/enoent.js"(exports, module) {
499
+ "use strict";
500
+ var isWin = process.platform === "win32";
501
+ function notFoundError(original, syscall) {
502
+ return Object.assign(new Error(`${syscall} ${original.command} ENOENT`), {
503
+ code: "ENOENT",
504
+ errno: "ENOENT",
505
+ syscall: `${syscall} ${original.command}`,
506
+ path: original.command,
507
+ spawnargs: original.args
508
+ });
509
+ }
510
+ function hookChildProcess(cp, parsed) {
511
+ if (!isWin) {
512
+ return;
513
+ }
514
+ const originalEmit = cp.emit;
515
+ cp.emit = function(name, arg1) {
516
+ if (name === "exit") {
517
+ const err = verifyENOENT(arg1, parsed);
518
+ if (err) {
519
+ return originalEmit.call(cp, "error", err);
520
+ }
521
+ }
522
+ return originalEmit.apply(cp, arguments);
523
+ };
524
+ }
525
+ function verifyENOENT(status, parsed) {
526
+ if (isWin && status === 1 && !parsed.file) {
527
+ return notFoundError(parsed.original, "spawn");
528
+ }
529
+ return null;
530
+ }
531
+ function verifyENOENTSync(status, parsed) {
532
+ if (isWin && status === 1 && !parsed.file) {
533
+ return notFoundError(parsed.original, "spawnSync");
534
+ }
535
+ return null;
536
+ }
537
+ module.exports = {
538
+ hookChildProcess,
539
+ verifyENOENT,
540
+ verifyENOENTSync,
541
+ notFoundError
542
+ };
543
+ }
544
+ });
545
+
546
+ // node_modules/.pnpm/cross-spawn@7.0.6/node_modules/cross-spawn/index.js
547
+ var require_cross_spawn = __commonJS({
548
+ "node_modules/.pnpm/cross-spawn@7.0.6/node_modules/cross-spawn/index.js"(exports, module) {
549
+ "use strict";
550
+ var cp = __require("child_process");
551
+ var parse = require_parse();
552
+ var enoent = require_enoent();
553
+ function spawn3(command, args, options) {
554
+ const parsed = parse(command, args, options);
555
+ const spawned = cp.spawn(parsed.command, parsed.args, parsed.options);
556
+ enoent.hookChildProcess(spawned, parsed);
557
+ return spawned;
558
+ }
559
+ function spawnSync(command, args, options) {
560
+ const parsed = parse(command, args, options);
561
+ const result = cp.spawnSync(parsed.command, parsed.args, parsed.options);
562
+ result.error = result.error || enoent.verifyENOENTSync(result.status, parsed);
563
+ return result;
564
+ }
565
+ module.exports = spawn3;
566
+ module.exports.spawn = spawn3;
567
+ module.exports.sync = spawnSync;
568
+ module.exports._parse = parse;
569
+ module.exports._enoent = enoent;
570
+ }
571
+ });
572
+
573
+ // node_modules/.pnpm/mcporter@0.13.0/node_modules/mcporter/dist/runtime-process-utils.js
574
+ import { execFile } from "node:child_process";
575
+ async function closeTransportAndWait(logger, transport, options = {}) {
576
+ const pidBeforeClose = getTransportPid(transport);
577
+ const targetsBeforeClose = pidBeforeClose ? await collectProcessTreePids(pidBeforeClose) : [];
578
+ let closeError;
579
+ let closeSettled = false;
580
+ const closePromise = (options.close ?? (() => transport.close()))().catch((error) => {
581
+ closeError = error;
582
+ if (!options.throwOnCloseError) {
583
+ logger.warn(`Failed to close transport cleanly: ${error.message}`);
584
+ }
585
+ }).finally(() => {
586
+ closeSettled = true;
587
+ });
588
+ if (pidBeforeClose) {
589
+ destroyTransportStreams(transport);
590
+ await ensureProcessTreeTerminated(logger, pidBeforeClose, targetsBeforeClose);
591
+ if (!closeSettled) {
592
+ await Promise.race([closePromise, delay(100)]);
593
+ }
594
+ } else {
595
+ await closePromise;
596
+ }
597
+ if (closeError && options.throwOnCloseError) {
598
+ throw closeError;
599
+ }
600
+ }
601
+ function getTransportPid(transport) {
602
+ if ("pid" in transport) {
603
+ const candidate = transport.pid;
604
+ if (typeof candidate === "number" && candidate > 0) {
605
+ return candidate;
606
+ }
607
+ }
608
+ return null;
609
+ }
610
+ function isProcessAlive(pid) {
611
+ try {
612
+ process.kill(pid, 0);
613
+ return true;
614
+ } catch {
615
+ return false;
616
+ }
617
+ }
618
+ async function ensureProcessTreeTerminated(logger, rootPid, capturedTargets = []) {
619
+ let targets = uniquePids([...capturedTargets, ...await collectProcessTreePids(rootPid)]);
620
+ if (targets.length === 0 || await waitForTreeExit(targets, 700)) {
621
+ return;
622
+ }
623
+ await sendSignalToTargets(targets, "SIGTERM");
624
+ targets = uniquePids([...targets, ...await collectProcessTreePids(rootPid)]);
625
+ if (await waitForTreeExit(targets, 700)) {
626
+ return;
627
+ }
628
+ targets = uniquePids([...targets, ...await collectProcessTreePids(rootPid)]);
629
+ await sendSignalToTargets(targets, "SIGKILL");
630
+ if (await waitForTreeExit(targets, 500)) {
631
+ return;
632
+ }
633
+ logger.warn(`Process tree rooted at pid=${rootPid} did not exit after SIGKILL.`);
634
+ }
635
+ function uniquePids(pids) {
636
+ return [...new Set(pids.filter((pid) => Number.isInteger(pid) && pid > 0))];
637
+ }
638
+ function destroyTransportStreams(transport) {
639
+ const candidate = transport;
640
+ for (const key of ["stdin", "stdout", "stderr"]) {
641
+ try {
642
+ const stream = candidate[key];
643
+ stream?.destroy?.();
644
+ } catch {
645
+ }
646
+ }
647
+ }
648
+ async function sendSignalToTargets(pids, signal) {
649
+ const seen = /* @__PURE__ */ new Set();
650
+ for (const pid of pids) {
651
+ if (seen.has(pid)) {
652
+ continue;
653
+ }
654
+ seen.add(pid);
655
+ sendSignal(pid, signal);
656
+ }
657
+ }
658
+ function sendSignal(pid, signal) {
659
+ try {
660
+ process.kill(pid, signal);
661
+ } catch (error) {
662
+ if (typeof error === "object" && error && "code" in error && error.code === "ESRCH") {
663
+ return;
664
+ }
665
+ throw error;
666
+ }
667
+ }
668
+ async function listDescendantPids(rootPid) {
669
+ if (!isProcessAlive(rootPid)) {
670
+ return [];
671
+ }
672
+ if (process.platform === "win32") {
673
+ return listDescendantPidsWindows(rootPid);
674
+ }
675
+ try {
676
+ const { stdout } = await execFileAsync("ps", ["-eo", "pid=,ppid="]);
677
+ const children = /* @__PURE__ */ new Map();
678
+ for (const line of stdout.split("\n")) {
679
+ const trimmed = line.trim();
680
+ if (!trimmed) {
681
+ continue;
682
+ }
683
+ const [pidText, ppidText] = trimmed.split(/\s+/, 2);
684
+ const pid = Number.parseInt(pidText ?? "", 10);
685
+ const ppid = Number.parseInt(ppidText ?? "", 10);
686
+ if (!Number.isFinite(pid) || !Number.isFinite(ppid)) {
687
+ continue;
688
+ }
689
+ const bucket = children.get(ppid) ?? [];
690
+ bucket.push(pid);
691
+ children.set(ppid, bucket);
692
+ }
693
+ return collectDescendantsFromChildren(rootPid, children);
694
+ } catch {
695
+ return [];
696
+ }
697
+ }
698
+ async function listDescendantPidsWindows(rootPid) {
699
+ try {
700
+ const powershellScript = "Get-CimInstance Win32_Process | Select-Object ProcessId,ParentProcessId | ConvertTo-Json -Compress";
701
+ const { stdout } = await execFileAsync("powershell.exe", ["-NoProfile", "-Command", powershellScript]);
702
+ const trimmed = stdout.trim();
703
+ if (!trimmed) {
704
+ return [];
705
+ }
706
+ const parsed = JSON.parse(trimmed);
707
+ const entries = Array.isArray(parsed) ? parsed : [parsed];
708
+ const children = /* @__PURE__ */ new Map();
709
+ for (const entry of entries) {
710
+ const pidCandidate = entry?.ProcessId;
711
+ const ppidCandidate = entry?.ParentProcessId;
712
+ if (typeof pidCandidate !== "number" || typeof ppidCandidate !== "number") {
713
+ continue;
714
+ }
715
+ const pid = Number.isFinite(pidCandidate) ? pidCandidate : void 0;
716
+ const ppid = Number.isFinite(ppidCandidate) ? ppidCandidate : void 0;
717
+ if (pid === void 0 || ppid === void 0) {
718
+ continue;
719
+ }
720
+ const bucket = children.get(ppid) ?? [];
721
+ bucket.push(pid);
722
+ children.set(ppid, bucket);
723
+ }
724
+ return collectDescendantsFromChildren(rootPid, children);
725
+ } catch {
726
+ return [];
727
+ }
728
+ }
729
+ function execFileAsync(command, args) {
730
+ return new Promise((resolve, reject) => {
731
+ execFile(command, args, { encoding: "utf8" }, (error, stdout, stderr) => {
732
+ if (error) {
733
+ reject(error);
734
+ return;
735
+ }
736
+ resolve({ stdout, stderr });
737
+ });
738
+ });
739
+ }
740
+ async function collectProcessTreePids(rootPid) {
741
+ const descendants = await listDescendantPids(rootPid);
742
+ return [...descendants, rootPid];
743
+ }
744
+ function collectDescendantsFromChildren(rootPid, children) {
745
+ const result = [];
746
+ const queue = [...children.get(rootPid) ?? []];
747
+ const seen = new Set(queue);
748
+ while (queue.length > 0) {
749
+ const current = queue.shift();
750
+ if (current === void 0) {
751
+ continue;
752
+ }
753
+ result.push(current);
754
+ for (const child of children.get(current) ?? []) {
755
+ if (!seen.has(child)) {
756
+ seen.add(child);
757
+ queue.push(child);
758
+ }
759
+ }
760
+ }
761
+ return result;
762
+ }
763
+ async function waitForTreeExit(pids, durationMs) {
764
+ const deadline = Date.now() + durationMs;
765
+ while (true) {
766
+ if (pids.every((pid) => !isProcessAlive(pid))) {
767
+ return true;
768
+ }
769
+ if (Date.now() >= deadline) {
770
+ return false;
771
+ }
772
+ const remaining = Math.max(10, Math.min(100, deadline - Date.now()));
773
+ await delay(remaining);
774
+ }
775
+ }
776
+ function delay(ms) {
777
+ return new Promise((resolve) => setTimeout(resolve, ms));
778
+ }
779
+
780
+ // node_modules/.pnpm/mcporter@0.13.0/node_modules/mcporter/dist/runtime/errors.js
781
+ var NON_FATAL_MCP_ERROR_CODES = /* @__PURE__ */ new Set([
782
+ ProtocolErrorCode.InvalidRequest,
783
+ ProtocolErrorCode.MethodNotFound,
784
+ ProtocolErrorCode.InvalidParams
785
+ ]);
786
+ function shouldResetConnection(error) {
787
+ if (!error) {
788
+ return false;
789
+ }
790
+ const code = protocolErrorCode(error);
791
+ if (code !== void 0) {
792
+ return !NON_FATAL_MCP_ERROR_CODES.has(code);
793
+ }
794
+ return error instanceof Error;
795
+ }
796
+ function protocolErrorCode(error) {
797
+ if (!error || typeof error !== "object" || !("code" in error))
798
+ return void 0;
799
+ return typeof error.code === "number" ? error.code : void 0;
800
+ }
801
+
802
+ // node_modules/.pnpm/mcporter@0.13.0/node_modules/mcporter/dist/runtime/replay-transport.js
803
+ import fs from "node:fs";
804
+ import { isDeepStrictEqual } from "node:util";
805
+ var CLIENT_IDENTITY_META_KEYS = [
806
+ "io.modelcontextprotocol/clientInfo",
807
+ "io.modelcontextprotocol/protocolVersion",
808
+ "io.modelcontextprotocol/clientCapabilities"
809
+ ];
810
+ var ReplayTransport = class {
811
+ opts;
812
+ hasPerRequestStream = void 0;
813
+ onclose;
814
+ onerror;
815
+ onmessage;
816
+ sessionId;
817
+ expectedSends;
818
+ requiresLegacyNegotiation;
819
+ constructor(opts) {
820
+ this.opts = opts;
821
+ this.expectedSends = buildReplayQueue(readRecordedMessages(opts.recordPath), opts.server);
822
+ this.requiresLegacyNegotiation = this.expectedSends[0]?.method === "initialize";
823
+ }
824
+ async start() {
825
+ }
826
+ async send(message, _options) {
827
+ const request = requestDetails(message);
828
+ if (!request) {
829
+ return;
830
+ }
831
+ const expected = this.expectedSends[0];
832
+ if (!expected || expected.method !== request.method || !paramsMatch(request.method, expected.params, request.params)) {
833
+ throw new Error(formatReplayMismatch(this.opts.server, request, expected));
834
+ }
835
+ this.expectedSends.shift();
836
+ if (expected.response) {
837
+ const response = withActiveRequestId(adaptInitializeResponse(request.method, expected.response, request.params), request.id);
838
+ const inbound = [
839
+ ...expected.notificationsBeforeResponse ?? [],
840
+ response,
841
+ ...expected.notificationsAfterResponse ?? []
842
+ ];
843
+ queueMicrotask(() => {
844
+ for (const inboundMessage of inbound)
845
+ this.onmessage?.(inboundMessage);
846
+ });
847
+ }
848
+ }
849
+ async close() {
850
+ if (this.expectedSends.length > 0) {
851
+ throw new Error(formatReplayRemainder(this.opts.server, this.expectedSends));
852
+ }
853
+ this.onclose?.();
854
+ }
855
+ };
856
+ function readRecordedMessages(recordPath) {
857
+ try {
858
+ const contents = fs.readFileSync(recordPath, "utf8");
859
+ return contents.split(/\r?\n/).map((line) => line.trim()).filter((line) => line.length > 0).map((line, index) => {
860
+ try {
861
+ return JSON.parse(line);
862
+ } catch (error) {
863
+ throw new Error(`Invalid JSON on recording line ${index + 1} in ${recordPath}: ${error instanceof Error ? error.message : String(error)}`, { cause: error });
864
+ }
865
+ });
866
+ } catch (error) {
867
+ if (error.code === "ENOENT") {
868
+ throw new Error(`Replay recording not found: ${recordPath}`, { cause: error });
869
+ }
870
+ throw error;
871
+ }
872
+ }
873
+ function buildReplayQueue(messages, server) {
874
+ const pendingRequests = /* @__PURE__ */ new Map();
875
+ const expected = [];
876
+ let bufferedNotifications = [];
877
+ let lastResponse;
878
+ for (const entry of messages) {
879
+ if (entry._meta?.server !== server) {
880
+ continue;
881
+ }
882
+ if (entry._meta.dir === "lifecycle") {
883
+ continue;
884
+ }
885
+ const clean = stripMeta(entry);
886
+ if (entry._meta.dir === "send") {
887
+ const request = requestDetails(clean);
888
+ if (!request) {
889
+ continue;
890
+ }
891
+ const expectedSend = {
892
+ method: request.method,
893
+ params: request.params,
894
+ expectsResponse: request.id !== void 0
895
+ };
896
+ expected.push(expectedSend);
897
+ if (request.id !== void 0) {
898
+ pendingRequests.set(String(request.id), expectedSend);
899
+ }
900
+ continue;
901
+ }
902
+ if (entry._meta.dir === "recv") {
903
+ if (isInboundNotification(clean)) {
904
+ bufferedNotifications.push(clean);
905
+ continue;
906
+ }
907
+ const responseId = responseIdOf(clean);
908
+ if (responseId === void 0) {
909
+ continue;
910
+ }
911
+ const pending = pendingRequests.get(String(responseId));
912
+ if (pending) {
913
+ pendingRequests.delete(String(responseId));
914
+ pending.notificationsBeforeResponse = bufferedNotifications;
915
+ bufferedNotifications = [];
916
+ pending.response = clean;
917
+ lastResponse = pending;
918
+ }
919
+ }
920
+ }
921
+ if (lastResponse && bufferedNotifications.length > 0) {
922
+ lastResponse.notificationsAfterResponse = bufferedNotifications;
923
+ }
924
+ return expected.filter((entry) => !entry.expectsResponse || entry.response);
925
+ }
926
+ function isInboundNotification(message) {
927
+ const record = message;
928
+ return typeof record.method === "string" && !("id" in record);
929
+ }
930
+ function stripMeta(message) {
931
+ const { _meta, ...jsonrpc } = message;
932
+ return jsonrpc;
933
+ }
934
+ function requestDetails(message) {
935
+ const record = message;
936
+ if (typeof record.method !== "string") {
937
+ return void 0;
938
+ }
939
+ if (record.method.startsWith("$transport/")) {
940
+ return void 0;
941
+ }
942
+ return {
943
+ id: typeof record.id === "string" || typeof record.id === "number" ? record.id : void 0,
944
+ method: record.method,
945
+ params: record.params
946
+ };
947
+ }
948
+ function responseIdOf(message) {
949
+ const record = message;
950
+ if (!("result" in record) && !("error" in record)) {
951
+ return void 0;
952
+ }
953
+ const id = record.id;
954
+ return typeof id === "string" || typeof id === "number" ? id : void 0;
955
+ }
956
+ function paramsMatch(method, expected, actual) {
957
+ if (method === "server/discover") {
958
+ return true;
959
+ }
960
+ const normalizedExpected = normalizeClientIdentityMeta(expected);
961
+ const normalizedActual = normalizeClientIdentityMeta(actual);
962
+ if (method !== "initialize") {
963
+ return isDeepStrictEqual(normalizedExpected, normalizedActual);
964
+ }
965
+ return isDeepStrictEqual(normalizeInitializeParams(normalizedExpected), normalizeInitializeParams(normalizedActual));
966
+ }
967
+ function normalizeClientIdentityMeta(params) {
968
+ if (!isJsonRpcRecord(params) || !isJsonRpcRecord(params._meta)) {
969
+ return params;
970
+ }
971
+ const meta = { ...params._meta };
972
+ for (const key of CLIENT_IDENTITY_META_KEYS) {
973
+ delete meta[key];
974
+ }
975
+ return { ...params, _meta: meta };
976
+ }
977
+ function normalizeInitializeParams(params) {
978
+ if (!isJsonRpcRecord(params)) {
979
+ return params;
980
+ }
981
+ const normalized = { ...params };
982
+ delete normalized.protocolVersion;
983
+ delete normalized.capabilities;
984
+ delete normalized.clientInfo;
985
+ return normalized;
986
+ }
987
+ function adaptInitializeResponse(method, response, requestParams) {
988
+ if (method !== "initialize" || !isJsonRpcRecord(requestParams) || !("result" in response)) {
989
+ return response;
990
+ }
991
+ const protocolVersion = requestParams.protocolVersion;
992
+ if (typeof protocolVersion !== "string" || !isJsonRpcRecord(response.result)) {
993
+ return response;
994
+ }
995
+ return {
996
+ ...response,
997
+ result: { ...response.result, protocolVersion }
998
+ };
999
+ }
1000
+ function isJsonRpcRecord(value) {
1001
+ return typeof value === "object" && value !== null && !Array.isArray(value);
1002
+ }
1003
+ function withActiveRequestId(response, requestId) {
1004
+ if (requestId === void 0) {
1005
+ return response;
1006
+ }
1007
+ return {
1008
+ ...response,
1009
+ id: requestId
1010
+ };
1011
+ }
1012
+ function formatReplayMismatch(server, request, expected) {
1013
+ const expectedText = expected ? `${expected.method} ${JSON.stringify(expected.params ?? {})}` : "no remaining recorded recv";
1014
+ return `Replay mismatch for server '${server}': request ${request.method} ${JSON.stringify(request.params ?? {})} did not match next expected recv ${expectedText}.`;
1015
+ }
1016
+ function formatReplayRemainder(server, expectedSends) {
1017
+ const expected = expectedSends[0];
1018
+ const count = expectedSends.length;
1019
+ const requestText = count === 1 ? "request" : "requests";
1020
+ const expectedText = expected ? `${expected.method} ${JSON.stringify(expected.params ?? {})}` : "no remaining recorded recv";
1021
+ return `Replay ended for server '${server}' with ${count} recorded ${requestText} still unused; next expected recv ${expectedText}.`;
1022
+ }
1023
+
1024
+ // node_modules/.pnpm/mcporter@0.13.0/node_modules/mcporter/dist/chrome-devtools-compat.js
1025
+ import fs3 from "node:fs";
1026
+ import os from "node:os";
1027
+ import path2 from "node:path";
1028
+ import { fileURLToPath, pathToFileURL } from "node:url";
1029
+
1030
+ // node_modules/.pnpm/mcporter@0.13.0/node_modules/mcporter/dist/chrome-devtools-auto-connect-patch.js
1031
+ import fs2 from "node:fs";
1032
+ import path from "node:path";
1033
+ var MARKER = "MCPORTER_DEVTOOLS_TIMEOUT_PATCH";
1034
+ var HELPER = `// ${MARKER}
1035
+ const MCPORTER_DEVTOOLS_DETECTION_TIMEOUT = 1_000;
1036
+ async function mcporterWithTimeout(promise, fallback) {
1037
+ let timer;
1038
+ try {
1039
+ return await Promise.race([
1040
+ promise,
1041
+ new Promise(resolve => {
1042
+ timer = setTimeout(resolve, MCPORTER_DEVTOOLS_DETECTION_TIMEOUT, fallback);
1043
+ timer.unref?.();
1044
+ }),
1045
+ ]);
1046
+ }
1047
+ finally {
1048
+ if (timer) {
1049
+ clearTimeout(timer);
1050
+ }
1051
+ }
1052
+ }
1053
+ `;
1054
+ var DETECTION_BLOCK = `if (await page.hasDevTools()) {
1055
+ mcpPage.devToolsPage = await page.openDevTools();
1056
+ }`;
1057
+ var PATCHED_DETECTION_BLOCK = `if (await mcporterWithTimeout(page.hasDevTools(), false)) {
1058
+ mcpPage.devToolsPage = await mcporterWithTimeout(page.openDevTools(), undefined);
1059
+ }`;
1060
+ patchChromeDevtoolsMcp();
1061
+ function patchChromeDevtoolsMcp(mainPath = process.argv[1]) {
1062
+ patchChromeDevtoolsMcpWithDependencies(mainPath, fs2, path, MARKER, HELPER, DETECTION_BLOCK, PATCHED_DETECTION_BLOCK);
1063
+ }
1064
+ function renderChromeDevtoolsAutoConnectPatchSource() {
1065
+ return `import fs from 'node:fs';
1066
+ import path from 'node:path';
1067
+
1068
+ const patchChromeDevtoolsMcp = ${patchChromeDevtoolsMcpWithDependencies.toString()};
1069
+
1070
+ patchChromeDevtoolsMcp(
1071
+ process.argv[1],
1072
+ fs,
1073
+ path,
1074
+ ${JSON.stringify(MARKER)},
1075
+ ${JSON.stringify(HELPER)},
1076
+ ${JSON.stringify(DETECTION_BLOCK)},
1077
+ ${JSON.stringify(PATCHED_DETECTION_BLOCK)}
1078
+ );
1079
+ `;
1080
+ }
1081
+ function patchChromeDevtoolsMcpWithDependencies(mainPath, fsApi, pathApi, marker, helper, detectionBlock, patchedDetectionBlock) {
1082
+ if (!mainPath || !mainPath.includes("chrome-devtools-mcp")) {
1083
+ return;
1084
+ }
1085
+ let resolvedMainPath;
1086
+ try {
1087
+ resolvedMainPath = fsApi.realpathSync(mainPath);
1088
+ } catch {
1089
+ return;
1090
+ }
1091
+ if (!resolvedMainPath.endsWith(pathApi.join("bin", "chrome-devtools-mcp.js"))) {
1092
+ return;
1093
+ }
1094
+ const contextPath = pathApi.resolve(pathApi.dirname(resolvedMainPath), "..", "McpContext.js");
1095
+ let source;
1096
+ try {
1097
+ source = fsApi.readFileSync(contextPath, "utf8");
1098
+ } catch {
1099
+ return;
1100
+ }
1101
+ if (source.includes(marker)) {
1102
+ return;
1103
+ }
1104
+ if (!source.includes(detectionBlock)) {
1105
+ return;
1106
+ }
1107
+ const withHelper = source.replace("const NAVIGATION_TIMEOUT = 10_000;\n", `const NAVIGATION_TIMEOUT = 10_000;
1108
+ ${helper}`);
1109
+ const patched = withHelper.replace(detectionBlock, patchedDetectionBlock);
1110
+ try {
1111
+ fsApi.writeFileSync(contextPath, patched);
1112
+ } catch {
1113
+ return;
1114
+ }
1115
+ }
1116
+
1117
+ // node_modules/.pnpm/mcporter@0.13.0/node_modules/mcporter/dist/chrome-devtools-compat.js
1118
+ var AUTO_CONNECT_FLAGS = /* @__PURE__ */ new Set(["--autoConnect", "--auto-connect"]);
1119
+ var FALLBACK_PATCH_FILENAME = "mcporter-chrome-devtools-auto-connect-patch.js";
1120
+ function applyChromeDevtoolsCompat(env, command, args) {
1121
+ if (!shouldApplyChromeDevtoolsCompat(command, args, env)) {
1122
+ return { env, applied: false };
1123
+ }
1124
+ const patchPath = resolveChromeDevtoolsCompatPatchPath();
1125
+ if (!patchPath) {
1126
+ return { env, applied: false };
1127
+ }
1128
+ const importFlag = `--import=${pathToFileURL(patchPath).href}`;
1129
+ const existingOptions = env.NODE_OPTIONS?.trim();
1130
+ if (existingOptions?.includes(importFlag)) {
1131
+ return { env, applied: true, patchPath };
1132
+ }
1133
+ return {
1134
+ env: {
1135
+ ...env,
1136
+ NODE_OPTIONS: existingOptions ? `${existingOptions} ${importFlag}` : importFlag
1137
+ },
1138
+ applied: true,
1139
+ patchPath
1140
+ };
1141
+ }
1142
+ function shouldApplyChromeDevtoolsCompat(command, args, env = process.env) {
1143
+ if (env.MCPORTER_DISABLE_CHROME_DEVTOOLS_COMPAT === "1") {
1144
+ return false;
1145
+ }
1146
+ const tokens = [command, ...args];
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");
1151
+ }
1152
+ function resolveChromeDevtoolsCompatPatchPath(candidates = defaultChromeDevtoolsPatchCandidates(), fallbackDir = os.tmpdir()) {
1153
+ const existing = candidates.find((candidate) => fs3.existsSync(candidate));
1154
+ if (existing) {
1155
+ return existing;
1156
+ }
1157
+ return writeFallbackPatch(fallbackDir);
1158
+ }
1159
+ function defaultChromeDevtoolsPatchCandidates() {
1160
+ const here = path2.dirname(fileURLToPath(import.meta.url));
1161
+ return [
1162
+ path2.join(here, "chrome-devtools-auto-connect-patch.js"),
1163
+ path2.resolve(here, "..", "dist", "chrome-devtools-auto-connect-patch.js")
1164
+ ];
1165
+ }
1166
+ function writeFallbackPatch(fallbackDir) {
1167
+ const patchPath = path2.join(fallbackDir, FALLBACK_PATCH_FILENAME);
1168
+ try {
1169
+ fs3.writeFileSync(patchPath, renderChromeDevtoolsAutoConnectPatchSource(), { mode: 384 });
1170
+ return patchPath;
1171
+ } catch {
1172
+ return void 0;
1173
+ }
1174
+ }
1175
+
1176
+ // node_modules/.pnpm/mcporter@0.13.0/node_modules/mcporter/dist/chrome-devtools-relay.js
1177
+ import fs4 from "node:fs";
1178
+ import os2 from "node:os";
1179
+ import path3 from "node:path";
1180
+ var AUTO_CONNECT_FLAGS2 = /* @__PURE__ */ new Set(["--autoConnect", "--auto-connect"]);
1181
+ var RELAY_PROBE_TIMEOUT_MS = 750;
1182
+ var DEFAULT_RELAY_URL = "http://127.0.0.1:18799";
1183
+ function isChromeDevtoolsToken2(token) {
1184
+ return token === "chrome-devtools-mcp" || token.startsWith("chrome-devtools-mcp@") || token.includes("/chrome-devtools-mcp");
1185
+ }
1186
+ function relayBaseUrl(env) {
1187
+ const raw = env.MCPORTER_CHROME_DEVTOOLS_RELAY_URL?.trim() || DEFAULT_RELAY_URL;
1188
+ let url;
1189
+ try {
1190
+ url = new URL(raw);
1191
+ } catch {
1192
+ return void 0;
1193
+ }
1194
+ if (url.protocol !== "http:" || !["127.0.0.1", "localhost", "[::1]", "::1"].includes(url.hostname)) {
1195
+ return void 0;
1196
+ }
1197
+ return url;
1198
+ }
1199
+ function defaultReadToken(env) {
1200
+ const stateDir = env.OPENCLAW_STATE_DIR?.trim() || path3.join(os2.homedir(), ".openclaw");
1201
+ const secretPath = path3.join(stateDir, "credentials", "browser-extension-relay.secret");
1202
+ let raw;
1203
+ try {
1204
+ raw = fs4.readFileSync(secretPath, "utf8");
1205
+ } catch {
1206
+ return void 0;
1207
+ }
1208
+ const token = raw.trim();
1209
+ return /^[0-9a-f]{64}$/.test(token) ? token : void 0;
1210
+ }
1211
+ async function defaultProbe(versionUrl, token) {
1212
+ const controller = new AbortController();
1213
+ const timer = setTimeout(() => controller.abort(), RELAY_PROBE_TIMEOUT_MS);
1214
+ timer.unref?.();
1215
+ try {
1216
+ const response = await fetch(versionUrl, {
1217
+ headers: { Authorization: `Bearer ${token}` },
1218
+ signal: controller.signal
1219
+ });
1220
+ return response.status === 200;
1221
+ } catch {
1222
+ return false;
1223
+ } finally {
1224
+ clearTimeout(timer);
1225
+ }
1226
+ }
1227
+ function shouldAttemptChromeDevtoolsRelay(command, args, env = process.env) {
1228
+ if (env.MCPORTER_DISABLE_CHROME_DEVTOOLS_RELAY === "1") {
1229
+ return false;
1230
+ }
1231
+ const tokens = [command, ...args];
1232
+ return tokens.some(isChromeDevtoolsToken2) && args.some((arg) => AUTO_CONNECT_FLAGS2.has(arg));
1233
+ }
1234
+ async function rewriteChromeDevtoolsArgsForRelay(command, args, env = process.env, options = {}) {
1235
+ if (!shouldAttemptChromeDevtoolsRelay(command, args, env)) {
1236
+ return { args, applied: false };
1237
+ }
1238
+ const base = relayBaseUrl(env);
1239
+ if (!base) {
1240
+ return { args, applied: false };
1241
+ }
1242
+ const token = (options.readToken ?? (() => defaultReadToken(env)))();
1243
+ if (!token) {
1244
+ return { args, applied: false };
1245
+ }
1246
+ const versionUrl = new URL("/json/version", base).toString();
1247
+ const alive = await (options.probe ?? defaultProbe)(versionUrl, token);
1248
+ if (!alive) {
1249
+ return { args, applied: false };
1250
+ }
1251
+ const wsEndpoint = `ws://${base.host}/cdp`;
1252
+ const rewritten = args.filter((arg) => !AUTO_CONNECT_FLAGS2.has(arg));
1253
+ rewritten.push("--wsEndpoint", wsEndpoint, "--wsHeaders", JSON.stringify({ Authorization: `Bearer ${token}` }));
1254
+ return { args: rewritten, applied: true, endpoint: wsEndpoint };
1255
+ }
1256
+
1257
+ // node_modules/.pnpm/mcporter@0.13.0/node_modules/mcporter/dist/runtime/cached-auth.js
1258
+ function hasAuthorizationHeader(headers) {
1259
+ return Boolean(headers && Object.keys(headers).some((key) => key.toLowerCase() === "authorization"));
1260
+ }
1261
+ async function applyCachedAuthIfAvailable(definition, logger, allowCachedAuth) {
1262
+ if (!allowCachedAuth && definition.auth !== "refreshable_bearer") {
1263
+ return definition;
1264
+ }
1265
+ if (definition.auth === "refreshable_bearer" && definition.command.kind === "stdio" && !definition.refresh?.accessTokenEnv) {
1266
+ throw new Error(`Server '${definition.name}' uses refreshable_bearer stdio auth but is missing refresh.accessTokenEnv.`);
1267
+ }
1268
+ if (definition.command.kind === "http" && hasAuthorizationHeader(definition.command.headers)) {
1269
+ return definition;
1270
+ }
1271
+ try {
1272
+ const cached = await readCachedAccessToken(definition, logger);
1273
+ if (!cached) {
1274
+ if (definition.auth === "refreshable_bearer") {
1275
+ throw new Error(`Server '${definition.name}' uses refreshable_bearer auth but has no cached access token.`);
1276
+ }
1277
+ return definition;
1278
+ }
1279
+ if (definition.command.kind === "stdio") {
1280
+ if (definition.auth !== "refreshable_bearer") {
1281
+ return definition;
1282
+ }
1283
+ const accessTokenEnv = definition.refresh?.accessTokenEnv;
1284
+ if (!accessTokenEnv) {
1285
+ throw new Error(`Server '${definition.name}' uses refreshable_bearer stdio auth but is missing refresh.accessTokenEnv.`);
1286
+ }
1287
+ logger.debug?.(`Using cached bearer access token for '${definition.name}' stdio env.`);
1288
+ return {
1289
+ ...definition,
1290
+ env: {
1291
+ ...definition.env,
1292
+ [accessTokenEnv]: cached
1293
+ }
1294
+ };
1295
+ }
1296
+ const existingHeaders = definition.command.headers ?? {};
1297
+ if (hasAuthorizationHeader(existingHeaders)) {
1298
+ return definition;
1299
+ }
1300
+ logger.debug?.(`Using cached OAuth access token for '${definition.name}' (non-interactive).`);
1301
+ return {
1302
+ ...definition,
1303
+ command: {
1304
+ ...definition.command,
1305
+ headers: {
1306
+ ...existingHeaders,
1307
+ Authorization: `Bearer ${cached}`
1308
+ }
1309
+ }
1310
+ };
1311
+ } catch (error) {
1312
+ if (definition.auth === "refreshable_bearer") {
1313
+ throw error;
1314
+ }
1315
+ logger.debug?.(`Failed to read cached OAuth token for '${definition.name}': ${error instanceof Error ? error.message : String(error)}`);
1316
+ return definition;
1317
+ }
1318
+ }
1319
+
1320
+ // node_modules/.pnpm/mcporter@0.13.0/node_modules/mcporter/dist/oauth.js
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
1706
+ function materializeHeaders(headers, serverName) {
1707
+ if (!headers) {
1708
+ return void 0;
1709
+ }
1710
+ const resolved = {};
1711
+ for (const [key, value] of Object.entries(headers)) {
1712
+ try {
1713
+ resolved[key] = resolveEnvPlaceholders(value);
1714
+ } catch (error) {
1715
+ const message = error instanceof Error ? error.message : String(error);
1716
+ throw new Error(`Failed to resolve header '${key}' for server '${serverName}': ${message}`, { cause: error });
1717
+ }
1718
+ }
1719
+ return resolved;
1720
+ }
1721
+
1722
+ // node_modules/.pnpm/mcporter@0.13.0/node_modules/mcporter/dist/runtime/node-http-fetch.js
1723
+ import http2 from "node:http";
1724
+ import https from "node:https";
1725
+ import { Buffer as Buffer2 } from "node:buffer";
1726
+ import { Readable } from "node:stream";
1727
+ var MAX_REDIRECTS = 20;
1728
+ var REDIRECT_STATUSES = /* @__PURE__ */ new Set([301, 302, 303, 307, 308]);
1729
+ var NULL_BODY_STATUSES = /* @__PURE__ */ new Set([204, 205, 304]);
1730
+ var nodeHttp1Fetch = async (input, init = {}) => {
1731
+ return nodeHttp1FetchWithRedirects(input, init, 0);
1732
+ };
1733
+ function createSseIsolatedFetch(defaultFetch) {
1734
+ return (input, init = {}) => {
1735
+ const method = (init.method ?? "GET").toUpperCase();
1736
+ const acceptsSse = new Headers(init.headers).get("accept")?.toLowerCase().includes("text/event-stream") ?? false;
1737
+ if (method === "GET" && acceptsSse) {
1738
+ return nodeHttp1Fetch(input, init);
1739
+ }
1740
+ return defaultFetch(input, init);
1741
+ };
1742
+ }
1743
+ var sseIsolatedFetch = createSseIsolatedFetch((input, init) => fetch(input, init));
1744
+ async function nodeHttp1FetchWithRedirects(input, init, redirectCount) {
1745
+ const url = input instanceof URL ? input : new URL(input);
1746
+ if (url.protocol !== "http:" && url.protocol !== "https:") {
1747
+ throw new TypeError(`node-http1 fetch only supports http: and https: URLs, got ${url.protocol}`);
1748
+ }
1749
+ if (init.signal?.aborted) {
1750
+ throw new DOMException("The operation was aborted.", "AbortError");
1751
+ }
1752
+ const headers = normalizeRequestHeaders(init.headers);
1753
+ const body = await materializeRequestBody(init.body);
1754
+ if (body !== void 0 && !hasHeader(headers, "content-length") && !hasHeader(headers, "transfer-encoding")) {
1755
+ headers["content-length"] = String(Buffer2.byteLength(body));
1756
+ }
1757
+ return new Promise((resolve, reject) => {
1758
+ const client = url.protocol === "https:" ? https : http2;
1759
+ const request = client.request(url, {
1760
+ method: init.method ?? "GET",
1761
+ headers
1762
+ }, (response) => {
1763
+ const responseHeaders = new Headers();
1764
+ for (const [key, value] of Object.entries(response.headers)) {
1765
+ if (Array.isArray(value)) {
1766
+ for (const item of value) {
1767
+ responseHeaders.append(key, item);
1768
+ }
1769
+ } else if (value !== void 0) {
1770
+ responseHeaders.set(key, String(value));
1771
+ }
1772
+ }
1773
+ const status = response.statusCode ?? 502;
1774
+ const location = responseHeaders.get("location");
1775
+ if (REDIRECT_STATUSES.has(status) && location && init.redirect !== "manual") {
1776
+ response.resume();
1777
+ if (init.redirect === "error") {
1778
+ reject(new TypeError(`Redirect encountered for ${url.href}`));
1779
+ return;
1780
+ }
1781
+ if (redirectCount >= MAX_REDIRECTS) {
1782
+ reject(new TypeError(`Too many redirects while fetching ${url.href}`));
1783
+ return;
1784
+ }
1785
+ let nextUrl;
1786
+ try {
1787
+ nextUrl = new URL(location, url);
1788
+ } catch (error) {
1789
+ reject(error);
1790
+ return;
1791
+ }
1792
+ resolve(nodeHttp1FetchWithRedirects(nextUrl, buildRedirectInit(init, status, url, nextUrl), redirectCount + 1));
1793
+ return;
1794
+ }
1795
+ if (NULL_BODY_STATUSES.has(status)) {
1796
+ response.resume();
1797
+ }
1798
+ resolve(new Response(NULL_BODY_STATUSES.has(status) ? null : Readable.toWeb(response), {
1799
+ status,
1800
+ statusText: response.statusMessage,
1801
+ headers: responseHeaders
1802
+ }));
1803
+ });
1804
+ const abort = () => {
1805
+ request.destroy(new DOMException("The operation was aborted.", "AbortError"));
1806
+ };
1807
+ init.signal?.addEventListener("abort", abort, { once: true });
1808
+ request.once("close", () => init.signal?.removeEventListener("abort", abort));
1809
+ request.once("error", reject);
1810
+ if (body !== void 0) {
1811
+ request.write(body);
1812
+ }
1813
+ request.end();
1814
+ });
1815
+ }
1816
+ function buildRedirectInit(init, status, currentUrl, nextUrl) {
1817
+ const method = (init.method ?? "GET").toUpperCase();
1818
+ const headers = new Headers(init.headers);
1819
+ if (currentUrl.origin !== nextUrl.origin) {
1820
+ stripCrossOriginRedirectHeaders(headers);
1821
+ }
1822
+ if ((status === 301 || status === 302 || status === 303) && method !== "GET" && method !== "HEAD") {
1823
+ headers.delete("content-length");
1824
+ headers.delete("content-type");
1825
+ return {
1826
+ ...init,
1827
+ method: "GET",
1828
+ body: null,
1829
+ headers
1830
+ };
1831
+ }
1832
+ return {
1833
+ ...init,
1834
+ headers
1835
+ };
1836
+ }
1837
+ function stripCrossOriginRedirectHeaders(headers) {
1838
+ headers.delete("authorization");
1839
+ headers.delete("cookie");
1840
+ headers.delete("proxy-authorization");
1841
+ }
1842
+ function normalizeRequestHeaders(headers) {
1843
+ const normalized = {};
1844
+ if (!headers) {
1845
+ return normalized;
1846
+ }
1847
+ new Headers(headers).forEach((value, key) => {
1848
+ normalized[key] = value;
1849
+ });
1850
+ return normalized;
1851
+ }
1852
+ function hasHeader(headers, name) {
1853
+ const lower = name.toLowerCase();
1854
+ return Object.keys(headers).some((key) => key.toLowerCase() === lower);
1855
+ }
1856
+ async function materializeRequestBody(body) {
1857
+ if (body == null) {
1858
+ return void 0;
1859
+ }
1860
+ if (typeof body === "string") {
1861
+ return body;
1862
+ }
1863
+ if (body instanceof URLSearchParams) {
1864
+ return body.toString();
1865
+ }
1866
+ if (body instanceof Blob) {
1867
+ return Buffer2.from(await body.arrayBuffer());
1868
+ }
1869
+ if (body instanceof ArrayBuffer) {
1870
+ return Buffer2.from(body);
1871
+ }
1872
+ if (ArrayBuffer.isView(body)) {
1873
+ return Buffer2.from(body.buffer, body.byteOffset, body.byteLength);
1874
+ }
1875
+ throw new TypeError("node-http1 fetch does not support streaming request bodies.");
1876
+ }
1877
+
1878
+ // node_modules/.pnpm/mcporter@0.13.0/node_modules/mcporter/dist/runtime/http-transport.js
1879
+ function extractTransportStatusCode(error) {
1880
+ if (!error || typeof error !== "object")
1881
+ return void 0;
1882
+ const record = error;
1883
+ for (const candidate of [record.code, record.status, record.statusCode]) {
1884
+ if (typeof candidate === "number")
1885
+ return candidate;
1886
+ if (typeof candidate === "string") {
1887
+ const parsed = Number.parseInt(candidate, 10);
1888
+ if (Number.isFinite(parsed))
1889
+ return parsed;
1890
+ }
1891
+ }
1892
+ return void 0;
1893
+ }
1894
+ function isLegacySseTransportMismatch(error) {
1895
+ if (error instanceof SdkHttpError)
1896
+ return error.status === 404 || error.status === 405;
1897
+ const directStatusCode = extractTransportStatusCode(error);
1898
+ if (directStatusCode === 404 || directStatusCode === 405)
1899
+ return true;
1900
+ const issue = analyzeConnectionError(error);
1901
+ return issue.kind === "http" && (issue.statusCode === 404 || issue.statusCode === 405);
1902
+ }
1903
+ function removeAuthorizationHeader(headers) {
1904
+ if (!headers)
1905
+ return void 0;
1906
+ for (const key of Object.keys(headers)) {
1907
+ if (key.toLowerCase() === "authorization")
1908
+ delete headers[key];
1909
+ }
1910
+ return Object.keys(headers).length > 0 ? headers : void 0;
1911
+ }
1912
+ var NODE_HTTP1_FETCH_HOSTS = /* @__PURE__ */ new Set(["api.sunsama.com"]);
1913
+ function resolveHttpFetchOverride(definition) {
1914
+ if (definition.command.kind !== "http" || definition.httpFetch === "default")
1915
+ return void 0;
1916
+ if (definition.httpFetch === "node-http1")
1917
+ return nodeHttp1Fetch;
1918
+ if (NODE_HTTP1_FETCH_HOSTS.has(definition.command.url.hostname.toLowerCase()))
1919
+ return nodeHttp1Fetch;
1920
+ if ("bun" in process.versions)
1921
+ return void 0;
1922
+ return sseIsolatedFetch;
1923
+ }
1924
+ function createHttpTransportOptions(definition, oauthSession, shouldEstablishOAuth) {
1925
+ const command = definition.command;
1926
+ if (command.kind !== "http")
1927
+ throw new Error(`Server '${definition.name}' is not configured for HTTP transport.`);
1928
+ const resolvedHeaders = materializeHeaders(command.headers, definition.name);
1929
+ const effectiveHeaders = shouldEstablishOAuth ? removeAuthorizationHeader(resolvedHeaders) : resolvedHeaders;
1930
+ const trackedFetch = trackStandaloneSseFetch(resolveHttpFetchOverride(definition));
1931
+ return {
1932
+ requestInit: effectiveHeaders ? { headers: effectiveHeaders } : void 0,
1933
+ authProvider: oauthSession?.provider,
1934
+ fetch: trackedFetch.fetch,
1935
+ standaloneSseStarted: trackedFetch.started
1936
+ };
1937
+ }
1938
+ function trackStandaloneSseFetch(fetchOverride) {
1939
+ let markStarted;
1940
+ const started = new Promise((resolve) => {
1941
+ markStarted = resolve;
1942
+ });
1943
+ const baseFetch = fetchOverride ?? ((input, init) => fetch(input, init));
1944
+ return {
1945
+ started,
1946
+ fetch: async (input, init = {}) => {
1947
+ const isStandaloneSse = (init.method ?? "GET").toUpperCase() === "GET" && (new Headers(init.headers).get("accept")?.toLowerCase().includes("text/event-stream") ?? false);
1948
+ try {
1949
+ return await baseFetch(input, init);
1950
+ } finally {
1951
+ if (isStandaloneSse)
1952
+ markStarted();
1953
+ }
1954
+ }
1955
+ };
1956
+ }
1957
+ async function closeOAuthSession(oauthSession) {
1958
+ await oauthSession?.close().catch(() => {
1959
+ });
1960
+ }
1961
+ function shouldAbortSseFallback(error) {
1962
+ if (isPostAuthConnectError(error))
1963
+ return !isLegacySseTransportMismatch(error);
1964
+ return isOAuthFlowError(error) || error instanceof OAuthTimeoutError;
1965
+ }
1966
+ function isEraNegotiationFailure(error) {
1967
+ return !!error && typeof error === "object" && "code" in error && error.code === SdkErrorCode.EraNegotiationFailed;
1968
+ }
1969
+ function maybePromoteHttpDefinition(definition, logger, options) {
1970
+ if (options.maxOAuthAttempts === 0 || options.disableOAuth === true)
1971
+ return void 0;
1972
+ return maybeEnableOAuth(definition, logger);
1973
+ }
1974
+ async function connectHttpTransport(client, transport, oauthSession, logger, connectOptions) {
1975
+ try {
1976
+ return await connectWithAuth(client, transport, oauthSession, logger, connectOptions);
1977
+ } catch (error) {
1978
+ if (!connectOptions.signal?.aborted) {
1979
+ await closeTransportAndWait(logger, transport).catch(() => {
1980
+ });
1981
+ }
1982
+ throw error;
1983
+ }
1984
+ }
1985
+ async function createHttpClientContext(definition, logger, options, wrapRecordTransport2, clientFactory) {
1986
+ let activeDefinition = definition;
1987
+ while (true) {
1988
+ const attempt = await attemptHttpClientContext(clientFactory.create(activeDefinition), activeDefinition, logger, options, wrapRecordTransport2, clientFactory);
1989
+ if (!attempt.nextDefinition)
1990
+ return attempt.context;
1991
+ activeDefinition = attempt.nextDefinition;
1992
+ options.onDefinitionPromoted?.(activeDefinition);
1993
+ }
1994
+ }
1995
+ async function attemptHttpClientContext(client, activeDefinition, logger, options, wrapRecordTransport2, clientFactory) {
1996
+ const command = activeDefinition.command;
1997
+ if (command.kind !== "http")
1998
+ throw new Error(`Server '${activeDefinition.name}' is not configured for HTTP transport.`);
1999
+ let oauthSession;
2000
+ const shouldEstablishOAuth = activeDefinition.auth === "oauth" && options.maxOAuthAttempts !== 0 && options.disableOAuth !== true;
2001
+ if (shouldEstablishOAuth)
2002
+ oauthSession = await createOAuthSession(activeDefinition, logger, options.oauthSessionOptions);
2003
+ const transportOptions = createHttpTransportOptions(activeDefinition, oauthSession, shouldEstablishOAuth);
2004
+ try {
2005
+ return {
2006
+ context: await connectPrimaryHttpTransport(client, activeDefinition, command, transportOptions, oauthSession, logger, options, wrapRecordTransport2)
2007
+ };
2008
+ } catch (primaryError) {
2009
+ if (options.signal?.aborted || isEraNegotiationFailure(primaryError)) {
2010
+ await closeOAuthSession(oauthSession);
2011
+ throw primaryError;
2012
+ }
2013
+ if (shouldAbortSseFallback(primaryError)) {
2014
+ await closeOAuthSession(oauthSession);
2015
+ throw primaryError;
2016
+ }
2017
+ if (isUnauthorizedError(primaryError)) {
2018
+ await closeOAuthSession(oauthSession);
2019
+ const promoted = maybePromoteHttpDefinition(activeDefinition, logger, options);
2020
+ if (promoted)
2021
+ return { nextDefinition: promoted };
2022
+ if (activeDefinition.auth)
2023
+ throw primaryError;
2024
+ oauthSession = void 0;
2025
+ }
2026
+ if (primaryError instanceof Error) {
2027
+ logger.info(`Falling back to SSE transport for '${activeDefinition.name}': ${primaryError.message}`);
2028
+ }
2029
+ return {
2030
+ context: await connectSseFallbackTransport(clientFactory.createLegacy(activeDefinition), activeDefinition, command, transportOptions, oauthSession, logger, options, wrapRecordTransport2, clientFactory)
2031
+ };
2032
+ }
2033
+ }
2034
+ async function connectPrimaryHttpTransport(client, definition, command, transportOptions, oauthSession, logger, options, wrapRecordTransport2) {
2035
+ const createStreamableTransport = () => wrapRecordTransport2(new StreamableHTTPClientTransport(command.url, transportOptions), definition, options);
2036
+ const transport = await connectHttpTransport(client, createStreamableTransport(), oauthSession, logger, {
2037
+ serverName: definition.name,
2038
+ serverUrl: command.url,
2039
+ maxAttempts: options.maxOAuthAttempts,
2040
+ oauthTimeoutMs: options.oauthTimeoutMs,
2041
+ signal: options.signal,
2042
+ recreateTransport: async () => createStreamableTransport()
2043
+ });
2044
+ if (typeof client.getProtocolEra === "function" && client.getProtocolEra() === "legacy") {
2045
+ await transportOptions.standaloneSseStarted;
2046
+ }
2047
+ return { client, transport, definition, oauthSession };
2048
+ }
2049
+ async function connectSseFallbackTransport(client, definition, command, transportOptions, oauthSession, logger, options, wrapRecordTransport2, clientFactory) {
2050
+ try {
2051
+ const transport = await connectHttpTransport(client, wrapRecordTransport2(new SSEClientTransport(command.url, transportOptions), definition, options), oauthSession, logger, {
2052
+ serverName: definition.name,
2053
+ serverUrl: command.url,
2054
+ maxAttempts: options.maxOAuthAttempts,
2055
+ oauthTimeoutMs: options.oauthTimeoutMs,
2056
+ signal: options.signal
2057
+ });
2058
+ return { client, transport, definition, oauthSession };
2059
+ } catch (sseError) {
2060
+ await closeOAuthSession(oauthSession);
2061
+ if (sseError instanceof OAuthTimeoutError)
2062
+ throw sseError;
2063
+ if (isUnauthorizedError(sseError)) {
2064
+ const promoted = maybePromoteHttpDefinition(definition, logger, options);
2065
+ if (promoted) {
2066
+ options.onDefinitionPromoted?.(promoted);
2067
+ return createHttpClientContext(promoted, logger, options, wrapRecordTransport2, clientFactory);
2068
+ }
2069
+ if (definition.auth)
2070
+ throw sseError;
2071
+ }
2072
+ throw sseError;
2073
+ }
2074
+ }
2075
+
2076
+ // node_modules/.pnpm/@modelcontextprotocol+client@2.0.0/node_modules/@modelcontextprotocol/client/dist/stdio.mjs
2077
+ var import_cross_spawn = __toESM(require_cross_spawn(), 1);
2078
+ import process2 from "node:process";
2079
+ import { PassThrough } from "node:stream";
2080
+ var DEFAULT_INHERITED_ENV_VARS = process2.platform === "win32" ? [
2081
+ "APPDATA",
2082
+ "HOMEDRIVE",
2083
+ "HOMEPATH",
2084
+ "LOCALAPPDATA",
2085
+ "PATH",
2086
+ "PROCESSOR_ARCHITECTURE",
2087
+ "SYSTEMDRIVE",
2088
+ "SYSTEMROOT",
2089
+ "TEMP",
2090
+ "USERNAME",
2091
+ "USERPROFILE",
2092
+ "PROGRAMFILES"
2093
+ ] : [
2094
+ "HOME",
2095
+ "LOGNAME",
2096
+ "PATH",
2097
+ "SHELL",
2098
+ "TERM",
2099
+ "USER"
2100
+ ];
2101
+ function getDefaultEnvironment() {
2102
+ const env = {};
2103
+ for (const key of DEFAULT_INHERITED_ENV_VARS) {
2104
+ const value = process2.env[key];
2105
+ if (value === void 0) continue;
2106
+ if (value.startsWith("()")) continue;
2107
+ env[key] = value;
2108
+ }
2109
+ return env;
2110
+ }
2111
+ var StdioClientTransport = class {
2112
+ _process;
2113
+ _readBuffer;
2114
+ _serverParams;
2115
+ _stderrStream = null;
2116
+ onclose;
2117
+ onerror;
2118
+ onmessage;
2119
+ constructor(server) {
2120
+ this._serverParams = server;
2121
+ this._readBuffer = new ReadBuffer({ maxBufferSize: server.maxBufferSize });
2122
+ if (server.stderr === "pipe" || server.stderr === "overlapped") this._stderrStream = new PassThrough();
2123
+ }
2124
+ /**
2125
+ * Starts the server process and prepares to communicate with it.
2126
+ */
2127
+ async start() {
2128
+ if (this._process) throw new Error("StdioClientTransport already started! If using Client class, note that connect() calls start() automatically.");
2129
+ return new Promise((resolve, reject) => {
2130
+ this._process = (0, import_cross_spawn.default)(this._serverParams.command, this._serverParams.args ?? [], {
2131
+ env: {
2132
+ ...getDefaultEnvironment(),
2133
+ ...this._serverParams.env
2134
+ },
2135
+ stdio: [
2136
+ "pipe",
2137
+ "pipe",
2138
+ this._serverParams.stderr ?? "inherit"
2139
+ ],
2140
+ shell: false,
2141
+ windowsHide: process2.platform === "win32",
2142
+ cwd: this._serverParams.cwd
2143
+ });
2144
+ this._process.on("error", (error) => {
2145
+ reject(error);
2146
+ this.onerror?.(error);
2147
+ });
2148
+ this._process.on("spawn", () => {
2149
+ resolve();
2150
+ });
2151
+ this._process.on("close", (_code) => {
2152
+ this._process = void 0;
2153
+ this.onclose?.();
2154
+ });
2155
+ this._process.stdin?.on("error", (error) => {
2156
+ this.onerror?.(error);
2157
+ });
2158
+ this._process.stdout?.on("data", (chunk) => {
2159
+ try {
2160
+ this._readBuffer.append(chunk);
2161
+ this.processReadBuffer();
2162
+ } catch (error) {
2163
+ this.onerror?.(error);
2164
+ this.close().catch(() => {
2165
+ });
2166
+ }
2167
+ });
2168
+ this._process.stdout?.on("error", (error) => {
2169
+ this.onerror?.(error);
2170
+ });
2171
+ if (this._stderrStream && this._process.stderr) this._process.stderr.pipe(this._stderrStream);
2172
+ });
2173
+ }
2174
+ /**
2175
+ * The `stderr` stream of the child process, if {@linkcode StdioServerParameters.stderr} was set to `"pipe"` or `"overlapped"`.
2176
+ *
2177
+ * If `stderr` piping was requested, a `PassThrough` stream is returned _immediately_, allowing callers to
2178
+ * attach listeners before the `start` method is invoked. This prevents loss of any early
2179
+ * error output emitted by the child process.
2180
+ */
2181
+ get stderr() {
2182
+ if (this._stderrStream) return this._stderrStream;
2183
+ return this._process?.stderr ?? null;
2184
+ }
2185
+ /**
2186
+ * The child process pid spawned by this transport.
2187
+ *
2188
+ * This is only available after the transport has been started.
2189
+ */
2190
+ get pid() {
2191
+ return this._process?.pid ?? null;
2192
+ }
2193
+ processReadBuffer() {
2194
+ while (true) try {
2195
+ const message = this._readBuffer.readMessage();
2196
+ if (message === null) break;
2197
+ this.onmessage?.(message);
2198
+ } catch (error) {
2199
+ this.onerror?.(error);
2200
+ }
2201
+ }
2202
+ /**
2203
+ * Reap a disposable probe sibling (see the version-negotiation sibling
2204
+ * flow): signal-first teardown awaiting process `exit` — never the `close`
2205
+ * event, so a helper process holding the child's stdio pipes can never
2206
+ * block disposal. Not part of the public transport lifecycle.
2207
+ *
2208
+ * @internal
2209
+ */
2210
+ async _dispose() {
2211
+ const proc = this._process;
2212
+ this._process = void 0;
2213
+ if (proc && proc.exitCode === null && proc.signalCode === null) {
2214
+ const exited = new Promise((resolve) => proc.once("exit", () => resolve()));
2215
+ try {
2216
+ proc.stdin?.end();
2217
+ } catch {
2218
+ }
2219
+ try {
2220
+ proc.kill("SIGTERM");
2221
+ } catch {
2222
+ }
2223
+ await Promise.race([exited, new Promise((resolve) => setTimeout(resolve, 1e3).unref())]);
2224
+ if (proc.exitCode === null && proc.signalCode === null) try {
2225
+ proc.kill("SIGKILL");
2226
+ } catch {
2227
+ }
2228
+ await exited;
2229
+ }
2230
+ try {
2231
+ proc?.stdout?.destroy();
2232
+ } catch {
2233
+ }
2234
+ try {
2235
+ proc?.stdin?.destroy();
2236
+ } catch {
2237
+ }
2238
+ try {
2239
+ proc?.stderr?.destroy();
2240
+ } catch {
2241
+ }
2242
+ this._readBuffer.clear();
2243
+ }
2244
+ async close() {
2245
+ if (this._process) {
2246
+ const processToClose = this._process;
2247
+ this._process = void 0;
2248
+ const closePromise = new Promise((resolve) => {
2249
+ processToClose.once("close", () => {
2250
+ resolve();
2251
+ });
2252
+ });
2253
+ try {
2254
+ processToClose.stdin?.end();
2255
+ } catch {
2256
+ }
2257
+ await Promise.race([closePromise, new Promise((resolve) => setTimeout(resolve, 2e3).unref())]);
2258
+ if (processToClose.exitCode === null) {
2259
+ try {
2260
+ processToClose.kill("SIGTERM");
2261
+ } catch {
2262
+ }
2263
+ await Promise.race([closePromise, new Promise((resolve) => setTimeout(resolve, 2e3).unref())]);
2264
+ }
2265
+ if (processToClose.exitCode === null) try {
2266
+ processToClose.kill("SIGKILL");
2267
+ } catch {
2268
+ }
2269
+ }
2270
+ this._readBuffer.clear();
2271
+ }
2272
+ send(message) {
2273
+ return new Promise((resolve) => {
2274
+ if (!this._process?.stdin) throw new SdkError(SdkErrorCode.NotConnected, "Not connected");
2275
+ const json = serializeMessage(message);
2276
+ if (this._process.stdin.write(json)) resolve();
2277
+ else this._process.stdin.once("drain", resolve);
2278
+ });
2279
+ }
2280
+ };
2281
+
2282
+ // node_modules/.pnpm/mcporter@0.13.0/node_modules/mcporter/dist/runtime/stdio-transport.js
2283
+ var McporterStdioTransport = class extends StdioClientTransport {
2284
+ meta;
2285
+ closing = false;
2286
+ closeDelegate;
2287
+ messageDelegate;
2288
+ closeInterceptor = () => {
2289
+ this.meta.code = this.closing ? 0 : 1;
2290
+ flushStdioLogs(this.meta);
2291
+ this.closeDelegate?.();
2292
+ };
2293
+ messageInterceptor = (message) => {
2294
+ if (STDIO_TRACE_ENABLED)
2295
+ this.meta.stdoutChunks?.push(JSON.stringify(message));
2296
+ this.messageDelegate?.(message);
2297
+ };
2298
+ constructor(parameters) {
2299
+ super({ ...parameters, stderr: "pipe" });
2300
+ this.meta = {
2301
+ stderrChunks: [],
2302
+ stdoutChunks: STDIO_TRACE_ENABLED ? [] : void 0,
2303
+ stdinChunks: STDIO_TRACE_ENABLED ? [] : void 0,
2304
+ command: parameters.command,
2305
+ code: null,
2306
+ listeners: []
2307
+ };
2308
+ const stderr = this.stderr;
2309
+ if (stderr) {
2310
+ stderr.setEncoding?.("utf8");
2311
+ const handleChunk = (chunk) => {
2312
+ this.meta.stderrChunks.push(Buffer.isBuffer(chunk) ? chunk.toString("utf8") : String(chunk));
2313
+ };
2314
+ stderr.on("data", handleChunk);
2315
+ stderr.on("error", ignoreStdioEmitterError);
2316
+ this.meta.listeners.push({ stream: stderr, event: "data", handler: handleChunk }, { stream: stderr, event: "error", handler: ignoreStdioEmitterError });
2317
+ }
2318
+ }
2319
+ async start() {
2320
+ if (STDIO_TRACE_ENABLED)
2321
+ console.log("[mcporter] STDIO trace: start() invoked for stdio transport.");
2322
+ this.installInterceptors();
2323
+ await super.start();
2324
+ if (STDIO_TRACE_ENABLED) {
2325
+ console.log(`[mcporter] STDIO trace: spawned ${this.meta.command ?? "stdio server"} (pid=${this.pid ?? "unknown"}).`);
2326
+ }
2327
+ }
2328
+ async send(message) {
2329
+ this.installInterceptors();
2330
+ if (STDIO_TRACE_ENABLED)
2331
+ this.meta.stdinChunks?.push(JSON.stringify(message));
2332
+ await super.send(message);
2333
+ }
2334
+ async close() {
2335
+ this.closing = true;
2336
+ this.installInterceptors();
2337
+ try {
2338
+ await super.close();
2339
+ } finally {
2340
+ this.meta.code ??= 0;
2341
+ flushStdioLogs(this.meta);
2342
+ }
2343
+ }
2344
+ installInterceptors() {
2345
+ if (this.onclose !== this.closeInterceptor) {
2346
+ this.closeDelegate = this.onclose;
2347
+ this.onclose = this.closeInterceptor;
2348
+ }
2349
+ if (this.onmessage !== this.messageInterceptor) {
2350
+ this.messageDelegate = this.onmessage;
2351
+ this.onmessage = this.messageInterceptor;
2352
+ }
2353
+ }
2354
+ };
2355
+
2356
+ // node_modules/.pnpm/mcporter@0.13.0/node_modules/mcporter/dist/runtime/transport.js
2357
+ function shouldUseModeForServer(definition, serverFilter) {
2358
+ return !serverFilter || serverFilter === definition.name;
2359
+ }
2360
+ var wrapRecordTransport = (transport, definition, options) => {
2361
+ const wrapped = options.recordPath && shouldUseModeForServer(definition, process.env.MCPORTER_RECORD_SERVER) ? new RecordTransport({
2362
+ inner: transport,
2363
+ recordPath: options.recordPath,
2364
+ server: definition.name
2365
+ }) : transport;
2366
+ options.onTransportCreated?.(wrapped);
2367
+ return wrapped;
2368
+ };
2369
+ var LIST_MAX_PAGES = 100;
2370
+ function resolveStdioProbeTimeoutMs() {
2371
+ const raw = process.env.MCPORTER_STDIO_PROBE_TIMEOUT_MS;
2372
+ if (!raw || !/^[1-9]\d*$/.test(raw))
2373
+ return DEFAULT_REQUEST_TIMEOUT_MSEC;
2374
+ const parsed = Number(raw);
2375
+ return Number.isFinite(parsed) ? parsed : DEFAULT_REQUEST_TIMEOUT_MSEC;
2376
+ }
2377
+ function resolveNegotiationMode(definition) {
2378
+ switch (definition.protocolVersion) {
2379
+ case "legacy":
2380
+ return "legacy";
2381
+ case "2026-07-28":
2382
+ return { pin: "2026-07-28" };
2383
+ default:
2384
+ return "auto";
2385
+ }
2386
+ }
2387
+ function shouldRetryStdioAsLegacy(error, definition) {
2388
+ return resolveNegotiationMode(definition) === "auto" && !!error && typeof error === "object" && "code" in error && error.code === SdkErrorCode.EraNegotiationFailed;
2389
+ }
2390
+ function createClient(definition, clientInfo, options = {}) {
2391
+ const mode = options.forceLegacy ? "legacy" : resolveNegotiationMode(definition);
2392
+ const clientOptions = {
2393
+ capabilities: { elicitation: { form: {}, url: {} } },
2394
+ listMaxPages: LIST_MAX_PAGES,
2395
+ versionNegotiation: {
2396
+ mode,
2397
+ ...options.stdio && mode !== "legacy" ? { probe: { timeoutMs: resolveStdioProbeTimeoutMs() } } : {}
2398
+ }
2399
+ };
2400
+ const client = new Client(clientInfo, clientOptions);
2401
+ if (options.elicitationHandler) {
2402
+ registerElicitationHandler(client, options.elicitationHandler, { server: definition.name });
2403
+ }
2404
+ return client;
2405
+ }
2406
+ async function createReplayClientContext(definition, replayPath, clientInfo, options) {
2407
+ const transport = new ReplayTransport({ recordPath: replayPath, server: definition.name });
2408
+ options.onTransportCreated?.(transport);
2409
+ const client = createClient(definition, clientInfo, {
2410
+ forceLegacy: transport.requiresLegacyNegotiation,
2411
+ elicitationHandler: options.elicitationHandler ?? createNonInteractiveElicitationResponder().handler
2412
+ });
2413
+ await client.connect(transport, { signal: options.signal });
2414
+ return { client, transport, definition, oauthSession: void 0 };
2415
+ }
2416
+ async function createStdioClientContext(client, definition, logger, options) {
2417
+ const resolvedEnvOverrides = definition.env && Object.keys(definition.env).length > 0 ? Object.fromEntries(Object.entries(definition.env).map(([key, raw]) => [key, resolveEnvValue(raw)]).filter(([, value]) => value !== "")) : void 0;
2418
+ const mergedEnv = resolvedEnvOverrides && Object.keys(resolvedEnvOverrides).length > 0 ? { ...process.env, ...resolvedEnvOverrides } : { ...process.env };
2419
+ const command = resolveCommandArgument(definition.command.command);
2420
+ const resolvedArgs = resolveCommandArguments(definition.command.args);
2421
+ const relay = await rewriteChromeDevtoolsArgsForRelay(command, resolvedArgs, mergedEnv);
2422
+ if (relay.applied) {
2423
+ logger.info(`Routing chrome-devtools-mcp through the OpenClaw extension relay at ${relay.endpoint} (no dialog).`);
2424
+ }
2425
+ const commandArgs = [...relay.args];
2426
+ const compat = applyChromeDevtoolsCompat(mergedEnv, command, commandArgs);
2427
+ if (compat.applied) {
2428
+ logger.info(`Injecting chrome-devtools-mcp --autoConnect compatibility patch from ${compat.patchPath}.`);
2429
+ }
2430
+ const rawTransport = new McporterStdioTransport({
2431
+ command,
2432
+ args: commandArgs,
2433
+ cwd: definition.command.cwd,
2434
+ env: compat.env
2435
+ });
2436
+ const transport = wrapRecordTransport(rawTransport, definition, options);
2437
+ try {
2438
+ await client.connect(transport, { signal: options.signal });
2439
+ } catch (error) {
2440
+ if (!options.signal?.aborted) {
2441
+ await closeTransportAndWait(logger, transport).catch(() => {
2442
+ });
2443
+ }
2444
+ throw error;
2445
+ }
2446
+ return { client, transport, definition, oauthSession: void 0 };
2447
+ }
2448
+ async function createClientContext(definition, logger, clientInfo, options = {}) {
2449
+ if (options.replayPath && shouldUseModeForServer(definition, process.env.MCPORTER_REPLAY_SERVER)) {
2450
+ return createReplayClientContext(definition, options.replayPath, clientInfo, options);
2451
+ }
2452
+ const activeDefinition = await applyCachedAuthIfAvailable(definition, logger, options.allowCachedAuth);
2453
+ return withEnvOverrides(activeDefinition.env, async () => {
2454
+ if (activeDefinition.command.kind === "stdio") {
2455
+ const stdioDefinition = activeDefinition;
2456
+ try {
2457
+ return await createStdioClientContext(createClient(stdioDefinition, clientInfo, { stdio: true, elicitationHandler: options.elicitationHandler }), stdioDefinition, logger, options);
2458
+ } catch (error) {
2459
+ if (!shouldRetryStdioAsLegacy(error, stdioDefinition))
2460
+ throw error;
2461
+ logger.info(`Retrying '${stdioDefinition.name}' in legacy mode after its stdio process exited during version negotiation.`);
2462
+ return createStdioClientContext(createClient(stdioDefinition, clientInfo, {
2463
+ stdio: true,
2464
+ forceLegacy: true,
2465
+ elicitationHandler: options.elicitationHandler
2466
+ }), stdioDefinition, logger, options);
2467
+ }
2468
+ }
2469
+ const httpClientFactory = {
2470
+ create: (httpDefinition) => createClient(httpDefinition, clientInfo, { elicitationHandler: options.elicitationHandler }),
2471
+ createLegacy: (httpDefinition) => createClient(httpDefinition, clientInfo, {
2472
+ forceLegacy: true,
2473
+ elicitationHandler: options.elicitationHandler
2474
+ })
2475
+ };
2476
+ return createHttpClientContext(activeDefinition, logger, options, wrapRecordTransport, httpClientFactory);
2477
+ });
2478
+ }
2479
+
2480
+ // node_modules/.pnpm/mcporter@0.13.0/node_modules/mcporter/dist/runtime/connection-cache.js
2481
+ var RuntimeConnectionCache = class {
2482
+ definitions;
2483
+ options;
2484
+ clients = /* @__PURE__ */ new Map();
2485
+ activeClientKeys = /* @__PURE__ */ new Map();
2486
+ contextCacheKeys = /* @__PURE__ */ new WeakMap();
2487
+ contextCachePromises = /* @__PURE__ */ new WeakMap();
2488
+ connectionSetupTails = /* @__PURE__ */ new Map();
2489
+ serverGenerations = /* @__PURE__ */ new Map();
2490
+ retirementPromises = /* @__PURE__ */ new Map();
2491
+ lastConnectionInfo = /* @__PURE__ */ new Map();
2492
+ constructor(definitions, options) {
2493
+ this.definitions = definitions;
2494
+ this.options = options;
2495
+ }
2496
+ get logger() {
2497
+ return this.options.logger;
2498
+ }
2499
+ get clientInfo() {
2500
+ return this.options.clientInfo;
2501
+ }
2502
+ get oauthTimeoutMs() {
2503
+ return this.options.oauthTimeoutMs;
2504
+ }
2505
+ get recordPath() {
2506
+ return this.options.recordPath;
2507
+ }
2508
+ get replayPath() {
2509
+ return this.options.replayPath;
2510
+ }
2511
+ supersedeDefinition(server, replace) {
2512
+ this.bumpServerGeneration(server);
2513
+ this.lastConnectionInfo.delete(server.trim());
2514
+ replace();
2515
+ this.retireCachedEntriesForServer(server);
2516
+ }
2517
+ async getInstructions(server) {
2518
+ const active = this.activeClientForServer(server);
2519
+ const fallbackEntries = active ? [] : this.cachedEntriesForServer(server);
2520
+ const cached = active ?? (fallbackEntries.length === 1 ? fallbackEntries[0] : void 0);
2521
+ if (!cached)
2522
+ return void 0;
2523
+ try {
2524
+ const context = await cached.promise;
2525
+ const instructions = typeof context.client.getInstructions === "function" ? context.client.getInstructions() : void 0;
2526
+ if (typeof instructions !== "string")
2527
+ return void 0;
2528
+ const trimmed = instructions.trim();
2529
+ return trimmed.length > 0 ? trimmed : void 0;
2530
+ } catch {
2531
+ return void 0;
2532
+ }
2533
+ }
2534
+ async getConnectionInfo(server) {
2535
+ const normalized = server.trim();
2536
+ const active = this.activeClientForServer(server);
2537
+ const fallbackEntries = active ? [] : this.cachedEntriesForServer(server);
2538
+ const cached = active ?? (fallbackEntries.length === 1 ? fallbackEntries[0] : void 0);
2539
+ if (!cached)
2540
+ return this.lastConnectionInfo.get(normalized);
2541
+ try {
2542
+ const { client } = await cached.promise;
2543
+ const info = connectionInfoFromClient(client);
2544
+ this.lastConnectionInfo.set(normalized, info);
2545
+ return info;
2546
+ } catch {
2547
+ return this.lastConnectionInfo.get(normalized);
2548
+ }
2549
+ }
2550
+ effectiveDisableOAuthForOperation(server, requested) {
2551
+ if (requested !== void 0) {
2552
+ return requested;
2553
+ }
2554
+ const cached = this.cachedEntriesForServer(server);
2555
+ const active = this.activeClientForServer(server);
2556
+ if (active) {
2557
+ return active.disableOAuth;
2558
+ }
2559
+ if (cached.length === 0) {
2560
+ return void 0;
2561
+ }
2562
+ const [first] = cached;
2563
+ return cached.every((entry) => entry.disableOAuth === first?.disableOAuth) ? first?.disableOAuth : void 0;
2564
+ }
2565
+ effectiveAllowCachedAuthForOperation(server, requested, disableOAuth, defaultValue) {
2566
+ if (requested !== void 0) {
2567
+ return requested;
2568
+ }
2569
+ if (disableOAuth !== true) {
2570
+ return defaultValue;
2571
+ }
2572
+ const active = this.activeClientForServer(server);
2573
+ if (active?.disableOAuth === true) {
2574
+ return active.allowCachedAuth;
2575
+ }
2576
+ const cached = this.cachedEntriesForServer(server).filter((entry) => entry.disableOAuth);
2577
+ return cached.length === 1 ? cached[0]?.allowCachedAuth : defaultValue;
2578
+ }
2579
+ cachedEntriesForServer(server) {
2580
+ const normalized = server.trim();
2581
+ return [...this.clients.values()].filter((entry) => entry.server === normalized);
2582
+ }
2583
+ retireCachedEntriesForServer(server) {
2584
+ const normalized = server.trim();
2585
+ const retired = [];
2586
+ for (const [key, cached] of this.clients.entries()) {
2587
+ if (cached.server === normalized) {
2588
+ this.clients.delete(key);
2589
+ retired.push(cached);
2590
+ }
2591
+ }
2592
+ this.activeClientKeys.delete(normalized);
2593
+ if (retired.length > 0) {
2594
+ const retirement = this.trackRetirement(normalized, this.closeCachedEntries(retired));
2595
+ void retirement.catch((error) => {
2596
+ const detail = error instanceof Error ? error.message : String(error);
2597
+ this.logger.warn(`Failed to close retired '${normalized}' connection: ${detail}`);
2598
+ });
2599
+ }
2600
+ }
2601
+ activeClientForServer(server) {
2602
+ const normalized = server.trim();
2603
+ const activeKey = this.activeClientKeys.get(normalized);
2604
+ if (!activeKey) {
2605
+ return void 0;
2606
+ }
2607
+ const active = this.clients.get(activeKey);
2608
+ return active?.server === normalized ? active : void 0;
2609
+ }
2610
+ serverGeneration(server) {
2611
+ return this.serverGenerations.get(server.trim()) ?? 0;
2612
+ }
2613
+ bumpServerGeneration(server) {
2614
+ const normalized = server.trim();
2615
+ this.serverGenerations.set(normalized, this.serverGeneration(normalized) + 1);
2616
+ }
2617
+ bumpAllServerGenerations() {
2618
+ const servers = /* @__PURE__ */ new Set([
2619
+ ...this.definitions.keys(),
2620
+ ...[...this.clients.values()].map((entry) => entry.server),
2621
+ ...this.connectionSetupTails.keys()
2622
+ ]);
2623
+ for (const server of servers) {
2624
+ this.bumpServerGeneration(server);
2625
+ }
2626
+ }
2627
+ // connect lazily instantiates a client context per server and memoizes it.
2628
+ async connect(server, options = {}) {
2629
+ const normalized = server.trim();
2630
+ let definition = this.definitions.get(normalized);
2631
+ if (!definition) {
2632
+ throw new Error(`Unknown MCP server '${normalized}'.`);
2633
+ }
2634
+ const generation = this.serverGeneration(normalized);
2635
+ const disableOAuth = options.disableOAuth === true;
2636
+ const effectiveAllowCachedAuth = options.allowCachedAuth ?? (disableOAuth ? true : void 0);
2637
+ const useCache = options.skipCache !== true && options.maxOAuthAttempts === void 0;
2638
+ let ignoresAuthCachePolicy = this.ignoresAuthCachePolicy(definition);
2639
+ let cacheAllowCachedAuth = ignoresAuthCachePolicy ? void 0 : effectiveAllowCachedAuth;
2640
+ let cacheDisableOAuth = ignoresAuthCachePolicy ? false : disableOAuth;
2641
+ let cacheKey = this.cacheKey(normalized, cacheAllowCachedAuth, cacheDisableOAuth);
2642
+ if (useCache) {
2643
+ const existing = this.findCachedEntryForRequest(normalized, definition, ignoresAuthCachePolicy ? void 0 : options.allowCachedAuth, cacheAllowCachedAuth, cacheDisableOAuth);
2644
+ if (existing) {
2645
+ const [existingKey, cached] = existing;
2646
+ const activeEntry = ignoresAuthCachePolicy ? {
2647
+ ...cached,
2648
+ allowCachedAuth: effectiveAllowCachedAuth,
2649
+ disableOAuth
2650
+ } : cached;
2651
+ if (activeEntry !== cached) {
2652
+ this.clients.set(existingKey, activeEntry);
2653
+ }
2654
+ this.activeClientKeys.set(normalized, existingKey);
2655
+ return activeEntry.promise;
2656
+ }
2657
+ }
2658
+ let releaseConnectionSetup;
2659
+ if (useCache && this.shouldSerializeConnectionSetup(definition, disableOAuth)) {
2660
+ releaseConnectionSetup = await this.enterConnectionSetup(normalized);
2661
+ try {
2662
+ if (this.serverGeneration(normalized) !== generation) {
2663
+ throw new Error(`Connection setup for MCP server '${normalized}' was superseded.`);
2664
+ }
2665
+ const refreshedDefinition = this.definitions.get(normalized);
2666
+ if (!refreshedDefinition) {
2667
+ throw new Error(`Unknown MCP server '${normalized}'.`);
2668
+ }
2669
+ definition = refreshedDefinition;
2670
+ ignoresAuthCachePolicy = this.ignoresAuthCachePolicy(definition);
2671
+ cacheAllowCachedAuth = ignoresAuthCachePolicy ? void 0 : effectiveAllowCachedAuth;
2672
+ cacheDisableOAuth = ignoresAuthCachePolicy ? false : disableOAuth;
2673
+ cacheKey = this.cacheKey(normalized, cacheAllowCachedAuth, cacheDisableOAuth);
2674
+ const existing = this.findCachedEntryForRequest(normalized, definition, ignoresAuthCachePolicy ? void 0 : options.allowCachedAuth, cacheAllowCachedAuth, cacheDisableOAuth);
2675
+ if (existing) {
2676
+ releaseConnectionSetup();
2677
+ releaseConnectionSetup = void 0;
2678
+ const [existingKey, cached] = existing;
2679
+ this.activeClientKeys.set(normalized, existingKey);
2680
+ return cached.promise;
2681
+ }
2682
+ await this.retireConflictingOAuthEntries(normalized, cacheKey);
2683
+ if (this.serverGeneration(normalized) !== generation) {
2684
+ throw new Error(`Connection setup for MCP server '${normalized}' was superseded.`);
2685
+ }
2686
+ const latestDefinition = this.definitions.get(normalized);
2687
+ if (!latestDefinition) {
2688
+ throw new Error(`Unknown MCP server '${normalized}'.`);
2689
+ }
2690
+ definition = latestDefinition;
2691
+ } catch (error) {
2692
+ releaseConnectionSetup?.();
2693
+ releaseConnectionSetup = void 0;
2694
+ throw error;
2695
+ }
2696
+ }
2697
+ let connectionDefinition = definition;
2698
+ const abortController = new AbortController();
2699
+ const transportRef = {};
2700
+ const contextRef = {};
2701
+ let contextPromise = createClientContext(definition, this.logger, this.clientInfo, {
2702
+ maxOAuthAttempts: options.maxOAuthAttempts,
2703
+ oauthTimeoutMs: options.oauthTimeoutMs ?? this.oauthTimeoutMs,
2704
+ onDefinitionPromoted: (promoted) => {
2705
+ if (this.serverGeneration(normalized) === generation && this.definitions.get(normalized) === connectionDefinition) {
2706
+ this.definitions.set(promoted.name, promoted);
2707
+ connectionDefinition = promoted;
2708
+ }
2709
+ },
2710
+ allowCachedAuth: effectiveAllowCachedAuth,
2711
+ oauthSessionOptions: options.oauthSessionOptions,
2712
+ disableOAuth,
2713
+ recordPath: this.recordPath,
2714
+ replayPath: this.replayPath,
2715
+ elicitationHandler: this.options.elicitationHandler,
2716
+ signal: abortController.signal,
2717
+ onTransportCreated: (transport) => {
2718
+ transportRef.current = transport;
2719
+ }
2720
+ }).then((context) => {
2721
+ contextRef.current = context;
2722
+ this.lastConnectionInfo.set(normalized, connectionInfoFromClient(context.client));
2723
+ return context;
2724
+ });
2725
+ if (useCache) {
2726
+ const previousActiveKey = this.activeClientKeys.get(normalized);
2727
+ contextPromise = contextPromise.then((context) => {
2728
+ this.contextCacheKeys.set(context, cacheKey);
2729
+ this.contextCachePromises.set(context, contextPromise);
2730
+ return context;
2731
+ });
2732
+ let connection;
2733
+ connection = contextPromise.then((context) => {
2734
+ const stillCached = this.clients.get(cacheKey)?.promise === connection;
2735
+ if (this.serverGeneration(normalized) !== generation || !stillCached) {
2736
+ this.contextCacheKeys.delete(context);
2737
+ this.contextCachePromises.delete(context);
2738
+ throw new Error(`Connection setup for MCP server '${normalized}' was superseded.`);
2739
+ }
2740
+ return context;
2741
+ });
2742
+ this.activeClientKeys.set(normalized, cacheKey);
2743
+ this.clients.set(cacheKey, {
2744
+ server: normalized,
2745
+ promise: connection,
2746
+ contextPromise,
2747
+ allowCachedAuth: ignoresAuthCachePolicy ? effectiveAllowCachedAuth : cacheAllowCachedAuth,
2748
+ disableOAuth: ignoresAuthCachePolicy ? disableOAuth : cacheDisableOAuth,
2749
+ abortController,
2750
+ transportRef,
2751
+ contextRef
2752
+ });
2753
+ try {
2754
+ return await connection;
2755
+ } catch (error) {
2756
+ const ownsCacheEntry = this.clients.get(cacheKey)?.promise === connection;
2757
+ if (ownsCacheEntry) {
2758
+ this.clients.delete(cacheKey);
2759
+ if (this.activeClientKeys.get(normalized) === cacheKey && previousActiveKey && this.clients.has(previousActiveKey)) {
2760
+ this.activeClientKeys.set(normalized, previousActiveKey);
2761
+ } else if (this.activeClientKeys.get(normalized) === cacheKey || this.cachedEntriesForServer(normalized).length === 0) {
2762
+ this.activeClientKeys.delete(normalized);
2763
+ }
2764
+ }
2765
+ throw error;
2766
+ } finally {
2767
+ releaseConnectionSetup?.();
2768
+ }
2769
+ }
2770
+ releaseConnectionSetup?.();
2771
+ return contextPromise;
2772
+ }
2773
+ // close tears down transports (and OAuth sessions) for a single server or all servers.
2774
+ async close(server) {
2775
+ if (server) {
2776
+ const normalized = server.trim();
2777
+ this.bumpServerGeneration(normalized);
2778
+ const entries2 = [...this.clients.entries()].filter(([, cached]) => cached.server === normalized);
2779
+ if (entries2.length === 0) {
2780
+ this.activeClientKeys.delete(normalized);
2781
+ }
2782
+ for (const [key] of entries2) {
2783
+ this.clients.delete(key);
2784
+ }
2785
+ this.activeClientKeys.delete(normalized);
2786
+ if (entries2.length > 0) {
2787
+ void this.trackRetirement(normalized, this.closeCachedEntries(entries2.map(([, cached]) => cached)));
2788
+ }
2789
+ await this.awaitRetirements(normalized);
2790
+ return;
2791
+ }
2792
+ this.bumpAllServerGenerations();
2793
+ const entries = [...this.clients.entries()];
2794
+ this.clients.clear();
2795
+ this.activeClientKeys.clear();
2796
+ const byServer = /* @__PURE__ */ new Map();
2797
+ for (const [, cached] of entries) {
2798
+ const serverEntries = byServer.get(cached.server) ?? [];
2799
+ serverEntries.push(cached);
2800
+ byServer.set(cached.server, serverEntries);
2801
+ }
2802
+ for (const [serverName, serverEntries] of byServer) {
2803
+ void this.trackRetirement(serverName, this.closeCachedEntries(serverEntries));
2804
+ }
2805
+ await this.awaitRetirements();
2806
+ }
2807
+ contextPromiseFor(cached) {
2808
+ return cached.contextPromise ?? cached.promise;
2809
+ }
2810
+ async closeCachedEntries(entries) {
2811
+ for (const cached of entries) {
2812
+ cached.abortController?.abort();
2813
+ }
2814
+ const results = await Promise.allSettled(entries.map(async (cached) => {
2815
+ const readyContext = cached.contextRef?.current;
2816
+ if (readyContext) {
2817
+ try {
2818
+ await this.closeContext(readyContext);
2819
+ } finally {
2820
+ this.contextCacheKeys.delete(readyContext);
2821
+ this.contextCachePromises.delete(readyContext);
2822
+ }
2823
+ return;
2824
+ }
2825
+ const pendingContext = this.contextPromiseFor(cached);
2826
+ const pendingTransport = cached.transportRef?.current;
2827
+ if (pendingTransport) {
2828
+ await closeTransportAndWait(this.logger, pendingTransport);
2829
+ void pendingContext.then(async (context) => {
2830
+ await context.client.close().catch(() => {
2831
+ });
2832
+ await context.oauthSession?.close().catch(() => {
2833
+ });
2834
+ this.contextCacheKeys.delete(context);
2835
+ this.contextCachePromises.delete(context);
2836
+ }, () => {
2837
+ });
2838
+ return;
2839
+ }
2840
+ try {
2841
+ const context = await pendingContext;
2842
+ await this.closeContext(context);
2843
+ this.contextCacheKeys.delete(context);
2844
+ this.contextCachePromises.delete(context);
2845
+ } catch (error) {
2846
+ if (!cached.abortController?.signal.aborted) {
2847
+ throw error;
2848
+ }
2849
+ }
2850
+ }));
2851
+ const firstFailure = results.find((result) => result.status === "rejected");
2852
+ if (firstFailure) {
2853
+ throw firstFailure.reason;
2854
+ }
2855
+ }
2856
+ async closeContext(context) {
2857
+ const propagateReplayCloseErrors = context.transport instanceof ReplayTransport;
2858
+ let closeError;
2859
+ try {
2860
+ await closeTransportAndWait(this.logger, context.transport, {
2861
+ throwOnCloseError: propagateReplayCloseErrors,
2862
+ close: async () => {
2863
+ let firstError;
2864
+ const clientClose = context.client.close;
2865
+ if (clientClose) {
2866
+ try {
2867
+ await clientClose.call(context.client);
2868
+ } catch (error) {
2869
+ firstError = error;
2870
+ }
2871
+ }
2872
+ try {
2873
+ await context.transport.close();
2874
+ } catch (error) {
2875
+ firstError ??= error;
2876
+ }
2877
+ if (firstError) {
2878
+ throw firstError;
2879
+ }
2880
+ }
2881
+ });
2882
+ } catch (error) {
2883
+ if (propagateReplayCloseErrors) {
2884
+ closeError ??= error;
2885
+ }
2886
+ }
2887
+ await context.oauthSession?.close().catch(() => {
2888
+ });
2889
+ if (closeError) {
2890
+ throw closeError;
2891
+ }
2892
+ }
2893
+ async resetConnectionOnError(server, error, failedContext) {
2894
+ if (!shouldResetConnection(error)) {
2895
+ return;
2896
+ }
2897
+ const normalized = server.trim();
2898
+ if (!failedContext) {
2899
+ return;
2900
+ }
2901
+ try {
2902
+ const failedKey = this.contextCacheKeys.get(failedContext);
2903
+ const failedEntry = failedKey ? this.clients.get(failedKey) : void 0;
2904
+ const failedContextPromise = this.contextCachePromises.get(failedContext);
2905
+ if (!failedKey || failedEntry?.server !== normalized || !failedContextPromise || this.contextPromiseFor(failedEntry) !== failedContextPromise) {
2906
+ return;
2907
+ }
2908
+ if (this.clients.get(failedKey)?.promise !== failedEntry.promise) {
2909
+ return;
2910
+ }
2911
+ this.clients.delete(failedKey);
2912
+ if (this.activeClientKeys.get(normalized) === failedKey || this.cachedEntriesForServer(normalized).length === 0) {
2913
+ this.activeClientKeys.delete(normalized);
2914
+ }
2915
+ try {
2916
+ await this.closeContext(failedContext);
2917
+ } finally {
2918
+ this.contextCacheKeys.delete(failedContext);
2919
+ this.contextCachePromises.delete(failedContext);
2920
+ }
2921
+ } catch (closeError) {
2922
+ const detail = closeError instanceof Error ? closeError.message : String(closeError);
2923
+ this.logger.warn(`Failed to reset '${normalized}' after error: ${detail}`);
2924
+ }
2925
+ }
2926
+ findCachedEntryForRequest(server, definition, requestedAllowCachedAuth, effectiveAllowCachedAuth, disableOAuth) {
2927
+ const exactKey = this.cacheKey(server, effectiveAllowCachedAuth, disableOAuth);
2928
+ if (this.ignoresAuthCachePolicy(definition)) {
2929
+ const exact2 = this.clients.get(exactKey);
2930
+ return exact2 ? [exactKey, exact2] : void 0;
2931
+ }
2932
+ if (requestedAllowCachedAuth !== void 0) {
2933
+ const exact2 = this.clients.get(exactKey);
2934
+ return exact2 ? [exactKey, exact2] : void 0;
2935
+ }
2936
+ const activeKey = this.activeClientKeys.get(server);
2937
+ const active = activeKey ? this.clients.get(activeKey) : void 0;
2938
+ const policyMatches = (cached) => effectiveAllowCachedAuth === void 0 || cached.allowCachedAuth === effectiveAllowCachedAuth;
2939
+ if (activeKey && active?.server === server && active.disableOAuth === disableOAuth && policyMatches(active)) {
2940
+ return [activeKey, active];
2941
+ }
2942
+ const matches = [...this.clients.entries()].filter(([, cached]) => cached.server === server && cached.disableOAuth === disableOAuth && policyMatches(cached));
2943
+ if (matches.length === 1) {
2944
+ return matches[0];
2945
+ }
2946
+ const exact = this.clients.get(exactKey);
2947
+ return exact ? [exactKey, exact] : void 0;
2948
+ }
2949
+ async retireConflictingOAuthEntries(server, keepKey) {
2950
+ const conflicting = [...this.clients.entries()].filter(([key, cached]) => key !== keepKey && cached.server === server && !cached.disableOAuth);
2951
+ if (conflicting.length === 0) {
2952
+ return;
2953
+ }
2954
+ for (const [key] of conflicting) {
2955
+ this.clients.delete(key);
2956
+ if (this.activeClientKeys.get(server) === key) {
2957
+ this.activeClientKeys.delete(server);
2958
+ }
2959
+ }
2960
+ await this.trackRetirement(server, this.closeCachedEntries(conflicting.map(([, cached]) => cached)));
2961
+ }
2962
+ shouldSerializeConnectionSetup(definition, disableOAuth) {
2963
+ return definition.command.kind === "http" && !disableOAuth && !this.ignoresAuthCachePolicy(definition);
2964
+ }
2965
+ ignoresAuthCachePolicy(definition) {
2966
+ const replayServer = process.env.MCPORTER_REPLAY_SERVER;
2967
+ const replaysDefinition = Boolean(this.replayPath) && (!replayServer || replayServer === definition.name);
2968
+ return definition.command.kind === "stdio" || replaysDefinition;
2969
+ }
2970
+ trackRetirement(server, retirement) {
2971
+ const pending = this.retirementPromises.get(server) ?? /* @__PURE__ */ new Set();
2972
+ pending.add(retirement);
2973
+ this.retirementPromises.set(server, pending);
2974
+ const cleanup = () => {
2975
+ pending.delete(retirement);
2976
+ if (pending.size === 0) {
2977
+ this.retirementPromises.delete(server);
2978
+ }
2979
+ };
2980
+ retirement.then(cleanup, cleanup);
2981
+ return retirement;
2982
+ }
2983
+ async awaitRetirements(server) {
2984
+ const pending = server ? [...this.retirementPromises.get(server) ?? []] : [];
2985
+ if (!server) {
2986
+ for (const retirements of this.retirementPromises.values()) {
2987
+ pending.push(...retirements);
2988
+ }
2989
+ }
2990
+ const results = await Promise.allSettled(pending);
2991
+ const firstFailure = results.find((result) => result.status === "rejected");
2992
+ if (firstFailure) {
2993
+ throw firstFailure.reason;
2994
+ }
2995
+ }
2996
+ async enterConnectionSetup(server) {
2997
+ const previous = this.connectionSetupTails.get(server) ?? Promise.resolve();
2998
+ let releaseCurrent;
2999
+ const current = new Promise((resolve) => {
3000
+ releaseCurrent = resolve;
3001
+ });
3002
+ const tail = previous.catch(() => {
3003
+ }).then(() => current);
3004
+ this.connectionSetupTails.set(server, tail);
3005
+ await previous.catch(() => {
3006
+ });
3007
+ let released = false;
3008
+ return () => {
3009
+ if (released) {
3010
+ return;
3011
+ }
3012
+ released = true;
3013
+ releaseCurrent();
3014
+ void tail.finally(() => {
3015
+ if (this.connectionSetupTails.get(server) === tail) {
3016
+ this.connectionSetupTails.delete(server);
3017
+ }
3018
+ });
3019
+ };
3020
+ }
3021
+ cacheKey(server, allowCachedAuth, disableOAuth) {
3022
+ const cachedAuthKey = allowCachedAuth === true ? "cached-auth-on" : allowCachedAuth === false ? "cached-auth-off" : "cached-auth-unset";
3023
+ return `${server}\0oauth-disabled:${disableOAuth ? "1" : "0"}\0${cachedAuthKey}`;
3024
+ }
3025
+ };
3026
+ function connectionInfoFromClient(client) {
3027
+ return {
3028
+ protocolVersion: typeof client.getNegotiatedProtocolVersion === "function" ? client.getNegotiatedProtocolVersion() : void 0,
3029
+ era: typeof client.getProtocolEra === "function" ? client.getProtocolEra() : void 0
3030
+ };
3031
+ }
3032
+
3033
+ // node_modules/.pnpm/mcporter@0.13.0/node_modules/mcporter/dist/tool-filters.js
3034
+ function validateToolFilters(name, filter) {
3035
+ if (filter.allowedTools !== void 0 && filter.blockedTools !== void 0) {
3036
+ throw new Error(`Server '${name}' cannot specify both allowedTools and blockedTools.`);
3037
+ }
3038
+ }
3039
+ function isToolAllowed(toolName, filter) {
3040
+ if (!filter) {
3041
+ return true;
3042
+ }
3043
+ if (filter.allowedTools !== void 0) {
3044
+ return filter.allowedTools.includes(toolName);
3045
+ }
3046
+ if (filter.blockedTools !== void 0) {
3047
+ return !filter.blockedTools.includes(toolName);
3048
+ }
3049
+ return true;
3050
+ }
3051
+ function filterTools(tools, filter) {
3052
+ return tools.filter((tool) => isToolAllowed(tool.name, filter));
3053
+ }
3054
+
3055
+ // node_modules/.pnpm/mcporter@0.13.0/node_modules/mcporter/dist/runtime.js
3056
+ var PACKAGE_NAME = "mcporter";
3057
+ var OAUTH_CODE_TIMEOUT_MS = resolveOAuthTimeoutFromEnv();
3058
+ var MAX_RESOURCE_LIST_PAGES = 100;
3059
+ async function createRuntime(options = {}) {
3060
+ const servers = options.servers ?? await loadServerDefinitions({
3061
+ configPath: options.configPath,
3062
+ rootDir: options.rootDir
3063
+ });
3064
+ const runtime = new McpRuntime(servers, options);
3065
+ return runtime;
3066
+ }
3067
+ async function callOnce(params) {
3068
+ const runtime = await createRuntime({ configPath: params.configPath });
3069
+ try {
3070
+ return await runtime.callTool(params.server, params.toolName, {
3071
+ args: params.args,
3072
+ disableOAuth: params.disableOAuth
3073
+ });
3074
+ } finally {
3075
+ await runtime.close(params.server);
3076
+ }
3077
+ }
3078
+ var McpRuntime = class {
3079
+ definitions;
3080
+ connectionCache;
3081
+ logger;
3082
+ constructor(servers, options = {}) {
3083
+ for (const server of servers) {
3084
+ validateToolFilters(server.name, server);
3085
+ }
3086
+ this.definitions = new Map(servers.map((entry) => [entry.name, entry]));
3087
+ this.logger = options.logger ?? createConsoleLogger();
3088
+ const clientInfo = options.clientInfo ?? {
3089
+ name: PACKAGE_NAME,
3090
+ version: MCPORTER_VERSION
3091
+ };
3092
+ const recordSession = process.env.MCPORTER_RECORD;
3093
+ const replaySession = process.env.MCPORTER_REPLAY;
3094
+ if (recordSession && replaySession) {
3095
+ this.logger.warn("Both MCPORTER_RECORD and MCPORTER_REPLAY are set; recording mode wins.");
3096
+ }
3097
+ const recordPath = recordSession ? resolveRecordingPath(recordSession) : void 0;
3098
+ const replayPath = !recordSession && replaySession ? resolveRecordingPath(replaySession) : void 0;
3099
+ let nonInteractiveHintPrinted = false;
3100
+ const defaultResponder = createNonInteractiveElicitationResponder({
3101
+ onDecline: () => {
3102
+ if (nonInteractiveHintPrinted)
3103
+ return;
3104
+ nonInteractiveHintPrinted = true;
3105
+ this.logger.warn(NON_INTERACTIVE_ELICITATION_HINT);
3106
+ }
3107
+ });
3108
+ this.connectionCache = new RuntimeConnectionCache(this.definitions, {
3109
+ logger: this.logger,
3110
+ clientInfo,
3111
+ oauthTimeoutMs: options.oauthTimeoutMs ?? OAUTH_CODE_TIMEOUT_MS,
3112
+ recordPath,
3113
+ replayPath,
3114
+ elicitationHandler: options.elicitationHandler ?? defaultResponder.handler
3115
+ });
3116
+ }
3117
+ // listServers returns configured names sorted alphabetically for stable CLI output.
3118
+ listServers() {
3119
+ return [...this.definitions.keys()].toSorted((a, b) => a.localeCompare(b));
3120
+ }
3121
+ // getDefinitions exposes raw server metadata to consumers such as the CLI.
3122
+ getDefinitions() {
3123
+ return [...this.definitions.values()];
3124
+ }
3125
+ // getDefinition throws when the caller requests an unknown server name.
3126
+ getDefinition(server) {
3127
+ const definition = this.definitions.get(server);
3128
+ if (!definition) {
3129
+ throw new Error(`Unknown MCP server '${server}'.`);
3130
+ }
3131
+ return definition;
3132
+ }
3133
+ registerDefinition(definition, options = {}) {
3134
+ validateToolFilters(definition.name, definition);
3135
+ if (!options.overwrite && this.definitions.has(definition.name)) {
3136
+ throw new Error(`MCP server '${definition.name}' already exists.`);
3137
+ }
3138
+ this.connectionCache.supersedeDefinition(definition.name, () => {
3139
+ this.definitions.set(definition.name, definition);
3140
+ });
3141
+ }
3142
+ async getInstructions(server) {
3143
+ return this.connectionCache.getInstructions(server);
3144
+ }
3145
+ async getConnectionInfo(server) {
3146
+ return this.connectionCache.getConnectionInfo(server);
3147
+ }
3148
+ // listTools queries tool metadata and optionally includes schemas when requested.
3149
+ async listTools(server, options = {}) {
3150
+ const autoAuthorize = options.autoAuthorize !== false;
3151
+ const disableOAuth = this.effectiveDisableOAuthForOperation(server, options.disableOAuth);
3152
+ const allowCachedAuth = this.effectiveAllowCachedAuthForOperation(server, options.allowCachedAuth, disableOAuth, true);
3153
+ const useLegacyNoAuthorize = !autoAuthorize && disableOAuth !== true;
3154
+ const timeoutMs = normalizeTimeout(options.timeoutMs);
3155
+ const context = await this.connect(server, {
3156
+ maxOAuthAttempts: useLegacyNoAuthorize ? 0 : void 0,
3157
+ skipCache: useLegacyNoAuthorize,
3158
+ allowCachedAuth,
3159
+ oauthSessionOptions: options.oauthSessionOptions,
3160
+ disableOAuth,
3161
+ oauthTimeoutMs: timeoutMs
3162
+ });
3163
+ let closeError;
3164
+ let tools = [];
3165
+ try {
3166
+ const listPromise = context.client.listTools(void 0, timeoutMs ? { timeout: timeoutMs, resetTimeoutOnProgress: true, maxTotalTimeout: timeoutMs } : void 0);
3167
+ const response = timeoutMs ? await raceWithTimeout(listPromise, timeoutMs) : await listPromise;
3168
+ tools = (response.tools ?? []).map((tool) => ({
3169
+ name: tool.name,
3170
+ description: tool.description ?? void 0,
3171
+ inputSchema: options.includeSchema ? tool.inputSchema : void 0,
3172
+ outputSchema: options.includeSchema ? tool.outputSchema : void 0
3173
+ }));
3174
+ } catch (error) {
3175
+ await this.resetConnectionOnError(server, error, context);
3176
+ throw error;
3177
+ } finally {
3178
+ if (useLegacyNoAuthorize) {
3179
+ try {
3180
+ await this.closeContext(context);
3181
+ } catch (error) {
3182
+ closeError = error;
3183
+ }
3184
+ }
3185
+ }
3186
+ if (closeError !== void 0) {
3187
+ throw closeError;
3188
+ }
3189
+ return filterTools(tools, this.definitions.get(server.trim()));
3190
+ }
3191
+ // callTool executes a tool using the args provided by the caller.
3192
+ async callTool(server, toolName, options = {}) {
3193
+ const definition = this.definitions.get(server.trim());
3194
+ if (definition && !isToolAllowed(toolName, definition)) {
3195
+ throw new Error(`Tool '${toolName}' is not accessible on server '${definition.name}' (blocked by configuration).`);
3196
+ }
3197
+ let context;
3198
+ try {
3199
+ const disableOAuth = this.effectiveDisableOAuthForOperation(server, options.disableOAuth);
3200
+ context = await this.connect(server, {
3201
+ allowCachedAuth: this.effectiveAllowCachedAuthForOperation(server, void 0, disableOAuth, true),
3202
+ disableOAuth
3203
+ });
3204
+ const { client } = context;
3205
+ const params = {
3206
+ name: toolName,
3207
+ arguments: options.args ?? {}
3208
+ };
3209
+ const timeoutMs = normalizeTimeout(options.timeoutMs);
3210
+ const resultPromise = client.callTool(params, {
3211
+ timeout: timeoutMs,
3212
+ // Long runs (e.g., GPT-5 Pro) emit progress/logging; allow that to refresh the timer.
3213
+ resetTimeoutOnProgress: true,
3214
+ maxTotalTimeout: timeoutMs
3215
+ });
3216
+ if (!timeoutMs) {
3217
+ return await resultPromise;
3218
+ }
3219
+ return await raceWithTimeout(resultPromise, timeoutMs);
3220
+ } catch (error) {
3221
+ await this.resetConnectionOnError(server, error, context);
3222
+ throw error;
3223
+ }
3224
+ }
3225
+ // listResources delegates to the MCP resources/list method with passthrough params.
3226
+ async listResources(server, options = {}) {
3227
+ const { allowCachedAuth, disableOAuth, oauthSessionOptions, ...params } = options;
3228
+ let context;
3229
+ try {
3230
+ const effectiveDisableOAuth = this.effectiveDisableOAuthForOperation(server, disableOAuth);
3231
+ context = await this.connect(server, {
3232
+ allowCachedAuth: this.effectiveAllowCachedAuthForOperation(server, allowCachedAuth, effectiveDisableOAuth, void 0),
3233
+ oauthSessionOptions,
3234
+ disableOAuth: effectiveDisableOAuth
3235
+ });
3236
+ const { client } = context;
3237
+ const requestParams = params;
3238
+ if (requestParams.cursor !== void 0) {
3239
+ return await client.listResources(requestParams);
3240
+ }
3241
+ let response = await client.request({ method: "resources/list", params: requestParams }, specTypeSchemas.ListResourcesResult);
3242
+ const resources = [...response.resources];
3243
+ const seenCursors = /* @__PURE__ */ new Set();
3244
+ for (let page = 1; page < MAX_RESOURCE_LIST_PAGES && response.nextCursor; page += 1) {
3245
+ if (seenCursors.has(response.nextCursor))
3246
+ break;
3247
+ seenCursors.add(response.nextCursor);
3248
+ response = await client.request({ method: "resources/list", params: { ...requestParams, cursor: response.nextCursor } }, specTypeSchemas.ListResourcesResult);
3249
+ resources.push(...response.resources);
3250
+ }
3251
+ return { ...response, resources };
3252
+ } catch (error) {
3253
+ await this.resetConnectionOnError(server, error, context);
3254
+ throw error;
3255
+ }
3256
+ }
3257
+ async readResource(server, uri, options = {}) {
3258
+ let context;
3259
+ try {
3260
+ const effectiveDisableOAuth = this.effectiveDisableOAuthForOperation(server, options.disableOAuth);
3261
+ context = await this.connect(server, {
3262
+ allowCachedAuth: this.effectiveAllowCachedAuthForOperation(server, options.allowCachedAuth, effectiveDisableOAuth, void 0),
3263
+ oauthSessionOptions: options.oauthSessionOptions,
3264
+ disableOAuth: effectiveDisableOAuth
3265
+ });
3266
+ const { client } = context;
3267
+ return await client.readResource({ uri });
3268
+ } catch (error) {
3269
+ await this.resetConnectionOnError(server, error, context);
3270
+ throw error;
3271
+ }
3272
+ }
3273
+ effectiveDisableOAuthForOperation(server, requested) {
3274
+ return this.connectionCache.effectiveDisableOAuthForOperation(server, requested);
3275
+ }
3276
+ effectiveAllowCachedAuthForOperation(server, requested, disableOAuth, defaultValue) {
3277
+ return this.connectionCache.effectiveAllowCachedAuthForOperation(server, requested, disableOAuth, defaultValue);
3278
+ }
3279
+ async connect(server, options = {}) {
3280
+ return this.connectionCache.connect(server, options);
3281
+ }
3282
+ async close(server) {
3283
+ await this.connectionCache.close(server);
3284
+ }
3285
+ async closeContext(context) {
3286
+ await this.connectionCache.closeContext(context);
3287
+ }
3288
+ async resetConnectionOnError(server, error, context) {
3289
+ await this.connectionCache.resetConnectionOnError(server, error, context);
3290
+ }
3291
+ };
3292
+ function createConsoleLogger(level = resolveLogLevelFromEnv()) {
3293
+ return createPrefixedConsoleLogger("mcporter", level);
3294
+ }
3295
+
3296
+ export {
3297
+ createRuntime,
3298
+ callOnce
3299
+ };