@mcp-use/client 2.2.1-canary.0 → 2.2.2-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.
@@ -1901,7 +1901,7 @@ var HttpConnector = class extends BaseConnector {
1901
1901
  };
1902
1902
 
1903
1903
  // src/utils/version.ts
1904
- var VERSION = "2.2.1-canary.0";
1904
+ var VERSION = "2.2.2-canary.0";
1905
1905
  function getPackageVersion() {
1906
1906
  return VERSION;
1907
1907
  }
@@ -4007,6 +4007,12 @@ var BaseMCPClient = class {
4007
4007
  * Map of server names to their active sessions.
4008
4008
  */
4009
4009
  sessions = {};
4010
+ /**
4011
+ * Tracks teardown by session identity so overlapping cleanup paths share the
4012
+ * same disconnect. In particular, createSession() can replace a session while
4013
+ * closeSession() is already disconnecting it.
4014
+ */
4015
+ sessionDisconnects = /* @__PURE__ */ new WeakMap();
4010
4016
  /**
4011
4017
  * List of server names that have active sessions.
4012
4018
  * This array is kept in sync with the sessions map and can be used
@@ -4040,6 +4046,15 @@ var BaseMCPClient = class {
4040
4046
  this.config = config;
4041
4047
  }
4042
4048
  }
4049
+ disconnectSession(session) {
4050
+ const existingDisconnect = this.sessionDisconnects.get(session);
4051
+ if (existingDisconnect) {
4052
+ return existingDisconnect;
4053
+ }
4054
+ const disconnect = Promise.resolve().then(() => session.disconnect());
4055
+ this.sessionDisconnects.set(session, disconnect);
4056
+ return disconnect;
4057
+ }
4043
4058
  /**
4044
4059
  * Creates a client instance from a configuration dictionary.
4045
4060
  *
@@ -4268,7 +4283,7 @@ var BaseMCPClient = class {
4268
4283
  if (previous && previous !== session) {
4269
4284
  try {
4270
4285
  logger.debug(`Disconnecting replaced session for server ${serverName}`);
4271
- await previous.disconnect();
4286
+ await this.disconnectSession(previous);
4272
4287
  } catch (e) {
4273
4288
  logger.error(
4274
4289
  `Error disconnecting replaced session for server '${serverName}': ${e}`
@@ -4453,7 +4468,7 @@ var BaseMCPClient = class {
4453
4468
  }
4454
4469
  try {
4455
4470
  logger.debug(`Closing session for server ${serverName}`);
4456
- await session.disconnect();
4471
+ await this.disconnectSession(session);
4457
4472
  } catch (e) {
4458
4473
  logger.error(`Error closing session for server '${serverName}': ${e}`);
4459
4474
  } finally {
@@ -5849,6 +5864,66 @@ function useMcp(options) {
5849
5864
  addLog("debug", "Server capabilities:", capabilities2);
5850
5865
  setCapabilities(capabilities2);
5851
5866
  }
5867
+ if (authProviderRef.current) {
5868
+ let tokens;
5869
+ try {
5870
+ tokens = await authProviderRef.current.tokens?.();
5871
+ } catch (error2) {
5872
+ addLog("warn", "Failed to read OAuth tokens:", error2);
5873
+ tokens = void 0;
5874
+ }
5875
+ if (!isMountedRef.current) {
5876
+ addLog(
5877
+ "debug",
5878
+ "Connection aborted after token fetch for auth tokens - component unmounted"
5879
+ );
5880
+ return "failed";
5881
+ }
5882
+ if (tokens?.access_token) {
5883
+ if (authorizationRef.current?.mode === "mixed") {
5884
+ const authenticatedAuthorization = {
5885
+ ...authorizationRef.current,
5886
+ authenticated: true
5887
+ };
5888
+ setAuthorization(authenticatedAuthorization);
5889
+ authorizationRef.current = authenticatedAuthorization;
5890
+ }
5891
+ const expiresAt = getOAuthTokenExpiry(tokens);
5892
+ let tokenEndpoint = null;
5893
+ let resource = null;
5894
+ let clientCreds = null;
5895
+ try {
5896
+ tokenEndpoint = await authProviderRef.current.getTokenEndpoint?.() ?? null;
5897
+ } catch {
5898
+ tokenEndpoint = null;
5899
+ }
5900
+ try {
5901
+ resource = await authProviderRef.current.getResource?.() ?? null;
5902
+ } catch {
5903
+ resource = null;
5904
+ }
5905
+ try {
5906
+ clientCreds = await authProviderRef.current.getClientCredentials?.() ?? null;
5907
+ } catch {
5908
+ clientCreds = null;
5909
+ }
5910
+ if (!isMountedRef.current) {
5911
+ addLog("debug", "Skipping state update - component unmounted");
5912
+ return "failed";
5913
+ }
5914
+ setAuthTokens({
5915
+ access_token: tokens.access_token,
5916
+ token_type: tokens.token_type || "Bearer",
5917
+ expires_at: expiresAt,
5918
+ refresh_token: tokens.refresh_token,
5919
+ scope: tokens.scope,
5920
+ ...tokenEndpoint ? { token_endpoint: tokenEndpoint } : {},
5921
+ ...resource ? { resource } : {},
5922
+ ...clientCreds?.client_id ? { client_id: clientCreds.client_id } : {},
5923
+ ...clientCreds?.client_secret ? { client_secret: clientCreds.client_secret } : {}
5924
+ });
5925
+ }
5926
+ }
5852
5927
  successfulTransportRef.current = transportTypeParam;
5853
5928
  setState("ready");
5854
5929
  const discoverAuthorizationAfterReady = () => {
@@ -5914,66 +5989,6 @@ function useMcp(options) {
5914
5989
  setSkills([]);
5915
5990
  }
5916
5991
  }
5917
- if (authProviderRef.current) {
5918
- let tokens;
5919
- try {
5920
- tokens = await authProviderRef.current.tokens?.();
5921
- } catch (error2) {
5922
- addLog("warn", "Failed to read OAuth tokens:", error2);
5923
- tokens = void 0;
5924
- }
5925
- if (!isMountedRef.current) {
5926
- addLog(
5927
- "debug",
5928
- "Connection aborted after token fetch for auth tokens - component unmounted"
5929
- );
5930
- return "failed";
5931
- }
5932
- if (tokens?.access_token) {
5933
- if (authorizationRef.current?.mode === "mixed") {
5934
- const authenticatedAuthorization = {
5935
- ...authorizationRef.current,
5936
- authenticated: true
5937
- };
5938
- setAuthorization(authenticatedAuthorization);
5939
- authorizationRef.current = authenticatedAuthorization;
5940
- }
5941
- const expiresAt = getOAuthTokenExpiry(tokens);
5942
- let tokenEndpoint = null;
5943
- let resource = null;
5944
- let clientCreds = null;
5945
- try {
5946
- tokenEndpoint = await authProviderRef.current.getTokenEndpoint?.() ?? null;
5947
- } catch {
5948
- tokenEndpoint = null;
5949
- }
5950
- try {
5951
- resource = await authProviderRef.current.getResource?.() ?? null;
5952
- } catch {
5953
- resource = null;
5954
- }
5955
- try {
5956
- clientCreds = await authProviderRef.current.getClientCredentials?.() ?? null;
5957
- } catch {
5958
- clientCreds = null;
5959
- }
5960
- if (!isMountedRef.current) {
5961
- addLog("debug", "Skipping state update - component unmounted");
5962
- return "failed";
5963
- }
5964
- setAuthTokens({
5965
- access_token: tokens.access_token,
5966
- token_type: tokens.token_type || "Bearer",
5967
- expires_at: expiresAt,
5968
- refresh_token: tokens.refresh_token,
5969
- scope: tokens.scope,
5970
- ...tokenEndpoint ? { token_endpoint: tokenEndpoint } : {},
5971
- ...resource ? { resource } : {},
5972
- ...clientCreds?.client_id ? { client_id: clientCreds.client_id } : {},
5973
- ...clientCreds?.client_secret ? { client_secret: clientCreds.client_secret } : {}
5974
- });
5975
- }
5976
- }
5977
5992
  return "success";
5978
5993
  } catch (err) {
5979
5994
  const error2 = err;