@mcp-use/client 2.1.0 → 2.1.1-canary.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.
@@ -128,7 +128,7 @@ var Logger = class {
128
128
  var logger = Logger.get();
129
129
 
130
130
  // src/utils/version.ts
131
- var VERSION = "2.1.0";
131
+ var VERSION = "2.1.1-canary.0";
132
132
  function getPackageVersion() {
133
133
  return VERSION;
134
134
  }
@@ -1530,29 +1530,43 @@ var BrowserOAuthClientProvider = class {
1530
1530
  * @param authorizationUrl - The fully constructed authorization URL from the SDK.
1531
1531
  */
1532
1532
  async redirectToAuthorization(authorizationUrl) {
1533
- const sanitizedAuthUrl = await this.prepareAuthorizationUrl(authorizationUrl);
1533
+ await this.prepareAuthorizationUrl(authorizationUrl);
1534
1534
  if (this.preventAutoAuth) {
1535
1535
  console.info(
1536
1536
  `[${this.storageKeyPrefix}] Auto-auth prevented. Authorization URL stored for manual trigger.`
1537
1537
  );
1538
1538
  return;
1539
1539
  }
1540
+ this.startAuthorization();
1541
+ }
1542
+ /**
1543
+ * Open the authorization URL prepared by the official SDK.
1544
+ *
1545
+ * This is the explicit-user-action counterpart to `preventAutoAuth`: the
1546
+ * provider still lets the SDK own discovery and PKCE state, while a host can
1547
+ * launch the stored authorization request later from an Authenticate button.
1548
+ */
1549
+ startAuthorization() {
1550
+ const authorizationUrl = this.lastAttemptedAuthUrl;
1551
+ if (!authorizationUrl) {
1552
+ throw new Error("No prepared OAuth authorization is available");
1553
+ }
1540
1554
  if (this.useRedirectFlow) {
1541
1555
  console.info(
1542
1556
  `[${this.storageKeyPrefix}] Redirecting to authorization URL (full-page redirect).`
1543
1557
  );
1544
- window.location.href = sanitizedAuthUrl;
1558
+ window.location.href = authorizationUrl;
1545
1559
  return;
1546
1560
  }
1547
1561
  const popupFeatures = "width=600,height=700,resizable=yes,scrollbars=yes,status=yes";
1548
1562
  try {
1549
1563
  const popup = window.open(
1550
- sanitizedAuthUrl,
1564
+ authorizationUrl,
1551
1565
  `mcp_auth_${this.serverUrlHash}`,
1552
1566
  popupFeatures
1553
1567
  );
1554
1568
  if (this.onPopupWindow) {
1555
- this.onPopupWindow(sanitizedAuthUrl, popupFeatures, popup);
1569
+ this.onPopupWindow(authorizationUrl, popupFeatures, popup);
1556
1570
  }
1557
1571
  if (!popup || popup.closed || typeof popup.closed === "undefined") {
1558
1572
  console.warn(
@@ -1931,6 +1945,7 @@ async function completeAuthorization() {
1931
1945
  // src/auth/flow.ts
1932
1946
  import {
1933
1947
  auth,
1948
+ InsufficientScopeError,
1934
1949
  UnauthorizedError
1935
1950
  } from "@modelcontextprotocol/client";
1936
1951
  var DEFAULT_AUTH_TIMEOUT_MS = 5 * 6e4;
@@ -1951,6 +1966,25 @@ function isUnauthorized(err, depth = 0) {
1951
1966
  }
1952
1967
  return false;
1953
1968
  }
1969
+ function isOAuthInteractionRequired(err, depth = 0) {
1970
+ if (!err || depth > 5) return false;
1971
+ if (err instanceof InsufficientScopeError || err instanceof UnauthorizedError) {
1972
+ return true;
1973
+ }
1974
+ if (err instanceof Error) {
1975
+ if (err.name === "InsufficientScopeError" || err.name === "UnauthorizedError") {
1976
+ return true;
1977
+ }
1978
+ if (err.cause && isOAuthInteractionRequired(err.cause, depth + 1)) {
1979
+ return true;
1980
+ }
1981
+ const data = err.data;
1982
+ if (data?.cause && isOAuthInteractionRequired(data.cause, depth + 1)) {
1983
+ return true;
1984
+ }
1985
+ }
1986
+ return false;
1987
+ }
1954
1988
  async function completeOAuthFlow(provider, serverUrl, options = {}) {
1955
1989
  const flowProvider = provider;
1956
1990
  const timeoutMs = options.timeoutMs ?? DEFAULT_AUTH_TIMEOUT_MS;
@@ -1962,14 +1996,21 @@ async function completeOAuthFlow(provider, serverUrl, options = {}) {
1962
1996
  throw new Error(`Unexpected OAuth auth() result: ${result}`);
1963
1997
  }
1964
1998
  }
1999
+ if (flowProvider.preventAutoAuth === true && typeof flowProvider.startAuthorization === "function") {
2000
+ flowProvider.startAuthorization();
2001
+ }
1965
2002
  if (typeof flowProvider.getAuthorizationResponse === "function" || typeof flowProvider.getAuthorizationCode === "function") {
1966
2003
  const response = typeof flowProvider.getAuthorizationResponse === "function" ? await flowProvider.getAuthorizationResponse() : { code: await flowProvider.getAuthorizationCode() };
1967
- await auth(provider, {
1968
- serverUrl,
1969
- authorizationCode: response.code,
1970
- ...response.iss !== void 0 ? { iss: response.iss } : {},
1971
- fetchFn
1972
- });
2004
+ if (options.finishAuthorization) {
2005
+ await options.finishAuthorization(response.code, response.iss);
2006
+ } else {
2007
+ await auth(provider, {
2008
+ serverUrl,
2009
+ authorizationCode: response.code,
2010
+ ...response.iss !== void 0 ? { iss: response.iss } : {},
2011
+ fetchFn
2012
+ });
2013
+ }
1973
2014
  return;
1974
2015
  }
1975
2016
  await waitForBrowserAuthComplete(flowProvider, timeoutMs);
@@ -2031,6 +2072,7 @@ import { auth as auth2, UnauthorizedError as UnauthorizedError3 } from "@modelco
2031
2072
  // src/transport/http.ts
2032
2073
  import {
2033
2074
  Client,
2075
+ discoverOAuthProtectedResourceMetadata,
2034
2076
  SdkError,
2035
2077
  SdkHttpError,
2036
2078
  StreamableHTTPClientTransport as StreamableHTTPClientTransport2,
@@ -2087,6 +2129,7 @@ var BaseConnector = class {
2087
2129
  toolsCache = null;
2088
2130
  capabilitiesCache = null;
2089
2131
  serverInfoCache = null;
2132
+ authorizationCache;
2090
2133
  connected = false;
2091
2134
  opts;
2092
2135
  notificationHandlers = [];
@@ -2350,6 +2393,21 @@ var BaseConnector = class {
2350
2393
  "setupElicitationHandler: Elicitation handler registered successfully"
2351
2394
  );
2352
2395
  }
2396
+ /**
2397
+ * Run one logical MCP operation. HTTP connectors override this host seam to
2398
+ * finish an SDK-started interactive OAuth flow and retry exactly once.
2399
+ */
2400
+ async executeRequest(operation) {
2401
+ return operation();
2402
+ }
2403
+ /** OAuth state discovered for the active connection, when available. */
2404
+ get authorization() {
2405
+ return this.authorizationCache;
2406
+ }
2407
+ /** Start optional OAuth for a connected mixed-auth server. */
2408
+ async authenticate() {
2409
+ throw new Error("This connector does not support interactive OAuth");
2410
+ }
2353
2411
  /**
2354
2412
  * Disconnects the SDK client and releases transport resources.
2355
2413
  *
@@ -2397,13 +2455,13 @@ var BaseConnector = class {
2397
2455
  icons: serverInfo.icons
2398
2456
  } : null;
2399
2457
  try {
2400
- const listToolsRes = await this.client.listTools(
2401
- void 0,
2402
- defaultRequestOptions
2458
+ const listToolsRes = await this.executeRequest(
2459
+ () => this.client.listTools(void 0, defaultRequestOptions)
2403
2460
  );
2404
2461
  this.toolsCache = listToolsRes.tools ?? [];
2405
2462
  logger.debug(`Fetched ${this.toolsCache.length} tools from server`);
2406
2463
  } catch (err) {
2464
+ if (isOAuthInteractionRequired(err)) throw err;
2407
2465
  const error = err;
2408
2466
  if (error.code === -32601) {
2409
2467
  logger.debug("Server does not implement tools/list, assuming no tools");
@@ -2477,9 +2535,8 @@ var BaseConnector = class {
2477
2535
  const progressHandler = enhancedOptions?.onprogress;
2478
2536
  if (progressHandler) this.activeProgressHandlers.add(progressHandler);
2479
2537
  try {
2480
- const res = await this.client.callTool(
2481
- { name, arguments: args },
2482
- enhancedOptions
2538
+ const res = await this.executeRequest(
2539
+ () => this.client.callTool({ name, arguments: args }, enhancedOptions)
2483
2540
  );
2484
2541
  logger.debug(`Tool '${name}' returned`, res);
2485
2542
  return res;
@@ -2499,7 +2556,9 @@ var BaseConnector = class {
2499
2556
  throw new Error("MCP client is not connected");
2500
2557
  }
2501
2558
  logger.debug("[listTools] Fetching fresh tools from server...");
2502
- const result = await this.client.listTools(void 0, options);
2559
+ const result = await this.executeRequest(
2560
+ () => this.client.listTools(void 0, options)
2561
+ );
2503
2562
  const tools = result.tools ? [...result.tools] : [];
2504
2563
  logger.debug(
2505
2564
  `[listTools] Returned ${tools.length} tools:`,
@@ -2519,7 +2578,9 @@ var BaseConnector = class {
2519
2578
  throw new Error("MCP client is not connected");
2520
2579
  }
2521
2580
  logger.debug("Listing resources", cursor ? `with cursor: ${cursor}` : "");
2522
- return await this.client.listResources({ cursor }, options);
2581
+ return await this.executeRequest(
2582
+ () => this.client.listResources({ cursor }, options)
2583
+ );
2523
2584
  }
2524
2585
  /**
2525
2586
  * List all resources from the server, automatically handling pagination
@@ -2537,14 +2598,16 @@ var BaseConnector = class {
2537
2598
  }
2538
2599
  try {
2539
2600
  logger.debug("Listing all resources (with auto-pagination)");
2540
- const allResources = [];
2541
- let cursor = void 0;
2542
- do {
2543
- const result = await this.client.listResources({ cursor }, options);
2544
- allResources.push(...result.resources || []);
2545
- cursor = result.nextCursor;
2546
- } while (cursor);
2547
- return { resources: allResources };
2601
+ return await this.executeRequest(async () => {
2602
+ const allResources = [];
2603
+ let cursor = void 0;
2604
+ do {
2605
+ const result = await this.client.listResources({ cursor }, options);
2606
+ allResources.push(...result.resources || []);
2607
+ cursor = result.nextCursor;
2608
+ } while (cursor);
2609
+ return { resources: allResources };
2610
+ });
2548
2611
  } catch (err) {
2549
2612
  const error = err;
2550
2613
  if (error.code === -32601) {
@@ -2565,7 +2628,9 @@ var BaseConnector = class {
2565
2628
  throw new Error("MCP client is not connected");
2566
2629
  }
2567
2630
  logger.debug("Listing resource templates");
2568
- return await this.client.listResourceTemplates(void 0, options);
2631
+ return await this.executeRequest(
2632
+ () => this.client.listResourceTemplates(void 0, options)
2633
+ );
2569
2634
  }
2570
2635
  /**
2571
2636
  * Request completion suggestions for a prompt or resource template argument
@@ -2579,7 +2644,9 @@ var BaseConnector = class {
2579
2644
  throw new Error("MCP client is not connected");
2580
2645
  }
2581
2646
  logger.debug("[complete] Requesting completions for:", params.ref);
2582
- const result = await this.client.complete(params, options);
2647
+ const result = await this.executeRequest(
2648
+ () => this.client.complete(params, options)
2649
+ );
2583
2650
  logger.debug(
2584
2651
  `[complete] Received ${result.completion.values.length} suggestions`
2585
2652
  );
@@ -2597,7 +2664,9 @@ var BaseConnector = class {
2597
2664
  throw new Error("MCP client is not connected");
2598
2665
  }
2599
2666
  logger.debug(`Reading resource ${uri}`);
2600
- const res = await this.client.readResource({ uri }, options);
2667
+ const res = await this.executeRequest(
2668
+ () => this.client.readResource({ uri }, options)
2669
+ );
2601
2670
  return res;
2602
2671
  }
2603
2672
  /**
@@ -2611,7 +2680,9 @@ var BaseConnector = class {
2611
2680
  throw new Error("MCP client is not connected");
2612
2681
  }
2613
2682
  logger.debug(`Subscribing to resource: ${uri}`);
2614
- return await this.client.subscribeResource({ uri }, options);
2683
+ return await this.executeRequest(
2684
+ () => this.client.subscribeResource({ uri }, options)
2685
+ );
2615
2686
  }
2616
2687
  /**
2617
2688
  * Unsubscribe from resource updates
@@ -2624,7 +2695,9 @@ var BaseConnector = class {
2624
2695
  throw new Error("MCP client is not connected");
2625
2696
  }
2626
2697
  logger.debug(`Unsubscribing from resource: ${uri}`);
2627
- return await this.client.unsubscribeResource({ uri }, options);
2698
+ return await this.executeRequest(
2699
+ () => this.client.unsubscribeResource({ uri }, options)
2700
+ );
2628
2701
  }
2629
2702
  /**
2630
2703
  * Lists prompts exposed by the server.
@@ -2641,7 +2714,7 @@ var BaseConnector = class {
2641
2714
  }
2642
2715
  try {
2643
2716
  logger.debug("Listing prompts");
2644
- return await this.client.listPrompts();
2717
+ return await this.executeRequest(() => this.client.listPrompts());
2645
2718
  } catch (err) {
2646
2719
  const error = err;
2647
2720
  if (error.code === -32601) {
@@ -2663,7 +2736,9 @@ var BaseConnector = class {
2663
2736
  throw new Error("MCP client is not connected");
2664
2737
  }
2665
2738
  logger.debug(`Getting prompt ${name}`);
2666
- return await this.client.getPrompt({ name, arguments: args });
2739
+ return await this.executeRequest(
2740
+ () => this.client.getPrompt({ name, arguments: args })
2741
+ );
2667
2742
  }
2668
2743
  /**
2669
2744
  * Sends a raw, potentially non-standard request through the SDK client.
@@ -2678,10 +2753,12 @@ var BaseConnector = class {
2678
2753
  throw new Error("MCP client is not connected");
2679
2754
  }
2680
2755
  logger.debug(`Sending raw request '${method}' with params`, params);
2681
- return await this.client.request(
2682
- { method, params: params ?? {} },
2683
- passthroughResultSchema,
2684
- options
2756
+ return await this.executeRequest(
2757
+ () => this.client.request(
2758
+ { method, params: params ?? {} },
2759
+ passthroughResultSchema,
2760
+ options
2761
+ )
2685
2762
  );
2686
2763
  }
2687
2764
  /**
@@ -2714,6 +2791,7 @@ var BaseConnector = class {
2714
2791
  }
2715
2792
  }
2716
2793
  this.toolsCache = null;
2794
+ this.authorizationCache = void 0;
2717
2795
  if (issues.length) {
2718
2796
  logger.warn(`Resource cleanup finished with ${issues.length} issue(s)`);
2719
2797
  }
@@ -2721,6 +2799,7 @@ var BaseConnector = class {
2721
2799
  };
2722
2800
 
2723
2801
  // src/transport/http.ts
2802
+ var MIXED_AUTH_DISCOVERY_TIMEOUT_MS = 2e3;
2724
2803
  function detectUnauthorized(err, depth = 0) {
2725
2804
  if (!err || depth > 5) return false;
2726
2805
  if (err instanceof UnauthorizedError2) return true;
@@ -2734,6 +2813,11 @@ function detectUnauthorized(err, depth = 0) {
2734
2813
  }
2735
2814
  return false;
2736
2815
  }
2816
+ function isOAuthClientProvider(provider) {
2817
+ return Boolean(
2818
+ provider && "redirectToAuthorization" in provider && typeof provider.redirectToAuthorization === "function" && "tokens" in provider && typeof provider.tokens === "function"
2819
+ );
2820
+ }
2737
2821
  function createMcpProxyFetch(logicalServerUrl, proxyUrl, baseFetch, serverId) {
2738
2822
  const logical = new URL(logicalServerUrl);
2739
2823
  const proxy = proxyUrl.replace(/\/$/, "");
@@ -2759,6 +2843,31 @@ function createMcpProxyFetch(logicalServerUrl, proxyUrl, baseFetch, serverId) {
2759
2843
  );
2760
2844
  };
2761
2845
  }
2846
+ function createDeadlineFetch(baseFetch, deadlineSignal) {
2847
+ return async (input, init) => {
2848
+ const requestSignal = init?.signal;
2849
+ if (!requestSignal) {
2850
+ return baseFetch(input, { ...init, signal: deadlineSignal });
2851
+ }
2852
+ const controller = new AbortController();
2853
+ const abortFromRequest = () => controller.abort(requestSignal.reason);
2854
+ const abortFromDeadline = () => controller.abort(deadlineSignal.reason);
2855
+ if (requestSignal.aborted) abortFromRequest();
2856
+ else
2857
+ requestSignal.addEventListener("abort", abortFromRequest, { once: true });
2858
+ if (deadlineSignal.aborted) abortFromDeadline();
2859
+ else
2860
+ deadlineSignal.addEventListener("abort", abortFromDeadline, {
2861
+ once: true
2862
+ });
2863
+ try {
2864
+ return await baseFetch(input, { ...init, signal: controller.signal });
2865
+ } finally {
2866
+ requestSignal.removeEventListener("abort", abortFromRequest);
2867
+ deadlineSignal.removeEventListener("abort", abortFromDeadline);
2868
+ }
2869
+ };
2870
+ }
2762
2871
  var HttpConnector = class extends BaseConnector {
2763
2872
  baseUrl;
2764
2873
  headers;
@@ -2769,8 +2878,11 @@ var HttpConnector = class extends BaseConnector {
2769
2878
  gatewayUrl;
2770
2879
  serverId;
2771
2880
  reconnectionOptions;
2881
+ detectMixedAuth;
2772
2882
  transportType = null;
2773
2883
  streamableTransport = null;
2884
+ hadAccessTokenAtConnect = false;
2885
+ pendingOAuthCompletion = null;
2774
2886
  /**
2775
2887
  * Creates an HTTP connector.
2776
2888
  *
@@ -2801,6 +2913,99 @@ var HttpConnector = class extends BaseConnector {
2801
2913
  };
2802
2914
  this.protocolNegotiation = opts.protocolNegotiation ?? "auto";
2803
2915
  this.reconnectionOptions = opts.reconnectionOptions;
2916
+ this.detectMixedAuth = opts.detectMixedAuth ?? true;
2917
+ }
2918
+ get oauthProvider() {
2919
+ return isOAuthClientProvider(this.opts.authProvider) ? this.opts.authProvider : void 0;
2920
+ }
2921
+ async completeInteractiveAuthorization() {
2922
+ const provider = this.oauthProvider;
2923
+ if (!provider) {
2924
+ throw new Error("No OAuth client provider is configured");
2925
+ }
2926
+ if (!this.pendingOAuthCompletion) {
2927
+ this.pendingOAuthCompletion = completeOAuthFlow(provider, this.baseUrl, {
2928
+ fetchFn: this.customFetch,
2929
+ finishAuthorization: async (code, iss) => {
2930
+ const transport = this.streamableTransport;
2931
+ if (!transport) {
2932
+ throw new Error("OAuth transport is no longer connected");
2933
+ }
2934
+ await transport.finishAuth(code, iss);
2935
+ }
2936
+ }).then(() => {
2937
+ if (this.authorizationCache) {
2938
+ this.authorizationCache = {
2939
+ ...this.authorizationCache,
2940
+ authenticated: true
2941
+ };
2942
+ }
2943
+ }).finally(() => {
2944
+ this.pendingOAuthCompletion = null;
2945
+ });
2946
+ }
2947
+ await this.pendingOAuthCompletion;
2948
+ }
2949
+ async executeRequest(operation) {
2950
+ try {
2951
+ return await operation();
2952
+ } catch (error) {
2953
+ const provider = this.oauthProvider;
2954
+ if (!provider || provider.preventAutoAuth === true || !isOAuthInteractionRequired(error)) {
2955
+ throw error;
2956
+ }
2957
+ await this.completeInteractiveAuthorization();
2958
+ return operation();
2959
+ }
2960
+ }
2961
+ /** Authenticate an already-connected server without requiring a 401 first. */
2962
+ async authenticate() {
2963
+ if (!this.connected || !this.streamableTransport) {
2964
+ throw new Error("MCP client is not connected");
2965
+ }
2966
+ await this.completeInteractiveAuthorization();
2967
+ }
2968
+ async initialize(defaultRequestOptions = this.opts.defaultRequestOptions ?? {}) {
2969
+ const capabilities = await super.initialize(defaultRequestOptions);
2970
+ if (!this.detectMixedAuth || !this.oauthProvider || this.hadAccessTokenAtConnect) {
2971
+ return capabilities;
2972
+ }
2973
+ const controller = new AbortController();
2974
+ let timeout;
2975
+ const discoveryTimeout = new Promise((_, reject) => {
2976
+ timeout = setTimeout(() => {
2977
+ const error = new Error(
2978
+ `Mixed-auth metadata discovery timed out after ${MIXED_AUTH_DISCOVERY_TIMEOUT_MS}ms`
2979
+ );
2980
+ controller.abort(error);
2981
+ reject(error);
2982
+ }, MIXED_AUTH_DISCOVERY_TIMEOUT_MS);
2983
+ });
2984
+ const baseFetch = this.customFetch ?? globalThis.fetch.bind(globalThis);
2985
+ try {
2986
+ const metadata = await Promise.race([
2987
+ discoverOAuthProtectedResourceMetadata(
2988
+ this.baseUrl,
2989
+ { protocolVersion: this.negotiatedProtocolVersion },
2990
+ createDeadlineFetch(baseFetch, controller.signal)
2991
+ ),
2992
+ discoveryTimeout
2993
+ ]);
2994
+ this.authorizationCache = {
2995
+ mode: "mixed",
2996
+ authenticated: false,
2997
+ ...metadata.resource ? { resource: metadata.resource } : {},
2998
+ ...metadata.scopes_supported ? { scopesSupported: [...metadata.scopes_supported] } : {}
2999
+ };
3000
+ logger.info(
3001
+ "OAuth protected-resource metadata found after anonymous connection; server uses mixed auth"
3002
+ );
3003
+ } catch (error) {
3004
+ logger.debug("Mixed-auth metadata was not discovered:", error);
3005
+ } finally {
3006
+ if (timeout) clearTimeout(timeout);
3007
+ }
3008
+ return capabilities;
2804
3009
  }
2805
3010
  buildClientOptions() {
2806
3011
  return {
@@ -2907,6 +3112,16 @@ var HttpConnector = class extends BaseConnector {
2907
3112
  }
2908
3113
  const baseUrl = this.baseUrl;
2909
3114
  logger.debug(`Connecting to MCP implementation via HTTP: ${baseUrl}`);
3115
+ const oauthProvider = this.oauthProvider;
3116
+ if (oauthProvider) {
3117
+ try {
3118
+ this.hadAccessTokenAtConnect = Boolean(
3119
+ (await oauthProvider.tokens())?.access_token
3120
+ );
3121
+ } catch {
3122
+ this.hadAccessTokenAtConnect = false;
3123
+ }
3124
+ }
2910
3125
  try {
2911
3126
  await this.connectWithStreamableHttp(baseUrl);
2912
3127
  logger.debug("\u2705 Successfully connected via streamable HTTP");
@@ -3258,6 +3473,7 @@ function createConnectorFromConfig(serverConfig, connectorOptions) {
3258
3473
  fetch: serverConfig.fetch,
3259
3474
  authToken: serverConfig.authToken,
3260
3475
  authProvider: serverConfig.authProvider,
3476
+ detectMixedAuth: serverConfig.detectMixedAuth,
3261
3477
  protocolNegotiation: serverConfig.protocolNegotiation,
3262
3478
  timeout: serverConfig.timeout,
3263
3479
  roots: serverConfig.roots,
@@ -3500,6 +3716,14 @@ var MCPConnection = class {
3500
3716
  get serverInfo() {
3501
3717
  return this.connector.serverInfo;
3502
3718
  }
3719
+ /** OAuth state discovered for this connection, when available. */
3720
+ get authorization() {
3721
+ return this.connector.authorization;
3722
+ }
3723
+ /** Authenticate an already-connected mixed-auth server. */
3724
+ async authenticate() {
3725
+ await this.connector.authenticate();
3726
+ }
3503
3727
  /**
3504
3728
  * The negotiated protocol era for this session's connection:
3505
3729
  * `"legacy"` (2025-era) or `"modern"` (2026-07-28-era).
@@ -3532,7 +3756,8 @@ var MCPConnection = class {
3532
3756
  ...server ? { server } : {},
3533
3757
  capabilities,
3534
3758
  instructions: this.connector.instructions,
3535
- extensions
3759
+ extensions,
3760
+ ...this.authorization ? { authorization: this.authorization } : {}
3536
3761
  };
3537
3762
  }
3538
3763
  /**
@@ -3763,7 +3988,7 @@ var MCPConnection = class {
3763
3988
  };
3764
3989
 
3765
3990
  // src/core/base.ts
3766
- function isOAuthClientProvider(provider) {
3991
+ function isOAuthClientProvider2(provider) {
3767
3992
  return !!provider && typeof provider === "object" && "redirectUrl" in provider && "clientMetadata" in provider;
3768
3993
  }
3769
3994
  var BaseMCPClient = class {
@@ -3996,7 +4221,7 @@ var BaseMCPClient = class {
3996
4221
  ...serverConfig,
3997
4222
  authProvider: oauthProvider
3998
4223
  };
3999
- } else if ("authProvider" in serverConfig && serverConfig.authProvider && isOAuthClientProvider(serverConfig.authProvider)) {
4224
+ } else if ("authProvider" in serverConfig && serverConfig.authProvider && isOAuthClientProvider2(serverConfig.authProvider)) {
4000
4225
  oauthProvider = serverConfig.authProvider;
4001
4226
  }
4002
4227
  const openSession = async () => {
@@ -4336,6 +4561,7 @@ var BrowserMCPClient = class _BrowserMCPClient extends BaseMCPClient {
4336
4561
  fetch: configuredFetch,
4337
4562
  authToken,
4338
4563
  authProvider,
4564
+ detectMixedAuth,
4339
4565
  wrapTransport,
4340
4566
  clientOptions,
4341
4567
  protocolNegotiation,
@@ -4360,6 +4586,7 @@ var BrowserMCPClient = class _BrowserMCPClient extends BaseMCPClient {
4360
4586
  fetch: configuredFetch ?? globalThis.fetch.bind(globalThis),
4361
4587
  authToken,
4362
4588
  authProvider,
4589
+ detectMixedAuth,
4363
4590
  wrapTransport,
4364
4591
  clientOptions,
4365
4592
  onSampling: resolved.onSampling,
@@ -4470,6 +4697,7 @@ export {
4470
4697
  createOAuthProvider,
4471
4698
  detectFavicon,
4472
4699
  getPackageVersion,
4700
+ isOAuthInteractionRequired,
4473
4701
  isUnauthorized,
4474
4702
  logger,
4475
4703
  normalizeClientInfo,