mcp-use 1.6.3-canary.0 → 1.7.0-canary.2

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 (105) hide show
  1. package/dist/.tsbuildinfo +1 -1
  2. package/dist/chunk-3R5PDYIN.js +403 -0
  3. package/dist/{chunk-BWOTID2D.js → chunk-AGKMD2ZM.js} +7 -350
  4. package/dist/{chunk-SJEHVCPM.js → chunk-BG2APH43.js} +120 -26
  5. package/dist/{chunk-YURRUCIM.js → chunk-CPG2WZUL.js} +9 -11
  6. package/dist/chunk-F4UHAA5L.js +854 -0
  7. package/dist/chunk-JQKKMUCT.js +0 -0
  8. package/dist/chunk-MTHLLDCX.js +97 -0
  9. package/dist/{chunk-MCF5P6GJ.js → chunk-S6K5QZBJ.js} +739 -29
  10. package/dist/{display-YIYC6WJE.js → display-A5IEINAP.js} +79 -17
  11. package/dist/index.cjs +1055 -136
  12. package/dist/index.js +14 -10
  13. package/dist/{langfuse-C4HKZ3NL.js → langfuse-N5Y5BSXK.js} +1 -1
  14. package/dist/oauth-U4NNKN4B.js +30 -0
  15. package/dist/src/agents/display.d.ts.map +1 -1
  16. package/dist/src/agents/index.cjs +854 -78
  17. package/dist/src/agents/index.js +3 -2
  18. package/dist/src/auth/browser-provider.d.ts +2 -0
  19. package/dist/src/auth/browser-provider.d.ts.map +1 -1
  20. package/dist/src/auth/callback.d.ts.map +1 -1
  21. package/dist/src/auth/index.cjs +421 -0
  22. package/dist/src/auth/index.js +10 -0
  23. package/dist/src/auth/types.d.ts +3 -1
  24. package/dist/src/auth/types.d.ts.map +1 -1
  25. package/dist/src/browser.cjs +924 -98
  26. package/dist/src/browser.js +8 -5
  27. package/dist/src/connectors/base.d.ts +52 -121
  28. package/dist/src/connectors/base.d.ts.map +1 -1
  29. package/dist/src/connectors/http.d.ts.map +1 -1
  30. package/dist/src/managers/server_manager.d.ts.map +1 -1
  31. package/dist/src/managers/tools/acquire_active_mcp_server.d.ts +2 -2
  32. package/dist/src/managers/tools/acquire_active_mcp_server.d.ts.map +1 -1
  33. package/dist/src/managers/tools/add_server_from_config.d.ts +1 -7
  34. package/dist/src/managers/tools/add_server_from_config.d.ts.map +1 -1
  35. package/dist/src/managers/tools/connect_mcp_server.d.ts +2 -10
  36. package/dist/src/managers/tools/connect_mcp_server.d.ts.map +1 -1
  37. package/dist/src/managers/tools/list_mcp_servers.d.ts +2 -2
  38. package/dist/src/managers/tools/list_mcp_servers.d.ts.map +1 -1
  39. package/dist/src/managers/tools/release_mcp_server_connection.d.ts +2 -2
  40. package/dist/src/managers/tools/release_mcp_server_connection.d.ts.map +1 -1
  41. package/dist/src/observability/langfuse.d.ts +4 -0
  42. package/dist/src/observability/langfuse.d.ts.map +1 -1
  43. package/dist/src/react/McpUseProvider.d.ts.map +1 -1
  44. package/dist/src/react/index.cjs +189 -41
  45. package/dist/src/react/index.js +4 -2
  46. package/dist/src/react/types.d.ts +12 -1
  47. package/dist/src/react/types.d.ts.map +1 -1
  48. package/dist/src/react/useMcp.d.ts.map +1 -1
  49. package/dist/src/server/connect-adapter.d.ts.map +1 -1
  50. package/dist/src/server/context-storage.d.ts +54 -0
  51. package/dist/src/server/context-storage.d.ts.map +1 -0
  52. package/dist/src/server/index.cjs +1413 -418
  53. package/dist/src/server/index.d.ts +4 -1
  54. package/dist/src/server/index.d.ts.map +1 -1
  55. package/dist/src/server/index.js +426 -420
  56. package/dist/src/server/mcp-server.d.ts +50 -81
  57. package/dist/src/server/mcp-server.d.ts.map +1 -1
  58. package/dist/src/server/oauth/index.d.ts +13 -0
  59. package/dist/src/server/oauth/index.d.ts.map +1 -0
  60. package/dist/src/server/oauth/middleware.d.ts +19 -0
  61. package/dist/src/server/oauth/middleware.d.ts.map +1 -0
  62. package/dist/src/server/oauth/providers/auth0.d.ts +22 -0
  63. package/dist/src/server/oauth/providers/auth0.d.ts.map +1 -0
  64. package/dist/src/server/oauth/providers/custom.d.ts +19 -0
  65. package/dist/src/server/oauth/providers/custom.d.ts.map +1 -0
  66. package/dist/src/server/oauth/providers/keycloak.d.ts +22 -0
  67. package/dist/src/server/oauth/providers/keycloak.d.ts.map +1 -0
  68. package/dist/src/server/oauth/providers/supabase.d.ts +24 -0
  69. package/dist/src/server/oauth/providers/supabase.d.ts.map +1 -0
  70. package/dist/src/server/oauth/providers/types.d.ts +138 -0
  71. package/dist/src/server/oauth/providers/types.d.ts.map +1 -0
  72. package/dist/src/server/oauth/providers/workos.d.ts +30 -0
  73. package/dist/src/server/oauth/providers/workos.d.ts.map +1 -0
  74. package/dist/src/server/oauth/providers.d.ts +208 -0
  75. package/dist/src/server/oauth/providers.d.ts.map +1 -0
  76. package/dist/src/server/oauth/routes.d.ts +33 -0
  77. package/dist/src/server/oauth/routes.d.ts.map +1 -0
  78. package/dist/src/server/oauth/utils.d.ts +155 -0
  79. package/dist/src/server/oauth/utils.d.ts.map +1 -0
  80. package/dist/src/server/types/common.d.ts +47 -0
  81. package/dist/src/server/types/common.d.ts.map +1 -1
  82. package/dist/src/server/types/context.d.ts +34 -0
  83. package/dist/src/server/types/context.d.ts.map +1 -0
  84. package/dist/src/server/types/index.d.ts +2 -1
  85. package/dist/src/server/types/index.d.ts.map +1 -1
  86. package/dist/src/server/types/tool.d.ts +82 -9
  87. package/dist/src/server/types/tool.d.ts.map +1 -1
  88. package/dist/src/server/utils/index.d.ts +6 -0
  89. package/dist/src/server/utils/index.d.ts.map +1 -0
  90. package/dist/src/server/utils/response-helpers.d.ts +151 -0
  91. package/dist/src/server/utils/response-helpers.d.ts.map +1 -0
  92. package/dist/src/server/utils/runtime.d.ts +25 -0
  93. package/dist/src/server/utils/runtime.d.ts.map +1 -0
  94. package/dist/src/task_managers/streamable_http.d.ts +1 -0
  95. package/dist/src/task_managers/streamable_http.d.ts.map +1 -1
  96. package/dist/src/utils/json-schema-to-zod/JSONSchemaToZod.d.ts +270 -0
  97. package/dist/src/utils/json-schema-to-zod/JSONSchemaToZod.d.ts.map +1 -0
  98. package/dist/src/utils/json-schema-to-zod/Type.d.ts +24 -0
  99. package/dist/src/utils/json-schema-to-zod/Type.d.ts.map +1 -0
  100. package/dist/src/utils/json-schema-to-zod/index.d.ts +3 -0
  101. package/dist/src/utils/json-schema-to-zod/index.d.ts.map +1 -0
  102. package/dist/src/utils/url-sanitize.d.ts +17 -0
  103. package/dist/src/utils/url-sanitize.d.ts.map +1 -0
  104. package/dist/tsup.config.d.ts.map +1 -1
  105. package/package.json +30 -38
