toolcraft 0.0.306 → 0.0.308

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 (21) hide show
  1. package/composition.json +3 -3
  2. package/dist/composition.json +3 -3
  3. package/node_modules/tiny-http-mcp-server/dist/composition.json +1 -1
  4. package/node_modules/tiny-http-mcp-server/node_modules/mcp-oauth/README.md +22 -1
  5. package/node_modules/tiny-http-mcp-server/node_modules/mcp-oauth/dist/client/default-oauth-client-provider.js +27 -13
  6. package/node_modules/tiny-http-mcp-server/node_modules/mcp-oauth/dist/client/loopback-authorization.d.ts +5 -0
  7. package/node_modules/tiny-http-mcp-server/node_modules/mcp-oauth/dist/client/loopback-authorization.js +134 -72
  8. package/node_modules/tiny-http-mcp-server/node_modules/mcp-oauth/dist/client/token-endpoint.d.ts +2 -0
  9. package/node_modules/tiny-http-mcp-server/node_modules/mcp-oauth/dist/client/token-endpoint.js +5 -1
  10. package/node_modules/tiny-http-mcp-server/node_modules/mcp-oauth/dist/client/types.d.ts +9 -1
  11. package/node_modules/tiny-http-mcp-server/package.json +1 -1
  12. package/node_modules/tiny-mcp-client/README.md +3 -1
  13. package/node_modules/tiny-mcp-client/dist/index.d.ts +12 -2
  14. package/node_modules/tiny-mcp-client/dist/index.js +235 -115
  15. package/node_modules/tiny-stdio-mcp-server/dist/composition.json +1 -1
  16. package/node_modules/toolcraft-schema/README.md +7 -0
  17. package/node_modules/toolcraft-schema/dist/index.d.ts +1 -0
  18. package/node_modules/toolcraft-schema/dist/json.d.ts +5 -1
  19. package/node_modules/toolcraft-schema/dist/json.js +9 -3
  20. package/node_modules/toolcraft-schema/package.json +1 -1
  21. package/package.json +2 -2
@@ -152,11 +152,17 @@ var HttpResponseMessages = class {
152
152
  };
153
153
 
154
154
  // ../toolcraft-schema/dist/json.js
