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.
@@ -1,7 +1,9 @@
1
1
  "use strict";
2
+ var __create = Object.create;
2
3
  var __defProp = Object.defineProperty;
3
4
  var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
4
5
  var __getOwnPropNames = Object.getOwnPropertyNames;
6
+ var __getProtoOf = Object.getPrototypeOf;
5
7
  var __hasOwnProp = Object.prototype.hasOwnProperty;
6
8
  var __name = (target, value) => __defProp(target, "name", { value, configurable: true });
7
9
  var __export = (target, all) => {
@@ -16,6 +18,14 @@ var __copyProps = (to, from, except, desc) => {
16
18
  }
17
19
  return to;
18
20
  };
21
+ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
22
+ // If the importer is in node compatibility mode or this is not an ESM
23
+ // file that has been converted to a CommonJS file using a Babel-
24
+ // compatible transform (i.e. "__esModule" has not been set), then set
25
+ // "default" to the CommonJS "module.exports" for node compatibility.
26
+ isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
27
+ mod
28
+ ));
19
29
  var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
20
30
 
21
31
  // src/react/index.ts
@@ -31,13 +41,1268 @@ __export(react_exports, {
31
41
  module.exports = __toCommonJS(react_exports);
32
42
 
33
43
  // src/react/useMcp.ts
34
- var import_types = require("@modelcontextprotocol/sdk/types.js");
35
44
  var import_react = require("react");
36
- var import_auth = require("@modelcontextprotocol/sdk/client/auth.js");
45
+ var import_strict_url_sanitise2 = require("strict-url-sanitise");
46
+
47
+ // src/connectors/http.ts
37
48
  var import_client = require("@modelcontextprotocol/sdk/client/index.js");
49
+ var import_streamableHttp2 = require("@modelcontextprotocol/sdk/client/streamableHttp.js");
50
+
51
+ // src/logging.ts
52
+ var import_winston = require("winston");
53
+ async function getNodeModules() {
54
+ if (typeof process !== "undefined" && process.platform) {
55
+ try {
56
+ const fs = await import("fs");
57
+ const path = await import("path");
58
+ return { fs: fs.default, path: path.default };
59
+ } catch {
60
+ return { fs: null, path: null };
61
+ }
62
+ }
63
+ return { fs: null, path: null };
64
+ }
65
+ __name(getNodeModules, "getNodeModules");
66
+ var { combine, timestamp, label, printf, colorize, splat } = import_winston.format;
67
+ var DEFAULT_LOGGER_NAME = "mcp-use";
68
+ function isNodeJSEnvironment() {
69
+ try {
70
+ if (typeof navigator !== "undefined" && navigator.userAgent?.includes("Cloudflare-Workers")) {
71
+ return false;
72
+ }
73
+ if (typeof globalThis.EdgeRuntime !== "undefined" || typeof globalThis.Deno !== "undefined") {
74
+ return false;
75
+ }
76
+ const hasNodeGlobals = typeof process !== "undefined" && typeof process.platform !== "undefined" && typeof __dirname !== "undefined";
77
+ const hasNodeModules = typeof import_winston.createLogger === "function";
78
+ return hasNodeGlobals && hasNodeModules;
79
+ } catch {
80
+ return false;
81
+ }
82
+ }
83
+ __name(isNodeJSEnvironment, "isNodeJSEnvironment");
84
+ var SimpleConsoleLogger = class {
85
+ static {
86
+ __name(this, "SimpleConsoleLogger");
87
+ }
88
+ _level;
89
+ name;
90
+ constructor(name = DEFAULT_LOGGER_NAME, level = "info") {
91
+ this.name = name;
92
+ this._level = level;
93
+ }
94
+ shouldLog(level) {
95
+ const levels = ["error", "warn", "info", "http", "verbose", "debug", "silly"];
96
+ const currentIndex = levels.indexOf(this._level);
97
+ const messageIndex = levels.indexOf(level);
98
+ return messageIndex <= currentIndex;
99
+ }
100
+ formatMessage(level, message) {
101
+ const timestamp2 = (/* @__PURE__ */ new Date()).toLocaleTimeString("en-US", { hour12: false });
102
+ return `${timestamp2} [${this.name}] ${level}: ${message}`;
103
+ }
104
+ error(message) {
105
+ if (this.shouldLog("error")) {
106
+ console.error(this.formatMessage("error", message));
107
+ }
108
+ }
109
+ warn(message) {
110
+ if (this.shouldLog("warn")) {
111
+ console.warn(this.formatMessage("warn", message));
112
+ }
113
+ }
114
+ info(message) {
115
+ if (this.shouldLog("info")) {
116
+ console.info(this.formatMessage("info", message));
117
+ }
118
+ }
119
+ debug(message) {
120
+ if (this.shouldLog("debug")) {
121
+ console.debug(this.formatMessage("debug", message));
122
+ }
123
+ }
124
+ http(message) {
125
+ if (this.shouldLog("http")) {
126
+ console.log(this.formatMessage("http", message));
127
+ }
128
+ }
129
+ verbose(message) {
130
+ if (this.shouldLog("verbose")) {
131
+ console.log(this.formatMessage("verbose", message));
132
+ }
133
+ }
134
+ silly(message) {
135
+ if (this.shouldLog("silly")) {
136
+ console.log(this.formatMessage("silly", message));
137
+ }
138
+ }
139
+ // Make it compatible with Winston interface
140
+ get level() {
141
+ return this._level;
142
+ }
143
+ set level(newLevel) {
144
+ this._level = newLevel;
145
+ }
146
+ };
147
+ function resolveLevel(env) {
148
+ const envValue = typeof process !== "undefined" && process.env ? env : void 0;
149
+ switch (envValue?.trim()) {
150
+ case "2":
151
+ return "debug";
152
+ case "1":
153
+ return "info";
154
+ default:
155
+ return "info";
156
+ }
157
+ }
158
+ __name(resolveLevel, "resolveLevel");
159
+ var minimalFormatter = printf(({ level, message, label: label2, timestamp: timestamp2 }) => {
160
+ return `${timestamp2} [${label2}] ${level}: ${message}`;
161
+ });
162
+ var detailedFormatter = printf(({ level, message, label: label2, timestamp: timestamp2 }) => {
163
+ return `${timestamp2} [${label2}] ${level.toUpperCase()}: ${message}`;
164
+ });
165
+ var emojiFormatter = printf(({ level, message, label: label2, timestamp: timestamp2 }) => {
166
+ return `${timestamp2} [${label2}] ${level.toUpperCase()}: ${message}`;
167
+ });
168
+ var Logger = class {
169
+ static {
170
+ __name(this, "Logger");
171
+ }
172
+ static instances = {};
173
+ static simpleInstances = {};
174
+ static currentFormat = "minimal";
175
+ static get(name = DEFAULT_LOGGER_NAME) {
176
+ if (!isNodeJSEnvironment()) {
177
+ if (!this.simpleInstances[name]) {
178
+ const debugEnv = typeof process !== "undefined" && process.env?.DEBUG || void 0;
179
+ this.simpleInstances[name] = new SimpleConsoleLogger(name, resolveLevel(debugEnv));
180
+ }
181
+ return this.simpleInstances[name];
182
+ }
183
+ if (!this.instances[name]) {
184
+ this.instances[name] = (0, import_winston.createLogger)({
185
+ level: resolveLevel(process.env.DEBUG),
186
+ format: combine(
187
+ colorize(),
188
+ splat(),
189
+ label({ label: name }),
190
+ timestamp({ format: "HH:mm:ss" }),
191
+ this.getFormatter()
192
+ ),
193
+ transports: []
194
+ });
195
+ }
196
+ return this.instances[name];
197
+ }
198
+ static getFormatter() {
199
+ switch (this.currentFormat) {
200
+ case "minimal":
201
+ return minimalFormatter;
202
+ case "detailed":
203
+ return detailedFormatter;
204
+ case "emoji":
205
+ return emojiFormatter;
206
+ default:
207
+ return minimalFormatter;
208
+ }
209
+ }
210
+ static async configure(options = {}) {
211
+ const { level, console: console2 = true, file, format: format2 = "minimal" } = options;
212
+ const debugEnv = typeof process !== "undefined" && process.env?.DEBUG || void 0;
213
+ const resolvedLevel = level ?? resolveLevel(debugEnv);
214
+ this.currentFormat = format2;
215
+ const root = this.get();
216
+ root.level = resolvedLevel;
217
+ const winstonRoot = root;
218
+ if (!isNodeJSEnvironment()) {
219
+ Object.values(this.simpleInstances).forEach((logger2) => {
220
+ logger2.level = resolvedLevel;
221
+ });
222
+ return;
223
+ }
224
+ winstonRoot.clear();
225
+ if (console2) {
226
+ winstonRoot.add(new import_winston.transports.Console());
227
+ }
228
+ if (file) {
229
+ const { fs: nodeFs, path: nodePath } = await getNodeModules();
230
+ if (nodeFs && nodePath) {
231
+ const dir = nodePath.dirname(nodePath.resolve(file));
232
+ if (!nodeFs.existsSync(dir)) {
233
+ nodeFs.mkdirSync(dir, { recursive: true });
234
+ }
235
+ winstonRoot.add(new import_winston.transports.File({ filename: file }));
236
+ }
237
+ }
238
+ Object.values(this.instances).forEach((logger2) => {
239
+ if (logger2 && "format" in logger2) {
240
+ logger2.level = resolvedLevel;
241
+ logger2.format = combine(
242
+ colorize(),
243
+ splat(),
244
+ label({ label: DEFAULT_LOGGER_NAME }),
245
+ timestamp({ format: "HH:mm:ss" }),
246
+ this.getFormatter()
247
+ );
248
+ }
249
+ });
250
+ }
251
+ static setDebug(enabled) {
252
+ let level;
253
+ if (enabled === 2 || enabled === true)
254
+ level = "debug";
255
+ else if (enabled === 1)
256
+ level = "info";
257
+ else level = "info";
258
+ Object.values(this.simpleInstances).forEach((logger2) => {
259
+ logger2.level = level;
260
+ });
261
+ Object.values(this.instances).forEach((logger2) => {
262
+ if (logger2) {
263
+ logger2.level = level;
264
+ }
265
+ });
266
+ if (typeof process !== "undefined" && process.env) {
267
+ process.env.DEBUG = enabled ? enabled === true ? "2" : String(enabled) : "0";
268
+ }
269
+ }
270
+ static setFormat(format2) {
271
+ this.currentFormat = format2;
272
+ this.configure({ format: format2 });
273
+ }
274
+ };
275
+ if (isNodeJSEnvironment()) {
276
+ Logger.configure();
277
+ } else {
278
+ Logger.configure({ console: true });
279
+ }
280
+ var logger = Logger.get();
281
+
282
+ // src/task_managers/sse.ts
38
283
  var import_sse = require("@modelcontextprotocol/sdk/client/sse.js");
284
+
285
+ // src/task_managers/base.ts
286
+ var ConnectionManager = class {
287
+ static {
288
+ __name(this, "ConnectionManager");
289
+ }
290
+ _readyPromise;
291
+ _readyResolver;
292
+ _donePromise;
293
+ _doneResolver;
294
+ _exception = null;
295
+ _connection = null;
296
+ _task = null;
297
+ _abortController = null;
298
+ constructor() {
299
+ this.reset();
300
+ }
301
+ /**
302
+ * Start the connection manager and establish a connection.
303
+ *
304
+ * @returns The established connection.
305
+ * @throws If the connection cannot be established.
306
+ */
307
+ async start() {
308
+ this.reset();
309
+ logger.debug(`Starting ${this.constructor.name}`);
310
+ this._task = this.connectionTask();
311
+ await this._readyPromise;
312
+ if (this._exception) {
313
+ throw this._exception;
314
+ }
315
+ if (this._connection === null) {
316
+ throw new Error("Connection was not established");
317
+ }
318
+ return this._connection;
319
+ }
320
+ /**
321
+ * Stop the connection manager and close the connection.
322
+ */
323
+ async stop() {
324
+ if (this._task && this._abortController) {
325
+ logger.debug(`Cancelling ${this.constructor.name} task`);
326
+ this._abortController.abort();
327
+ try {
328
+ await this._task;
329
+ } catch (e) {
330
+ if (e instanceof Error && e.name === "AbortError") {
331
+ logger.debug(`${this.constructor.name} task aborted successfully`);
332
+ } else {
333
+ logger.warn(`Error stopping ${this.constructor.name} task: ${e}`);
334
+ }
335
+ }
336
+ }
337
+ await this._donePromise;
338
+ logger.debug(`${this.constructor.name} task completed`);
339
+ }
340
+ /**
341
+ * Reset all internal state.
342
+ */
343
+ reset() {
344
+ this._readyPromise = new Promise((res) => this._readyResolver = res);
345
+ this._donePromise = new Promise((res) => this._doneResolver = res);
346
+ this._exception = null;
347
+ this._connection = null;
348
+ this._task = null;
349
+ this._abortController = new AbortController();
350
+ }
351
+ /**
352
+ * The background task responsible for establishing and maintaining the
353
+ * connection until it is cancelled.
354
+ */
355
+ async connectionTask() {
356
+ logger.debug(`Running ${this.constructor.name} task`);
357
+ try {
358
+ this._connection = await this.establishConnection();
359
+ logger.debug(`${this.constructor.name} connected successfully`);
360
+ this._readyResolver();
361
+ await this.waitForAbort();
362
+ } catch (err) {
363
+ this._exception = err;
364
+ logger.error(`Error in ${this.constructor.name} task: ${err}`);
365
+ this._readyResolver();
366
+ } finally {
367
+ if (this._connection !== null) {
368
+ try {
369
+ await this.closeConnection(this._connection);
370
+ } catch (closeErr) {
371
+ logger.warn(`Error closing connection in ${this.constructor.name}: ${closeErr}`);
372
+ }
373
+ this._connection = null;
374
+ }
375
+ this._doneResolver();
376
+ }
377
+ }
378
+ /**
379
+ * Helper that returns a promise which resolves when the abort signal fires.
380
+ */
381
+ async waitForAbort() {
382
+ return new Promise((_resolve, _reject) => {
383
+ if (!this._abortController) {
384
+ return;
385
+ }
386
+ const signal = this._abortController.signal;
387
+ if (signal.aborted) {
388
+ _resolve();
389
+ return;
390
+ }
391
+ const onAbort = /* @__PURE__ */ __name(() => {
392
+ signal.removeEventListener("abort", onAbort);
393
+ _resolve();
394
+ }, "onAbort");
395
+ signal.addEventListener("abort", onAbort);
396
+ });
397
+ }
398
+ };
399
+
400
+ // src/task_managers/sse.ts
401
+ var SseConnectionManager = class extends ConnectionManager {
402
+ static {
403
+ __name(this, "SseConnectionManager");
404
+ }
405
+ url;
406
+ opts;
407
+ _transport = null;
408
+ /**
409
+ * Create an SSE connection manager.
410
+ *
411
+ * @param url The SSE endpoint URL.
412
+ * @param opts Optional transport options (auth, headers, etc.).
413
+ */
414
+ constructor(url, opts) {
415
+ super();
416
+ this.url = typeof url === "string" ? new URL(url) : url;
417
+ this.opts = opts;
418
+ }
419
+ /**
420
+ * Spawn a new `SSEClientTransport` and start the connection.
421
+ */
422
+ async establishConnection() {
423
+ this._transport = new import_sse.SSEClientTransport(this.url, this.opts);
424
+ logger.debug(`${this.constructor.name} connected successfully`);
425
+ return this._transport;
426
+ }
427
+ /**
428
+ * Close the underlying transport and clean up resources.
429
+ */
430
+ async closeConnection(_connection) {
431
+ if (this._transport) {
432
+ try {
433
+ await this._transport.close();
434
+ } catch (e) {
435
+ logger.warn(`Error closing SSE transport: ${e}`);
436
+ } finally {
437
+ this._transport = null;
438
+ }
439
+ }
440
+ }
441
+ };
442
+
443
+ // src/task_managers/streamable_http.ts
39
444
  var import_streamableHttp = require("@modelcontextprotocol/sdk/client/streamableHttp.js");
40
- var import_strict_url_sanitise2 = require("strict-url-sanitise");
445
+ var StreamableHttpConnectionManager = class extends ConnectionManager {
446
+ static {
447
+ __name(this, "StreamableHttpConnectionManager");
448
+ }
449
+ url;
450
+ opts;
451
+ _transport = null;
452
+ /**
453
+ * Create a Streamable HTTP connection manager.
454
+ *
455
+ * @param url The HTTP endpoint URL.
456
+ * @param opts Optional transport options (auth, headers, etc.).
457
+ */
458
+ constructor(url, opts) {
459
+ super();
460
+ this.url = typeof url === "string" ? new URL(url) : url;
461
+ this.opts = opts;
462
+ }
463
+ /**
464
+ * Spawn a new `StreamableHTTPClientTransport` and return it.
465
+ * The Client.connect() method will handle starting the transport.
466
+ */
467
+ async establishConnection() {
468
+ this._transport = new import_streamableHttp.StreamableHTTPClientTransport(this.url, this.opts);
469
+ logger.debug(`${this.constructor.name} created successfully`);
470
+ return this._transport;
471
+ }
472
+ /**
473
+ * Close the underlying transport and clean up resources.
474
+ */
475
+ async closeConnection(_connection) {
476
+ if (this._transport) {
477
+ try {
478
+ await this._transport.close();
479
+ } catch (e) {
480
+ logger.warn(`Error closing Streamable HTTP transport: ${e}`);
481
+ } finally {
482
+ this._transport = null;
483
+ }
484
+ }
485
+ }
486
+ /**
487
+ * Get the session ID from the transport if available.
488
+ */
489
+ get sessionId() {
490
+ return this._transport?.sessionId;
491
+ }
492
+ };
493
+
494
+ // src/connectors/base.ts
495
+ var BaseConnector = class {
496
+ static {
497
+ __name(this, "BaseConnector");
498
+ }
499
+ client = null;
500
+ connectionManager = null;
501
+ toolsCache = null;
502
+ capabilitiesCache = null;
503
+ connected = false;
504
+ opts;
505
+ constructor(opts = {}) {
506
+ this.opts = opts;
507
+ }
508
+ /** Disconnect and release resources. */
509
+ async disconnect() {
510
+ if (!this.connected) {
511
+ logger.debug("Not connected to MCP implementation");
512
+ return;
513
+ }
514
+ logger.debug("Disconnecting from MCP implementation");
515
+ await this.cleanupResources();
516
+ this.connected = false;
517
+ logger.debug("Disconnected from MCP implementation");
518
+ }
519
+ /** Check if the client is connected */
520
+ get isClientConnected() {
521
+ return this.client != null;
522
+ }
523
+ /**
524
+ * Initialise the MCP session **after** `connect()` has succeeded.
525
+ *
526
+ * In the SDK, `Client.connect(transport)` automatically performs the
527
+ * protocol‑level `initialize` handshake, so we only need to cache the list of
528
+ * tools and expose some server info.
529
+ */
530
+ async initialize(defaultRequestOptions = this.opts.defaultRequestOptions ?? {}) {
531
+ if (!this.client) {
532
+ throw new Error("MCP client is not connected");
533
+ }
534
+ logger.debug("Caching server capabilities & tools");
535
+ const capabilities = this.client.getServerCapabilities();
536
+ this.capabilitiesCache = capabilities;
537
+ const listToolsRes = await this.client.listTools(void 0, defaultRequestOptions);
538
+ this.toolsCache = listToolsRes.tools ?? [];
539
+ logger.debug(`Fetched ${this.toolsCache.length} tools from server`);
540
+ logger.debug("Server capabilities:", capabilities);
541
+ return capabilities;
542
+ }
543
+ /** Lazily expose the cached tools list. */
544
+ get tools() {
545
+ if (!this.toolsCache) {
546
+ throw new Error("MCP client is not initialized; call initialize() first");
547
+ }
548
+ return this.toolsCache;
549
+ }
550
+ /** Call a tool on the server. */
551
+ async callTool(name, args, options) {
552
+ if (!this.client) {
553
+ throw new Error("MCP client is not connected");
554
+ }
555
+ logger.debug(`Calling tool '${name}' with args`, args);
556
+ const res = await this.client.callTool({ name, arguments: args }, void 0, options);
557
+ logger.debug(`Tool '${name}' returned`, res);
558
+ return res;
559
+ }
560
+ /**
561
+ * List resources from the server with optional pagination
562
+ *
563
+ * @param cursor - Optional cursor for pagination
564
+ * @param options - Request options
565
+ * @returns Resource list with optional nextCursor for pagination
566
+ */
567
+ async listResources(cursor, options) {
568
+ if (!this.client) {
569
+ throw new Error("MCP client is not connected");
570
+ }
571
+ logger.debug("Listing resources", cursor ? `with cursor: ${cursor}` : "");
572
+ return await this.client.listResources({ cursor }, options);
573
+ }
574
+ /**
575
+ * List all resources from the server, automatically handling pagination
576
+ *
577
+ * @param options - Request options
578
+ * @returns Complete list of all resources
579
+ */
580
+ async listAllResources(options) {
581
+ if (!this.client) {
582
+ throw new Error("MCP client is not connected");
583
+ }
584
+ if (!this.capabilitiesCache?.resources) {
585
+ logger.debug("Server does not advertise resources capability, skipping");
586
+ return { resources: [] };
587
+ }
588
+ try {
589
+ logger.debug("Listing all resources (with auto-pagination)");
590
+ const allResources = [];
591
+ let cursor = void 0;
592
+ do {
593
+ const result = await this.client.listResources({ cursor }, options);
594
+ allResources.push(...result.resources || []);
595
+ cursor = result.nextCursor;
596
+ } while (cursor);
597
+ return { resources: allResources };
598
+ } catch (err) {
599
+ if (err.code === -32601) {
600
+ logger.debug("Server advertised resources but method not found");
601
+ return { resources: [] };
602
+ }
603
+ throw err;
604
+ }
605
+ }
606
+ /**
607
+ * List resource templates from the server
608
+ *
609
+ * @param options - Request options
610
+ * @returns List of available resource templates
611
+ */
612
+ async listResourceTemplates(options) {
613
+ if (!this.client) {
614
+ throw new Error("MCP client is not connected");
615
+ }
616
+ logger.debug("Listing resource templates");
617
+ return await this.client.listResourceTemplates(void 0, options);
618
+ }
619
+ /** Read a resource by URI. */
620
+ async readResource(uri, options) {
621
+ if (!this.client) {
622
+ throw new Error("MCP client is not connected");
623
+ }
624
+ logger.debug(`Reading resource ${uri}`);
625
+ const res = await this.client.readResource({ uri }, options);
626
+ return res;
627
+ }
628
+ /**
629
+ * Subscribe to resource updates
630
+ *
631
+ * @param uri - URI of the resource to subscribe to
632
+ * @param options - Request options
633
+ */
634
+ async subscribeToResource(uri, options) {
635
+ if (!this.client) {
636
+ throw new Error("MCP client is not connected");
637
+ }
638
+ logger.debug(`Subscribing to resource: ${uri}`);
639
+ return await this.client.subscribeResource({ uri }, options);
640
+ }
641
+ /**
642
+ * Unsubscribe from resource updates
643
+ *
644
+ * @param uri - URI of the resource to unsubscribe from
645
+ * @param options - Request options
646
+ */
647
+ async unsubscribeFromResource(uri, options) {
648
+ if (!this.client) {
649
+ throw new Error("MCP client is not connected");
650
+ }
651
+ logger.debug(`Unsubscribing from resource: ${uri}`);
652
+ return await this.client.unsubscribeResource({ uri }, options);
653
+ }
654
+ async listPrompts() {
655
+ if (!this.client) {
656
+ throw new Error("MCP client is not connected");
657
+ }
658
+ if (!this.capabilitiesCache?.prompts) {
659
+ logger.debug("Server does not advertise prompts capability, skipping");
660
+ return { prompts: [] };
661
+ }
662
+ try {
663
+ logger.debug("Listing prompts");
664
+ return await this.client.listPrompts();
665
+ } catch (err) {
666
+ if (err.code === -32601) {
667
+ logger.debug("Server advertised prompts but method not found");
668
+ return { prompts: [] };
669
+ }
670
+ throw err;
671
+ }
672
+ }
673
+ async getPrompt(name, args) {
674
+ if (!this.client) {
675
+ throw new Error("MCP client is not connected");
676
+ }
677
+ logger.debug(`Getting prompt ${name}`);
678
+ return await this.client.getPrompt({ name, arguments: args });
679
+ }
680
+ /** Send a raw request through the client. */
681
+ async request(method, params = null, options) {
682
+ if (!this.client) {
683
+ throw new Error("MCP client is not connected");
684
+ }
685
+ logger.debug(`Sending raw request '${method}' with params`, params);
686
+ return await this.client.request({ method, params: params ?? {} }, void 0, options);
687
+ }
688
+ /**
689
+ * Helper to tear down the client & connection manager safely.
690
+ */
691
+ async cleanupResources() {
692
+ const issues = [];
693
+ if (this.client) {
694
+ try {
695
+ if (typeof this.client.close === "function") {
696
+ await this.client.close();
697
+ }
698
+ } catch (e) {
699
+ const msg = `Error closing client: ${e}`;
700
+ logger.warn(msg);
701
+ issues.push(msg);
702
+ } finally {
703
+ this.client = null;
704
+ }
705
+ }
706
+ if (this.connectionManager) {
707
+ try {
708
+ await this.connectionManager.stop();
709
+ } catch (e) {
710
+ const msg = `Error stopping connection manager: ${e}`;
711
+ logger.warn(msg);
712
+ issues.push(msg);
713
+ } finally {
714
+ this.connectionManager = null;
715
+ }
716
+ }
717
+ this.toolsCache = null;
718
+ if (issues.length) {
719
+ logger.warn(`Resource cleanup finished with ${issues.length} issue(s)`);
720
+ }
721
+ }
722
+ };
723
+
724
+ // src/connectors/http.ts
725
+ var HttpConnector = class extends BaseConnector {
726
+ static {
727
+ __name(this, "HttpConnector");
728
+ }
729
+ baseUrl;
730
+ headers;
731
+ timeout;
732
+ sseReadTimeout;
733
+ clientInfo;
734
+ preferSse;
735
+ transportType = null;
736
+ constructor(baseUrl, opts = {}) {
737
+ super(opts);
738
+ this.baseUrl = baseUrl.replace(/\/$/, "");
739
+ this.headers = { ...opts.headers ?? {} };
740
+ if (opts.authToken) {
741
+ this.headers.Authorization = `Bearer ${opts.authToken}`;
742
+ }
743
+ this.timeout = opts.timeout ?? 3e4;
744
+ this.sseReadTimeout = opts.sseReadTimeout ?? 3e5;
745
+ this.clientInfo = opts.clientInfo ?? { name: "http-connector", version: "1.0.0" };
746
+ this.preferSse = opts.preferSse ?? false;
747
+ }
748
+ /** Establish connection to the MCP implementation via HTTP (streamable or SSE). */
749
+ async connect() {
750
+ if (this.connected) {
751
+ logger.debug("Already connected to MCP implementation");
752
+ return;
753
+ }
754
+ const baseUrl = this.baseUrl;
755
+ if (this.preferSse) {
756
+ logger.debug(`Connecting to MCP implementation via HTTP/SSE: ${baseUrl}`);
757
+ await this.connectWithSse(baseUrl);
758
+ return;
759
+ }
760
+ logger.debug(`Connecting to MCP implementation via HTTP: ${baseUrl}`);
761
+ try {
762
+ logger.info("\u{1F504} Attempting streamable HTTP transport...");
763
+ await this.connectWithStreamableHttp(baseUrl);
764
+ logger.info("\u2705 Successfully connected via streamable HTTP");
765
+ } catch (err) {
766
+ let fallbackReason = "Unknown error";
767
+ let is401Error = false;
768
+ if (err instanceof import_streamableHttp2.StreamableHTTPError) {
769
+ is401Error = err.code === 401;
770
+ if (err.code === 400 && err.message.includes("Missing session ID")) {
771
+ fallbackReason = "Server requires session ID (FastMCP compatibility) - using SSE transport";
772
+ logger.warn(`\u26A0\uFE0F ${fallbackReason}`);
773
+ } else if (err.code === 404 || err.code === 405) {
774
+ fallbackReason = `Server returned ${err.code} - server likely doesn't support streamable HTTP`;
775
+ logger.debug(fallbackReason);
776
+ } else {
777
+ fallbackReason = `Server returned ${err.code}: ${err.message}`;
778
+ logger.debug(fallbackReason);
779
+ }
780
+ } else if (err instanceof Error) {
781
+ const errorStr = err.toString();
782
+ const errorMsg = err.message || "";
783
+ is401Error = errorStr.includes("401") || errorMsg.includes("Unauthorized");
784
+ if (errorStr.includes("Missing session ID") || errorStr.includes("Bad Request: Missing session ID") || errorMsg.includes("FastMCP session ID error")) {
785
+ fallbackReason = "Server requires session ID (FastMCP compatibility) - using SSE transport";
786
+ logger.warn(`\u26A0\uFE0F ${fallbackReason}`);
787
+ } else if (errorStr.includes("405 Method Not Allowed") || errorStr.includes("404 Not Found")) {
788
+ fallbackReason = "Server doesn't support streamable HTTP (405/404)";
789
+ logger.debug(fallbackReason);
790
+ } else {
791
+ fallbackReason = `Streamable HTTP failed: ${err.message}`;
792
+ logger.debug(fallbackReason);
793
+ }
794
+ }
795
+ if (is401Error) {
796
+ logger.info("Authentication required - skipping SSE fallback");
797
+ await this.cleanupResources();
798
+ const authError = new Error("Authentication required");
799
+ authError.code = 401;
800
+ throw authError;
801
+ }
802
+ logger.info("\u{1F504} Falling back to SSE transport...");
803
+ try {
804
+ await this.connectWithSse(baseUrl);
805
+ } catch (sseErr) {
806
+ logger.error(`Failed to connect with both transports:`);
807
+ logger.error(` Streamable HTTP: ${fallbackReason}`);
808
+ logger.error(` SSE: ${sseErr}`);
809
+ await this.cleanupResources();
810
+ const sseIs401 = sseErr?.message?.includes("401") || sseErr?.message?.includes("Unauthorized");
811
+ if (sseIs401) {
812
+ const authError = new Error("Authentication required");
813
+ authError.code = 401;
814
+ throw authError;
815
+ }
816
+ throw new Error("Could not connect to server with any available transport");
817
+ }
818
+ }
819
+ }
820
+ async connectWithStreamableHttp(baseUrl) {
821
+ try {
822
+ this.connectionManager = new StreamableHttpConnectionManager(
823
+ baseUrl,
824
+ {
825
+ authProvider: this.opts.authProvider,
826
+ // ← Pass OAuth provider to SDK
827
+ requestInit: {
828
+ headers: this.headers
829
+ },
830
+ // Pass through timeout and other options
831
+ reconnectionOptions: {
832
+ maxReconnectionDelay: 3e4,
833
+ initialReconnectionDelay: 1e3,
834
+ reconnectionDelayGrowFactor: 1.5,
835
+ maxRetries: 2
836
+ }
837
+ }
838
+ );
839
+ const transport = await this.connectionManager.start();
840
+ this.client = new import_client.Client(this.clientInfo, this.opts.clientOptions);
841
+ try {
842
+ await this.client.connect(transport);
843
+ } catch (connectErr) {
844
+ if (connectErr instanceof Error) {
845
+ const errMsg = connectErr.message || connectErr.toString();
846
+ if (errMsg.includes("Missing session ID") || errMsg.includes("Bad Request: Missing session ID")) {
847
+ const wrappedError = new Error(`FastMCP session ID error: ${errMsg}`);
848
+ wrappedError.cause = connectErr;
849
+ throw wrappedError;
850
+ }
851
+ }
852
+ throw connectErr;
853
+ }
854
+ this.connected = true;
855
+ this.transportType = "streamable-http";
856
+ logger.debug(`Successfully connected to MCP implementation via streamable HTTP: ${baseUrl}`);
857
+ } catch (err) {
858
+ await this.cleanupResources();
859
+ throw err;
860
+ }
861
+ }
862
+ async connectWithSse(baseUrl) {
863
+ try {
864
+ this.connectionManager = new SseConnectionManager(
865
+ baseUrl,
866
+ {
867
+ requestInit: {
868
+ headers: this.headers
869
+ }
870
+ }
871
+ );
872
+ const transport = await this.connectionManager.start();
873
+ this.client = new import_client.Client(this.clientInfo, this.opts.clientOptions);
874
+ await this.client.connect(transport);
875
+ this.connected = true;
876
+ this.transportType = "sse";
877
+ logger.debug(`Successfully connected to MCP implementation via HTTP/SSE: ${baseUrl}`);
878
+ } catch (err) {
879
+ await this.cleanupResources();
880
+ throw err;
881
+ }
882
+ }
883
+ get publicIdentifier() {
884
+ return {
885
+ type: "http",
886
+ url: this.baseUrl,
887
+ transport: this.transportType || "unknown"
888
+ };
889
+ }
890
+ /**
891
+ * Get the transport type being used (streamable-http or sse)
892
+ */
893
+ getTransportType() {
894
+ return this.transportType;
895
+ }
896
+ };
897
+
898
+ // src/connectors/websocket.ts
899
+ var import_uuid = require("uuid");
900
+
901
+ // src/task_managers/websocket.ts
902
+ var import_ws = __toESM(require("ws"), 1);
903
+ var WebSocketConnectionManager = class extends ConnectionManager {
904
+ static {
905
+ __name(this, "WebSocketConnectionManager");
906
+ }
907
+ url;
908
+ headers;
909
+ _ws = null;
910
+ /**
911
+ * @param url The WebSocket URL to connect to.
912
+ * @param headers Optional headers to include in the connection handshake.
913
+ */
914
+ constructor(url, headers = {}) {
915
+ super();
916
+ this.url = url;
917
+ this.headers = headers;
918
+ }
919
+ /** Establish a WebSocket connection and wait until it is open. */
920
+ async establishConnection() {
921
+ logger.debug(`Connecting to WebSocket: ${this.url}`);
922
+ return new Promise((resolve, reject) => {
923
+ const ws = new import_ws.default(this.url, { headers: this.headers });
924
+ this._ws = ws;
925
+ const onOpen = /* @__PURE__ */ __name(() => {
926
+ cleanup();
927
+ logger.debug("WebSocket connected successfully");
928
+ resolve(ws);
929
+ }, "onOpen");
930
+ const onError = /* @__PURE__ */ __name((err) => {
931
+ cleanup();
932
+ logger.error(`Failed to connect to WebSocket: ${err}`);
933
+ reject(err);
934
+ }, "onError");
935
+ const cleanup = /* @__PURE__ */ __name(() => {
936
+ ws.off("open", onOpen);
937
+ ws.off("error", onError);
938
+ }, "cleanup");
939
+ ws.on("open", onOpen);
940
+ ws.on("error", onError);
941
+ });
942
+ }
943
+ /** Cleanly close the WebSocket connection. */
944
+ async closeConnection(connection) {
945
+ logger.debug("Closing WebSocket connection");
946
+ return new Promise((resolve) => {
947
+ const onClose = /* @__PURE__ */ __name(() => {
948
+ connection.off("close", onClose);
949
+ this._ws = null;
950
+ resolve();
951
+ }, "onClose");
952
+ if (connection.readyState === import_ws.default.CLOSED) {
953
+ onClose();
954
+ return;
955
+ }
956
+ connection.on("close", onClose);
957
+ try {
958
+ connection.close();
959
+ } catch (e) {
960
+ logger.warn(`Error closing WebSocket connection: ${e}`);
961
+ onClose();
962
+ }
963
+ });
964
+ }
965
+ };
966
+
967
+ // src/connectors/websocket.ts
968
+ var WebSocketConnector = class extends BaseConnector {
969
+ static {
970
+ __name(this, "WebSocketConnector");
971
+ }
972
+ url;
973
+ headers;
974
+ connectionManager = null;
975
+ ws = null;
976
+ receiverTask = null;
977
+ pending = /* @__PURE__ */ new Map();
978
+ toolsCache = null;
979
+ constructor(url, opts = {}) {
980
+ super();
981
+ this.url = url;
982
+ this.headers = { ...opts.headers ?? {} };
983
+ if (opts.authToken)
984
+ this.headers.Authorization = `Bearer ${opts.authToken}`;
985
+ }
986
+ async connect() {
987
+ if (this.connected) {
988
+ logger.debug("Already connected to MCP implementation");
989
+ return;
990
+ }
991
+ logger.debug(`Connecting via WebSocket: ${this.url}`);
992
+ try {
993
+ this.connectionManager = new WebSocketConnectionManager(this.url, this.headers);
994
+ this.ws = await this.connectionManager.start();
995
+ this.receiverTask = this.receiveLoop();
996
+ this.connected = true;
997
+ logger.debug("WebSocket connected successfully");
998
+ } catch (e) {
999
+ logger.error(`Failed to connect: ${e}`);
1000
+ await this.cleanupResources();
1001
+ throw e;
1002
+ }
1003
+ }
1004
+ async disconnect() {
1005
+ if (!this.connected) {
1006
+ logger.debug("Not connected to MCP implementation");
1007
+ return;
1008
+ }
1009
+ logger.debug("Disconnecting \u2026");
1010
+ await this.cleanupResources();
1011
+ this.connected = false;
1012
+ }
1013
+ sendRequest(method, params = null) {
1014
+ if (!this.ws)
1015
+ throw new Error("WebSocket is not connected");
1016
+ const id = (0, import_uuid.v4)();
1017
+ const payload = JSON.stringify({ id, method, params: params ?? {} });
1018
+ return new Promise((resolve, reject) => {
1019
+ this.pending.set(id, { resolve, reject });
1020
+ this.ws.send(payload, (err) => {
1021
+ if (err) {
1022
+ this.pending.delete(id);
1023
+ reject(err);
1024
+ }
1025
+ });
1026
+ });
1027
+ }
1028
+ async receiveLoop() {
1029
+ if (!this.ws)
1030
+ return;
1031
+ const socket = this.ws;
1032
+ const onMessage = /* @__PURE__ */ __name((msg) => {
1033
+ let data;
1034
+ try {
1035
+ data = JSON.parse(msg.data ?? msg);
1036
+ } catch (e) {
1037
+ logger.warn("Received non\u2011JSON frame", e);
1038
+ return;
1039
+ }
1040
+ const id = data.id;
1041
+ if (id && this.pending.has(id)) {
1042
+ const { resolve, reject } = this.pending.get(id);
1043
+ this.pending.delete(id);
1044
+ if ("result" in data)
1045
+ resolve(data.result);
1046
+ else if ("error" in data)
1047
+ reject(data.error);
1048
+ } else {
1049
+ logger.debug("Received unsolicited message", data);
1050
+ }
1051
+ }, "onMessage");
1052
+ if (socket.addEventListener) {
1053
+ socket.addEventListener("message", onMessage);
1054
+ } else {
1055
+ socket.on("message", onMessage);
1056
+ }
1057
+ return new Promise((resolve) => {
1058
+ const onClose = /* @__PURE__ */ __name(() => {
1059
+ if (socket.removeEventListener) {
1060
+ socket.removeEventListener("message", onMessage);
1061
+ } else {
1062
+ socket.off("message", onMessage);
1063
+ }
1064
+ this.rejectAll(new Error("WebSocket closed"));
1065
+ resolve();
1066
+ }, "onClose");
1067
+ if (socket.addEventListener) {
1068
+ socket.addEventListener("close", onClose);
1069
+ } else {
1070
+ socket.on("close", onClose);
1071
+ }
1072
+ });
1073
+ }
1074
+ rejectAll(err) {
1075
+ for (const { reject } of this.pending.values()) reject(err);
1076
+ this.pending.clear();
1077
+ }
1078
+ async initialize() {
1079
+ logger.debug("Initializing MCP session over WebSocket");
1080
+ const result = await this.sendRequest("initialize");
1081
+ const toolsList = await this.listTools();
1082
+ this.toolsCache = toolsList.map((t) => t);
1083
+ logger.debug(`Initialized with ${this.toolsCache.length} tools`);
1084
+ return result;
1085
+ }
1086
+ async listTools() {
1087
+ const res = await this.sendRequest("tools/list");
1088
+ return res.tools ?? [];
1089
+ }
1090
+ async callTool(name, args) {
1091
+ return await this.sendRequest("tools/call", { name, arguments: args });
1092
+ }
1093
+ async listResources() {
1094
+ const resources = await this.sendRequest("resources/list");
1095
+ return { resources: Array.isArray(resources) ? resources : [] };
1096
+ }
1097
+ async readResource(uri) {
1098
+ const res = await this.sendRequest("resources/read", { uri });
1099
+ return res;
1100
+ }
1101
+ async request(method, params = null) {
1102
+ return await this.sendRequest(method, params);
1103
+ }
1104
+ get tools() {
1105
+ if (!this.toolsCache)
1106
+ throw new Error("MCP client is not initialized");
1107
+ return this.toolsCache;
1108
+ }
1109
+ async cleanupResources() {
1110
+ if (this.receiverTask)
1111
+ await this.receiverTask.catch(() => {
1112
+ });
1113
+ this.receiverTask = null;
1114
+ this.rejectAll(new Error("WebSocket disconnected"));
1115
+ if (this.connectionManager) {
1116
+ await this.connectionManager.stop();
1117
+ this.connectionManager = null;
1118
+ this.ws = null;
1119
+ }
1120
+ this.toolsCache = null;
1121
+ }
1122
+ get publicIdentifier() {
1123
+ return {
1124
+ type: "websocket",
1125
+ url: this.url
1126
+ };
1127
+ }
1128
+ };
1129
+
1130
+ // src/session.ts
1131
+ var MCPSession = class {
1132
+ static {
1133
+ __name(this, "MCPSession");
1134
+ }
1135
+ connector;
1136
+ autoConnect;
1137
+ constructor(connector, autoConnect = true) {
1138
+ this.connector = connector;
1139
+ this.autoConnect = autoConnect;
1140
+ }
1141
+ async connect() {
1142
+ await this.connector.connect();
1143
+ }
1144
+ async disconnect() {
1145
+ await this.connector.disconnect();
1146
+ }
1147
+ async initialize() {
1148
+ if (!this.isConnected && this.autoConnect) {
1149
+ await this.connect();
1150
+ }
1151
+ await this.connector.initialize();
1152
+ }
1153
+ get isConnected() {
1154
+ return this.connector && this.connector.isClientConnected;
1155
+ }
1156
+ };
1157
+
1158
+ // src/client/base.ts
1159
+ var BaseMCPClient = class {
1160
+ static {
1161
+ __name(this, "BaseMCPClient");
1162
+ }
1163
+ config = {};
1164
+ sessions = {};
1165
+ activeSessions = [];
1166
+ constructor(config) {
1167
+ if (config) {
1168
+ this.config = config;
1169
+ }
1170
+ }
1171
+ static fromDict(_cfg) {
1172
+ throw new Error("fromDict must be implemented by concrete class");
1173
+ }
1174
+ addServer(name, serverConfig) {
1175
+ this.config.mcpServers = this.config.mcpServers || {};
1176
+ this.config.mcpServers[name] = serverConfig;
1177
+ }
1178
+ removeServer(name) {
1179
+ if (this.config.mcpServers?.[name]) {
1180
+ delete this.config.mcpServers[name];
1181
+ this.activeSessions = this.activeSessions.filter((n) => n !== name);
1182
+ }
1183
+ }
1184
+ getServerNames() {
1185
+ return Object.keys(this.config.mcpServers ?? {});
1186
+ }
1187
+ getServerConfig(name) {
1188
+ return this.config.mcpServers?.[name];
1189
+ }
1190
+ getConfig() {
1191
+ return this.config ?? {};
1192
+ }
1193
+ async createSession(serverName, autoInitialize = true) {
1194
+ const servers = this.config.mcpServers ?? {};
1195
+ if (Object.keys(servers).length === 0) {
1196
+ logger.warn("No MCP servers defined in config");
1197
+ }
1198
+ if (!servers[serverName]) {
1199
+ throw new Error(`Server '${serverName}' not found in config`);
1200
+ }
1201
+ const connector = this.createConnectorFromConfig(servers[serverName]);
1202
+ const session = new MCPSession(connector);
1203
+ if (autoInitialize) {
1204
+ await session.initialize();
1205
+ }
1206
+ this.sessions[serverName] = session;
1207
+ if (!this.activeSessions.includes(serverName)) {
1208
+ this.activeSessions.push(serverName);
1209
+ }
1210
+ return session;
1211
+ }
1212
+ async createAllSessions(autoInitialize = true) {
1213
+ const servers = this.config.mcpServers ?? {};
1214
+ if (Object.keys(servers).length === 0) {
1215
+ logger.warn("No MCP servers defined in config");
1216
+ }
1217
+ for (const name of Object.keys(servers)) {
1218
+ await this.createSession(name, autoInitialize);
1219
+ }
1220
+ return this.sessions;
1221
+ }
1222
+ getSession(serverName) {
1223
+ const session = this.sessions[serverName];
1224
+ if (!session) {
1225
+ return null;
1226
+ }
1227
+ return session;
1228
+ }
1229
+ getAllActiveSessions() {
1230
+ return Object.fromEntries(
1231
+ this.activeSessions.map((n) => [n, this.sessions[n]])
1232
+ );
1233
+ }
1234
+ async closeSession(serverName) {
1235
+ const session = this.sessions[serverName];
1236
+ if (!session) {
1237
+ logger.warn(`No session exists for server ${serverName}, nothing to close`);
1238
+ return;
1239
+ }
1240
+ try {
1241
+ logger.debug(`Closing session for server ${serverName}`);
1242
+ await session.disconnect();
1243
+ } catch (e) {
1244
+ logger.error(`Error closing session for server '${serverName}': ${e}`);
1245
+ } finally {
1246
+ delete this.sessions[serverName];
1247
+ this.activeSessions = this.activeSessions.filter((n) => n !== serverName);
1248
+ }
1249
+ }
1250
+ async closeAllSessions() {
1251
+ const serverNames = Object.keys(this.sessions);
1252
+ const errors = [];
1253
+ for (const serverName of serverNames) {
1254
+ try {
1255
+ logger.debug(`Closing session for server ${serverName}`);
1256
+ await this.closeSession(serverName);
1257
+ } catch (e) {
1258
+ const errorMsg = `Failed to close session for server '${serverName}': ${e}`;
1259
+ logger.error(errorMsg);
1260
+ errors.push(errorMsg);
1261
+ }
1262
+ }
1263
+ if (errors.length) {
1264
+ logger.error(`Encountered ${errors.length} errors while closing sessions`);
1265
+ } else {
1266
+ logger.debug("All sessions closed successfully");
1267
+ }
1268
+ }
1269
+ };
1270
+
1271
+ // src/client/browser.ts
1272
+ var BrowserMCPClient = class _BrowserMCPClient extends BaseMCPClient {
1273
+ static {
1274
+ __name(this, "BrowserMCPClient");
1275
+ }
1276
+ constructor(config) {
1277
+ super(config);
1278
+ }
1279
+ static fromDict(cfg) {
1280
+ return new _BrowserMCPClient(cfg);
1281
+ }
1282
+ /**
1283
+ * Create a connector from server configuration (Browser version)
1284
+ * Supports HTTP and WebSocket connectors only
1285
+ */
1286
+ createConnectorFromConfig(serverConfig) {
1287
+ const { url, transport, headers, authToken, authProvider } = serverConfig;
1288
+ if (!url) {
1289
+ throw new Error("Server URL is required");
1290
+ }
1291
+ const connectorOptions = {
1292
+ headers,
1293
+ authToken,
1294
+ authProvider
1295
+ // ← Pass OAuth provider to connector
1296
+ };
1297
+ if (transport === "websocket" || url.startsWith("ws://") || url.startsWith("wss://")) {
1298
+ return new WebSocketConnector(url, connectorOptions);
1299
+ } else if (transport === "http" || url.startsWith("http://") || url.startsWith("https://")) {
1300
+ return new HttpConnector(url, connectorOptions);
1301
+ } else {
1302
+ return new HttpConnector(url, connectorOptions);
1303
+ }
1304
+ }
1305
+ };
41
1306
 
42
1307
  // src/auth/browser-provider.ts
43
1308
  var import_strict_url_sanitise = require("strict-url-sanitise");
@@ -281,7 +1546,6 @@ function useMcp(options) {
281
1546
  const [log, setLog] = (0, import_react.useState)([]);
282
1547
  const [authUrl, setAuthUrl] = (0, import_react.useState)(void 0);
283
1548
  const clientRef = (0, import_react.useRef)(null);
284
- const transportRef = (0, import_react.useRef)(null);
285
1549
  const authProviderRef = (0, import_react.useRef)(null);
286
1550
  const connectingRef = (0, import_react.useRef)(false);
287
1551
  const isMountedRef = (0, import_react.useRef)(true);
@@ -310,9 +1574,15 @@ function useMcp(options) {
310
1574
  connectingRef.current = false;
311
1575
  if (authTimeoutRef.current) clearTimeout(authTimeoutRef.current);
312
1576
  authTimeoutRef.current = null;
313
- const transport = transportRef.current;
1577
+ if (clientRef.current) {
1578
+ try {
1579
+ const serverName = "inspector-server";
1580
+ await clientRef.current.closeSession(serverName);
1581
+ } catch (err) {
1582
+ if (!quiet) addLog("warn", "Error closing session:", err);
1583
+ }
1584
+ }
314
1585
  clientRef.current = null;
315
- transportRef.current = null;
316
1586
  if (isMountedRef.current && !quiet) {
317
1587
  setState("discovering");
318
1588
  setTools([]);
@@ -322,14 +1592,6 @@ function useMcp(options) {
322
1592
  setError(void 0);
323
1593
  setAuthUrl(void 0);
324
1594
  }
325
- if (transport) {
326
- try {
327
- await transport.close();
328
- if (!quiet) addLog("debug", "Transport closed");
329
- } catch (err) {
330
- if (!quiet) addLog("warn", "Error closing transport:", err);
331
- }
332
- }
333
1595
  },
334
1596
  [addLog]
335
1597
  );
@@ -381,187 +1643,60 @@ function useMcp(options) {
381
1643
  addLog("debug", "BrowserOAuthClientProvider initialized in connect.");
382
1644
  }
383
1645
  if (!clientRef.current) {
384
- clientRef.current = new import_client.Client(
385
- { name: clientConfig.name || "mcp-use", version: clientConfig.version || "0.1.0" },
386
- { capabilities: {} }
387
- );
388
- addLog("debug", "MCP Client initialized in connect.");
1646
+ clientRef.current = new BrowserMCPClient();
1647
+ addLog("debug", "BrowserMCPClient initialized in connect.");
389
1648
  }
390
1649
  const tryConnectWithTransport = /* @__PURE__ */ __name(async (transportTypeParam, isAuthRetry = false) => {
391
- addLog("info", `Attempting connection with ${transportTypeParam.toUpperCase()} transport${isAuthRetry ? " (after auth)" : ""}...`);
392
- if (stateRef.current !== "authenticating") {
393
- setState("connecting");
394
- }
395
- let transportInstance;
1650
+ addLog("info", `Attempting connection with transport: ${transportTypeParam}`);
396
1651
  try {
397
- assert(authProviderRef.current, "Auth Provider must be initialized");
398
- assert(clientRef.current, "Client must be initialized");
399
- if (transportRef.current) {
400
- await transportRef.current.close().catch((e) => addLog("warn", `Error closing previous transport: ${e.message}`));
401
- transportRef.current = null;
402
- }
403
- const commonOptions = {
404
- authProvider: authProviderRef.current,
405
- requestInit: {
406
- headers: {
407
- Accept: "application/json, text/event-stream",
408
- ...customHeaders
409
- }
410
- }
411
- // Note: The MCP SDK's SSEClientTransport doesn't expose timeout configuration directly
412
- // Timeout handling is managed by the underlying EventSource and browser/Node.js fetch implementations
413
- // The timeout and sseReadTimeout options are preserved for future use or custom implementations
1652
+ const serverName = "inspector-server";
1653
+ const serverConfig = {
1654
+ url,
1655
+ transport: transportTypeParam === "sse" ? "http" : transportTypeParam
414
1656
  };
415
- const sanitizedUrl = (0, import_strict_url_sanitise2.sanitizeUrl)(url);
416
- const targetUrl = new URL(sanitizedUrl);
417
- addLog("debug", `Creating ${transportTypeParam.toUpperCase()} transport for URL: ${targetUrl.toString()}`);
418
- if (transportTypeParam === "http") {
419
- addLog("debug", "Creating StreamableHTTPClientTransport...");
420
- transportInstance = new import_streamableHttp.StreamableHTTPClientTransport(targetUrl, commonOptions);
421
- addLog("debug", "StreamableHTTPClientTransport created successfully");
422
- } else {
423
- addLog("debug", "Creating SSEClientTransport...");
424
- transportInstance = new import_sse.SSEClientTransport(targetUrl, commonOptions);
425
- addLog("debug", "SSEClientTransport created successfully");
426
- }
427
- transportRef.current = transportInstance;
428
- addLog("debug", `${transportTypeParam.toUpperCase()} transport created and assigned to ref.`);
429
- } catch (err) {
430
- failConnection(
431
- `Failed to create ${transportTypeParam.toUpperCase()} transport: ${err instanceof Error ? err.message : String(err)}`,
432
- err instanceof Error ? err : void 0
433
- );
434
- return "failed";
435
- }
436
- transportInstance.onmessage = (message) => {
437
- addLog("debug", `[Transport] Received: ${JSON.stringify(message)}`);
438
- clientRef.current?.handleMessage?.(message);
439
- };
440
- transportInstance.onerror = (err) => {
441
- addLog("warn", `Transport error event (${transportTypeParam.toUpperCase()}):`, err);
442
- failConnection(`Transport error (${transportTypeParam.toUpperCase()}): ${err.message}`, err);
443
- };
444
- transportInstance.onclose = () => {
445
- if (!isMountedRef.current || connectingRef.current) return;
446
- addLog("info", `Transport connection closed (${successfulTransportRef.current || "unknown"} type).`);
447
- const currentState = stateRef.current;
448
- const currentAutoReconnect = autoReconnectRef.current;
449
- if (currentState === "ready" && currentAutoReconnect) {
450
- const delay = typeof currentAutoReconnect === "number" ? currentAutoReconnect : DEFAULT_RECONNECT_DELAY;
451
- addLog("info", `Attempting to reconnect in ${delay}ms...`);
452
- setState("connecting");
453
- setTimeout(() => {
454
- if (isMountedRef.current) {
455
- connect();
456
- }
457
- }, delay);
458
- } else if (currentState !== "failed" && currentState !== "authenticating") {
459
- failConnection("Cannot connect to server");
460
- }
461
- };
462
- try {
463
- addLog("info", `Connecting client via ${transportTypeParam.toUpperCase()}...`);
464
- await clientRef.current.connect(transportInstance);
465
- addLog("info", `Client connected via ${transportTypeParam.toUpperCase()}. Loading tools, resources, and prompts...`);
466
- successfulTransportRef.current = transportTypeParam;
467
- setState("loading");
468
- const toolsResponse = await clientRef.current.request({ method: "tools/list" }, import_types.ListToolsResultSchema);
469
- let resourcesResponse = { resources: [], resourceTemplates: [] };
470
- try {
471
- resourcesResponse = await clientRef.current.request({ method: "resources/list" }, import_types.ListResourcesResultSchema);
472
- } catch (err) {
473
- addLog("debug", "Server does not support resources/list method", err);
1657
+ if (customHeaders && Object.keys(customHeaders).length > 0) {
1658
+ serverConfig.headers = customHeaders;
474
1659
  }
475
- let promptsResponse = { prompts: [] };
476
- try {
477
- promptsResponse = await clientRef.current.request({ method: "prompts/list" }, import_types.ListPromptsResultSchema);
478
- } catch (err) {
479
- addLog("debug", "Server does not support prompts/list method", err);
480
- }
481
- if (isMountedRef.current) {
482
- setTools(toolsResponse.tools);
483
- setResources(resourcesResponse.resources);
484
- setResourceTemplates(Array.isArray(resourcesResponse.resourceTemplates) ? resourcesResponse.resourceTemplates : []);
485
- setPrompts(promptsResponse.prompts);
486
- const summary = [`Loaded ${toolsResponse.tools.length} tools`];
487
- if (resourcesResponse.resources.length > 0 || resourcesResponse.resourceTemplates && resourcesResponse.resourceTemplates.length > 0) {
488
- summary.push(`${resourcesResponse.resources.length} resources`);
489
- if (Array.isArray(resourcesResponse.resourceTemplates) && resourcesResponse.resourceTemplates.length > 0) {
490
- summary.push(`${resourcesResponse.resourceTemplates.length} resource templates`);
491
- }
492
- }
493
- if (promptsResponse.prompts.length > 0) {
494
- summary.push(`${promptsResponse.prompts.length} prompts`);
1660
+ if (authProviderRef.current) {
1661
+ const tokens = await authProviderRef.current.tokens();
1662
+ if (tokens?.access_token) {
1663
+ serverConfig.headers = {
1664
+ ...serverConfig.headers,
1665
+ Authorization: `Bearer ${tokens.access_token}`
1666
+ };
495
1667
  }
496
- addLog("info", summary.join(", ") + ".");
497
- setState("ready");
498
- connectAttemptRef.current = 0;
499
- return "success";
500
- } else {
501
- return "failed";
502
- }
503
- } catch (connectErr) {
504
- addLog("debug", `Client connect error via ${transportTypeParam.toUpperCase()}:`, connectErr);
505
- const errorInstance = connectErr instanceof Error ? connectErr : new Error(String(connectErr));
506
- const errorMessage = errorInstance.message;
507
- const is404 = errorMessage.includes("404") || errorMessage.includes("Not Found");
508
- const is405 = errorMessage.includes("405") || errorMessage.includes("Method Not Allowed");
509
- const isLikelyCors = errorMessage === "Failed to fetch" || errorMessage === "NetworkError when attempting to fetch resource." || errorMessage === "Load failed";
510
- if (transportTypeParam === "http" && (is404 || is405 || isLikelyCors)) {
511
- addLog("warn", `HTTP transport failed (${isLikelyCors ? "CORS" : is404 ? "404" : "405"}), will try fallback.`);
512
- return "fallback";
513
1668
  }
514
- if (errorInstance instanceof import_auth.UnauthorizedError || errorMessage.includes("Unauthorized") || errorMessage.includes("401")) {
515
- if (isAuthRetry) {
516
- addLog("error", "Authentication failed even after successful token refresh. This may indicate a server issue.");
517
- failConnection("Authentication loop detected - auth succeeded but connection still unauthorized.");
518
- return "failed";
519
- }
520
- addLog("info", "Authentication required.");
521
- assert(authProviderRef.current, "Auth Provider not available for auth flow");
522
- const existingTokens = await authProviderRef.current.tokens();
523
- if (preventAutoAuth && !existingTokens) {
524
- addLog("info", "Authentication required but auto-auth prevented. User action needed.");
525
- setState("pending_auth");
526
- return "auth_redirect";
527
- }
528
- if (stateRef.current !== "authenticating" && stateRef.current !== "pending_auth") {
529
- setState("authenticating");
530
- if (authTimeoutRef.current) clearTimeout(authTimeoutRef.current);
531
- authTimeoutRef.current = setTimeout(() => {
532
- if (isMountedRef.current) {
533
- const currentState = stateRef.current;
534
- if (currentState === "authenticating") {
535
- failConnection("Authentication timed out. Please try again.");
536
- }
537
- }
538
- }, AUTH_TIMEOUT);
539
- }
540
- try {
541
- assert(url, "Server URL is required for authentication");
542
- const baseUrl = new URL(url).origin;
543
- const authResult = await (0, import_auth.auth)(authProviderRef.current, { serverUrl: baseUrl });
544
- if (!isMountedRef.current) return "failed";
545
- if (authResult === "AUTHORIZED") {
546
- addLog("info", "Authentication successful via existing token or refresh. Retrying transport connection...");
547
- if (authTimeoutRef.current) clearTimeout(authTimeoutRef.current);
548
- authTimeoutRef.current = null;
549
- return await tryConnectWithTransport(transportTypeParam, true);
550
- } else if (authResult === "REDIRECT") {
551
- addLog("info", "Redirecting for authentication. Waiting for callback...");
552
- return "auth_redirect";
553
- }
554
- } catch (sdkAuthError) {
555
- if (!isMountedRef.current) return "failed";
556
- if (authTimeoutRef.current) clearTimeout(authTimeoutRef.current);
1669
+ clientRef.current.addServer(serverName, {
1670
+ ...serverConfig,
1671
+ authProvider: authProviderRef.current
1672
+ // SDK handles OAuth automatically!
1673
+ });
1674
+ const session = await clientRef.current.createSession(serverName);
1675
+ await session.initialize();
1676
+ addLog("info", "\u2705 Successfully connected to MCP server");
1677
+ setState("ready");
1678
+ successfulTransportRef.current = transportTypeParam;
1679
+ setTools(session.connector.tools || []);
1680
+ const resourcesResult = await session.connector.listAllResources();
1681
+ setResources(resourcesResult.resources || []);
1682
+ const promptsResult = await session.connector.listPrompts();
1683
+ setPrompts(promptsResult.prompts || []);
1684
+ return "success";
1685
+ } catch (err) {
1686
+ const errorMessage = err?.message || String(err);
1687
+ if (err.code === 401 || errorMessage.includes("401") || errorMessage.includes("Unauthorized")) {
1688
+ if (customHeaders && Object.keys(customHeaders).length > 0) {
557
1689
  failConnection(
558
- `Failed to initiate authentication: ${sdkAuthError instanceof Error ? sdkAuthError.message : String(sdkAuthError)}`,
559
- sdkAuthError instanceof Error ? sdkAuthError : void 0
1690
+ "Authentication failed: Server returned 401 Unauthorized. Check your Authorization header value is correct."
560
1691
  );
561
1692
  return "failed";
562
1693
  }
1694
+ failConnection(
1695
+ "Authentication required: Server returned 401 Unauthorized. Add an Authorization header in the Custom Headers section (e.g., Authorization: Bearer YOUR_API_KEY)."
1696
+ );
1697
+ return "failed";
563
1698
  }
564
- failConnection(`Failed to connect via ${transportTypeParam.toUpperCase()}: ${errorMessage}`, errorInstance);
1699
+ failConnection(errorMessage, err);
565
1700
  return "failed";
566
1701
  }
567
1702
  }, "tryConnectWithTransport");
@@ -613,55 +1748,20 @@ function useMcp(options) {
613
1748
  }
614
1749
  addLog("info", `Calling tool: ${name}`, args);
615
1750
  try {
616
- const result = await clientRef.current.request({ method: "tools/call", params: { name, arguments: args } }, import_types.CallToolResultSchema);
1751
+ const serverName = "inspector-server";
1752
+ const session = clientRef.current.getSession(serverName);
1753
+ if (!session) {
1754
+ throw new Error("No active session found");
1755
+ }
1756
+ const result = await session.connector.callTool(name, args || {});
617
1757
  addLog("info", `Tool "${name}" call successful:`, result);
618
1758
  return result;
619
1759
  } catch (err) {
620
- addLog("error", `Error calling tool "${name}": ${err instanceof Error ? err.message : String(err)}`, err);
621
- const errorInstance = err instanceof Error ? err : new Error(String(err));
622
- if (errorInstance instanceof import_auth.UnauthorizedError || errorInstance.message.includes("Unauthorized") || errorInstance.message.includes("401")) {
623
- addLog("warn", "Tool call unauthorized, attempting re-authentication...");
624
- setState("authenticating");
625
- if (authTimeoutRef.current) clearTimeout(authTimeoutRef.current);
626
- authTimeoutRef.current = setTimeout(() => {
627
- if (isMountedRef.current) {
628
- const currentState2 = stateRef.current;
629
- if (currentState2 === "authenticating") {
630
- failConnection("Authentication timed out. Please try again.");
631
- }
632
- }
633
- }, AUTH_TIMEOUT);
634
- try {
635
- assert(authProviderRef.current, "Auth Provider not available for tool re-auth");
636
- assert(url, "Server URL is required for authentication");
637
- const baseUrl = new URL(url).origin;
638
- const authResult = await (0, import_auth.auth)(authProviderRef.current, { serverUrl: baseUrl });
639
- if (!isMountedRef.current) return;
640
- if (authResult === "AUTHORIZED") {
641
- addLog("info", "Re-authentication successful. Retrying tool call is recommended, or reconnecting.");
642
- if (authTimeoutRef.current) clearTimeout(authTimeoutRef.current);
643
- connectingRef.current = false;
644
- connect();
645
- } else if (authResult === "REDIRECT") {
646
- addLog("info", "Redirecting for re-authentication for tool call.");
647
- }
648
- } catch (sdkAuthError) {
649
- if (!isMountedRef.current) return;
650
- if (authTimeoutRef.current) clearTimeout(authTimeoutRef.current);
651
- failConnection(
652
- `Re-authentication failed: ${sdkAuthError instanceof Error ? sdkAuthError.message : String(sdkAuthError)}`,
653
- sdkAuthError instanceof Error ? sdkAuthError : void 0
654
- );
655
- }
656
- }
657
- const currentState = stateRef.current;
658
- if (currentState !== "authenticating") {
659
- throw err;
660
- }
661
- return void 0;
1760
+ addLog("error", `Tool "${name}" call failed:`, err);
1761
+ throw err;
662
1762
  }
663
1763
  },
664
- [state, url, addLog, failConnection, connect]
1764
+ [state]
665
1765
  );
666
1766
  const retry = (0, import_react.useCallback)(() => {
667
1767
  if (stateRef.current === "failed") {
@@ -692,17 +1792,7 @@ function useMcp(options) {
692
1792
  try {
693
1793
  assert(authProviderRef.current, "Auth Provider not available for manual auth");
694
1794
  assert(url, "Server URL is required for authentication");
695
- const baseUrl = new URL(url).origin;
696
- const authResult = await (0, import_auth.auth)(authProviderRef.current, { serverUrl: baseUrl });
697
- if (!isMountedRef.current) return;
698
- if (authResult === "AUTHORIZED") {
699
- addLog("info", "Manual authentication successful. Re-attempting connection...");
700
- if (authTimeoutRef.current) clearTimeout(authTimeoutRef.current);
701
- connectingRef.current = false;
702
- connect();
703
- } else if (authResult === "REDIRECT") {
704
- addLog("info", "Redirecting for manual authentication. Waiting for callback...");
705
- }
1795
+ addLog("info", "Redirecting for manual authentication. Waiting for callback...");
706
1796
  } catch (authError) {
707
1797
  if (!isMountedRef.current) return;
708
1798
  if (authTimeoutRef.current) clearTimeout(authTimeoutRef.current);
@@ -735,75 +1825,93 @@ function useMcp(options) {
735
1825
  addLog("warn", "Auth provider not initialized, cannot clear storage.");
736
1826
  }
737
1827
  }, [url, addLog, disconnect]);
738
- const listResources = (0, import_react.useCallback)(async () => {
739
- if (stateRef.current !== "ready" || !clientRef.current) {
740
- throw new Error(`MCP client is not ready (current state: ${state}). Cannot list resources.`);
741
- }
742
- addLog("info", "Listing resources...");
743
- try {
744
- const resourcesResponse = await clientRef.current.request({ method: "resources/list" }, import_types.ListResourcesResultSchema);
745
- if (isMountedRef.current) {
746
- setResources(resourcesResponse.resources);
747
- setResourceTemplates(Array.isArray(resourcesResponse.resourceTemplates) ? resourcesResponse.resourceTemplates : []);
748
- addLog(
749
- "info",
750
- `Listed ${resourcesResponse.resources.length} resources, ${Array.isArray(resourcesResponse.resourceTemplates) ? resourcesResponse.resourceTemplates.length : 0} resource templates.`
751
- );
1828
+ const listResources = (0, import_react.useCallback)(
1829
+ async () => {
1830
+ if (stateRef.current !== "ready" || !clientRef.current) {
1831
+ throw new Error(`MCP client is not ready (current state: ${state}). Cannot list resources.`);
752
1832
  }
753
- } catch (err) {
754
- addLog("error", `Error listing resources: ${err instanceof Error ? err.message : String(err)}`, err);
755
- throw err;
756
- }
757
- }, [state, addLog]);
1833
+ addLog("info", "Listing resources");
1834
+ try {
1835
+ const serverName = "inspector-server";
1836
+ const session = clientRef.current.getSession(serverName);
1837
+ if (!session) {
1838
+ throw new Error("No active session found");
1839
+ }
1840
+ const resourcesResult = await session.connector.listAllResources();
1841
+ setResources(resourcesResult.resources || []);
1842
+ addLog("info", "Resources listed successfully");
1843
+ } catch (err) {
1844
+ addLog("error", "List resources failed:", err);
1845
+ throw err;
1846
+ }
1847
+ },
1848
+ [state]
1849
+ );
758
1850
  const readResource = (0, import_react.useCallback)(
759
1851
  async (uri) => {
760
1852
  if (stateRef.current !== "ready" || !clientRef.current) {
761
- throw new Error(`MCP client is not ready (current state: ${state}). Cannot read resource "${uri}".`);
1853
+ throw new Error(`MCP client is not ready (current state: ${state}). Cannot read resource.`);
762
1854
  }
763
1855
  addLog("info", `Reading resource: ${uri}`);
764
1856
  try {
765
- const result = await clientRef.current.request({ method: "resources/read", params: { uri } }, import_types.ReadResourceResultSchema);
766
- addLog("info", `Resource "${uri}" read successfully`);
1857
+ const serverName = "inspector-server";
1858
+ const session = clientRef.current.getSession(serverName);
1859
+ if (!session) {
1860
+ throw new Error("No active session found");
1861
+ }
1862
+ const result = await session.connector.readResource(uri);
1863
+ addLog("info", "Resource read successful:", result);
767
1864
  return result;
768
1865
  } catch (err) {
769
- addLog("error", `Error reading resource "${uri}": ${err instanceof Error ? err.message : String(err)}`, err);
1866
+ addLog("error", "Resource read failed:", err);
770
1867
  throw err;
771
1868
  }
772
1869
  },
773
- [state, addLog]
1870
+ [state]
774
1871
  );
775
- const listPrompts = (0, import_react.useCallback)(async () => {
776
- if (stateRef.current !== "ready" || !clientRef.current) {
777
- throw new Error(`MCP client is not ready (current state: ${state}). Cannot list prompts.`);
778
- }
779
- addLog("info", "Listing prompts...");
780
- try {
781
- const promptsResponse = await clientRef.current.request({ method: "prompts/list" }, import_types.ListPromptsResultSchema);
782
- if (isMountedRef.current) {
783
- setPrompts(promptsResponse.prompts);
784
- addLog("info", `Listed ${promptsResponse.prompts.length} prompts.`);
1872
+ const listPrompts = (0, import_react.useCallback)(
1873
+ async () => {
1874
+ if (stateRef.current !== "ready" || !clientRef.current) {
1875
+ throw new Error(`MCP client is not ready (current state: ${state}). Cannot list prompts.`);
785
1876
  }
786
- } catch (err) {
787
- addLog("error", `Error listing prompts: ${err instanceof Error ? err.message : String(err)}`, err);
788
- throw err;
789
- }
790
- }, [state, addLog]);
1877
+ addLog("info", "Listing prompts");
1878
+ try {
1879
+ const serverName = "inspector-server";
1880
+ const session = clientRef.current.getSession(serverName);
1881
+ if (!session) {
1882
+ throw new Error("No active session found");
1883
+ }
1884
+ const promptsResult = await session.connector.listPrompts();
1885
+ setPrompts(promptsResult.prompts || []);
1886
+ addLog("info", "Prompts listed successfully");
1887
+ } catch (err) {
1888
+ addLog("error", "List prompts failed:", err);
1889
+ throw err;
1890
+ }
1891
+ },
1892
+ [state]
1893
+ );
791
1894
  const getPrompt = (0, import_react.useCallback)(
792
1895
  async (name, args) => {
793
1896
  if (stateRef.current !== "ready" || !clientRef.current) {
794
- throw new Error(`MCP client is not ready (current state: ${state}). Cannot get prompt "${name}".`);
1897
+ throw new Error(`MCP client is not ready (current state: ${state}). Cannot get prompt.`);
795
1898
  }
796
1899
  addLog("info", `Getting prompt: ${name}`, args);
797
1900
  try {
798
- const result = await clientRef.current.request({ method: "prompts/get", params: { name, arguments: args } }, import_types.GetPromptResultSchema);
799
- addLog("info", `Prompt "${name}" retrieved successfully`);
1901
+ const serverName = "inspector-server";
1902
+ const session = clientRef.current.getSession(serverName);
1903
+ if (!session) {
1904
+ throw new Error("No active session found");
1905
+ }
1906
+ const result = await session.connector.getPrompt(name, args || {});
1907
+ addLog("info", `Prompt "${name}" retrieved successfully:`, result);
800
1908
  return result;
801
1909
  } catch (err) {
802
- addLog("error", `Error getting prompt "${name}": ${err instanceof Error ? err.message : String(err)}`, err);
1910
+ addLog("error", `Prompt "${name}" retrieval failed:`, err);
803
1911
  throw err;
804
1912
  }
805
1913
  },
806
- [state, addLog]
1914
+ [state]
807
1915
  );
808
1916
  const connectRef = (0, import_react.useRef)(connect);
809
1917
  const failConnectionRef = (0, import_react.useRef)(failConnection);
@@ -896,9 +2004,10 @@ function useMcp(options) {
896
2004
  error,
897
2005
  log,
898
2006
  authUrl,
2007
+ client: clientRef.current,
899
2008
  callTool,
900
- listResources,
901
2009
  readResource,
2010
+ listResources,
902
2011
  listPrompts,
903
2012
  getPrompt,
904
2013
  retry,
@@ -910,7 +2019,7 @@ function useMcp(options) {
910
2019
  __name(useMcp, "useMcp");
911
2020
 
912
2021
  // src/auth/callback.ts
913
- var import_auth2 = require("@modelcontextprotocol/sdk/client/auth.js");
2022
+ var import_auth = require("@modelcontextprotocol/sdk/client/auth.js");
914
2023
  async function onMcpAuthorization() {
915
2024
  const queryParams = new URLSearchParams(window.location.search);
916
2025
  const code = queryParams.get("code");
@@ -953,7 +2062,7 @@ async function onMcpAuthorization() {
953
2062
  provider = new BrowserOAuthClientProvider(serverUrl, providerOptions);
954
2063
  console.log(`${logPrefix} Calling SDK auth() to exchange code...`);
955
2064
  const baseUrl = new URL(serverUrl).origin;
956
- const authResult = await (0, import_auth2.auth)(provider, { serverUrl: baseUrl, authorizationCode: code });
2065
+ const authResult = await (0, import_auth.auth)(provider, { serverUrl: baseUrl, authorizationCode: code });
957
2066
  if (authResult === "AUTHORIZED") {
958
2067
  console.log(`${logPrefix} Authorization successful via SDK auth(). Notifying opener...`);
959
2068
  if (window.opener && !window.opener.closed) {