@mcp-use/client 2.4.3 → 2.4.4-canary.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js CHANGED
@@ -446,6 +446,95 @@ var init_json_schema_validator = __esm({
446
446
  }
447
447
  });
448
448
 
449
+ // src/transport/mcp-param-headers.ts
450
+ function sdkMirrorsMcpParamHeaders() {
451
+ const g = globalThis;
452
+ return g.window === void 0 || g.document === void 0;
453
+ }
454
+ function collectDeclarations(schema, path2, seen, out) {
455
+ if (schema === null || typeof schema !== "object") return;
456
+ const node = schema;
457
+ const headerName = node[X_MCP_HEADER_KEY];
458
+ if (path2.length > 0 && typeof headerName === "string" && RFC9110_TOKEN.test(headerName) && typeof node.type === "string" && PERMITTED_TYPES.has(node.type) && !seen.has(headerName.toLowerCase())) {
459
+ seen.add(headerName.toLowerCase());
460
+ out.push({ path: path2, headerName });
461
+ }
462
+ const properties = node.properties;
463
+ if (properties !== null && typeof properties === "object") {
464
+ for (const [key, child] of Object.entries(properties)) {
465
+ collectDeclarations(child, [...path2, key], seen, out);
466
+ }
467
+ }
468
+ }
469
+ function valueAtPath(root, path2) {
470
+ let node = root;
471
+ for (const key of path2) {
472
+ if (node === null || typeof node !== "object") return void 0;
473
+ node = node[key];
474
+ }
475
+ return node;
476
+ }
477
+ function primitiveToString(value) {
478
+ if (typeof value === "string") return value;
479
+ if (typeof value === "boolean") return value ? "true" : "false";
480
+ if (typeof value === "number") {
481
+ if (!Number.isFinite(value)) return void 0;
482
+ if (Number.isInteger(value) && !Number.isSafeInteger(value)) {
483
+ return void 0;
484
+ }
485
+ return String(value);
486
+ }
487
+ return void 0;
488
+ }
489
+ function needsBase64(value) {
490
+ if (value.length === 0) return true;
491
+ if (value.startsWith(BASE64_SENTINEL_PREFIX) && value.endsWith(BASE64_SENTINEL_SUFFIX)) {
492
+ return true;
493
+ }
494
+ if (value !== value.trim()) return true;
495
+ for (let i = 0; i < value.length; i++) {
496
+ const code = value.charCodeAt(i);
497
+ if (code === 9 || code >= 32 && code <= 126) continue;
498
+ return true;
499
+ }
500
+ return false;
501
+ }
502
+ function utf8ToBase64(value) {
503
+ let binary = "";
504
+ for (const byte of new TextEncoder().encode(value)) {
505
+ binary += String.fromCharCode(byte);
506
+ }
507
+ return btoa(binary);
508
+ }
509
+ function encodeValue(value) {
510
+ return needsBase64(value) ? `${BASE64_SENTINEL_PREFIX}${utf8ToBase64(value)}${BASE64_SENTINEL_SUFFIX}` : value;
511
+ }
512
+ function buildMcpParamHeaders(inputSchema, args) {
513
+ const declarations = [];
514
+ collectDeclarations(inputSchema, [], /* @__PURE__ */ new Set(), declarations);
515
+ const headers = {};
516
+ for (const { path: path2, headerName } of declarations) {
517
+ const raw = valueAtPath(args, path2);
518
+ if (raw === void 0 || raw === null) continue;
519
+ const value = primitiveToString(raw);
520
+ if (value === void 0) continue;
521
+ headers[`${MCP_PARAM_HEADER_PREFIX}${headerName}`] = encodeValue(value);
522
+ }
523
+ return headers;
524
+ }
525
+ var MCP_PARAM_HEADER_PREFIX, X_MCP_HEADER_KEY, RFC9110_TOKEN, PERMITTED_TYPES, BASE64_SENTINEL_PREFIX, BASE64_SENTINEL_SUFFIX;
526
+ var init_mcp_param_headers = __esm({
527
+ "src/transport/mcp-param-headers.ts"() {
528
+ "use strict";
529
+ MCP_PARAM_HEADER_PREFIX = "Mcp-Param-";
530
+ X_MCP_HEADER_KEY = "x-mcp-header";
531
+ RFC9110_TOKEN = /^[!#$%&'*+\-.^_`|~0-9A-Za-z]+$/;
532
+ PERMITTED_TYPES = /* @__PURE__ */ new Set(["string", "integer", "boolean", "number"]);
533
+ BASE64_SENTINEL_PREFIX = "=?base64?";
534
+ BASE64_SENTINEL_SUFFIX = "?=";
535
+ }
536
+ });
537
+
449
538
  // src/transport/base.ts
450
539
  var passthroughResultSchema, BaseConnector;
451
540
  var init_base = __esm({
@@ -454,6 +543,7 @@ var init_base = __esm({
454
543
  init_logging();
455
544
  init_flow();
456
545
  init_connector_telemetry();
546
+ init_mcp_param_headers();
457
547
  passthroughResultSchema = {
458
548
  "~standard": {
459
549
  version: 1,
@@ -913,7 +1003,7 @@ var init_base = __esm({
913
1003
  if (!this.client) {
914
1004
  throw new Error("MCP client is not connected");
915
1005
  }
916
- const enhancedOptions = options ? { ...options } : void 0;
1006
+ let enhancedOptions = options ? { ...options } : void 0;
917
1007
  if (enhancedOptions?.resetTimeoutOnProgress && !enhancedOptions.onprogress) {
918
1008
  enhancedOptions.onprogress = () => {
919
1009
  };
@@ -921,6 +1011,16 @@ var init_base = __esm({
921
1011
  `[BaseConnector] Added onprogress callback for tool '${name}' to enable progressToken`
922
1012
  );
923
1013
  }
1014
+ if (this.protocolEra === "modern" && !sdkMirrorsMcpParamHeaders()) {
1015
+ const tool = this.toolsCache?.find((t) => t.name === name);
1016
+ const paramHeaders = tool ? buildMcpParamHeaders(tool.inputSchema, args) : {};
1017
+ if (Object.keys(paramHeaders).length > 0) {
1018
+ enhancedOptions = {
1019
+ ...enhancedOptions,
1020
+ headers: { ...enhancedOptions?.headers, ...paramHeaders }
1021
+ };
1022
+ }
1023
+ }
924
1024
  logger.debug(`Calling tool '${name}' with args`, args);
925
1025
  const res = await this.executeRequest(
926
1026
  () => this.client.callTool({ name, arguments: args }, enhancedOptions)
@@ -1559,7 +1659,7 @@ init_connector_telemetry();
1559
1659
  init_logging();
1560
1660
 
1561
1661
  // src/utils/version.ts
1562
- var VERSION = "2.4.3";
1662
+ var VERSION = "2.4.4-canary.1";
1563
1663
  function getPackageVersion() {
1564
1664
  return VERSION;
1565
1665
  }
@@ -2297,7 +2397,11 @@ var OAuthSessionStore = class _OAuthSessionStore {
2297
2397
  if (legacyData) {
2298
2398
  try {
2299
2399
  const legacyValue = JSON.parse(legacyData);
2300
- if (!legacyValue.issuer || legacyValue.issuer === ctx.issuer) {
2400
+ if (typeof legacyValue.issuer !== "string" || !legacyValue.issuer.trim()) {
2401
+ await this.store.remove(legacyKey);
2402
+ return void 0;
2403
+ }
2404
+ if (legacyValue.issuer === ctx.issuer) {
2301
2405
  const migratedValue = {
2302
2406
  ...legacyValue,
2303
2407
  issuer: ctx.issuer
@@ -2315,7 +2419,12 @@ var OAuthSessionStore = class _OAuthSessionStore {
2315
2419
  }
2316
2420
  if (!data) return void 0;
2317
2421
  try {
2318
- return { key, value: JSON.parse(data) };
2422
+ const value = JSON.parse(data);
2423
+ if (typeof value?.issuer !== "string" || !value.issuer.trim() || ctx && value.issuer !== ctx.issuer) {
2424
+ await this.store.remove(key);
2425
+ return void 0;
2426
+ }
2427
+ return { key, value };
2319
2428
  } catch (e) {
2320
2429
  console.warn(
2321
2430
  `[${this.storageKeyPrefix}] Failed to parse ${kind.replace("_", " ")}:`,
@@ -2984,6 +3093,7 @@ import {
2984
3093
  discoverOAuthProtectedResourceMetadata,
2985
3094
  SdkError,
2986
3095
  SdkHttpError,
3096
+ selectResourceURL,
2987
3097
  StreamableHTTPClientTransport,
2988
3098
  UnauthorizedError as UnauthorizedError2
2989
3099
  } from "@modelcontextprotocol/client";
@@ -3156,19 +3266,20 @@ var HttpConnector = class extends BaseConnector {
3156
3266
  await this.completeInteractiveAuthorization();
3157
3267
  }
3158
3268
  async discoverAuthorization() {
3159
- if (!this.detectMixedAuth || !this.oauthProvider || this.hadAccessTokenAtConnect) {
3269
+ const provider = this.oauthProvider;
3270
+ if (!this.detectMixedAuth || !provider || this.hadAccessTokenAtConnect) {
3160
3271
  return this.authorizationCache;
3161
3272
  }
3162
3273
  if (this.authorizationDiscovery) return this.authorizationDiscovery;
3163
- this.authorizationDiscovery = this.discoverMixedAuthorization().then(
3164
- (authorization) => {
3165
- if (!authorization) this.authorizationDiscovery = null;
3166
- return authorization;
3167
- }
3168
- );
3274
+ this.authorizationDiscovery = this.discoverMixedAuthorization(
3275
+ provider
3276
+ ).then((authorization) => {
3277
+ if (!authorization) this.authorizationDiscovery = null;
3278
+ return authorization;
3279
+ });
3169
3280
  return this.authorizationDiscovery;
3170
3281
  }
3171
- async discoverMixedAuthorization() {
3282
+ async discoverMixedAuthorization(provider) {
3172
3283
  const controller = new AbortController();
3173
3284
  let timeout;
3174
3285
  const discoveryTimeout = new Promise((_, reject) => {
@@ -3190,6 +3301,7 @@ var HttpConnector = class extends BaseConnector {
3190
3301
  ),
3191
3302
  discoveryTimeout
3192
3303
  ]);
3304
+ await selectResourceURL(this.baseUrl, provider, metadata);
3193
3305
  this.authorizationCache = {
3194
3306
  mode: "mixed",
3195
3307
  authenticated: false,