155
- function isJsonValue(value) {
155
+ function isJsonValue(value, options = {}) {
156
+ const maxNodes = options.maxNodes ?? 1e4;
157
+ const maxDepth = options.maxDepth ?? 64;
158
+ if (!Number.isSafeInteger(maxNodes) || maxNodes < 1)
159
+ throw new Error("maxNodes must be a positive safe integer");
160
+ if (!Number.isSafeInteger(maxDepth) || maxDepth < 0 || maxDepth > 256)
161
+ throw new Error("maxDepth must be an integer between 0 and 256");
156
162
  const ancestors = /* @__PURE__ */ new Set();
157
163
  let nodes = 0;
158
164
  const visit = (item, depth) => {
159
- if (++nodes > 1e4 || depth > 64)
165
+ if (++nodes > maxNodes || depth > maxDepth)
160
166
  return false;
161
167
  if (item === null || typeof item === "string" || typeof item === "boolean")
162
168
  return true;
@@ -182,7 +188,7 @@ function isJsonValue(value) {
182
188
  ancestors.add(item);
183
189
  let valid = true;
184
190
  if (Array.isArray(item)) {
185
- if (item.length > 1e4)
191
+ if (item.length > maxNodes)
186
192
  valid = false;
187
193
  else
188
194
  for (let index = 0; index < item.length; index++) {
@@ -4102,47 +4108,137 @@ function getOwnEntry4(record2, key2) {
4102
4108
 
4103
4109
  // ../mcp-oauth/dist/client/loopback-authorization.js
4104
4110
  async function createLoopbackAuthorizationSession(options = {}) {
4105
- const callbackPath = options.callbackPath ?? "/callback";
4111
+ options.signal?.throwIfAborted();
4112
+ const timeoutMs = options.timeoutMs ?? 12e4;
4113
+ if (!Number.isSafeInteger(timeoutMs) || timeoutMs < 1 || timeoutMs > 2147483647)
4114
+ throw new Error("OAuth authorization timeoutMs must be a positive supported timer interval");
4115
+ const target = loopbackTarget(options);
4106
4116
  const server = options.createServer ? options.createServer() : http.createServer();
4107
- const port = await startServer(server);
4108
- const redirectUri = `http://127.0.0.1:${port}${callbackPath}`;
4117
+ const controller = new AbortController();
4118
+ let closed = false;
4119
+ let used = false;
4120
+ const callerAbort = () => controller.abort(options.signal?.reason);
4121
+ const teardown = () => {
4122
+ if (closed)
4123
+ return;
4124
+ closed = true;
4125
+ clearTimeout(timer);
4126
+ options.signal?.removeEventListener("abort", callerAbort);
4127
+ server.closeAllConnections?.();
4128
+ server.close();
4129
+ };
4130
+ const timer = setTimeout(() => controller.abort(new Error("OAuth authorization timed out")), timeoutMs);
4131
+ timer.unref?.();
4132
+ controller.signal.addEventListener("abort", teardown, { once: true });
4133
+ options.signal?.addEventListener("abort", callerAbort, { once: true });
4134
+ if (options.signal?.aborted)
4135
+ callerAbort();
4136
+ let port;
4137
+ try {
4138
+ port = await startServer(server, target.port, target.host, controller.signal);
4139
+ } catch (error) {
4140
+ controller.abort(error);
4141
+ throw error;
4142
+ }
4143
+ const redirectUri = options.redirectUri ?? `http://127.0.0.1:${port}${target.callbackPath}`;
4109
4144
  return {
4110
4145
  redirectUri,
4111
4146
  async waitForCode(authorizationUrl) {
4112
- return waitForAuthorizationCode(server, authorizationUrl, options, callbackPath);
4147
+ controller.signal.throwIfAborted();
4148
+ if (used)
4149
+ throw new Error("OAuth authorization session has already been used");
4150
+ used = true;
4151
+ try {
4152
+ return await waitForAuthorizationCode(server, authorizationUrl, options, target.callbackPath, controller.signal);
4153
+ } finally {
4154
+ clearTimeout(timer);
4155
+ }
4113
4156
  },
4114
4157
  close() {
4115
- server.closeAllConnections?.();
4116
- server.close();
4158
+ controller.abort(new Error("OAuth authorization session closed"));
4117
4159
  }
4118
4160
  };
4119
4161
  }
4120
- async function startServer(server) {
4162
+ function loopbackTarget(options) {
4163
+ if (options.redirectUri !== void 0) {
4164
+ let url;
4165
+ try {
4166
+ url = new URL(options.redirectUri);
4167
+ } catch (cause) {
4168
+ throw new Error("Invalid OAuth loopback redirect URI", { cause });
4169
+ }
4170
+ const forbiddenQuery = ["code", "state", "error", "error_description", "iss"];
4171
+ if (url.protocol !== "http:" || !["localhost", "127.0.0.1", "[::1]"].includes(url.hostname) || url.username || url.password || url.hash || url.port === "0" || forbiddenQuery.some((name) => url.searchParams.has(name)) || [...options.redirectUri].some((char) => char.codePointAt(0) <= 32) || options.callbackPath !== void 0 && options.callbackPath !== url.pathname)
4172
+ throw new Error("Invalid OAuth loopback redirect URI");
4173
+ return { port: url.port ? Number(url.port) : 80, host: url.hostname === "[::1]" ? "::1" : url.hostname, callbackPath: url.pathname };
4174
+ }
4175
+ const callbackPath = options.callbackPath ?? "/callback";
4176
+ const parsed = new URL(callbackPath, "http://127.0.0.1");
4177
+ if (!callbackPath.startsWith("/") || parsed.origin !== "http://127.0.0.1" || parsed.pathname !== callbackPath || parsed.search || parsed.hash)
4178
+ throw new Error("Invalid OAuth loopback callback path");
4179
+ return { port: 0, host: "127.0.0.1", callbackPath };
4180
+ }
4181
+ async function startServer(server, port, host, signal) {
4182
+ signal.throwIfAborted();
4121
4183
  return new Promise((resolve, reject) => {
4122
- const handleError = (error) => {
4184
+ const cleanup = () => {
4123
4185
  server.off("error", handleError);
4186
+ signal.removeEventListener("abort", aborted);
4187
+ };
4188
+ const handleError = (error) => {
4189
+ cleanup();
4124
4190
  reject(error);
4125
4191
  };
4192
+ const aborted = () => {
4193
+ cleanup();
4194
+ reject(signal.reason);
4195
+ };
4126
4196
  server.once("error", handleError);
4127
- server.listen(0, "127.0.0.1", () => {
4128
- server.off("error", handleError);
4129
- const address = server.address();
4130
- resolve(address.port);
4131
- });
4197
+ signal.addEventListener("abort", aborted, { once: true });
4198
+ try {
4199
+ server.listen(port, host, () => {
4200
+ cleanup();
4201
+ if (signal.aborted) {
4202
+ server.close();
4203
+ reject(signal.reason);
4204
+ return;
4205
+ }
4206
+ const address = server.address();
4207
+ if (address === null || typeof address === "string") {
4208
+ reject(new Error("OAuth listener has no TCP address"));
4209
+ return;
4210
+ }
4211
+ resolve(address.port);
4212
+ });
4213
+ } catch (error) {
4214
+ cleanup();
4215
+ reject(error);
4216
+ }
4132
4217
  });
4133
4218
  }
4134
- function waitForAuthorizationCode(server, authorizationUrl, options, callbackPath) {
4219
+ function waitForAuthorizationCode(server, authorizationUrl, options, callbackPath, signal) {
4220
+ signal.throwIfAborted();
4135
4221
  const expectedAuthorization = readExpectedAuthorizationCallback(authorizationUrl);
4136
4222
  return new Promise((resolve, reject) => {
4137
4223
  let settled = false;
4138
4224
  const settle = (fn) => {
4139
- if (!settled) {
4140
- settled = true;
4141
- fn();
4142
- }
4225
+ if (settled)
4226
+ return;
4227
+ settled = true;
4228
+ server.off("request", request);
4229
+ signal.removeEventListener("abort", aborted);
4230
+ fn();
4143
4231
  };
4144
- server.on("request", (req, res) => {
4145
- const url = new URL(req.url ?? "/", "http://127.0.0.1");
4232
+ const aborted = () => settle(() => reject(signal.reason));
4233
+ const request = (req, res) => {
4234
+ let url;
4235
+ try {
4236
+ url = new URL(req.url ?? "/", "http://127.0.0.1");
4237
+ } catch {
4238
+ res.writeHead(400);
4239
+ res.end("Invalid callback URL");
4240
+ return;
4241
+ }
4146
4242
  if (url.pathname !== callbackPath) {
4147
4243
  res.writeHead(404);
4148
4244
  res.end("Not found");
@@ -4157,21 +4253,8 @@ function waitForAuthorizationCode(server, authorizationUrl, options, callbackPat
4157
4253
  };
4158
4254
  try {
4159
4255
  validateAuthorizationCallbackBinding(callbackParameters, expectedAuthorization);
4160
- } catch (error) {
4161
- res.writeHead(400);
4162
- res.end(error instanceof Error ? error.message : "Invalid OAuth callback");
4163
- settle(() => reject(error instanceof Error ? error : new Error(String(error))));
4164
- return;
4165
- }
4166
- const authorizationError = callbackParameters.error;
4167
- if (authorizationError !== null) {
4168
- const description = callbackParameters.errorDescription ?? authorizationError;
4169
- res.writeHead(400);
4170
- res.end(`Authorization failed: ${description}`);
4171
- settle(() => reject(createAuthorizationError(authorizationError, description)));
4172
- return;
4173
- }
4174
- try {
4256
+ if (callbackParameters.error !== null)
4257
+ throw createAuthorizationError(callbackParameters.error, callbackParameters.errorDescription ?? callbackParameters.error);
4175
4258
  const code = validateAuthorizationCallbackParameters(callbackParameters, expectedAuthorization);
4176
4259
  res.writeHead(200, { "Content-Type": "text/html" });
4177
4260
  res.end(buildSuccessPage(options.landingPage));
@@ -4179,35 +4262,27 @@ function waitForAuthorizationCode(server, authorizationUrl, options, callbackPat
4179
4262
  } catch (error) {
4180
4263
  res.writeHead(400);
4181
4264
  res.end(error instanceof Error ? error.message : "Invalid OAuth callback");
4182
- settle(() => reject(error instanceof Error ? error : new Error(String(error))));
4265
+ settle(() => reject(error));
4183
4266
  }
4184
- });
4267
+ };
4268
+ server.on("request", request);
4269
+ signal.addEventListener("abort", aborted, { once: true });
4185
4270
  if (options.readLine !== void 0) {
4186
- options.readLine().then((input) => {
4187
- const callbackParameters = extractCallbackParametersFromInput(input);
4188
- if (callbackParameters === null) {
4189
- settle(() => reject(new Error("OAuth callback missing authorization code")));
4271
+ void Promise.resolve().then(() => settled ? void 0 : options.readLine()).then((input) => {
4272
+ if (settled)
4190
4273
  return;
4191
- }
4192
- try {
4193
- validateAuthorizationCallbackBinding(callbackParameters, expectedAuthorization);
4194
- if (callbackParameters.error !== null) {
4195
- const description = callbackParameters.errorDescription ?? callbackParameters.error;
4196
- throw createAuthorizationError(callbackParameters.error, description);
4197
- }
4198
- const code = validateAuthorizationCallbackParameters(callbackParameters, expectedAuthorization);
4199
- settle(() => resolve(code));
4200
- } catch (error) {
4201
- settle(() => reject(error instanceof Error ? error : new Error(String(error))));
4202
- }
4203
- }).catch((error) => {
4204
- settle(() => reject(error instanceof Error ? error : new Error(String(error))));
4205
- });
4274
+ const callbackParameters = extractCallbackParametersFromInput(input);
4275
+ if (callbackParameters === null)
4276
+ throw new Error("OAuth callback missing authorization code");
4277
+ validateAuthorizationCallbackBinding(callbackParameters, expectedAuthorization);
4278
+ if (callbackParameters.error !== null)
4279
+ throw createAuthorizationError(callbackParameters.error, callbackParameters.errorDescription ?? callbackParameters.error);
4280
+ const code = validateAuthorizationCallbackParameters(callbackParameters, expectedAuthorization);
4281
+ settle(() => resolve(code));
4282
+ }).catch((error) => settle(() => reject(error)));
4206
4283
  }
4207
4284
  if (options.openBrowser !== void 0) {
4208
- options.openBrowser(authorizationUrl).catch((error) => {
4209
- settle(() => reject(error));
4210
- });
4285
+ void Promise.resolve().then(() => settled ? void 0 : options.openBrowser(authorizationUrl)).catch((error) => settle(() => reject(error)));
4211
4286
  }
4212
4287
  });
4213
4288
  }
@@ -4387,6 +4462,7 @@ async function exchangeAuthorizationCode(input) {
4387
4462
  resource
4388
4463
  },
4389
4464
  fetch: input.fetch,
4465
+ signal: input.signal,
4390
4466
  now: input.now
4391
4467
  });
4392
4468
  }
@@ -4402,6 +4478,7 @@ async function refreshAccessToken(input) {
4402
4478
  resource
4403
4479
  },
4404
4480
  fetch: input.fetch,
4481
+ signal: input.signal,
4405
4482
  now: input.now
4406
4483
  });
4407
4484
  }
@@ -4413,7 +4490,9 @@ async function requestTokens(input) {
4413
4490
  if (input.clientSecret !== void 0) {
4414
4491
  body.set("client_secret", input.clientSecret);
4415
4492
  }
4416
- const signal = AbortSignal.timeout(3e4);
4493
+ input.signal?.throwIfAborted();
4494
+ const deadline = AbortSignal.timeout(3e4);
4495
+ const signal = input.signal === void 0 ? deadline : AbortSignal.any([input.signal, deadline]);
4417
4496
  const response = await fetchMcpResponse(input.fetch, input.tokenEndpoint, {
4418
4497
  method: "POST",
4419
4498
  headers: {
@@ -4525,7 +4604,7 @@ function createDefaultOAuthClientProvider(options) {
4525
4604
  async authorizeRequest(input) {
4526
4605
  assertNoAccessTokenInUrl(input.requestUrl, "Protected resource request URL");
4527
4606
  const requestUrl = canonicalizeResourceIndicator(input.requestUrl);
4528
- const session = await ensureAuthorizedSession(requestUrl, void 0, input.fetch, false);
4607
+ const session = await ensureAuthorizedSession(requestUrl, void 0, input.fetch, false, false, input.signal);
4529
4608
  const accessToken = session?.tokens?.accessToken;
4530
4609
  if (session === null || accessToken === void 0 || session.tokens === void 0 || isExpired(session.tokens, now)) {
4531
4610
  return;
@@ -4543,12 +4622,13 @@ function createDefaultOAuthClientProvider(options) {
4543
4622
  const session = await ensureAuthorizedSession(resource, {
4544
4623
  ...input.discovery,
4545
4624
  resource
4546
- }, input.fetch, true, forceRefresh);
4625
+ }, input.fetch, true, forceRefresh, input.signal);
4547
4626
  if (session?.tokens?.accessToken === void 0) {
4548
4627
  return { action: "fail" };
4549
4628
  }
4550
4629
  return { action: "retry" };
4551
4630
  } catch (error) {
4631
+ input.signal?.throwIfAborted();
4552
4632
  return {
4553
4633
  action: "fail",
4554
4634
  error: error instanceof Error ? error : new Error(String(error))
@@ -4556,9 +4636,11 @@ function createDefaultOAuthClientProvider(options) {
4556
4636
  }
4557
4637
  }
4558
4638
  };
4559
- async function ensureAuthorizedSession(resource, discovery, fetch2, allowInteractive, forceRefresh = false) {
4639
+ async function ensureAuthorizedSession(resource, discovery, fetch2, allowInteractive, forceRefresh = false, signal) {
4640
+ signal?.throwIfAborted();
4560
4641
  const canonicalResource = canonicalizeResourceIndicator(resource);
4561
4642
  let session = await loadSession(canonicalResource);
4643
+ signal?.throwIfAborted();
4562
4644
  if (discovery !== void 0 && getOwnString2(discovery.authorizationServerMetadata, "issuer") !== discovery.authorizationServer) {
4563
4645
  throw new Error("OAuth discovery authorization-server issuer mismatch");
4564
4646
  }
@@ -4571,7 +4653,7 @@ function createDefaultOAuthClientProvider(options) {
4571
4653
  return session;
4572
4654
  }
4573
4655
  if (session?.tokens?.refreshToken !== void 0 && sessionDiscovery !== void 0 && (forceRefresh || isExpired(session.tokens, now))) {
4574
- session = await refreshSession(canonicalResource, session, sessionDiscovery, fetch2);
4656
+ session = await refreshSession(canonicalResource, session, sessionDiscovery, fetch2, signal);
4575
4657
  if (session?.tokens !== void 0 && !isExpired(session.tokens, now)) {
4576
4658
  return session;
4577
4659
  }
@@ -4583,9 +4665,12 @@ function createDefaultOAuthClientProvider(options) {
4583
4665
  if (!allowInteractive || sessionDiscovery === void 0) {
4584
4666
  return session;
4585
4667
  }
4586
- return authorizeSession(canonicalResource, session, sessionDiscovery, fetch2);
4668
+ if (options.allowInteractive === false)
4669
+ throw new Error("OAuth interactive authorization is disabled");
4670
+ return authorizeSession(canonicalResource, session, sessionDiscovery, fetch2, signal);
4587
4671
  }
4588
- async function refreshSession(resource, session, discovery, fetch2) {
4672
+ async function refreshSession(resource, session, discovery, fetch2, signal) {
4673
+ signal?.throwIfAborted();
4589
4674
  assertSecureOAuthFlowEndpoints(discovery.authorizationServerMetadata);
4590
4675
  const inFlight = refreshPromises.get(resource);
4591
4676
  if (inFlight !== void 0) {
@@ -4607,10 +4692,12 @@ function createDefaultOAuthClientProvider(options) {
4607
4692
  refreshToken: session.tokens.refreshToken,
4608
4693
  resource,
4609
4694
  fetch: fetch2,
4695
+ signal,
4610
4696
  now
4611
4697
  });
4612
4698
  break;
4613
4699
  } catch (error) {
4700
+ signal?.throwIfAborted();
4614
4701
  if (error instanceof OAuthError && error.error === "invalid_grant") {
4615
4702
  const clearedSession = clearSessionTokens(session);
4616
4703
  await saveSession(resource, clearedSession);
@@ -4645,7 +4732,8 @@ function createDefaultOAuthClientProvider(options) {
4645
4732
  refreshPromises.set(resource, promise);
4646
4733
  return promise;
4647
4734
  }
4648
- async function authorizeSession(resource, existingSession, discovery, fetch2) {
4735
+ async function authorizeSession(resource, existingSession, discovery, fetch2, signal) {
4736
+ signal?.throwIfAborted();
4649
4737
  const inFlight = authorizationPromises.get(resource);
4650
4738
  if (inFlight !== void 0) {
4651
4739
  return inFlight;
@@ -4661,11 +4749,14 @@ function createDefaultOAuthClientProvider(options) {
4661
4749
  openBrowser: options.browser.openBrowser,
4662
4750
  readLine: options.browser.readLine,
4663
4751
  createServer: options.browser.createServer,
4664
- landingPage: options.browser.landingPage
4752
+ landingPage: options.browser.landingPage,
4753
+ redirectUri: options.browser.redirectUri,
4754
+ signal: options.browser.signal === void 0 ? signal : signal === void 0 ? options.browser.signal : AbortSignal.any([signal, options.browser.signal]),
4755
+ timeoutMs: options.browser.timeoutMs
4665
4756
  });
4666
4757
  let resolvedClient = null;
4667
4758
  try {
4668
- resolvedClient = await resolveClient(currentSession, discovery, loopback.redirectUri, fetch2);
4759
+ resolvedClient = await resolveClient(currentSession, discovery, loopback.redirectUri, fetch2, signal);
4669
4760
  const sessionWithoutTokens = {
4670
4761
  resource,
4671
4762
  authorizationServer: discovery.authorizationServer,
@@ -4693,6 +4784,7 @@ function createDefaultOAuthClientProvider(options) {
4693
4784
  redirectUri: loopback.redirectUri,
4694
4785
  resource,
4695
4786
  fetch: fetch2,
4787
+ signal,
4696
4788
  now
4697
4789
  });
4698
4790
  const session = {
@@ -4702,6 +4794,7 @@ function createDefaultOAuthClientProvider(options) {
4702
4794
  await saveSession(resource, session);
4703
4795
  return session;
4704
4796
  } catch (error) {
4797
+ signal?.throwIfAborted();
4705
4798
  if (shouldReRegisterStoredDynamicClient(error, resolvedClient, reRegistrationAttempted)) {
4706
4799
  reRegistrationAttempted = true;
4707
4800
  await clearRegisteredClient(discovery.authorizationServer);
@@ -4727,7 +4820,8 @@ function createDefaultOAuthClientProvider(options) {
4727
4820
  authorizationPromises.set(resource, finalPromise);
4728
4821
  return finalPromise;
4729
4822
  }
4730
- async function resolveClient(existingSession, discovery, redirectUri, fetch2) {
4823
+ async function resolveClient(existingSession, discovery, redirectUri, fetch2, parentSignal) {
4824
+ parentSignal?.throwIfAborted();
4731
4825
  const configuredClient = normalizeConfiguredClient(options.client);
4732
4826
  if (options.client.mode === "static") {
4733
4827
  if (configuredClient === null) {
@@ -4777,7 +4871,8 @@ function createDefaultOAuthClientProvider(options) {
4777
4871
  }
4778
4872
  }
4779
4873
  const registrationBody = buildClientRegistrationBody(getClientMetadata(options.client), redirectUri);
4780
- const signal = AbortSignal.timeout(3e4);
4874
+ const deadline = AbortSignal.timeout(3e4);
4875
+ const signal = parentSignal === void 0 ? deadline : AbortSignal.any([parentSignal, deadline]);
4781
4876
  const response = await fetchMcpResponse(fetch2, registrationEndpoint, {
4782
4877
  method: "POST",
4783
4878
  headers: {
@@ -5340,8 +5435,10 @@ async function readJsonResponse(response, label, signal) {
5340
5435
  throw new Error(`${label} response must be valid JSON`);
5341
5436
  }
5342
5437
  }
5343
- async function fetchMetadata(fetch2, location, label) {
5344
- const signal = AbortSignal.timeout(1e4);
5438
+ async function fetchMetadata(fetch2, location, label, parentSignal) {
5439
+ parentSignal?.throwIfAborted();
5440
+ const deadline = AbortSignal.timeout(1e4);
5441
+ const signal = parentSignal === void 0 ? deadline : AbortSignal.any([deadline, parentSignal]);
5345
5442
  const response = await fetchMcpResponse(fetch2, location, {
5346
5443
  method: "GET",
5347
5444
  headers: { Accept: "application/json" },
@@ -5443,7 +5540,7 @@ var OAuthMetadataDiscovery = class {
5443
5540
  this.fetchImpl = fetch2;
5444
5541
  this.cache = cache;
5445
5542
  }
5446
- async discoverProtectedResource(resource, resourceMetadataUrl) {
5543
+ async discoverProtectedResource(resource, resourceMetadataUrl, signal) {
5447
5544
  const locations = /* @__PURE__ */ new Set([resolveProtectedResourceMetadataUrl(resource, resourceMetadataUrl)]);
5448
5545
  if (resourceMetadataUrl === void 0) {
5449
5546
  locations.add(new URL("/.well-known/oauth-protected-resource", resource).toString());
@@ -5452,17 +5549,19 @@ var OAuthMetadataDiscovery = class {
5452
5549
  for (const location of locations) {
5453
5550
  try {
5454
5551
  const metadata = validateProtectedResourceMetadata(
5455
- await fetchMetadata(this.fetchImpl, location, "Protected resource metadata"),
5552
+ await fetchMetadata(this.fetchImpl, location, "Protected resource metadata", signal),
5456
5553
  resource
5457
5554
  );
5458
5555
  return { location, metadata };
5459
5556
  } catch (error) {
5557
+ signal?.throwIfAborted();
5460
5558
  lastError = error;
5461
5559
  }
5462
5560
  }
5463
5561
  throw lastError;
5464
5562
  }
5465
- async discover(resourceUrl, { resourceMetadataUrl } = {}) {
5563
+ async discover(resourceUrl, { resourceMetadataUrl, signal } = {}) {
5564
+ signal?.throwIfAborted();
5466
5565
  const cacheKey = canonicalizeResourceIndicator(resourceUrl);
5467
5566
  resolveProtectedResourceMetadataUrl(cacheKey, resourceMetadataUrl);
5468
5567
  const memoryCachedResult = this.memoryCache.get(cacheKey);
@@ -5470,6 +5569,7 @@ var OAuthMetadataDiscovery = class {
5470
5569
  return structuredClone(memoryCachedResult);
5471
5570
  }
5472
5571
  const sharedCachedResult = await this.cache?.get(cacheKey);
5572
+ signal?.throwIfAborted();
5473
5573
  if (sharedCachedResult !== null && sharedCachedResult !== void 0 && resourceMetadataUrl === void 0) {
5474
5574
  try {
5475
5575
  const result = validateCachedDiscovery(sharedCachedResult, cacheKey);
@@ -5479,7 +5579,7 @@ var OAuthMetadataDiscovery = class {
5479
5579
  await this.cache?.delete?.(cacheKey);
5480
5580
  }
5481
5581
  }
5482
- const { location: resourceMetadataLocation, metadata: resourceMetadata } = await this.discoverProtectedResource(cacheKey, resourceMetadataUrl);
5582
+ const { location: resourceMetadataLocation, metadata: resourceMetadata } = await this.discoverProtectedResource(cacheKey, resourceMetadataUrl, signal);
5483
5583
  const authorizationServerErrors = [];
5484
5584
  for (const authorizationServer of resourceMetadata.authorization_servers) {
5485
5585
  const normalizedAuthorizationServer = validateAuthorizationServerIssuer(authorizationServer);
@@ -5487,7 +5587,7 @@ var OAuthMetadataDiscovery = class {
5487
5587
  for (const authorizationServerMetadataUrl of metadataLocations) {
5488
5588
  try {
5489
5589
  const authorizationServerMetadata = validateAuthorizationServerMetadata(
5490
- await fetchMetadata(this.fetchImpl, authorizationServerMetadataUrl, "Authorization server metadata"),
5590
+ await fetchMetadata(this.fetchImpl, authorizationServerMetadataUrl, "Authorization server metadata", signal),
5491
5591
  normalizedAuthorizationServer
5492
5592
  );
5493
5593
  const result = {
@@ -5502,6 +5602,7 @@ var OAuthMetadataDiscovery = class {
5502
5602
  await this.cache?.set(cacheKey, structuredClone(result));
5503
5603
  return result;
5504
5604
  } catch (error) {
5605
+ signal?.throwIfAborted();
5505
5606
  authorizationServerErrors.push(
5506
5607
  `${authorizationServerMetadataUrl}: ${error instanceof Error ? error.message : String(error)}`
5507
5608
  );
@@ -6642,6 +6743,7 @@ var HttpTransport = class {
6642
6743
  oauthProvider;
6643
6744
  oauthMetadataDiscovery;
6644
6745
  inFlightFetchAbortControllers = /* @__PURE__ */ new Set();
6746
+ inFlightOAuthAbortControllers = /* @__PURE__ */ new Set();
6645
6747
  openResponseReaders = /* @__PURE__ */ new Set();
6646
6748
  modernRequests = /* @__PURE__ */ new Map();
6647
6749
  modernMode = false;
@@ -6711,7 +6813,7 @@ var HttpTransport = class {
6711
6813
  this.rejectLegacyEndpoint = void 0;
6712
6814
  this.resolveLegacyEndpoint = void 0;
6713
6815
  this.toolParameterHeaders.clear();
6714
- this.abortInFlightFetches();
6816
+ this.abortInFlightFetches(reason);
6715
6817
  this.cancelOpenResponseReaders();
6716
6818
  if (!this.writeStream.destroyed && !this.writeStream.writableEnded) {
6717
6819
  this.writeStream.end();
@@ -6747,12 +6849,14 @@ var HttpTransport = class {
6747
6849
  this.resolveClosed = void 0;
6748
6850
  resolveClosed?.({ reason: closeReason });
6749
6851
  }
6750
- abortInFlightFetches() {
6751
- for (const controller of this.modernRequests.values()) controller.abort();
6852
+ abortInFlightFetches(reason) {
6853
+ for (const controller of this.modernRequests.values()) controller.abort(reason);
6752
6854
  this.modernRequests.clear();
6753
6855
  for (const abortController of this.inFlightFetchAbortControllers) {
6754
- abortController.abort();
6856
+ abortController.abort(reason);
6755
6857
  }
6858
+ for (const controller of this.inFlightOAuthAbortControllers) controller.abort(reason);
6859
+ this.inFlightOAuthAbortControllers.clear();
6756
6860
  this.inFlightFetchAbortControllers.clear();
6757
6861
  }
6758
6862
  cancelOpenResponseReaders() {
@@ -6818,7 +6922,7 @@ var HttpTransport = class {
6818
6922
  const response = await this.fetchWithOAuthRetry({
6819
6923
  url: postUrl,
6820
6924
  method: "POST",
6821
- createHeaders: () => this.createPostHeaders(message, modern),
6925
+ createHeaders: (signal) => this.createPostHeaders(message, modern, signal),
6822
6926
  body: line,
6823
6927
  controller
6824
6928
  });
@@ -6858,7 +6962,7 @@ var HttpTransport = class {
6858
6962
  this.modernRequests.delete(id);
6859
6963
  }
6860
6964
  }
6861
- async createPostHeaders(message, modern = false) {
6965
+ async createPostHeaders(message, modern = false, signal) {
6862
6966
  const headers = new Headers(this.headers);
6863
6967
  headers.set("Accept", "application/json, text/event-stream");
6864
6968
  headers.set("Content-Type", "application/json");
@@ -6888,9 +6992,9 @@ var HttpTransport = class {
6888
6992
  headers.set("Mcp-Session-Id", this.sessionId);
6889
6993
  headers.set("MCP-Protocol-Version", MCP_PROTOCOL_VERSION);
6890
6994
  }
6891
- return this.authorizeRequestHeaders(headers);
6995
+ return this.authorizeRequestHeaders(headers, signal);
6892
6996
  }
6893
- async createGetHeaders() {
6997
+ async createGetHeaders(signal) {
6894
6998
  const headers = new Headers(this.headers);
6895
6999
  headers.set("Accept", "text/event-stream");
6896
7000
  if (this.sessionId !== void 0) {
@@ -6900,20 +7004,26 @@ var HttpTransport = class {
6900
7004
  if (this.lastEventId !== void 0) {
6901
7005
  headers.set("Last-Event-ID", this.lastEventId);
6902
7006
  }
6903
- return this.authorizeRequestHeaders(headers);
7007
+ return this.authorizeRequestHeaders(headers, signal);
6904
7008
  }
6905
- async createDeleteHeaders(sessionId) {
7009
+ async createDeleteHeaders(sessionId, signal) {
6906
7010
  const headers = new Headers(this.headers);
6907
7011
  headers.set("Mcp-Session-Id", sessionId);
6908
7012
  headers.set("MCP-Protocol-Version", MCP_PROTOCOL_VERSION);
6909
- return this.authorizeRequestHeaders(headers);
7013
+ return this.authorizeRequestHeaders(headers, signal);
6910
7014
  }
6911
- async authorizeRequestHeaders(headers) {
7015
+ async authorizeRequestHeaders(headers, signal) {
7016
+ signal?.throwIfAborted();
6912
7017
  await this.oauthProvider?.authorizeRequest?.({
6913
7018
  requestUrl: new URL(this.url),
6914
7019
  headers,
6915
- fetch: this.fetchImpl
7020
+ signal,
7021
+ fetch: (url, init) => fetchMcpResponse(this.fetchImpl, url, {
7022
+ ...init,
7023
+ signal: signal === void 0 ? init?.signal : init?.signal == null ? signal : AbortSignal.any([signal, init.signal])
7024
+ })
6916
7025
  });
7026
+ signal?.throwIfAborted();
6917
7027
  return headers;
6918
7028
  }
6919
7029
  captureSessionId(response) {
@@ -6950,7 +7060,7 @@ var HttpTransport = class {
6950
7060
  return this.legacyEndpointReady;
6951
7061
  }
6952
7062
  async sendSessionTerminationRequest(sessionId, signal) {
6953
- const headers = await this.createDeleteHeaders(sessionId);
7063
+ const headers = await this.createDeleteHeaders(sessionId, signal);
6954
7064
  signal.throwIfAborted();
6955
7065
  const response = await fetchMcpResponse(this.fetchImpl, this.url, {
6956
7066
  method: "DELETE",
@@ -6973,7 +7083,7 @@ var HttpTransport = class {
6973
7083
  async consumeGetSseStream() {
6974
7084
  const response = await this.fetchWithOAuthRetry({
6975
7085
  method: "GET",
6976
- createHeaders: () => this.createGetHeaders()
7086
+ createHeaders: (signal) => this.createGetHeaders(signal)
6977
7087
  });
6978
7088
  if (this.disposed) {
6979
7089
  void response.body?.cancel().catch(() => void 0);
@@ -7056,7 +7166,7 @@ var HttpTransport = class {
7056
7166
  const message = responseBody.length === 0 ? `HTTP transport POST failed (${statusDescriptor})` : `HTTP transport POST failed (${statusDescriptor}): ${responseBody}`;
7057
7167
  throw new HttpTransportError(message, response.status, "POST");
7058
7168
  }
7059
- async maybeHandleUnauthorizedResponse(response) {
7169
+ async maybeHandleUnauthorizedResponse(response, signal) {
7060
7170
  if (response.status !== 401 || this.oauthProvider === void 0) {
7061
7171
  return false;
7062
7172
  }
@@ -7067,7 +7177,7 @@ var HttpTransport = class {
7067
7177
  const challenge = parseBearerWwwAuthenticateHeader(response.headers.get("WWW-Authenticate"));
7068
7178
  const resourceMetadataUrl = challenge?.params.resource_metadata;
7069
7179
  try {
7070
- const discovery = await discoveryClient.discover(this.url, { resourceMetadataUrl });
7180
+ const discovery = await discoveryClient.discover(this.url, { resourceMetadataUrl, signal });
7071
7181
  const providerResponse = response.clone();
7072
7182
  let result;
7073
7183
  try {
@@ -7076,8 +7186,13 @@ var HttpTransport = class {
7076
7186
  response: providerResponse,
7077
7187
  challenge,
7078
7188
  discovery,
7079
- fetch: this.fetchImpl
7189
+ signal,
7190
+ fetch: (url, init) => fetchMcpResponse(this.fetchImpl, url, {
7191
+ ...init,
7192
+ signal: init?.signal == null ? signal : AbortSignal.any([signal, init.signal])
7193
+ })
7080
7194
  });
7195
+ signal.throwIfAborted();
7081
7196
  } finally {
7082
7197
  void providerResponse.body?.cancel().catch(() => void 0);
7083
7198
  }
@@ -7207,25 +7322,30 @@ var HttpTransport = class {
7207
7322
  `);
7208
7323
  }
7209
7324
  async fetchWithOAuthRetry(input) {
7210
- const request = async () => this.fetchWithAbort(
7211
- input.url ?? this.url,
7212
- {
7325
+ const controller = input.controller ?? new AbortController();
7326
+ this.inFlightOAuthAbortControllers.add(controller);
7327
+ const request = async () => {
7328
+ controller.signal.throwIfAborted();
7329
+ const headers = await input.createHeaders(controller.signal);
7330
+ controller.signal.throwIfAborted();
7331
+ return this.fetchWithAbort(input.url ?? this.url, {
7213
7332
  method: input.method,
7214
- headers: await input.createHeaders(),
7333
+ headers,
7215
7334
  body: input.body
7216
- },
7217
- input.controller
7218
- );
7219
- let response = await request();
7220
- if (await this.maybeHandleUnauthorizedResponse(response)) {
7221
- response = await request();
7222
- }
7223
- const oauthError = this.oauthProvider === void 0 ? null : this.readOAuthChallengeError(response);
7224
- if (oauthError !== null) {
7225
- void response.body?.cancel().catch(() => void 0);
7226
- throw oauthError;
7335
+ }, controller);
7336
+ };
7337
+ try {
7338
+ let response = await request();
7339
+ if (await this.maybeHandleUnauthorizedResponse(response, controller.signal)) response = await request();
7340
+ const oauthError = this.oauthProvider === void 0 ? null : this.readOAuthChallengeError(response);
7341
+ if (oauthError !== null) {
7342
+ void response.body?.cancel().catch(() => void 0);
7343
+ throw oauthError;
7344
+ }
7345
+ return response;
7346
+ } finally {
7347
+ this.inFlightOAuthAbortControllers.delete(controller);
7227
7348
  }
7228
- return response;
7229
7349
  }
7230
7350
  readOAuthChallengeError(response) {
7231
7351
  if (response.status !== 401 && response.status !== 403) {