mcp-use 1.2.1-canary.0 → 1.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.
package/dist/index.cjs CHANGED
@@ -3325,6 +3325,7 @@ var BaseConnector = class {
3325
3325
  client = null;
3326
3326
  connectionManager = null;
3327
3327
  toolsCache = null;
3328
+ capabilitiesCache = null;
3328
3329
  connected = false;
3329
3330
  opts;
3330
3331
  constructor(opts = {}) {
@@ -3358,9 +3359,11 @@ var BaseConnector = class {
3358
3359
  }
3359
3360
  logger.debug("Caching server capabilities & tools");
3360
3361
  const capabilities = this.client.getServerCapabilities();
3362
+ this.capabilitiesCache = capabilities;
3361
3363
  const listToolsRes = await this.client.listTools(void 0, defaultRequestOptions);
3362
3364
  this.toolsCache = listToolsRes.tools ?? [];
3363
3365
  logger.debug(`Fetched ${this.toolsCache.length} tools from server`);
3366
+ logger.debug("Server capabilities:", capabilities);
3364
3367
  return capabilities;
3365
3368
  }
3366
3369
  /** Lazily expose the cached tools list. */
@@ -3382,7 +3385,7 @@ var BaseConnector = class {
3382
3385
  }
3383
3386
  /**
3384
3387
  * List resources from the server with optional pagination
3385
- *
3388
+ *
3386
3389
  * @param cursor - Optional cursor for pagination
3387
3390
  * @param options - Request options
3388
3391
  * @returns Resource list with optional nextCursor for pagination
@@ -3396,7 +3399,7 @@ var BaseConnector = class {
3396
3399
  }
3397
3400
  /**
3398
3401
  * List all resources from the server, automatically handling pagination
3399
- *
3402
+ *
3400
3403
  * @param options - Request options
3401
3404
  * @returns Complete list of all resources
3402
3405
  */
@@ -3404,19 +3407,31 @@ var BaseConnector = class {
3404
3407
  if (!this.client) {
3405
3408
  throw new Error("MCP client is not connected");
3406
3409
  }
3407
- logger.debug("Listing all resources (with auto-pagination)");
3408
- const allResources = [];
3409
- let cursor = void 0;
3410
- do {
3411
- const result = await this.client.listResources({ cursor }, options);
3412
- allResources.push(...result.resources || []);
3413
- cursor = result.nextCursor;
3414
- } while (cursor);
3415
- return { resources: allResources };
3410
+ if (!this.capabilitiesCache?.resources) {
3411
+ logger.debug("Server does not advertise resources capability, skipping");
3412
+ return { resources: [] };
3413
+ }
3414
+ try {
3415
+ logger.debug("Listing all resources (with auto-pagination)");
3416
+ const allResources = [];
3417
+ let cursor = void 0;
3418
+ do {
3419
+ const result = await this.client.listResources({ cursor }, options);
3420
+ allResources.push(...result.resources || []);
3421
+ cursor = result.nextCursor;
3422
+ } while (cursor);
3423
+ return { resources: allResources };
3424
+ } catch (err) {
3425
+ if (err.code === -32601) {
3426
+ logger.debug("Server advertised resources but method not found");
3427
+ return { resources: [] };
3428
+ }
3429
+ throw err;
3430
+ }
3416
3431
  }
3417
3432
  /**
3418
3433
  * List resource templates from the server
3419
- *
3434
+ *
3420
3435
  * @param options - Request options
3421
3436
  * @returns List of available resource templates
3422
3437
  */
@@ -3434,11 +3449,11 @@ var BaseConnector = class {
3434
3449
  }
3435
3450
  logger.debug(`Reading resource ${uri}`);
3436
3451
  const res = await this.client.readResource({ uri }, options);
3437
- return { content: res.content, mimeType: res.mimeType };
3452
+ return res;
3438
3453
  }
3439
3454
  /**
3440
3455
  * Subscribe to resource updates
3441
- *
3456
+ *
3442
3457
  * @param uri - URI of the resource to subscribe to
3443
3458
  * @param options - Request options
3444
3459
  */
@@ -3451,7 +3466,7 @@ var BaseConnector = class {
3451
3466
  }
3452
3467
  /**
3453
3468
  * Unsubscribe from resource updates
3454
- *
3469
+ *
3455
3470
  * @param uri - URI of the resource to unsubscribe from
3456
3471
  * @param options - Request options
3457
3472
  */
@@ -3466,8 +3481,20 @@ var BaseConnector = class {
3466
3481
  if (!this.client) {
3467
3482
  throw new Error("MCP client is not connected");
3468
3483
  }
3469
- logger.debug("Listing prompt");
3470
- return await this.client.listPrompts();
3484
+ if (!this.capabilitiesCache?.prompts) {
3485
+ logger.debug("Server does not advertise prompts capability, skipping");
3486
+ return { prompts: [] };
3487
+ }
3488
+ try {
3489
+ logger.debug("Listing prompts");
3490
+ return await this.client.listPrompts();
3491
+ } catch (err) {
3492
+ if (err.code === -32601) {
3493
+ logger.debug("Server advertised prompts but method not found");
3494
+ return { prompts: [] };
3495
+ }
3496
+ throw err;
3497
+ }
3471
3498
  }