@@ -1,3 +1,6 @@
1
+ import {
2
+ generateUUID
3
+ } from "./chunk-MTHLLDCX.js";
1
4
  import {
2
5
  BaseConnector
3
6
  } from "./chunk-2JBWOW4S.js";
@@ -428,6 +431,7 @@ var HttpConnector = class extends BaseConnector {
428
431
  stop: /* @__PURE__ */ __name(async () => {
429
432
  if (this.streamableTransport) {
430
433
  try {
434
+ await this.streamableTransport.terminateSession();
431
435
  await this.streamableTransport.close();
432
436
  } catch (e) {
433
437
  logger.warn(`Error closing Streamable HTTP transport: ${e}`);
@@ -452,6 +456,8 @@ var HttpConnector = class extends BaseConnector {
452
456
  async connectWithSse(baseUrl) {
453
457
  try {
454
458
  this.connectionManager = new SseConnectionManager(baseUrl, {
459
+ authProvider: this.opts.authProvider,
460
+ // ← Pass OAuth provider to SDK (same as streamable HTTP)
455
461
  requestInit: {
456
462
  headers: this.headers
457
463
  }
@@ -506,9 +512,6 @@ var HttpConnector = class extends BaseConnector {
506
512
  }
507
513
  };
508
514
 
509
- // src/connectors/websocket.ts
510
- import { v4 as uuidv4 } from "uuid";
511
-
512
515
  // src/task_managers/websocket.ts
513
516
  import WS from "ws";
514
517
  var WebSocketConnectionManager = class extends ConnectionManager {
@@ -627,7 +630,7 @@ var WebSocketConnector = class extends BaseConnector {
627
630
  }
628
631
  sendRequest(method, params = null) {
629
632
  if (!this.ws) throw new Error("WebSocket is not connected");
630
- const id = uuidv4();
633
+ const id = generateUUID();
631
634
  const payload = JSON.stringify({ id, method, params: params ?? {} });
632
635
  return new Promise((resolve, reject) => {
633
636
  this.pending.set(id, { resolve, reject });
@@ -782,350 +785,6 @@ var WebSocketConnector = class extends BaseConnector {
782
785
  }
783
786
  };
784
787
 
785
- // src/auth/browser-provider.ts
786
- import { sanitizeUrl } from "strict-url-sanitise";
787
- var BrowserOAuthClientProvider = class {
788
- static {
789
- __name(this, "BrowserOAuthClientProvider");
790
- }
791
- serverUrl;
792
- storageKeyPrefix;
793
- serverUrlHash;
794
- clientName;
795
- clientUri;
796
- callbackUrl;
797
- preventAutoAuth;
798
- onPopupWindow;
799
- constructor(serverUrl, options = {}) {
800
- this.serverUrl = serverUrl;
801
- this.storageKeyPrefix = options.storageKeyPrefix || "mcp:auth";
802
- this.serverUrlHash = this.hashString(serverUrl);
803
- this.clientName = options.clientName || "mcp-use";
804
- this.clientUri = options.clientUri || (typeof window !== "undefined" ? window.location.origin : "");
805
- this.callbackUrl = sanitizeUrl(
806
- options.callbackUrl || (typeof window !== "undefined" ? new URL("/oauth/callback", window.location.origin).toString() : "/oauth/callback")
807
- );
808
- this.preventAutoAuth = options.preventAutoAuth;
809
- this.onPopupWindow = options.onPopupWindow;
810
- }
811
- // --- SDK Interface Methods ---
812
- get redirectUrl() {
813
- return sanitizeUrl(this.callbackUrl);
814
- }
815
- get clientMetadata() {
816
- return {
817
- redirect_uris: [this.redirectUrl],
818
- token_endpoint_auth_method: "none",
819
- // Public client
820
- grant_types: ["authorization_code", "refresh_token"],
821
- response_types: ["code"],
822
- client_name: this.clientName,
823
- client_uri: this.clientUri
824
- // scope: 'openid profile email mcp', // Example scopes, adjust as needed
825
- };
826
- }
827
- async clientInformation() {
828
- const key = this.getKey("client_info");
829
- const data = localStorage.getItem(key);
830
- if (!data) return void 0;
831
- try {
832
- return JSON.parse(data);
833
- } catch (e) {
834
- console.warn(
835
- `[${this.storageKeyPrefix}] Failed to parse client information:`,
836
- e
837
- );
838
- localStorage.removeItem(key);
839
- return void 0;
840
- }
841
- }
842
- // NOTE: The SDK's auth() function uses this if dynamic registration is needed.
843
- // Ensure your OAuthClientInformationFull matches the expected structure if DCR is used.
844
- async saveClientInformation(clientInformation) {
845
- const key = this.getKey("client_info");
846
- localStorage.setItem(key, JSON.stringify(clientInformation));
847
- }
848
- async tokens() {
849
- const key = this.getKey("tokens");
850
- const data = localStorage.getItem(key);
851
- if (!data) return void 0;
852
- try {
853
- return JSON.parse(data);
854
- } catch (e) {
855
- console.warn(`[${this.storageKeyPrefix}] Failed to parse tokens:`, e);
856
- localStorage.removeItem(key);
857
- return void 0;
858
- }
859
- }
860
- async saveTokens(tokens) {
861
- const key = this.getKey("tokens");
862
- localStorage.setItem(key, JSON.stringify(tokens));
863
- localStorage.removeItem(this.getKey("code_verifier"));
864
- localStorage.removeItem(this.getKey("last_auth_url"));
865
- }
866
- async saveCodeVerifier(codeVerifier) {
867
- const key = this.getKey("code_verifier");
868
- localStorage.setItem(key, codeVerifier);
869
- }
870
- async codeVerifier() {
871
- const key = this.getKey("code_verifier");
872
- const verifier = localStorage.getItem(key);
873
- if (!verifier) {
874
- throw new Error(
875
- `[${this.storageKeyPrefix}] Code verifier not found in storage for key ${key}. Auth flow likely corrupted or timed out.`
876
- );
877
- }
878
- return verifier;
879
- }
880
- /**
881
- * Generates and stores the authorization URL with state, without opening a popup.
882
- * Used when preventAutoAuth is enabled to provide the URL for manual navigation.
883
- * @param authorizationUrl The fully constructed authorization URL from the SDK.
884
- * @returns The full authorization URL with state parameter.
885
- */
886
- async prepareAuthorizationUrl(authorizationUrl) {
887
- const state = globalThis.crypto.randomUUID();
888
- const stateKey = `${this.storageKeyPrefix}:state_${state}`;
889
- const stateData = {
890
- serverUrlHash: this.serverUrlHash,
891
- expiry: Date.now() + 1e3 * 60 * 10,
892
- // State expires in 10 minutes
893
- // Store provider options needed to reconstruct on callback
894
- providerOptions: {
895
- serverUrl: this.serverUrl,
896
- storageKeyPrefix: this.storageKeyPrefix,
897
- clientName: this.clientName,
898
- clientUri: this.clientUri,
899
- callbackUrl: this.callbackUrl
900
- }
901
- };
902
- localStorage.setItem(stateKey, JSON.stringify(stateData));
903
- authorizationUrl.searchParams.set("state", state);
904
- const authUrlString = authorizationUrl.toString();
905
- const sanitizedAuthUrl = sanitizeUrl(authUrlString);
906
- localStorage.setItem(this.getKey("last_auth_url"), sanitizedAuthUrl);
907
- return sanitizedAuthUrl;
908
- }
909
- /**
910
- * Redirects the user agent to the authorization URL, storing necessary state.
911
- * This now adheres to the SDK's void return type expectation for the interface.
912
- * @param authorizationUrl The fully constructed authorization URL from the SDK.
913
- */
914
- async redirectToAuthorization(authorizationUrl) {
915
- if (this.preventAutoAuth) return;
916
- const sanitizedAuthUrl = await this.prepareAuthorizationUrl(authorizationUrl);
917
- const popupFeatures = "width=600,height=700,resizable=yes,scrollbars=yes,status=yes";
918
- try {
919
- const popup = window.open(
920
- sanitizedAuthUrl,
921
- `mcp_auth_${this.serverUrlHash}`,
922
- popupFeatures
923
- );
924
- if (this.onPopupWindow) {
925
- this.onPopupWindow(sanitizedAuthUrl, popupFeatures, popup);
926
- }
927
- if (!popup || popup.closed || typeof popup.closed === "undefined") {
928
- console.warn(
929
- `[${this.storageKeyPrefix}] Popup likely blocked by browser. Manual navigation might be required using the stored URL.`
930
- );
931
- } else {
932
- popup.focus();
933
- console.info(
934
- `[${this.storageKeyPrefix}] Redirecting to authorization URL in popup.`
935
- );
936
- }
937
- } catch (e) {
938
- console.error(
939
- `[${this.storageKeyPrefix}] Error opening popup window:`,
940
- e
941
- );
942
- }
943
- }
944
- // --- Helper Methods ---
945
- /**
946
- * Retrieves the last URL passed to `redirectToAuthorization`. Useful for manual fallback.
947
- */
948
- getLastAttemptedAuthUrl() {
949
- const storedUrl = localStorage.getItem(this.getKey("last_auth_url"));
950
- return storedUrl ? sanitizeUrl(storedUrl) : null;
951
- }
952
- clearStorage() {
953
- const prefixPattern = `${this.storageKeyPrefix}_${this.serverUrlHash}_`;
954
- const statePattern = `${this.storageKeyPrefix}:state_`;
955
- const keysToRemove = [];
956
- let count = 0;
957
- for (let i = 0; i < localStorage.length; i++) {
958
- const key = localStorage.key(i);
959
- if (!key) continue;
960
- if (key.startsWith(prefixPattern)) {
961
- keysToRemove.push(key);
962
- } else if (key.startsWith(statePattern)) {
963
- try {
964
- const item = localStorage.getItem(key);
965
- if (item) {
966
- const state = JSON.parse(item);
967
- if (state.serverUrlHash === this.serverUrlHash) {
968
- keysToRemove.push(key);
969
- }
970
- }
971
- } catch (e) {
972
- console.warn(
973
- `[${this.storageKeyPrefix}] Error parsing state key ${key} during clearStorage:`,
974
- e
975
- );
976
- }
977
- }
978
- }
979
- const uniqueKeysToRemove = [...new Set(keysToRemove)];
980
- uniqueKeysToRemove.forEach((key) => {
981
- localStorage.removeItem(key);
982
- count++;
983
- });
984
- return count;
985
- }
986
- hashString(str) {
987
- let hash = 0;
988
- for (let i = 0; i < str.length; i++) {
989
- const char = str.charCodeAt(i);
990
- hash = (hash << 5) - hash + char;
991
- hash = hash & hash;
992
- }
993
- return Math.abs(hash).toString(16);
994
- }
995
- getKey(keySuffix) {
996
- return `${this.storageKeyPrefix}_${this.serverUrlHash}_${keySuffix}`;
997
- }
998
- };
999
-
1000
- // src/auth/callback.ts
1001
- import { auth } from "@modelcontextprotocol/sdk/client/auth.js";
1002
- async function onMcpAuthorization() {
1003
- const queryParams = new URLSearchParams(window.location.search);
1004
- const code = queryParams.get("code");
1005
- const state = queryParams.get("state");
1006
- const error = queryParams.get("error");
1007
- const errorDescription = queryParams.get("error_description");
1008
- const logPrefix = "[mcp-callback]";
1009
- console.log(`${logPrefix} Handling callback...`, {
1010
- code,
1011
- state,
1012
- error,
1013
- errorDescription
1014
- });
1015
- let provider = null;
1016
- let storedStateData = null;
1017
- const stateKey = state ? `mcp:auth:state_${state}` : null;
1018
- try {
1019
- if (error) {
1020
- throw new Error(
1021
- `OAuth error: ${error} - ${errorDescription || "No description provided."}`
1022
- );
1023
- }
1024
- if (!code) {
1025
- throw new Error(
1026
- "Authorization code not found in callback query parameters."
1027
- );
1028
- }
1029
- if (!state || !stateKey) {
1030
- throw new Error(
1031
- "State parameter not found or invalid in callback query parameters."
1032
- );
1033
- }
1034
- const storedStateJSON = localStorage.getItem(stateKey);
1035
- if (!storedStateJSON) {
1036
- throw new Error(
1037
- `Invalid or expired state parameter "${state}". No matching state found in storage.`
1038
- );
1039
- }
1040
- try {
1041
- storedStateData = JSON.parse(storedStateJSON);
1042
- } catch (e) {
1043
- throw new Error("Failed to parse stored OAuth state.");
1044
- }
1045
- if (!storedStateData.expiry || storedStateData.expiry < Date.now()) {
1046
- localStorage.removeItem(stateKey);
1047
- throw new Error(
1048
- "OAuth state has expired. Please try initiating authentication again."
1049
- );
1050
- }
1051
- if (!storedStateData.providerOptions) {
1052
- throw new Error("Stored state is missing required provider options.");
1053
- }
1054
- const { serverUrl, ...providerOptions } = storedStateData.providerOptions;
1055
- console.log(
1056
- `${logPrefix} Re-instantiating provider for server: ${serverUrl}`
1057
- );
1058
- provider = new BrowserOAuthClientProvider(serverUrl, providerOptions);
1059
- console.log(`${logPrefix} Calling SDK auth() to exchange code...`);
1060
- const baseUrl = new URL(serverUrl).origin;
1061
- const authResult = await auth(provider, {
1062
- serverUrl: baseUrl,
1063
- authorizationCode: code
1064
- });
1065
- if (authResult === "AUTHORIZED") {
1066
- console.log(
1067
- `${logPrefix} Authorization successful via SDK auth(). Notifying opener...`
1068
- );
1069
- if (window.opener && !window.opener.closed) {
1070
- window.opener.postMessage(
1071
- { type: "mcp_auth_callback", success: true },
1072
- window.location.origin
1073
- );
1074
- window.close();
1075
- } else {
1076
- console.warn(
1077
- `${logPrefix} No opener window detected. Redirecting to root.`
1078
- );
1079
- const pathParts = window.location.pathname.split("/").filter(Boolean);
1080
- const basePath = pathParts.length > 0 && pathParts[pathParts.length - 1] === "callback" ? "/" + pathParts.slice(0, -2).join("/") : "/";
1081
- window.location.href = basePath || "/";
1082
- }
1083
- localStorage.removeItem(stateKey);
1084
- } else {
1085
- console.warn(
1086
- `${logPrefix} SDK auth() returned unexpected status: ${authResult}`
1087
- );
1088
- throw new Error(
1089
- `Unexpected result from authentication library: ${authResult}`
1090
- );
1091
- }
1092
- } catch (err) {
1093
- console.error(`${logPrefix} Error during OAuth callback handling:`, err);
1094
- const errorMessage = err instanceof Error ? err.message : String(err);
1095
- if (window.opener && !window.opener.closed) {
1096
- window.opener.postMessage(
1097
- { type: "mcp_auth_callback", success: false, error: errorMessage },
1098
- window.location.origin
1099
- );
1100
- }
1101
- try {
1102
- document.body.innerHTML = `
1103
- <div style="font-family: sans-serif; padding: 20px;">
1104
- <h1>Authentication Error</h1>
1105
- <p style="color: red; background-color: #ffebeb; border: 1px solid red; padding: 10px; border-radius: 4px;">
1106
- ${errorMessage}
1107
- </p>
1108
- <p>You can close this window or <a href="#" onclick="window.close(); return false;">click here to close</a>.</p>
1109
- <pre style="font-size: 0.8em; color: #555; margin-top: 20px; white-space: pre-wrap;">${err instanceof Error ? err.stack : ""}</pre>
1110
- </div>
1111
- `;
1112
- } catch (displayError) {
1113
- console.error(
1114
- `${logPrefix} Could not display error in callback window:`,
1115
- displayError
1116
- );
1117
- }
1118
- if (stateKey) {
1119
- localStorage.removeItem(stateKey);
1120
- }
1121
- if (provider) {
1122
- localStorage.removeItem(provider.getKey("code_verifier"));
1123
- localStorage.removeItem(provider.getKey("last_auth_url"));
1124
- }
1125
- }
1126
- }
1127
- __name(onMcpAuthorization, "onMcpAuthorization");
1128
-
1129
788
  // src/client/base.ts
1130
789
  var BaseMCPClient = class {
1131
790
  static {
@@ -1310,7 +969,5 @@ export {
1310
969
  ConnectionManager,
1311
970
  HttpConnector,
1312
971
  WebSocketConnector,
1313
- BrowserOAuthClientProvider,
1314
- onMcpAuthorization,
1315
972
  BrowserMCPClient
1316
973
  };
@@ -1,14 +1,16 @@
1
1
  import {
2
- BrowserMCPClient,
3
- BrowserOAuthClientProvider
4
- } from "./chunk-BWOTID2D.js";
2
+ BrowserMCPClient
3
+ } from "./chunk-AGKMD2ZM.js";
4
+ import {
5
+ BrowserOAuthClientProvider,
6
+ sanitizeUrl
7
+ } from "./chunk-3R5PDYIN.js";
5
8
  import {
6
9
  __name
7
10
  } from "./chunk-3GQAWCBQ.js";
8
11
 
9
12
  // src/react/useMcp.ts
10
13
  import { useCallback, useEffect, useRef, useState } from "react";
11
- import { sanitizeUrl } from "strict-url-sanitise";
12
14
 
13
15
  // src/utils/assert.ts
14
16
  function assert(condition, message) {
@@ -21,7 +23,6 @@ __name(assert, "assert");
21
23
  // src/react/useMcp.ts
22
24
  var DEFAULT_RECONNECT_DELAY = 3e3;
23
25
  var DEFAULT_RETRY_DELAY = 5e3;
24
- var AUTH_TIMEOUT = 5 * 60 * 1e3;
25
26
  function useMcp(options) {
26
27
  const {
27
28
  url,
@@ -39,6 +40,9 @@ function useMcp(options) {
39
40
  autoReconnect = DEFAULT_RECONNECT_DELAY,
40
41
  transportType = "auto",
41
42
  preventAutoAuth = false,
43
+ // Default to false for backward compatibility (auto-trigger OAuth)
44
+ useRedirectFlow = false,
45
+ // Default to false for backward compatibility (use popup)
42
46
  onPopupWindow,
43
47
  timeout = 3e4,
44
48
  // 30 seconds default for connection timeout
@@ -164,6 +168,7 @@ function useMcp(options) {
164
168
  clientUri,
165
169
  callbackUrl,
166
170
  preventAutoAuth,
171
+ useRedirectFlow,
167
172
  onPopupWindow
168
173
  });
169
174
  addLog("debug", "BrowserOAuthClientProvider initialized in connect.");
@@ -254,6 +259,42 @@ function useMcp(options) {
254
259
  } catch (err) {
255
260
  const errorMessage = err?.message || String(err);
256
261
  if (err.code === 401 || errorMessage.includes("401") || errorMessage.includes("Unauthorized")) {
262
+ if (authProviderRef.current) {
263
+ addLog(
264
+ "info",
265
+ "Authentication required. OAuth provider available."
266
+ );
267
+ try {
268
+ const { auth } = await import("@modelcontextprotocol/sdk/client/auth.js");
269
+ const baseUrl = new URL(url).origin;
270
+ auth(authProviderRef.current, { serverUrl: baseUrl }).catch(
271
+ () => {
272
+ }
273
+ );
274
+ setTimeout(() => {
275
+ if (isMountedRef.current) {
276
+ const manualUrl = authProviderRef.current?.getLastAttemptedAuthUrl();
277
+ if (manualUrl) {
278
+ setAuthUrl(manualUrl);
279
+ addLog(
280
+ "info",
281
+ "Manual authentication URL available:",
282
+ manualUrl
283
+ );
284
+ } else {
285
+ addLog("warn", "Could not generate authentication URL");
286
+ }
287
+ }
288
+ }, 100);
289
+ } catch (authGenError) {
290
+ addLog("warn", "Error generating auth URL:", authGenError);
291
+ }
292
+ if (isMountedRef.current) {
293
+ setState("pending_auth");
294
+ }
295
+ connectingRef.current = false;
296
+ return "auth_redirect";
297
+ }
257
298
  if (customHeaders && Object.keys(customHeaders).length > 0) {
258
299
  failConnection(
259
300
  "Authentication failed: Server returned 401 Unauthorized. Check your Authorization header value is correct."
@@ -305,6 +346,7 @@ function useMcp(options) {
305
346
  customHeaders,
306
347
  transportType,
307
348
  preventAutoAuth,
349
+ useRedirectFlow,
308
350
  onPopupWindow,
309
351
  enabled,
310
352
  timeout,
@@ -357,32 +399,54 @@ function useMcp(options) {
357
399
  retry();
358
400
  } else if (currentState === "pending_auth") {
359
401
  addLog("info", "Proceeding with authentication from pending state...");
360
- setState("authenticating");
361
- if (authTimeoutRef.current) clearTimeout(authTimeoutRef.current);
362
- authTimeoutRef.current = setTimeout(() => {
363
- if (isMountedRef.current) {
364
- const currentStateValue = stateRef.current;
365
- if (currentStateValue === "authenticating") {
366
- failConnection("Authentication timed out. Please try again.");
367
- }
368
- }
369
- }, AUTH_TIMEOUT);
370
402
  try {
371
403
  assert(
372
404
  authProviderRef.current,
373
405
  "Auth Provider not available for manual auth"
374
406
  );
375
407
  assert(url, "Server URL is required for authentication");
376
- addLog(
377
- "info",
378
- "Redirecting for manual authentication. Waiting for callback..."
379
- );
408
+ addLog("info", "Clearing all OAuth state and initiating fresh flow...");
409
+ const hashPrefix = `${storageKeyPrefix}:${authProviderRef.current.serverUrlHash}`;
410
+ Object.keys(localStorage).forEach((key) => {
411
+ if (key.startsWith(hashPrefix)) {
412
+ addLog("debug", `Removing stale OAuth key: ${key}`);
413
+ localStorage.removeItem(key);
414
+ }
415
+ if (key.startsWith(`${storageKeyPrefix}:state_`)) {
416
+ addLog("debug", `Removing orphaned state: ${key}`);
417
+ localStorage.removeItem(key);
418
+ }
419
+ });
420
+ setState("authenticating");
421
+ const freshAuthProvider = new BrowserOAuthClientProvider(url, {
422
+ storageKeyPrefix,
423
+ clientName,
424
+ clientUri,
425
+ callbackUrl,
426
+ preventAutoAuth: false,
427
+ // ← Allow OAuth to proceed
428
+ useRedirectFlow,
429
+ onPopupWindow
430
+ });
431
+ authProviderRef.current = freshAuthProvider;
432
+ addLog("info", "Triggering fresh OAuth authorization...");
433
+ const { auth } = await import("@modelcontextprotocol/sdk/client/auth.js");
434
+ const baseUrl = new URL(url).origin;
435
+ auth(freshAuthProvider, {
436
+ serverUrl: baseUrl
437
+ }).catch((err) => {
438
+ addLog(
439
+ "info",
440
+ "OAuth flow initiated:",
441
+ err?.message || "Redirecting..."
442
+ );
443
+ });
380
444
  } catch (authError) {
381
445
  if (!isMountedRef.current) return;
382
- if (authTimeoutRef.current) clearTimeout(authTimeoutRef.current);
383
- failConnection(
384
- `Manual authentication failed: ${authError instanceof Error ? authError.message : String(authError)}`,
385
- authError instanceof Error ? authError : void 0
446
+ setState("pending_auth");
447
+ addLog(
448
+ "error",
449
+ `Manual authentication failed: ${authError instanceof Error ? authError.message : String(authError)}`
386
450
  );
387
451
  }
388
452
  } else if (currentState === "authenticating") {
@@ -401,7 +465,18 @@ function useMcp(options) {
401
465
  `Client not in a state requiring manual authentication trigger (state: ${currentState}). If needed, try disconnecting and reconnecting.`
402
466
  );
403
467
  }
404
- }, [addLog, retry, authUrl, url, failConnection, connect]);
468
+ }, [
469
+ addLog,
470
+ retry,
471
+ authUrl,
472
+ url,
473
+ useRedirectFlow,
474
+ onPopupWindow,
475
+ storageKeyPrefix,
476
+ clientName,
477
+ clientUri,
478
+ callbackUrl
479
+ ]);
405
480
  const clearStorage = useCallback(() => {
406
481
  if (authProviderRef.current) {
407
482
  const count = authProviderRef.current.clearStorage();
@@ -572,6 +647,7 @@ function useMcp(options) {
572
647
  clientUri,
573
648
  callbackUrl,
574
649
  preventAutoAuth,
650
+ useRedirectFlow,
575
651
  onPopupWindow
576
652
  });
577
653
  addLog(
@@ -593,7 +669,8 @@ function useMcp(options) {
593
669
  clientName,
594
670
  clientUri,
595
671
  clientConfig.name,
596
- clientConfig.version
672
+ clientConfig.version,
673
+ useRedirectFlow
597
674
  ]);
598
675
  useEffect(() => {
599
676
  let retryTimeoutId = null;
@@ -1414,7 +1491,18 @@ __name(WidgetControls, "WidgetControls");
1414
1491
 
1415
1492
  // src/react/McpUseProvider.tsx
1416
1493
  import React5, { StrictMode, useCallback as useCallback3, useEffect as useEffect5, useRef as useRef3 } from "react";
1417
- import { BrowserRouter } from "react-router-dom";
1494
+ var BrowserRouter = null;
1495
+ var routerError = null;
1496
+ (async () => {
1497
+ try {
1498
+ const routerModule = await import("react-router-dom");
1499
+ BrowserRouter = routerModule.BrowserRouter;
1500
+ } catch (error) {
1501
+ routerError = new Error(
1502
+ "\u274C react-router-dom not installed!\n\nTo use MCP widgets with McpUseProvider, you need to install:\n\n npm install react-router-dom\n # or\n pnpm add react-router-dom\n\nThis dependency is automatically included in projects created with 'create-mcp-use-app'."
1503
+ );
1504
+ }
1505
+ })();
1418
1506
  function getBasename() {
1419
1507
  if (typeof window === "undefined") return "/";
1420
1508
  const path = window.location.pathname;
@@ -1508,6 +1596,12 @@ function McpUseProvider({
1508
1596
  if (enableDebugger || viewControls) {
1509
1597
  content = /* @__PURE__ */ React5.createElement(WidgetControls, { debugger: enableDebugger, viewControls }, content);
1510
1598
  }
1599
+ if (routerError) {
1600
+ throw routerError;
1601
+ }
1602
+ if (!BrowserRouter) {
1603
+ throw new Error("react-router-dom is still loading, please try again.");
1604
+ }
1511
1605
  content = /* @__PURE__ */ React5.createElement(BrowserRouter, { basename }, content);
1512
1606
  content = /* @__PURE__ */ React5.createElement(ThemeProvider, null, content);
1513
1607
  if (autoSize) {
@@ -6,8 +6,6 @@ import {
6
6
  } from "./chunk-3GQAWCBQ.js";
7
7
 
8
8
  // src/observability/langfuse.ts
9
- import { config } from "dotenv";
10
- config();
11
9
  var langfuseDisabled = process.env.MCP_USE_LANGFUSE?.toLowerCase() === "false";
12
10
  var langfuseState = {
13
11
  handler: null,
@@ -33,13 +31,13 @@ async function initializeLangfuse(agentId, metadata, metadataProvider, tagsProvi
33
31
  metadataProvider;
34
32
  tagsProvider;
35
33
  verbose;
36
- constructor(config3, agentId2, metadata2, metadataProvider2, tagsProvider2) {
37
- super(config3);
34
+ constructor(config2, agentId2, metadata2, metadataProvider2, tagsProvider2) {
35
+ super(config2);
38
36
  this.agentId = agentId2;
39
37
  this.metadata = metadata2;
40
38
  this.metadataProvider = metadataProvider2;
41
39
  this.tagsProvider = tagsProvider2;
42
- this.verbose = config3?.verbose ?? false;
40
+ this.verbose = config2?.verbose ?? false;
43
41
  }
44
42
  // Override to add custom metadata to traces
45
43
  async handleChainStart(chain, inputs, runId, parentRunId, tags, metadata2, name, kwargs) {
@@ -164,7 +162,7 @@ async function initializeLangfuse(agentId, metadata, metadataProvider, tagsProvi
164
162
  }
165
163
  const initialMetadata = metadata || (metadataProvider ? metadataProvider() : {});
166
164
  const initialTags = tagsProvider ? tagsProvider() : [];
167
- const config2 = {
165
+ const config = {
168
166
  publicKey: process.env.LANGFUSE_PUBLIC_KEY,
169
167
  secretKey: process.env.LANGFUSE_SECRET_KEY,
170
168
  baseUrl: process.env.LANGFUSE_HOST || process.env.LANGFUSE_BASEURL || "https://cloud.langfuse.com",
@@ -189,17 +187,17 @@ async function initializeLangfuse(agentId, metadata, metadataProvider, tagsProvi
189
187
  "Langfuse handler config:",
190
188
  JSON.stringify(
191
189
  {
192
- traceName: config2.traceName,
193
- sessionId: config2.sessionId,
194
- userId: config2.userId,
195
- tags: config2.tags
190
+ traceName: config.traceName,
191
+ sessionId: config.sessionId,
192
+ userId: config.userId,
193
+ tags: config.tags
196
194
  },
197
195
  null,
198
196
  2
199
197
  )
200
198
  );
201
199
  langfuseState.handler = new LoggingCallbackHandler(
202
- config2,
200
+ config,
203
201
  agentId,
204
202
  metadata,
205
203
  metadataProvider,