3472
3499
  async getPrompt(name, args) {
3473
3500
  if (!this.client) {
@@ -3563,7 +3590,9 @@ var HttpConnector = class extends BaseConnector {
3563
3590
  logger.info("\u2705 Successfully connected via streamable HTTP");
3564
3591
  } catch (err) {
3565
3592
  let fallbackReason = "Unknown error";
3593
+ let is401Error = false;
3566
3594
  if (err instanceof import_streamableHttp2.StreamableHTTPError) {
3595
+ is401Error = err.code === 401;
3567
3596
  if (err.code === 400 && err.message.includes("Missing session ID")) {
3568
3597
  fallbackReason = "Server requires session ID (FastMCP compatibility) - using SSE transport";
3569
3598
  logger.warn(`\u26A0\uFE0F ${fallbackReason}`);
@@ -3577,6 +3606,7 @@ var HttpConnector = class extends BaseConnector {
3577
3606
  } else if (err instanceof Error) {
3578
3607
  const errorStr = err.toString();
3579
3608
  const errorMsg = err.message || "";
3609
+ is401Error = errorStr.includes("401") || errorMsg.includes("Unauthorized");
3580
3610
  if (errorStr.includes("Missing session ID") || errorStr.includes("Bad Request: Missing session ID") || errorMsg.includes("FastMCP session ID error")) {
3581
3611
  fallbackReason = "Server requires session ID (FastMCP compatibility) - using SSE transport";
3582
3612
  logger.warn(`\u26A0\uFE0F ${fallbackReason}`);
@@ -3588,6 +3618,13 @@ var HttpConnector = class extends BaseConnector {
3588
3618
  logger.debug(fallbackReason);
3589
3619
  }
3590
3620
  }
3621
+ if (is401Error) {
3622
+ logger.info("Authentication required - skipping SSE fallback");
3623
+ await this.cleanupResources();
3624
+ const authError = new Error("Authentication required");
3625
+ authError.code = 401;
3626
+ throw authError;
3627
+ }
3591
3628
  logger.info("\u{1F504} Falling back to SSE transport...");
3592
3629
  try {
3593
3630
  await this.connectWithSse(baseUrl);
@@ -3596,6 +3633,12 @@ var HttpConnector = class extends BaseConnector {
3596
3633
  logger.error(` Streamable HTTP: ${fallbackReason}`);
3597
3634
  logger.error(` SSE: ${sseErr}`);
3598
3635
  await this.cleanupResources();
3636
+ const sseIs401 = sseErr?.message?.includes("401") || sseErr?.message?.includes("Unauthorized");
3637
+ if (sseIs401) {
3638
+ const authError = new Error("Authentication required");
3639
+ authError.code = 401;
3640
+ throw authError;
3641
+ }
3599
3642
  throw new Error("Could not connect to server with any available transport");
3600
3643
  }
3601
3644
  }
@@ -3605,6 +3648,8 @@ var HttpConnector = class extends BaseConnector {
3605
3648
  this.connectionManager = new StreamableHttpConnectionManager(
3606
3649
  baseUrl,
3607
3650
  {
3651
+ authProvider: this.opts.authProvider,
3652
+ // ← Pass OAuth provider to SDK
3608
3653
  requestInit: {
3609
3654
  headers: this.headers
3610
3655
  },
@@ -4002,7 +4047,7 @@ var WebSocketConnector = class extends BaseConnector {
4002
4047
  }
4003
4048
  async readResource(uri) {
4004
4049
  const res = await this.sendRequest("resources/read", { uri });
4005
- return { content: res.content, mimeType: res.mimeType };
4050
+ return res;
4006
4051
  }
4007
4052
  async request(method, params = null) {
4008
4053
  return await this.sendRequest(method, params);
@@ -4821,14 +4866,45 @@ async function onMcpAuthorization() {
4821
4866
  __name(onMcpAuthorization, "onMcpAuthorization");
4822
4867
 
4823
4868
  // src/react/useMcp.ts
4824
- var import_types = require("@modelcontextprotocol/sdk/types.js");
4825
4869
  var import_react = require("react");
4826
- var import_auth2 = require("@modelcontextprotocol/sdk/client/auth.js");
4827
- var import_client3 = require("@modelcontextprotocol/sdk/client/index.js");
4828
- var import_sse3 = require("@modelcontextprotocol/sdk/client/sse.js");
4829
- var import_streamableHttp3 = require("@modelcontextprotocol/sdk/client/streamableHttp.js");
4830
4870
  var import_strict_url_sanitise2 = require("strict-url-sanitise");
4831
4871
 
4872
+ // src/client/browser.ts
4873
+ var BrowserMCPClient = class _BrowserMCPClient extends BaseMCPClient {
4874
+ static {
4875
+ __name(this, "BrowserMCPClient");
4876
+ }
4877
+ constructor(config2) {
4878
+ super(config2);
4879
+ }
4880
+ static fromDict(cfg) {
4881
+ return new _BrowserMCPClient(cfg);
4882
+ }
4883
+ /**
4884
+ * Create a connector from server configuration (Browser version)
4885
+ * Supports HTTP and WebSocket connectors only
4886
+ */
4887
+ createConnectorFromConfig(serverConfig) {
4888
+ const { url, transport, headers, authToken, authProvider } = serverConfig;
4889
+ if (!url) {
4890
+ throw new Error("Server URL is required");
4891
+ }
4892
+ const connectorOptions = {
4893
+ headers,
4894
+ authToken,
4895
+ authProvider
4896
+ // ← Pass OAuth provider to connector
4897
+ };
4898
+ if (transport === "websocket" || url.startsWith("ws://") || url.startsWith("wss://")) {
4899
+ return new WebSocketConnector(url, connectorOptions);
4900
+ } else if (transport === "http" || url.startsWith("http://") || url.startsWith("https://")) {
4901
+ return new HttpConnector(url, connectorOptions);
4902
+ } else {
4903
+ return new HttpConnector(url, connectorOptions);
4904
+ }
4905
+ }
4906
+ };
4907
+
4832
4908
  // src/utils/assert.ts
4833
4909
  function assert(condition, message) {
4834
4910
  if (!condition) {
@@ -4871,7 +4947,6 @@ function useMcp(options) {
4871
4947
  const [log, setLog] = (0, import_react.useState)([]);
4872
4948
  const [authUrl, setAuthUrl] = (0, import_react.useState)(void 0);
4873
4949
  const clientRef = (0, import_react.useRef)(null);
4874
- const transportRef = (0, import_react.useRef)(null);
4875
4950
  const authProviderRef = (0, import_react.useRef)(null);
4876
4951
  const connectingRef = (0, import_react.useRef)(false);
4877
4952
  const isMountedRef = (0, import_react.useRef)(true);
@@ -4900,9 +4975,15 @@ function useMcp(options) {
4900
4975
  connectingRef.current = false;
4901
4976
  if (authTimeoutRef.current) clearTimeout(authTimeoutRef.current);
4902
4977
  authTimeoutRef.current = null;
4903
- const transport = transportRef.current;
4978
+ if (clientRef.current) {
4979
+ try {
4980
+ const serverName = "inspector-server";
4981
+ await clientRef.current.closeSession(serverName);
4982
+ } catch (err) {
4983
+ if (!quiet) addLog("warn", "Error closing session:", err);
4984
+ }
4985
+ }
4904
4986
  clientRef.current = null;
4905
- transportRef.current = null;
4906
4987
  if (isMountedRef.current && !quiet) {
4907
4988
  setState("discovering");
4908
4989
  setTools([]);
@@ -4912,14 +4993,6 @@ function useMcp(options) {
4912
4993
  setError(void 0);
4913
4994
  setAuthUrl(void 0);
4914
4995
  }
4915
- if (transport) {
4916
- try {
4917
- await transport.close();
4918
- if (!quiet) addLog("debug", "Transport closed");
4919
- } catch (err) {
4920
- if (!quiet) addLog("warn", "Error closing transport:", err);
4921
- }
4922
- }
4923
4996
  },
4924
4997
  [addLog]
4925
4998
  );
@@ -4971,187 +5044,60 @@ function useMcp(options) {
4971
5044
  addLog("debug", "BrowserOAuthClientProvider initialized in connect.");
4972
5045
  }
4973
5046
  if (!clientRef.current) {
4974
- clientRef.current = new import_client3.Client(
4975
- { name: clientConfig.name || "mcp-use", version: clientConfig.version || "0.1.0" },
4976
- { capabilities: {} }
4977
- );
4978
- addLog("debug", "MCP Client initialized in connect.");
5047
+ clientRef.current = new BrowserMCPClient();
5048
+ addLog("debug", "BrowserMCPClient initialized in connect.");
4979
5049
  }
4980
5050
  const tryConnectWithTransport = /* @__PURE__ */ __name(async (transportTypeParam, isAuthRetry = false) => {
4981
- addLog("info", `Attempting connection with ${transportTypeParam.toUpperCase()} transport${isAuthRetry ? " (after auth)" : ""}...`);
4982
- if (stateRef.current !== "authenticating") {
4983
- setState("connecting");
4984
- }
4985
- let transportInstance;
5051
+ addLog("info", `Attempting connection with transport: ${transportTypeParam}`);
4986
5052
  try {
4987
- assert(authProviderRef.current, "Auth Provider must be initialized");
4988
- assert(clientRef.current, "Client must be initialized");
4989
- if (transportRef.current) {
4990
- await transportRef.current.close().catch((e) => addLog("warn", `Error closing previous transport: ${e.message}`));
4991
- transportRef.current = null;
4992
- }
4993
- const commonOptions = {
4994
- authProvider: authProviderRef.current,
4995
- requestInit: {
4996
- headers: {
4997
- Accept: "application/json, text/event-stream",
4998
- ...customHeaders
4999
- }
5000
- }
5001
- // Note: The MCP SDK's SSEClientTransport doesn't expose timeout configuration directly
5002
- // Timeout handling is managed by the underlying EventSource and browser/Node.js fetch implementations
5003
- // The timeout and sseReadTimeout options are preserved for future use or custom implementations
5053
+ const serverName = "inspector-server";
5054
+ const serverConfig = {
5055
+ url,
5056
+ transport: transportTypeParam === "sse" ? "http" : transportTypeParam
5004
5057
  };
5005
- const sanitizedUrl = (0, import_strict_url_sanitise2.sanitizeUrl)(url);
5006
- const targetUrl = new URL(sanitizedUrl);
5007
- addLog("debug", `Creating ${transportTypeParam.toUpperCase()} transport for URL: ${targetUrl.toString()}`);
5008
- if (transportTypeParam === "http") {
5009
- addLog("debug", "Creating StreamableHTTPClientTransport...");
5010
- transportInstance = new import_streamableHttp3.StreamableHTTPClientTransport(targetUrl, commonOptions);
5011
- addLog("debug", "StreamableHTTPClientTransport created successfully");
5012
- } else {
5013
- addLog("debug", "Creating SSEClientTransport...");
5014
- transportInstance = new import_sse3.SSEClientTransport(targetUrl, commonOptions);
5015
- addLog("debug", "SSEClientTransport created successfully");
5016
- }
5017
- transportRef.current = transportInstance;
5018
- addLog("debug", `${transportTypeParam.toUpperCase()} transport created and assigned to ref.`);
5019
- } catch (err) {
5020
- failConnection(
5021
- `Failed to create ${transportTypeParam.toUpperCase()} transport: ${err instanceof Error ? err.message : String(err)}`,
5022
- err instanceof Error ? err : void 0
5023
- );
5024
- return "failed";
5025
- }
5026
- transportInstance.onmessage = (message) => {
5027
- addLog("debug", `[Transport] Received: ${JSON.stringify(message)}`);
5028
- clientRef.current?.handleMessage?.(message);
5029
- };
5030
- transportInstance.onerror = (err) => {
5031
- addLog("warn", `Transport error event (${transportTypeParam.toUpperCase()}):`, err);
5032
- failConnection(`Transport error (${transportTypeParam.toUpperCase()}): ${err.message}`, err);
5033
- };
5034
- transportInstance.onclose = () => {
5035
- if (!isMountedRef.current || connectingRef.current) return;
5036
- addLog("info", `Transport connection closed (${successfulTransportRef.current || "unknown"} type).`);
5037
- const currentState = stateRef.current;
5038
- const currentAutoReconnect = autoReconnectRef.current;
5039
- if (currentState === "ready" && currentAutoReconnect) {
5040
- const delay = typeof currentAutoReconnect === "number" ? currentAutoReconnect : DEFAULT_RECONNECT_DELAY;
5041
- addLog("info", `Attempting to reconnect in ${delay}ms...`);
5042
- setState("connecting");
5043
- setTimeout(() => {
5044
- if (isMountedRef.current) {
5045
- connect();
5046
- }
5047
- }, delay);
5048
- } else if (currentState !== "failed" && currentState !== "authenticating") {
5049
- failConnection("Cannot connect to server");
5050
- }
5051
- };
5052
- try {
5053
- addLog("info", `Connecting client via ${transportTypeParam.toUpperCase()}...`);
5054
- await clientRef.current.connect(transportInstance);
5055
- addLog("info", `Client connected via ${transportTypeParam.toUpperCase()}. Loading tools, resources, and prompts...`);
5056
- successfulTransportRef.current = transportTypeParam;
5057
- setState("loading");
5058
- const toolsResponse = await clientRef.current.request({ method: "tools/list" }, import_types.ListToolsResultSchema);
5059
- let resourcesResponse = { resources: [], resourceTemplates: [] };
5060
- try {
5061
- resourcesResponse = await clientRef.current.request({ method: "resources/list" }, import_types.ListResourcesResultSchema);
5062
- } catch (err) {
5063
- addLog("debug", "Server does not support resources/list method", err);
5058
+ if (customHeaders && Object.keys(customHeaders).length > 0) {
5059
+ serverConfig.headers = customHeaders;
5064
5060
  }
5065
- let promptsResponse = { prompts: [] };
5066
- try {
5067
- promptsResponse = await clientRef.current.request({ method: "prompts/list" }, import_types.ListPromptsResultSchema);
5068
- } catch (err) {
5069
- addLog("debug", "Server does not support prompts/list method", err);
5070
- }
5071
- if (isMountedRef.current) {
5072
- setTools(toolsResponse.tools);
5073
- setResources(resourcesResponse.resources);
5074
- setResourceTemplates(Array.isArray(resourcesResponse.resourceTemplates) ? resourcesResponse.resourceTemplates : []);
5075
- setPrompts(promptsResponse.prompts);
5076
- const summary = [`Loaded ${toolsResponse.tools.length} tools`];
5077
- if (resourcesResponse.resources.length > 0 || resourcesResponse.resourceTemplates && resourcesResponse.resourceTemplates.length > 0) {
5078
- summary.push(`${resourcesResponse.resources.length} resources`);
5079
- if (Array.isArray(resourcesResponse.resourceTemplates) && resourcesResponse.resourceTemplates.length > 0) {
5080
- summary.push(`${resourcesResponse.resourceTemplates.length} resource templates`);
5081
- }
5082
- }
5083
- if (promptsResponse.prompts.length > 0) {
5084
- summary.push(`${promptsResponse.prompts.length} prompts`);
5061
+ if (authProviderRef.current) {
5062
+ const tokens = await authProviderRef.current.tokens();
5063
+ if (tokens?.access_token) {
5064
+ serverConfig.headers = {
5065
+ ...serverConfig.headers,
5066
+ Authorization: `Bearer ${tokens.access_token}`
5067
+ };
5085
5068
  }
5086
- addLog("info", summary.join(", ") + ".");
5087
- setState("ready");
5088
- connectAttemptRef.current = 0;
5089
- return "success";
5090
- } else {
5091
- return "failed";
5092
5069
  }
5093
- } catch (connectErr) {
5094
- addLog("debug", `Client connect error via ${transportTypeParam.toUpperCase()}:`, connectErr);
5095
- const errorInstance = connectErr instanceof Error ? connectErr : new Error(String(connectErr));
5096
- const errorMessage = errorInstance.message;
5097
- const is404 = errorMessage.includes("404") || errorMessage.includes("Not Found");
5098
- const is405 = errorMessage.includes("405") || errorMessage.includes("Method Not Allowed");
5099
- const isLikelyCors = errorMessage === "Failed to fetch" || errorMessage === "NetworkError when attempting to fetch resource." || errorMessage === "Load failed";
5100
- if (transportTypeParam === "http" && (is404 || is405 || isLikelyCors)) {
5101
- addLog("warn", `HTTP transport failed (${isLikelyCors ? "CORS" : is404 ? "404" : "405"}), will try fallback.`);
5102
- return "fallback";
5103
- }
5104
- if (errorInstance instanceof import_auth2.UnauthorizedError || errorMessage.includes("Unauthorized") || errorMessage.includes("401")) {
5105
- if (isAuthRetry) {
5106
- addLog("error", "Authentication failed even after successful token refresh. This may indicate a server issue.");
5107
- failConnection("Authentication loop detected - auth succeeded but connection still unauthorized.");
5108
- return "failed";
5109
- }
5110
- addLog("info", "Authentication required.");
5111
- assert(authProviderRef.current, "Auth Provider not available for auth flow");
5112
- const existingTokens = await authProviderRef.current.tokens();
5113
- if (preventAutoAuth && !existingTokens) {
5114
- addLog("info", "Authentication required but auto-auth prevented. User action needed.");
5115
- setState("pending_auth");
5116
- return "auth_redirect";
5117
- }
5118
- if (stateRef.current !== "authenticating" && stateRef.current !== "pending_auth") {
5119
- setState("authenticating");
5120
- if (authTimeoutRef.current) clearTimeout(authTimeoutRef.current);
5121
- authTimeoutRef.current = setTimeout(() => {
5122
- if (isMountedRef.current) {
5123
- const currentState = stateRef.current;
5124
- if (currentState === "authenticating") {
5125
- failConnection("Authentication timed out. Please try again.");
5126
- }
5127
- }
5128
- }, AUTH_TIMEOUT);
5129
- }
5130
- try {
5131
- assert(url, "Server URL is required for authentication");
5132
- const baseUrl = new URL(url).origin;
5133
- const authResult = await (0, import_auth2.auth)(authProviderRef.current, { serverUrl: baseUrl });
5134
- if (!isMountedRef.current) return "failed";
5135
- if (authResult === "AUTHORIZED") {
5136
- addLog("info", "Authentication successful via existing token or refresh. Retrying transport connection...");
5137
- if (authTimeoutRef.current) clearTimeout(authTimeoutRef.current);
5138
- authTimeoutRef.current = null;
5139
- return await tryConnectWithTransport(transportTypeParam, true);
5140
- } else if (authResult === "REDIRECT") {
5141
- addLog("info", "Redirecting for authentication. Waiting for callback...");
5142
- return "auth_redirect";
5143
- }
5144
- } catch (sdkAuthError) {
5145
- if (!isMountedRef.current) return "failed";
5146
- if (authTimeoutRef.current) clearTimeout(authTimeoutRef.current);
5070
+ clientRef.current.addServer(serverName, {
5071
+ ...serverConfig,
5072
+ authProvider: authProviderRef.current
5073
+ // SDK handles OAuth automatically!
5074
+ });
5075
+ const session = await clientRef.current.createSession(serverName);
5076
+ await session.initialize();
5077
+ addLog("info", "\u2705 Successfully connected to MCP server");
5078
+ setState("ready");
5079
+ successfulTransportRef.current = transportTypeParam;
5080
+ setTools(session.connector.tools || []);
5081
+ const resourcesResult = await session.connector.listAllResources();
5082
+ setResources(resourcesResult.resources || []);
5083
+ const promptsResult = await session.connector.listPrompts();
5084
+ setPrompts(promptsResult.prompts || []);
5085
+ return "success";
5086
+ } catch (err) {
5087
+ const errorMessage = err?.message || String(err);
5088
+ if (err.code === 401 || errorMessage.includes("401") || errorMessage.includes("Unauthorized")) {
5089
+ if (customHeaders && Object.keys(customHeaders).length > 0) {
5147
5090
  failConnection(
5148
- `Failed to initiate authentication: ${sdkAuthError instanceof Error ? sdkAuthError.message : String(sdkAuthError)}`,
5149
- sdkAuthError instanceof Error ? sdkAuthError : void 0
5091
+ "Authentication failed: Server returned 401 Unauthorized. Check your Authorization header value is correct."
5150
5092
  );
5151
5093
  return "failed";
5152
5094
  }
5095
+ failConnection(
5096
+ "Authentication required: Server returned 401 Unauthorized. Add an Authorization header in the Custom Headers section (e.g., Authorization: Bearer YOUR_API_KEY)."
5097
+ );
5098
+ return "failed";
5153
5099
  }
5154
- failConnection(`Failed to connect via ${transportTypeParam.toUpperCase()}: ${errorMessage}`, errorInstance);
5100
+ failConnection(errorMessage, err);
5155
5101
  return "failed";
5156
5102
  }
5157
5103
  }, "tryConnectWithTransport");
@@ -5203,55 +5149,20 @@ function useMcp(options) {
5203
5149
  }
5204
5150
  addLog("info", `Calling tool: ${name}`, args);
5205
5151
  try {
5206
- const result = await clientRef.current.request({ method: "tools/call", params: { name, arguments: args } }, import_types.CallToolResultSchema);
5152
+ const serverName = "inspector-server";
5153
+ const session = clientRef.current.getSession(serverName);
5154
+ if (!session) {
5155
+ throw new Error("No active session found");
5156
+ }
5157
+ const result = await session.connector.callTool(name, args || {});
5207
5158
  addLog("info", `Tool "${name}" call successful:`, result);
5208
5159
  return result;
5209
5160
  } catch (err) {
5210
- addLog("error", `Error calling tool "${name}": ${err instanceof Error ? err.message : String(err)}`, err);
5211
- const errorInstance = err instanceof Error ? err : new Error(String(err));
5212
- if (errorInstance instanceof import_auth2.UnauthorizedError || errorInstance.message.includes("Unauthorized") || errorInstance.message.includes("401")) {
5213
- addLog("warn", "Tool call unauthorized, attempting re-authentication...");
5214
- setState("authenticating");
5215
- if (authTimeoutRef.current) clearTimeout(authTimeoutRef.current);
5216
- authTimeoutRef.current = setTimeout(() => {
5217
- if (isMountedRef.current) {
5218
- const currentState2 = stateRef.current;
5219
- if (currentState2 === "authenticating") {
5220
- failConnection("Authentication timed out. Please try again.");
5221
- }
5222
- }
5223
- }, AUTH_TIMEOUT);
5224
- try {
5225
- assert(authProviderRef.current, "Auth Provider not available for tool re-auth");
5226
- assert(url, "Server URL is required for authentication");
5227
- const baseUrl = new URL(url).origin;
5228
- const authResult = await (0, import_auth2.auth)(authProviderRef.current, { serverUrl: baseUrl });
5229
- if (!isMountedRef.current) return;
5230
- if (authResult === "AUTHORIZED") {
5231
- addLog("info", "Re-authentication successful. Retrying tool call is recommended, or reconnecting.");
5232
- if (authTimeoutRef.current) clearTimeout(authTimeoutRef.current);
5233
- connectingRef.current = false;
5234
- connect();
5235
- } else if (authResult === "REDIRECT") {
5236
- addLog("info", "Redirecting for re-authentication for tool call.");
5237
- }
5238
- } catch (sdkAuthError) {
5239
- if (!isMountedRef.current) return;
5240
- if (authTimeoutRef.current) clearTimeout(authTimeoutRef.current);
5241
- failConnection(
5242
- `Re-authentication failed: ${sdkAuthError instanceof Error ? sdkAuthError.message : String(sdkAuthError)}`,
5243
- sdkAuthError instanceof Error ? sdkAuthError : void 0
5244
- );
5245
- }
5246
- }
5247
- const currentState = stateRef.current;
5248
- if (currentState !== "authenticating") {
5249
- throw err;
5250
- }
5251
- return void 0;
5161
+ addLog("error", `Tool "${name}" call failed:`, err);
5162
+ throw err;
5252
5163
  }
5253
5164
  },
5254
- [state, url, addLog, failConnection, connect]
5165
+ [state]
5255
5166
  );
5256
5167
  const retry = (0, import_react.useCallback)(() => {
5257
5168
  if (stateRef.current === "failed") {
@@ -5282,17 +5193,7 @@ function useMcp(options) {
5282
5193
  try {
5283
5194
  assert(authProviderRef.current, "Auth Provider not available for manual auth");
5284
5195
  assert(url, "Server URL is required for authentication");
5285
- const baseUrl = new URL(url).origin;
5286
- const authResult = await (0, import_auth2.auth)(authProviderRef.current, { serverUrl: baseUrl });
5287
- if (!isMountedRef.current) return;
5288
- if (authResult === "AUTHORIZED") {
5289
- addLog("info", "Manual authentication successful. Re-attempting connection...");
5290
- if (authTimeoutRef.current) clearTimeout(authTimeoutRef.current);
5291
- connectingRef.current = false;
5292
- connect();
5293
- } else if (authResult === "REDIRECT") {
5294
- addLog("info", "Redirecting for manual authentication. Waiting for callback...");
5295
- }
5196
+ addLog("info", "Redirecting for manual authentication. Waiting for callback...");
5296
5197
  } catch (authError) {
5297
5198
  if (!isMountedRef.current) return;
5298
5199
  if (authTimeoutRef.current) clearTimeout(authTimeoutRef.current);
@@ -5325,75 +5226,93 @@ function useMcp(options) {
5325
5226
  addLog("warn", "Auth provider not initialized, cannot clear storage.");
5326
5227
  }
5327
5228
  }, [url, addLog, disconnect]);
5328
- const listResources = (0, import_react.useCallback)(async () => {
5329
- if (stateRef.current !== "ready" || !clientRef.current) {
5330
- throw new Error(`MCP client is not ready (current state: ${state}). Cannot list resources.`);
5331
- }
5332
- addLog("info", "Listing resources...");
5333
- try {
5334
- const resourcesResponse = await clientRef.current.request({ method: "resources/list" }, import_types.ListResourcesResultSchema);
5335
- if (isMountedRef.current) {
5336
- setResources(resourcesResponse.resources);
5337
- setResourceTemplates(Array.isArray(resourcesResponse.resourceTemplates) ? resourcesResponse.resourceTemplates : []);
5338
- addLog(
5339
- "info",
5340
- `Listed ${resourcesResponse.resources.length} resources, ${Array.isArray(resourcesResponse.resourceTemplates) ? resourcesResponse.resourceTemplates.length : 0} resource templates.`
5341
- );
5229
+ const listResources = (0, import_react.useCallback)(
5230
+ async () => {
5231
+ if (stateRef.current !== "ready" || !clientRef.current) {
5232
+ throw new Error(`MCP client is not ready (current state: ${state}). Cannot list resources.`);
5342
5233
  }
5343
- } catch (err) {
5344
- addLog("error", `Error listing resources: ${err instanceof Error ? err.message : String(err)}`, err);
5345
- throw err;
5346
- }
5347
- }, [state, addLog]);
5234
+ addLog("info", "Listing resources");
5235
+ try {
5236
+ const serverName = "inspector-server";
5237
+ const session = clientRef.current.getSession(serverName);
5238
+ if (!session) {
5239
+ throw new Error("No active session found");
5240
+ }
5241
+ const resourcesResult = await session.connector.listAllResources();
5242
+ setResources(resourcesResult.resources || []);
5243
+ addLog("info", "Resources listed successfully");
5244
+ } catch (err) {
5245
+ addLog("error", "List resources failed:", err);
5246
+ throw err;
5247
+ }
5248
+ },
5249
+ [state]
5250
+ );
5348
5251
  const readResource = (0, import_react.useCallback)(
5349
5252
  async (uri) => {
5350
5253
  if (stateRef.current !== "ready" || !clientRef.current) {
5351
- throw new Error(`MCP client is not ready (current state: ${state}). Cannot read resource "${uri}".`);
5254
+ throw new Error(`MCP client is not ready (current state: ${state}). Cannot read resource.`);
5352
5255
  }
5353
5256
  addLog("info", `Reading resource: ${uri}`);
5354
5257
  try {
5355
- const result = await clientRef.current.request({ method: "resources/read", params: { uri } }, import_types.ReadResourceResultSchema);
5356
- addLog("info", `Resource "${uri}" read successfully`);
5258
+ const serverName = "inspector-server";
5259
+ const session = clientRef.current.getSession(serverName);
5260
+ if (!session) {
5261
+ throw new Error("No active session found");
5262
+ }
5263
+ const result = await session.connector.readResource(uri);
5264
+ addLog("info", "Resource read successful:", result);
5357
5265
  return result;
5358
5266
  } catch (err) {
5359
- addLog("error", `Error reading resource "${uri}": ${err instanceof Error ? err.message : String(err)}`, err);
5267
+ addLog("error", "Resource read failed:", err);
5360
5268
  throw err;
5361
5269
  }
5362
5270
  },
5363
- [state, addLog]
5271
+ [state]
5364
5272
  );
5365
- const listPrompts = (0, import_react.useCallback)(async () => {
5366
- if (stateRef.current !== "ready" || !clientRef.current) {
5367
- throw new Error(`MCP client is not ready (current state: ${state}). Cannot list prompts.`);
5368
- }
5369
- addLog("info", "Listing prompts...");
5370
- try {
5371
- const promptsResponse = await clientRef.current.request({ method: "prompts/list" }, import_types.ListPromptsResultSchema);
5372
- if (isMountedRef.current) {
5373
- setPrompts(promptsResponse.prompts);
5374
- addLog("info", `Listed ${promptsResponse.prompts.length} prompts.`);
5273
+ const listPrompts = (0, import_react.useCallback)(
5274
+ async () => {
5275
+ if (stateRef.current !== "ready" || !clientRef.current) {
5276
+ throw new Error(`MCP client is not ready (current state: ${state}). Cannot list prompts.`);
5375
5277
  }
5376
- } catch (err) {
5377
- addLog("error", `Error listing prompts: ${err instanceof Error ? err.message : String(err)}`, err);
5378
- throw err;
5379
- }
5380
- }, [state, addLog]);
5278
+ addLog("info", "Listing prompts");
5279
+ try {
5280
+ const serverName = "inspector-server";
5281
+ const session = clientRef.current.getSession(serverName);
5282
+ if (!session) {
5283
+ throw new Error("No active session found");
5284
+ }
5285
+ const promptsResult = await session.connector.listPrompts();
5286
+ setPrompts(promptsResult.prompts || []);
5287
+ addLog("info", "Prompts listed successfully");
5288
+ } catch (err) {
5289
+ addLog("error", "List prompts failed:", err);
5290
+ throw err;
5291
+ }
5292
+ },
5293
+ [state]
5294
+ );
5381
5295
  const getPrompt = (0, import_react.useCallback)(
5382
5296
  async (name, args) => {
5383
5297
  if (stateRef.current !== "ready" || !clientRef.current) {
5384
- throw new Error(`MCP client is not ready (current state: ${state}). Cannot get prompt "${name}".`);
5298
+ throw new Error(`MCP client is not ready (current state: ${state}). Cannot get prompt.`);
5385
5299
  }
5386
5300
  addLog("info", `Getting prompt: ${name}`, args);
5387
5301
  try {
5388
- const result = await clientRef.current.request({ method: "prompts/get", params: { name, arguments: args } }, import_types.GetPromptResultSchema);
5389
- addLog("info", `Prompt "${name}" retrieved successfully`);
5302
+ const serverName = "inspector-server";
5303
+ const session = clientRef.current.getSession(serverName);
5304
+ if (!session) {
5305
+ throw new Error("No active session found");
5306
+ }
5307
+ const result = await session.connector.getPrompt(name, args || {});
5308
+ addLog("info", `Prompt "${name}" retrieved successfully:`, result);
5390
5309
  return result;
5391
5310
  } catch (err) {
5392
- addLog("error", `Error getting prompt "${name}": ${err instanceof Error ? err.message : String(err)}`, err);
5311
+ addLog("error", `Prompt "${name}" retrieval failed:`, err);
5393
5312
  throw err;
5394
5313
  }
5395
5314
  },
5396
- [state, addLog]
5315
+ [state]
5397
5316
  );
5398
5317
  const connectRef = (0, import_react.useRef)(connect);
5399
5318
  const failConnectionRef = (0, import_react.useRef)(failConnection);
@@ -5486,9 +5405,10 @@ function useMcp(options) {
5486
5405
  error,
5487
5406
  log,
5488
5407
  authUrl,
5408
+ client: clientRef.current,
5489
5409
  callTool,
5490
- listResources,
5491
5410
  readResource,
5411
+ listResources,
5492
5412
  listPrompts,
5493
5413
  getPrompt,
5494
5414
  retry,