@mcp-use/inspector 0.7.0 → 0.7.1-canary.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/cli.js +2 -1
- package/dist/client/assets/{browser-BdCJ_qyB.js → browser-C03pLkVq.js} +5 -5
- package/dist/client/assets/{chunk-VL2OQCWN-CxD8xDNw.js → chunk-VL2OQCWN-B1xABO_P.js} +1 -1
- package/dist/client/assets/{display-YIYC6WJE-B6ZSv77R.js → display-YIYC6WJE-DLKKaM6A.js} +1 -1
- package/dist/client/assets/{embeddings-DlCMB9po.js → embeddings-flTeKf82.js} +1 -1
- package/dist/client/assets/{index-kVFYovMy.css → index-C2qHJtN-.css} +19 -0
- package/dist/client/assets/{index-CsP5AdwX.js → index-DIp48bR6.js} +4 -4
- package/dist/client/assets/{index-CKXUnlZB.js → index-DYMy4sDT.js} +1239 -372
- package/dist/client/assets/{index-Cb09SlUY.js → index-DzNL2BIj.js} +2 -2
- package/dist/client/assets/{index-B0NYybvW.js → index-SW6h169v.js} +3 -3
- package/dist/client/assets/{index-Q_pqNaNk.js → index-fTSANe1E.js} +4 -4
- package/dist/client/assets/{winston-qgF6niUt.js → winston-D4V1GzRN.js} +1 -1
- package/dist/client/index.html +3 -3
- package/dist/server/{chunk-RRPLH7DL.js → chunk-26WTIZ4S.js} +1 -1
- package/dist/server/{chunk-S7NOZBMG.js → chunk-6ZFXPXO4.js} +6 -6
- package/dist/server/{chunk-ZONLXYBO.js → chunk-KW44WB52.js} +2 -1
- package/dist/server/{chunk-3T2VCYG6.js → chunk-V5FEV5SU.js} +2 -1
- package/dist/server/{chunk-FS77NTZN.js → chunk-XU7SXB3C.js} +1 -1
- package/dist/server/cli.js +4 -4
- package/dist/server/index.js +5 -5
- package/dist/server/middleware.d.ts +5 -1
- package/dist/server/middleware.d.ts.map +1 -1
- package/dist/server/middleware.js +5 -5
- package/dist/server/server.js +4 -4
- package/dist/server/shared-routes.js +2 -2
- package/dist/server/shared-static.js +2 -2
- package/dist/server/shared-utils-browser.d.ts.map +1 -1
- package/dist/server/shared-utils-browser.js +1 -1
- package/dist/server/shared-utils.d.ts.map +1 -1
- package/dist/server/shared-utils.js +1 -1
- package/package.json +2 -2
|
@@ -1,8 +1,8 @@
|
|
|
1
|
-
const __vite__mapDeps=(i,m=__vite__mapDeps,d=(m.f||(m.f=["assets/winston-
|
|
1
|
+
const __vite__mapDeps=(i,m=__vite__mapDeps,d=(m.f||(m.f=["assets/winston-D4V1GzRN.js","assets/__vite-browser-external-CHS79mP1.js","assets/index-DX0TIfSM.js","assets/path-QsnVvLoj.js","assets/index-DIp48bR6.js","assets/index-DzNL2BIj.js","assets/chunk-VL2OQCWN-B1xABO_P.js","assets/embeddings-flTeKf82.js","assets/index-SW6h169v.js","assets/index-fTSANe1E.js","assets/browser-C03pLkVq.js"])))=>i.map(i=>d[i]);
|
|
2
2
|
var __defProp = Object.defineProperty;
|
|
3
3
|
var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
|
|
4
4
|
var __publicField = (obj, key, value) => __defNormalProp(obj, typeof key !== "symbol" ? key + "" : key, value);
|
|
5
|
-
var _a, _b, _c, _d, _e2, _f, _g, _h, _i, _j, _k, _l, _m
|
|
5
|
+
var _a, _b, _c, _d, _e2, _f, _g, _h, _i, _j, _k, _l, _m;
|
|
6
6
|
function _mergeNamespaces(n2, m2) {
|
|
7
7
|
for (var i2 = 0; i2 < m2.length; i2++) {
|
|
8
8
|
const e = m2[i2];
|
|
@@ -211,7 +211,7 @@ function loadWinstonSync() {
|
|
|
211
211
|
__name(loadWinstonSync, "loadWinstonSync");
|
|
212
212
|
async function getWinston() {
|
|
213
213
|
if (!winston) {
|
|
214
|
-
winston = await __vitePreload(() => import("./winston-
|
|
214
|
+
winston = await __vitePreload(() => import("./winston-D4V1GzRN.js").then((n2) => n2.w), true ? __vite__mapDeps([0,1,2,3]) : void 0);
|
|
215
215
|
}
|
|
216
216
|
return winston;
|
|
217
217
|
}
|
|
@@ -446,254 +446,6 @@ if (isNodeJSEnvironment()) {
|
|
|
446
446
|
}
|
|
447
447
|
}
|
|
448
448
|
var logger = Logger.get();
|
|
449
|
-
var BaseConnector = (_c = class {
|
|
450
|
-
client = null;
|
|
451
|
-
connectionManager = null;
|
|
452
|
-
toolsCache = null;
|
|
453
|
-
capabilitiesCache = null;
|
|
454
|
-
serverInfoCache = null;
|
|
455
|
-
connected = false;
|
|
456
|
-
opts;
|
|
457
|
-
constructor(opts = {}) {
|
|
458
|
-
this.opts = opts;
|
|
459
|
-
}
|
|
460
|
-
/** Disconnect and release resources. */
|
|
461
|
-
async disconnect() {
|
|
462
|
-
if (!this.connected) {
|
|
463
|
-
logger.debug("Not connected to MCP implementation");
|
|
464
|
-
return;
|
|
465
|
-
}
|
|
466
|
-
logger.debug("Disconnecting from MCP implementation");
|
|
467
|
-
await this.cleanupResources();
|
|
468
|
-
this.connected = false;
|
|
469
|
-
logger.debug("Disconnected from MCP implementation");
|
|
470
|
-
}
|
|
471
|
-
/** Check if the client is connected */
|
|
472
|
-
get isClientConnected() {
|
|
473
|
-
return this.client != null;
|
|
474
|
-
}
|
|
475
|
-
/**
|
|
476
|
-
* Initialise the MCP session **after** `connect()` has succeeded.
|
|
477
|
-
*
|
|
478
|
-
* In the SDK, `Client.connect(transport)` automatically performs the
|
|
479
|
-
* protocol‑level `initialize` handshake, so we only need to cache the list of
|
|
480
|
-
* tools and expose some server info.
|
|
481
|
-
*/
|
|
482
|
-
async initialize(defaultRequestOptions = this.opts.defaultRequestOptions ?? {}) {
|
|
483
|
-
if (!this.client) {
|
|
484
|
-
throw new Error("MCP client is not connected");
|
|
485
|
-
}
|
|
486
|
-
logger.debug("Caching server capabilities & tools");
|
|
487
|
-
const capabilities = this.client.getServerCapabilities();
|
|
488
|
-
this.capabilitiesCache = capabilities;
|
|
489
|
-
const serverInfo = this.client.getServerVersion();
|
|
490
|
-
this.serverInfoCache = serverInfo || null;
|
|
491
|
-
const listToolsRes = await this.client.listTools(
|
|
492
|
-
void 0,
|
|
493
|
-
defaultRequestOptions
|
|
494
|
-
);
|
|
495
|
-
this.toolsCache = listToolsRes.tools ?? [];
|
|
496
|
-
logger.debug(`Fetched ${this.toolsCache.length} tools from server`);
|
|
497
|
-
logger.debug("Server capabilities:", capabilities);
|
|
498
|
-
logger.debug("Server info:", serverInfo);
|
|
499
|
-
return capabilities;
|
|
500
|
-
}
|
|
501
|
-
/** Lazily expose the cached tools list. */
|
|
502
|
-
get tools() {
|
|
503
|
-
if (!this.toolsCache) {
|
|
504
|
-
throw new Error("MCP client is not initialized; call initialize() first");
|
|
505
|
-
}
|
|
506
|
-
return this.toolsCache;
|
|
507
|
-
}
|
|
508
|
-
/** Expose cached server capabilities. */
|
|
509
|
-
get serverCapabilities() {
|
|
510
|
-
return this.capabilitiesCache;
|
|
511
|
-
}
|
|
512
|
-
/** Expose cached server info. */
|
|
513
|
-
get serverInfo() {
|
|
514
|
-
return this.serverInfoCache;
|
|
515
|
-
}
|
|
516
|
-
/** Call a tool on the server. */
|
|
517
|
-
async callTool(name, args, options) {
|
|
518
|
-
if (!this.client) {
|
|
519
|
-
throw new Error("MCP client is not connected");
|
|
520
|
-
}
|
|
521
|
-
logger.debug(`Calling tool '${name}' with args`, args);
|
|
522
|
-
const res = await this.client.callTool(
|
|
523
|
-
{ name, arguments: args },
|
|
524
|
-
void 0,
|
|
525
|
-
options
|
|
526
|
-
);
|
|
527
|
-
logger.debug(`Tool '${name}' returned`, res);
|
|
528
|
-
return res;
|
|
529
|
-
}
|
|
530
|
-
/**
|
|
531
|
-
* List resources from the server with optional pagination
|
|
532
|
-
*
|
|
533
|
-
* @param cursor - Optional cursor for pagination
|
|
534
|
-
* @param options - Request options
|
|
535
|
-
* @returns Resource list with optional nextCursor for pagination
|
|
536
|
-
*/
|
|
537
|
-
async listResources(cursor, options) {
|
|
538
|
-
if (!this.client) {
|
|
539
|
-
throw new Error("MCP client is not connected");
|
|
540
|
-
}
|
|
541
|
-
logger.debug("Listing resources", cursor ? `with cursor: ${cursor}` : "");
|
|
542
|
-
return await this.client.listResources({ cursor }, options);
|
|
543
|
-
}
|
|
544
|
-
/**
|
|
545
|
-
* List all resources from the server, automatically handling pagination
|
|
546
|
-
*
|
|
547
|
-
* @param options - Request options
|
|
548
|
-
* @returns Complete list of all resources
|
|
549
|
-
*/
|
|
550
|
-
async listAllResources(options) {
|
|
551
|
-
if (!this.client) {
|
|
552
|
-
throw new Error("MCP client is not connected");
|
|
553
|
-
}
|
|
554
|
-
if (!this.capabilitiesCache?.resources) {
|
|
555
|
-
logger.debug("Server does not advertise resources capability, skipping");
|
|
556
|
-
return { resources: [] };
|
|
557
|
-
}
|
|
558
|
-
try {
|
|
559
|
-
logger.debug("Listing all resources (with auto-pagination)");
|
|
560
|
-
const allResources = [];
|
|
561
|
-
let cursor = void 0;
|
|
562
|
-
do {
|
|
563
|
-
const result = await this.client.listResources({ cursor }, options);
|
|
564
|
-
allResources.push(...result.resources || []);
|
|
565
|
-
cursor = result.nextCursor;
|
|
566
|
-
} while (cursor);
|
|
567
|
-
return { resources: allResources };
|
|
568
|
-
} catch (err) {
|
|
569
|
-
if (err.code === -32601) {
|
|
570
|
-
logger.debug("Server advertised resources but method not found");
|
|
571
|
-
return { resources: [] };
|
|
572
|
-
}
|
|
573
|
-
throw err;
|
|
574
|
-
}
|
|
575
|
-
}
|
|
576
|
-
/**
|
|
577
|
-
* List resource templates from the server
|
|
578
|
-
*
|
|
579
|
-
* @param options - Request options
|
|
580
|
-
* @returns List of available resource templates
|
|
581
|
-
*/
|
|
582
|
-
async listResourceTemplates(options) {
|
|
583
|
-
if (!this.client) {
|
|
584
|
-
throw new Error("MCP client is not connected");
|
|
585
|
-
}
|
|
586
|
-
logger.debug("Listing resource templates");
|
|
587
|
-
return await this.client.listResourceTemplates(void 0, options);
|
|
588
|
-
}
|
|
589
|
-
/** Read a resource by URI. */
|
|
590
|
-
async readResource(uri, options) {
|
|
591
|
-
if (!this.client) {
|
|
592
|
-
throw new Error("MCP client is not connected");
|
|
593
|
-
}
|
|
594
|
-
logger.debug(`Reading resource ${uri}`);
|
|
595
|
-
const res = await this.client.readResource({ uri }, options);
|
|
596
|
-
return res;
|
|
597
|
-
}
|
|
598
|
-
/**
|
|
599
|
-
* Subscribe to resource updates
|
|
600
|
-
*
|
|
601
|
-
* @param uri - URI of the resource to subscribe to
|
|
602
|
-
* @param options - Request options
|
|
603
|
-
*/
|
|
604
|
-
async subscribeToResource(uri, options) {
|
|
605
|
-
if (!this.client) {
|
|
606
|
-
throw new Error("MCP client is not connected");
|
|
607
|
-
}
|
|
608
|
-
logger.debug(`Subscribing to resource: ${uri}`);
|
|
609
|
-
return await this.client.subscribeResource({ uri }, options);
|
|
610
|
-
}
|
|
611
|
-
/**
|
|
612
|
-
* Unsubscribe from resource updates
|
|
613
|
-
*
|
|
614
|
-
* @param uri - URI of the resource to unsubscribe from
|
|
615
|
-
* @param options - Request options
|
|
616
|
-
*/
|
|
617
|
-
async unsubscribeFromResource(uri, options) {
|
|
618
|
-
if (!this.client) {
|
|
619
|
-
throw new Error("MCP client is not connected");
|
|
620
|
-
}
|
|
621
|
-
logger.debug(`Unsubscribing from resource: ${uri}`);
|
|
622
|
-
return await this.client.unsubscribeResource({ uri }, options);
|
|
623
|
-
}
|
|
624
|
-
async listPrompts() {
|
|
625
|
-
if (!this.client) {
|
|
626
|
-
throw new Error("MCP client is not connected");
|
|
627
|
-
}
|
|
628
|
-
if (!this.capabilitiesCache?.prompts) {
|
|
629
|
-
logger.debug("Server does not advertise prompts capability, skipping");
|
|
630
|
-
return { prompts: [] };
|
|
631
|
-
}
|
|
632
|
-
try {
|
|
633
|
-
logger.debug("Listing prompts");
|
|
634
|
-
return await this.client.listPrompts();
|
|
635
|
-
} catch (err) {
|
|
636
|
-
if (err.code === -32601) {
|
|
637
|
-
logger.debug("Server advertised prompts but method not found");
|
|
638
|
-
return { prompts: [] };
|
|
639
|
-
}
|
|
640
|
-
throw err;
|
|
641
|
-
}
|
|
642
|
-
}
|
|
643
|
-
async getPrompt(name, args) {
|
|
644
|
-
if (!this.client) {
|
|
645
|
-
throw new Error("MCP client is not connected");
|
|
646
|
-
}
|
|
647
|
-
logger.debug(`Getting prompt ${name}`);
|
|
648
|
-
return await this.client.getPrompt({ name, arguments: args });
|
|
649
|
-
}
|
|
650
|
-
/** Send a raw request through the client. */
|
|
651
|
-
async request(method, params = null, options) {
|
|
652
|
-
if (!this.client) {
|
|
653
|
-
throw new Error("MCP client is not connected");
|
|
654
|
-
}
|
|
655
|
-
logger.debug(`Sending raw request '${method}' with params`, params);
|
|
656
|
-
return await this.client.request(
|
|
657
|
-
{ method, params: params ?? {} },
|
|
658
|
-
void 0,
|
|
659
|
-
options
|
|
660
|
-
);
|
|
661
|
-
}
|
|
662
|
-
/**
|
|
663
|
-
* Helper to tear down the client & connection manager safely.
|
|
664
|
-
*/
|
|
665
|
-
async cleanupResources() {
|
|
666
|
-
const issues = [];
|
|
667
|
-
if (this.client) {
|
|
668
|
-
try {
|
|
669
|
-
if (typeof this.client.close === "function") {
|
|
670
|
-
await this.client.close();
|
|
671
|
-
}
|
|
672
|
-
} catch (e) {
|
|
673
|
-
const msg = `Error closing client: ${e}`;
|
|
674
|
-
logger.warn(msg);
|
|
675
|
-
issues.push(msg);
|
|
676
|
-
} finally {
|
|
677
|
-
this.client = null;
|
|
678
|
-
}
|
|
679
|
-
}
|
|
680
|
-
if (this.connectionManager) {
|
|
681
|
-
try {
|
|
682
|
-
await this.connectionManager.stop();
|
|
683
|
-
} catch (e) {
|
|
684
|
-
const msg = `Error stopping connection manager: ${e}`;
|
|
685
|
-
logger.warn(msg);
|
|
686
|
-
issues.push(msg);
|
|
687
|
-
} finally {
|
|
688
|
-
this.connectionManager = null;
|
|
689
|
-
}
|
|
690
|
-
}
|
|
691
|
-
this.toolsCache = null;
|
|
692
|
-
if (issues.length) {
|
|
693
|
-
logger.warn(`Resource cleanup finished with ${issues.length} issue(s)`);
|
|
694
|
-
}
|
|
695
|
-
}
|
|
696
|
-
}, __name(_c, "BaseConnector"), _c);
|
|
697
449
|
var util$1;
|
|
698
450
|
(function(util2) {
|
|
699
451
|
util2.assertEqual = (_2) => {
|
|
@@ -5516,6 +5268,400 @@ class McpError extends Error {
|
|
|
5516
5268
|
this.name = "McpError";
|
|
5517
5269
|
}
|
|
5518
5270
|
}
|
|
5271
|
+
var BaseConnector = (_c = class {
|
|
5272
|
+
client = null;
|
|
5273
|
+
connectionManager = null;
|
|
5274
|
+
toolsCache = null;
|
|
5275
|
+
capabilitiesCache = null;
|
|
5276
|
+
serverInfoCache = null;
|
|
5277
|
+
connected = false;
|
|
5278
|
+
opts;
|
|
5279
|
+
notificationHandlers = [];
|
|
5280
|
+
rootsCache = [];
|
|
5281
|
+
constructor(opts = {}) {
|
|
5282
|
+
this.opts = opts;
|
|
5283
|
+
if (opts.roots) {
|
|
5284
|
+
this.rootsCache = [...opts.roots];
|
|
5285
|
+
}
|
|
5286
|
+
}
|
|
5287
|
+
/**
|
|
5288
|
+
* Register a handler for server notifications
|
|
5289
|
+
*
|
|
5290
|
+
* @param handler - Function to call when a notification is received
|
|
5291
|
+
*
|
|
5292
|
+
* @example
|
|
5293
|
+
* ```typescript
|
|
5294
|
+
* connector.onNotification((notification) => {
|
|
5295
|
+
* console.log(`Received: ${notification.method}`, notification.params);
|
|
5296
|
+
* });
|
|
5297
|
+
* ```
|
|
5298
|
+
*/
|
|
5299
|
+
onNotification(handler) {
|
|
5300
|
+
this.notificationHandlers.push(handler);
|
|
5301
|
+
if (this.client) {
|
|
5302
|
+
this.setupNotificationHandler();
|
|
5303
|
+
}
|
|
5304
|
+
}
|
|
5305
|
+
/**
|
|
5306
|
+
* Internal: wire notification handlers to the SDK client
|
|
5307
|
+
* Includes automatic handling for list_changed notifications per MCP spec
|
|
5308
|
+
*/
|
|
5309
|
+
setupNotificationHandler() {
|
|
5310
|
+
if (!this.client) return;
|
|
5311
|
+
this.client.fallbackNotificationHandler = async (notification) => {
|
|
5312
|
+
switch (notification.method) {
|
|
5313
|
+
case "notifications/tools/list_changed":
|
|
5314
|
+
await this.refreshToolsCache();
|
|
5315
|
+
break;
|
|
5316
|
+
case "notifications/resources/list_changed":
|
|
5317
|
+
await this.onResourcesListChanged();
|
|
5318
|
+
break;
|
|
5319
|
+
case "notifications/prompts/list_changed":
|
|
5320
|
+
await this.onPromptsListChanged();
|
|
5321
|
+
break;
|
|
5322
|
+
}
|
|
5323
|
+
for (const handler of this.notificationHandlers) {
|
|
5324
|
+
try {
|
|
5325
|
+
await handler(notification);
|
|
5326
|
+
} catch (err) {
|
|
5327
|
+
logger.error("Error in notification handler:", err);
|
|
5328
|
+
}
|
|
5329
|
+
}
|
|
5330
|
+
};
|
|
5331
|
+
}
|
|
5332
|
+
/**
|
|
5333
|
+
* Auto-refresh tools cache when server sends tools/list_changed notification
|
|
5334
|
+
*/
|
|
5335
|
+
async refreshToolsCache() {
|
|
5336
|
+
if (!this.client) return;
|
|
5337
|
+
try {
|
|
5338
|
+
logger.debug(
|
|
5339
|
+
"[Auto] Refreshing tools cache due to list_changed notification"
|
|
5340
|
+
);
|
|
5341
|
+
const result = await this.client.listTools();
|
|
5342
|
+
this.toolsCache = result.tools ?? [];
|
|
5343
|
+
logger.debug(
|
|
5344
|
+
`[Auto] Refreshed tools cache: ${this.toolsCache.length} tools`
|
|
5345
|
+
);
|
|
5346
|
+
} catch (err) {
|
|
5347
|
+
logger.warn("[Auto] Failed to refresh tools cache:", err);
|
|
5348
|
+
}
|
|
5349
|
+
}
|
|
5350
|
+
/**
|
|
5351
|
+
* Called when server sends resources/list_changed notification
|
|
5352
|
+
* Resources aren't cached by default, but we log for user awareness
|
|
5353
|
+
*/
|
|
5354
|
+
async onResourcesListChanged() {
|
|
5355
|
+
logger.debug(
|
|
5356
|
+
"[Auto] Resources list changed - clients should re-fetch if needed"
|
|
5357
|
+
);
|
|
5358
|
+
}
|
|
5359
|
+
/**
|
|
5360
|
+
* Called when server sends prompts/list_changed notification
|
|
5361
|
+
* Prompts aren't cached by default, but we log for user awareness
|
|
5362
|
+
*/
|
|
5363
|
+
async onPromptsListChanged() {
|
|
5364
|
+
logger.debug(
|
|
5365
|
+
"[Auto] Prompts list changed - clients should re-fetch if needed"
|
|
5366
|
+
);
|
|
5367
|
+
}
|
|
5368
|
+
/**
|
|
5369
|
+
* Set roots and notify the server.
|
|
5370
|
+
* Roots represent directories or files that the client has access to.
|
|
5371
|
+
*
|
|
5372
|
+
* @param roots - Array of Root objects with `uri` (must start with "file://") and optional `name`
|
|
5373
|
+
*
|
|
5374
|
+
* @example
|
|
5375
|
+
* ```typescript
|
|
5376
|
+
* await connector.setRoots([
|
|
5377
|
+
* { uri: "file:///home/user/project", name: "My Project" },
|
|
5378
|
+
* { uri: "file:///home/user/data" }
|
|
5379
|
+
* ]);
|
|
5380
|
+
* ```
|
|
5381
|
+
*/
|
|
5382
|
+
async setRoots(roots) {
|
|
5383
|
+
this.rootsCache = [...roots];
|
|
5384
|
+
if (this.client) {
|
|
5385
|
+
logger.debug(
|
|
5386
|
+
`Sending roots/list_changed notification with ${roots.length} root(s)`
|
|
5387
|
+
);
|
|
5388
|
+
await this.client.sendRootsListChanged();
|
|
5389
|
+
}
|
|
5390
|
+
}
|
|
5391
|
+
/**
|
|
5392
|
+
* Get the current roots.
|
|
5393
|
+
*/
|
|
5394
|
+
getRoots() {
|
|
5395
|
+
return [...this.rootsCache];
|
|
5396
|
+
}
|
|
5397
|
+
/**
|
|
5398
|
+
* Internal: set up roots/list request handler.
|
|
5399
|
+
* This is called after the client connects to register the handler for server requests.
|
|
5400
|
+
*/
|
|
5401
|
+
setupRootsHandler() {
|
|
5402
|
+
if (!this.client) return;
|
|
5403
|
+
this.client.setRequestHandler(
|
|
5404
|
+
ListRootsRequestSchema,
|
|
5405
|
+
async (_request, _extra) => {
|
|
5406
|
+
logger.debug(
|
|
5407
|
+
`Server requested roots list, returning ${this.rootsCache.length} root(s)`
|
|
5408
|
+
);
|
|
5409
|
+
return { roots: this.rootsCache };
|
|
5410
|
+
}
|
|
5411
|
+
);
|
|
5412
|
+
}
|
|
5413
|
+
/**
|
|
5414
|
+
* Internal: set up sampling/createMessage request handler.
|
|
5415
|
+
* This is called after the client connects to register the handler for sampling requests.
|
|
5416
|
+
*/
|
|
5417
|
+
setupSamplingHandler() {
|
|
5418
|
+
if (!this.client) return;
|
|
5419
|
+
if (!this.opts.samplingCallback) return;
|
|
5420
|
+
this.client.setRequestHandler(
|
|
5421
|
+
CreateMessageRequestSchema,
|
|
5422
|
+
async (request, _extra) => {
|
|
5423
|
+
logger.debug("Server requested sampling, forwarding to callback");
|
|
5424
|
+
return await this.opts.samplingCallback(request.params);
|
|
5425
|
+
}
|
|
5426
|
+
);
|
|
5427
|
+
}
|
|
5428
|
+
/** Disconnect and release resources. */
|
|
5429
|
+
async disconnect() {
|
|
5430
|
+
if (!this.connected) {
|
|
5431
|
+
logger.debug("Not connected to MCP implementation");
|
|
5432
|
+
return;
|
|
5433
|
+
}
|
|
5434
|
+
logger.debug("Disconnecting from MCP implementation");
|
|
5435
|
+
await this.cleanupResources();
|
|
5436
|
+
this.connected = false;
|
|
5437
|
+
logger.debug("Disconnected from MCP implementation");
|
|
5438
|
+
}
|
|
5439
|
+
/** Check if the client is connected */
|
|
5440
|
+
get isClientConnected() {
|
|
5441
|
+
return this.client != null;
|
|
5442
|
+
}
|
|
5443
|
+
/**
|
|
5444
|
+
* Initialise the MCP session **after** `connect()` has succeeded.
|
|
5445
|
+
*
|
|
5446
|
+
* In the SDK, `Client.connect(transport)` automatically performs the
|
|
5447
|
+
* protocol‑level `initialize` handshake, so we only need to cache the list of
|
|
5448
|
+
* tools and expose some server info.
|
|
5449
|
+
*/
|
|
5450
|
+
async initialize(defaultRequestOptions = this.opts.defaultRequestOptions ?? {}) {
|
|
5451
|
+
if (!this.client) {
|
|
5452
|
+
throw new Error("MCP client is not connected");
|
|
5453
|
+
}
|
|
5454
|
+
logger.debug("Caching server capabilities & tools");
|
|
5455
|
+
const capabilities = this.client.getServerCapabilities();
|
|
5456
|
+
this.capabilitiesCache = capabilities;
|
|
5457
|
+
const serverInfo = this.client.getServerVersion();
|
|
5458
|
+
this.serverInfoCache = serverInfo || null;
|
|
5459
|
+
const listToolsRes = await this.client.listTools(
|
|
5460
|
+
void 0,
|
|
5461
|
+
defaultRequestOptions
|
|
5462
|
+
);
|
|
5463
|
+
this.toolsCache = listToolsRes.tools ?? [];
|
|
5464
|
+
logger.debug(`Fetched ${this.toolsCache.length} tools from server`);
|
|
5465
|
+
logger.debug("Server capabilities:", capabilities);
|
|
5466
|
+
logger.debug("Server info:", serverInfo);
|
|
5467
|
+
return capabilities;
|
|
5468
|
+
}
|
|
5469
|
+
/** Lazily expose the cached tools list. */
|
|
5470
|
+
get tools() {
|
|
5471
|
+
if (!this.toolsCache) {
|
|
5472
|
+
throw new Error("MCP client is not initialized; call initialize() first");
|
|
5473
|
+
}
|
|
5474
|
+
return this.toolsCache;
|
|
5475
|
+
}
|
|
5476
|
+
/** Expose cached server capabilities. */
|
|
5477
|
+
get serverCapabilities() {
|
|
5478
|
+
return this.capabilitiesCache;
|
|
5479
|
+
}
|
|
5480
|
+
/** Expose cached server info. */
|
|
5481
|
+
get serverInfo() {
|
|
5482
|
+
return this.serverInfoCache;
|
|
5483
|
+
}
|
|
5484
|
+
/** Call a tool on the server. */
|
|
5485
|
+
async callTool(name, args, options) {
|
|
5486
|
+
if (!this.client) {
|
|
5487
|
+
throw new Error("MCP client is not connected");
|
|
5488
|
+
}
|
|
5489
|
+
logger.debug(`Calling tool '${name}' with args`, args);
|
|
5490
|
+
const res = await this.client.callTool(
|
|
5491
|
+
{ name, arguments: args },
|
|
5492
|
+
void 0,
|
|
5493
|
+
options
|
|
5494
|
+
);
|
|
5495
|
+
logger.debug(`Tool '${name}' returned`, res);
|
|
5496
|
+
return res;
|
|
5497
|
+
}
|
|
5498
|
+
/**
|
|
5499
|
+
* List resources from the server with optional pagination
|
|
5500
|
+
*
|
|
5501
|
+
* @param cursor - Optional cursor for pagination
|
|
5502
|
+
* @param options - Request options
|
|
5503
|
+
* @returns Resource list with optional nextCursor for pagination
|
|
5504
|
+
*/
|
|
5505
|
+
async listResources(cursor, options) {
|
|
5506
|
+
if (!this.client) {
|
|
5507
|
+
throw new Error("MCP client is not connected");
|
|
5508
|
+
}
|
|
5509
|
+
logger.debug("Listing resources", cursor ? `with cursor: ${cursor}` : "");
|
|
5510
|
+
return await this.client.listResources({ cursor }, options);
|
|
5511
|
+
}
|
|
5512
|
+
/**
|
|
5513
|
+
* List all resources from the server, automatically handling pagination
|
|
5514
|
+
*
|
|
5515
|
+
* @param options - Request options
|
|
5516
|
+
* @returns Complete list of all resources
|
|
5517
|
+
*/
|
|
5518
|
+
async listAllResources(options) {
|
|
5519
|
+
if (!this.client) {
|
|
5520
|
+
throw new Error("MCP client is not connected");
|
|
5521
|
+
}
|
|
5522
|
+
if (!this.capabilitiesCache?.resources) {
|
|
5523
|
+
logger.debug("Server does not advertise resources capability, skipping");
|
|
5524
|
+
return { resources: [] };
|
|
5525
|
+
}
|
|
5526
|
+
try {
|
|
5527
|
+
logger.debug("Listing all resources (with auto-pagination)");
|
|
5528
|
+
const allResources = [];
|
|
5529
|
+
let cursor = void 0;
|
|
5530
|
+
do {
|
|
5531
|
+
const result = await this.client.listResources({ cursor }, options);
|
|
5532
|
+
allResources.push(...result.resources || []);
|
|
5533
|
+
cursor = result.nextCursor;
|
|
5534
|
+
} while (cursor);
|
|
5535
|
+
return { resources: allResources };
|
|
5536
|
+
} catch (err) {
|
|
5537
|
+
if (err.code === -32601) {
|
|
5538
|
+
logger.debug("Server advertised resources but method not found");
|
|
5539
|
+
return { resources: [] };
|
|
5540
|
+
}
|
|
5541
|
+
throw err;
|
|
5542
|
+
}
|
|
5543
|
+
}
|
|
5544
|
+
/**
|
|
5545
|
+
* List resource templates from the server
|
|
5546
|
+
*
|
|
5547
|
+
* @param options - Request options
|
|
5548
|
+
* @returns List of available resource templates
|
|
5549
|
+
*/
|
|
5550
|
+
async listResourceTemplates(options) {
|
|
5551
|
+
if (!this.client) {
|
|
5552
|
+
throw new Error("MCP client is not connected");
|
|
5553
|
+
}
|
|
5554
|
+
logger.debug("Listing resource templates");
|
|
5555
|
+
return await this.client.listResourceTemplates(void 0, options);
|
|
5556
|
+
}
|
|
5557
|
+
/** Read a resource by URI. */
|
|
5558
|
+
async readResource(uri, options) {
|
|
5559
|
+
if (!this.client) {
|
|
5560
|
+
throw new Error("MCP client is not connected");
|
|
5561
|
+
}
|
|
5562
|
+
logger.debug(`Reading resource ${uri}`);
|
|
5563
|
+
const res = await this.client.readResource({ uri }, options);
|
|
5564
|
+
return res;
|
|
5565
|
+
}
|
|
5566
|
+
/**
|
|
5567
|
+
* Subscribe to resource updates
|
|
5568
|
+
*
|
|
5569
|
+
* @param uri - URI of the resource to subscribe to
|
|
5570
|
+
* @param options - Request options
|
|
5571
|
+
*/
|
|
5572
|
+
async subscribeToResource(uri, options) {
|
|
5573
|
+
if (!this.client) {
|
|
5574
|
+
throw new Error("MCP client is not connected");
|
|
5575
|
+
}
|
|
5576
|
+
logger.debug(`Subscribing to resource: ${uri}`);
|
|
5577
|
+
return await this.client.subscribeResource({ uri }, options);
|
|
5578
|
+
}
|
|
5579
|
+
/**
|
|
5580
|
+
* Unsubscribe from resource updates
|
|
5581
|
+
*
|
|
5582
|
+
* @param uri - URI of the resource to unsubscribe from
|
|
5583
|
+
* @param options - Request options
|
|
5584
|
+
*/
|
|
5585
|
+
async unsubscribeFromResource(uri, options) {
|
|
5586
|
+
if (!this.client) {
|
|
5587
|
+
throw new Error("MCP client is not connected");
|
|
5588
|
+
}
|
|
5589
|
+
logger.debug(`Unsubscribing from resource: ${uri}`);
|
|
5590
|
+
return await this.client.unsubscribeResource({ uri }, options);
|
|
5591
|
+
}
|
|
5592
|
+
async listPrompts() {
|
|
5593
|
+
if (!this.client) {
|
|
5594
|
+
throw new Error("MCP client is not connected");
|
|
5595
|
+
}
|
|
5596
|
+
if (!this.capabilitiesCache?.prompts) {
|
|
5597
|
+
logger.debug("Server does not advertise prompts capability, skipping");
|
|
5598
|
+
return { prompts: [] };
|
|
5599
|
+
}
|
|
5600
|
+
try {
|
|
5601
|
+
logger.debug("Listing prompts");
|
|
5602
|
+
return await this.client.listPrompts();
|
|
5603
|
+
} catch (err) {
|
|
5604
|
+
if (err.code === -32601) {
|
|
5605
|
+
logger.debug("Server advertised prompts but method not found");
|
|
5606
|
+
return { prompts: [] };
|
|
5607
|
+
}
|
|
5608
|
+
throw err;
|
|
5609
|
+
}
|
|
5610
|
+
}
|
|
5611
|
+
async getPrompt(name, args) {
|
|
5612
|
+
if (!this.client) {
|
|
5613
|
+
throw new Error("MCP client is not connected");
|
|
5614
|
+
}
|
|
5615
|
+
logger.debug(`Getting prompt ${name}`);
|
|
5616
|
+
return await this.client.getPrompt({ name, arguments: args });
|
|
5617
|
+
}
|
|
5618
|
+
/** Send a raw request through the client. */
|
|
5619
|
+
async request(method, params = null, options) {
|
|
5620
|
+
if (!this.client) {
|
|
5621
|
+
throw new Error("MCP client is not connected");
|
|
5622
|
+
}
|
|
5623
|
+
logger.debug(`Sending raw request '${method}' with params`, params);
|
|
5624
|
+
return await this.client.request(
|
|
5625
|
+
{ method, params: params ?? {} },
|
|
5626
|
+
void 0,
|
|
5627
|
+
options
|
|
5628
|
+
);
|
|
5629
|
+
}
|
|
5630
|
+
/**
|
|
5631
|
+
* Helper to tear down the client & connection manager safely.
|
|
5632
|
+
*/
|
|
5633
|
+
async cleanupResources() {
|
|
5634
|
+
const issues = [];
|
|
5635
|
+
if (this.client) {
|
|
5636
|
+
try {
|
|
5637
|
+
if (typeof this.client.close === "function") {
|
|
5638
|
+
await this.client.close();
|
|
5639
|
+
}
|
|
5640
|
+
} catch (e) {
|
|
5641
|
+
const msg = `Error closing client: ${e}`;
|
|
5642
|
+
logger.warn(msg);
|
|
5643
|
+
issues.push(msg);
|
|
5644
|
+
} finally {
|
|
5645
|
+
this.client = null;
|
|
5646
|
+
}
|
|
5647
|
+
}
|
|
5648
|
+
if (this.connectionManager) {
|
|
5649
|
+
try {
|
|
5650
|
+
await this.connectionManager.stop();
|
|
5651
|
+
} catch (e) {
|
|
5652
|
+
const msg = `Error stopping connection manager: ${e}`;
|
|
5653
|
+
logger.warn(msg);
|
|
5654
|
+
issues.push(msg);
|
|
5655
|
+
} finally {
|
|
5656
|
+
this.connectionManager = null;
|
|
5657
|
+
}
|
|
5658
|
+
}
|
|
5659
|
+
this.toolsCache = null;
|
|
5660
|
+
if (issues.length) {
|
|
5661
|
+
logger.warn(`Resource cleanup finished with ${issues.length} issue(s)`);
|
|
5662
|
+
}
|
|
5663
|
+
}
|
|
5664
|
+
}, __name(_c, "BaseConnector"), _c);
|
|
5519
5665
|
const DEFAULT_REQUEST_TIMEOUT_MSEC = 6e4;
|
|
5520
5666
|
class Protocol {
|
|
5521
5667
|
constructor(_options) {
|
|
@@ -5974,11 +6120,11 @@ function requireUri_all() {
|
|
|
5974
6120
|
var slicedToArray = /* @__PURE__ */ (function() {
|
|
5975
6121
|
function sliceIterator(arr, i2) {
|
|
5976
6122
|
var _arr = [];
|
|
5977
|
-
var
|
|
6123
|
+
var _n = true;
|
|
5978
6124
|
var _d2 = false;
|
|
5979
6125
|
var _e3 = void 0;
|
|
5980
6126
|
try {
|
|
5981
|
-
for (var _i2 = arr[Symbol.iterator](), _s; !(
|
|
6127
|
+
for (var _i2 = arr[Symbol.iterator](), _s; !(_n = (_s = _i2.next()).done); _n = true) {
|
|
5982
6128
|
_arr.push(_s.value);
|
|
5983
6129
|
if (i2 && _arr.length === i2) break;
|
|
5984
6130
|
}
|
|
@@ -5987,7 +6133,7 @@ function requireUri_all() {
|
|
|
5987
6133
|
_e3 = err;
|
|
5988
6134
|
} finally {
|
|
5989
6135
|
try {
|
|
5990
|
-
if (!
|
|
6136
|
+
if (!_n && _i2["return"]) _i2["return"]();
|
|
5991
6137
|
} finally {
|
|
5992
6138
|
if (_d2) throw _e3;
|
|
5993
6139
|
}
|
|
@@ -13887,6 +14033,51 @@ var MCPSession = (_d = class {
|
|
|
13887
14033
|
get isConnected() {
|
|
13888
14034
|
return this.connector && this.connector.isClientConnected;
|
|
13889
14035
|
}
|
|
14036
|
+
/**
|
|
14037
|
+
* Register an event handler for session events
|
|
14038
|
+
*
|
|
14039
|
+
* @param event - The event type to listen for
|
|
14040
|
+
* @param handler - The handler function to call when the event occurs
|
|
14041
|
+
*
|
|
14042
|
+
* @example
|
|
14043
|
+
* ```typescript
|
|
14044
|
+
* session.on("notification", async (notification) => {
|
|
14045
|
+
* console.log(`Received: ${notification.method}`, notification.params);
|
|
14046
|
+
*
|
|
14047
|
+
* if (notification.method === "notifications/tools/list_changed") {
|
|
14048
|
+
* // Refresh tools list
|
|
14049
|
+
* }
|
|
14050
|
+
* });
|
|
14051
|
+
* ```
|
|
14052
|
+
*/
|
|
14053
|
+
on(event, handler) {
|
|
14054
|
+
if (event === "notification") {
|
|
14055
|
+
this.connector.onNotification(handler);
|
|
14056
|
+
}
|
|
14057
|
+
}
|
|
14058
|
+
/**
|
|
14059
|
+
* Set roots and notify the server.
|
|
14060
|
+
* Roots represent directories or files that the client has access to.
|
|
14061
|
+
*
|
|
14062
|
+
* @param roots - Array of Root objects with `uri` (must start with "file://") and optional `name`
|
|
14063
|
+
*
|
|
14064
|
+
* @example
|
|
14065
|
+
* ```typescript
|
|
14066
|
+
* await session.setRoots([
|
|
14067
|
+
* { uri: "file:///home/user/project", name: "My Project" },
|
|
14068
|
+
* { uri: "file:///home/user/data" }
|
|
14069
|
+
* ]);
|
|
14070
|
+
* ```
|
|
14071
|
+
*/
|
|
14072
|
+
async setRoots(roots) {
|
|
14073
|
+
return this.connector.setRoots(roots);
|
|
14074
|
+
}
|
|
14075
|
+
/**
|
|
14076
|
+
* Get the current roots.
|
|
14077
|
+
*/
|
|
14078
|
+
getRoots() {
|
|
14079
|
+
return this.connector.getRoots();
|
|
14080
|
+
}
|
|
13890
14081
|
}, __name(_d, "MCPSession"), _d);
|
|
13891
14082
|
var ConnectionManager = (_e2 = class {
|
|
13892
14083
|
_readyPromise;
|
|
@@ -14038,52 +14229,7 @@ var SseConnectionManager = (_f = class extends ConnectionManager {
|
|
|
14038
14229
|
}
|
|
14039
14230
|
}
|
|
14040
14231
|
}, __name(_f, "SseConnectionManager"), _f);
|
|
14041
|
-
var
|
|
14042
|
-
url;
|
|
14043
|
-
opts;
|
|
14044
|
-
_transport = null;
|
|
14045
|
-
/**
|
|
14046
|
-
* Create a Streamable HTTP connection manager.
|
|
14047
|
-
*
|
|
14048
|
-
* @param url The HTTP endpoint URL.
|
|
14049
|
-
* @param opts Optional transport options (auth, headers, etc.).
|
|
14050
|
-
*/
|
|
14051
|
-
constructor(url, opts) {
|
|
14052
|
-
super();
|
|
14053
|
-
this.url = typeof url === "string" ? new URL(url) : url;
|
|
14054
|
-
this.opts = opts;
|
|
14055
|
-
}
|
|
14056
|
-
/**
|
|
14057
|
-
* Spawn a new `StreamableHTTPClientTransport` and return it.
|
|
14058
|
-
* The Client.connect() method will handle starting the transport.
|
|
14059
|
-
*/
|
|
14060
|
-
async establishConnection() {
|
|
14061
|
-
this._transport = new StreamableHTTPClientTransport(this.url, this.opts);
|
|
14062
|
-
logger.debug(`${this.constructor.name} created successfully`);
|
|
14063
|
-
return this._transport;
|
|
14064
|
-
}
|
|
14065
|
-
/**
|
|
14066
|
-
* Close the underlying transport and clean up resources.
|
|
14067
|
-
*/
|
|
14068
|
-
async closeConnection(_connection) {
|
|
14069
|
-
if (this._transport) {
|
|
14070
|
-
try {
|
|
14071
|
-
await this._transport.close();
|
|
14072
|
-
} catch (e) {
|
|
14073
|
-
logger.warn(`Error closing Streamable HTTP transport: ${e}`);
|
|
14074
|
-
} finally {
|
|
14075
|
-
this._transport = null;
|
|
14076
|
-
}
|
|
14077
|
-
}
|
|
14078
|
-
}
|
|
14079
|
-
/**
|
|
14080
|
-
* Get the session ID from the transport if available.
|
|
14081
|
-
*/
|
|
14082
|
-
get sessionId() {
|
|
14083
|
-
return this._transport?.sessionId;
|
|
14084
|
-
}
|
|
14085
|
-
}, __name(_g, "StreamableHttpConnectionManager"), _g);
|
|
14086
|
-
var HttpConnector = (_h = class extends BaseConnector {
|
|
14232
|
+
var HttpConnector = (_g = class extends BaseConnector {
|
|
14087
14233
|
baseUrl;
|
|
14088
14234
|
headers;
|
|
14089
14235
|
timeout;
|
|
@@ -14091,6 +14237,7 @@ var HttpConnector = (_h = class extends BaseConnector {
|
|
|
14091
14237
|
clientInfo;
|
|
14092
14238
|
preferSse;
|
|
14093
14239
|
transportType = null;
|
|
14240
|
+
streamableTransport = null;
|
|
14094
14241
|
constructor(baseUrl, opts = {}) {
|
|
14095
14242
|
super(opts);
|
|
14096
14243
|
this.baseUrl = baseUrl.replace(/\/$/, "");
|
|
@@ -14182,34 +14329,67 @@ var HttpConnector = (_h = class extends BaseConnector {
|
|
|
14182
14329
|
}
|
|
14183
14330
|
async connectWithStreamableHttp(baseUrl) {
|
|
14184
14331
|
try {
|
|
14185
|
-
|
|
14186
|
-
|
|
14187
|
-
|
|
14188
|
-
|
|
14189
|
-
|
|
14190
|
-
|
|
14191
|
-
|
|
14192
|
-
|
|
14193
|
-
|
|
14194
|
-
|
|
14195
|
-
|
|
14196
|
-
|
|
14332
|
+
const streamableTransport = new StreamableHTTPClientTransport(
|
|
14333
|
+
new URL(baseUrl),
|
|
14334
|
+
{
|
|
14335
|
+
authProvider: this.opts.authProvider,
|
|
14336
|
+
// ← Pass OAuth provider to SDK
|
|
14337
|
+
requestInit: {
|
|
14338
|
+
headers: this.headers
|
|
14339
|
+
},
|
|
14340
|
+
// Pass through reconnection options
|
|
14341
|
+
reconnectionOptions: {
|
|
14342
|
+
maxReconnectionDelay: 3e4,
|
|
14343
|
+
initialReconnectionDelay: 1e3,
|
|
14344
|
+
reconnectionDelayGrowFactor: 1.5,
|
|
14345
|
+
maxRetries: 2
|
|
14346
|
+
}
|
|
14347
|
+
// Don't pass sessionId - let the SDK generate it automatically during connect()
|
|
14197
14348
|
}
|
|
14198
|
-
|
|
14199
|
-
let transport =
|
|
14349
|
+
);
|
|
14350
|
+
let transport = streamableTransport;
|
|
14200
14351
|
if (this.opts.wrapTransport) {
|
|
14201
14352
|
const serverId = this.baseUrl;
|
|
14202
|
-
transport = this.opts.wrapTransport(
|
|
14353
|
+
transport = this.opts.wrapTransport(
|
|
14354
|
+
transport,
|
|
14355
|
+
serverId
|
|
14356
|
+
);
|
|
14203
14357
|
}
|
|
14204
|
-
|
|
14358
|
+
const clientOptions = {
|
|
14359
|
+
...this.opts.clientOptions || {},
|
|
14360
|
+
capabilities: {
|
|
14361
|
+
...this.opts.clientOptions?.capabilities || {},
|
|
14362
|
+
roots: { listChanged: true },
|
|
14363
|
+
// Always advertise roots capability
|
|
14364
|
+
// Add sampling capability if callback is provided
|
|
14365
|
+
...this.opts.samplingCallback ? { sampling: {} } : {}
|
|
14366
|
+
}
|
|
14367
|
+
};
|
|
14368
|
+
logger.debug(
|
|
14369
|
+
`Creating Client with capabilities:`,
|
|
14370
|
+
JSON.stringify(clientOptions.capabilities, null, 2)
|
|
14371
|
+
);
|
|
14372
|
+
this.client = new Client(this.clientInfo, clientOptions);
|
|
14373
|
+
this.setupRootsHandler();
|
|
14374
|
+
logger.debug("Roots handler registered before connect");
|
|
14205
14375
|
try {
|
|
14206
|
-
await this.client.connect(transport
|
|
14376
|
+
await this.client.connect(transport, {
|
|
14377
|
+
timeout: Math.min(this.timeout, 3e3)
|
|
14378
|
+
});
|
|
14379
|
+
const sessionId = streamableTransport.sessionId;
|
|
14380
|
+
if (sessionId) {
|
|
14381
|
+
logger.debug(`Session ID obtained: ${sessionId}`);
|
|
14382
|
+
} else {
|
|
14383
|
+
logger.warn(
|
|
14384
|
+
"Session ID not available after connect - this may cause issues with SSE stream"
|
|
14385
|
+
);
|
|
14386
|
+
}
|
|
14207
14387
|
} catch (connectErr) {
|
|
14208
14388
|
if (connectErr instanceof Error) {
|
|
14209
14389
|
const errMsg = connectErr.message || connectErr.toString();
|
|
14210
|
-
if (errMsg.includes("Missing session ID") || errMsg.includes("Bad Request: Missing session ID")) {
|
|
14390
|
+
if (errMsg.includes("Missing session ID") || errMsg.includes("Bad Request: Missing session ID") || errMsg.includes("Mcp-Session-Id header is required")) {
|
|
14211
14391
|
const wrappedError = new Error(
|
|
14212
|
-
`
|
|
14392
|
+
`Session ID error: ${errMsg}. The SDK should automatically extract session ID from initialize response.`
|
|
14213
14393
|
);
|
|
14214
14394
|
wrappedError.cause = connectErr;
|
|
14215
14395
|
throw wrappedError;
|
|
@@ -14217,8 +14397,24 @@ var HttpConnector = (_h = class extends BaseConnector {
|
|
|
14217
14397
|
}
|
|
14218
14398
|
throw connectErr;
|
|
14219
14399
|
}
|
|
14400
|
+
this.streamableTransport = streamableTransport;
|
|
14401
|
+
this.connectionManager = {
|
|
14402
|
+
stop: /* @__PURE__ */ __name(async () => {
|
|
14403
|
+
if (this.streamableTransport) {
|
|
14404
|
+
try {
|
|
14405
|
+
await this.streamableTransport.close();
|
|
14406
|
+
} catch (e) {
|
|
14407
|
+
logger.warn(`Error closing Streamable HTTP transport: ${e}`);
|
|
14408
|
+
} finally {
|
|
14409
|
+
this.streamableTransport = null;
|
|
14410
|
+
}
|
|
14411
|
+
}
|
|
14412
|
+
}, "stop")
|
|
14413
|
+
};
|
|
14220
14414
|
this.connected = true;
|
|
14221
14415
|
this.transportType = "streamable-http";
|
|
14416
|
+
this.setupNotificationHandler();
|
|
14417
|
+
this.setupSamplingHandler();
|
|
14222
14418
|
logger.debug(
|
|
14223
14419
|
`Successfully connected to MCP implementation via streamable HTTP: ${baseUrl}`
|
|
14224
14420
|
);
|
|
@@ -14239,10 +14435,28 @@ var HttpConnector = (_h = class extends BaseConnector {
|
|
|
14239
14435
|
const serverId = this.baseUrl;
|
|
14240
14436
|
transport = this.opts.wrapTransport(transport, serverId);
|
|
14241
14437
|
}
|
|
14242
|
-
|
|
14438
|
+
const clientOptions = {
|
|
14439
|
+
...this.opts.clientOptions || {},
|
|
14440
|
+
capabilities: {
|
|
14441
|
+
...this.opts.clientOptions?.capabilities || {},
|
|
14442
|
+
roots: { listChanged: true },
|
|
14443
|
+
// Always advertise roots capability
|
|
14444
|
+
// Add sampling capability if callback is provided
|
|
14445
|
+
...this.opts.samplingCallback ? { sampling: {} } : {}
|
|
14446
|
+
}
|
|
14447
|
+
};
|
|
14448
|
+
logger.debug(
|
|
14449
|
+
`Creating Client with capabilities (SSE):`,
|
|
14450
|
+
JSON.stringify(clientOptions.capabilities, null, 2)
|
|
14451
|
+
);
|
|
14452
|
+
this.client = new Client(this.clientInfo, clientOptions);
|
|
14453
|
+
this.setupRootsHandler();
|
|
14454
|
+
logger.debug("Roots handler registered before connect (SSE)");
|
|
14243
14455
|
await this.client.connect(transport);
|
|
14244
14456
|
this.connected = true;
|
|
14245
14457
|
this.transportType = "sse";
|
|
14458
|
+
this.setupNotificationHandler();
|
|
14459
|
+
this.setupSamplingHandler();
|
|
14246
14460
|
logger.debug(
|
|
14247
14461
|
`Successfully connected to MCP implementation via HTTP/SSE: ${baseUrl}`
|
|
14248
14462
|
);
|
|
@@ -14264,8 +14478,8 @@ var HttpConnector = (_h = class extends BaseConnector {
|
|
|
14264
14478
|
getTransportType() {
|
|
14265
14479
|
return this.transportType;
|
|
14266
14480
|
}
|
|
14267
|
-
}, __name(
|
|
14268
|
-
var WebSocketConnectionManager = (
|
|
14481
|
+
}, __name(_g, "HttpConnector"), _g);
|
|
14482
|
+
var WebSocketConnectionManager = (_h = class extends ConnectionManager {
|
|
14269
14483
|
url;
|
|
14270
14484
|
headers;
|
|
14271
14485
|
_ws = null;
|
|
@@ -14326,8 +14540,8 @@ var WebSocketConnectionManager = (_i = class extends ConnectionManager {
|
|
|
14326
14540
|
}
|
|
14327
14541
|
});
|
|
14328
14542
|
}
|
|
14329
|
-
}, __name(
|
|
14330
|
-
var WebSocketConnector = (
|
|
14543
|
+
}, __name(_h, "WebSocketConnectionManager"), _h);
|
|
14544
|
+
var WebSocketConnector = (_i = class extends BaseConnector {
|
|
14331
14545
|
url;
|
|
14332
14546
|
headers;
|
|
14333
14547
|
connectionManager = null;
|
|
@@ -14402,6 +14616,9 @@ var WebSocketConnector = (_j = class extends BaseConnector {
|
|
|
14402
14616
|
this.pending.delete(id2);
|
|
14403
14617
|
if ("result" in data2) resolve(data2.result);
|
|
14404
14618
|
else if ("error" in data2) reject(data2.error);
|
|
14619
|
+
} else if (data2.method && !data2.id) {
|
|
14620
|
+
logger.debug("Received notification", data2.method, data2.params);
|
|
14621
|
+
this.handleNotification(data2);
|
|
14405
14622
|
} else {
|
|
14406
14623
|
logger.debug("Received unsolicited message", data2);
|
|
14407
14624
|
}
|
|
@@ -14432,6 +14649,47 @@ var WebSocketConnector = (_j = class extends BaseConnector {
|
|
|
14432
14649
|
for (const { reject } of this.pending.values()) reject(err);
|
|
14433
14650
|
this.pending.clear();
|
|
14434
14651
|
}
|
|
14652
|
+
async handleNotification(data2) {
|
|
14653
|
+
switch (data2.method) {
|
|
14654
|
+
case "notifications/tools/list_changed":
|
|
14655
|
+
await this.refreshToolsCache();
|
|
14656
|
+
break;
|
|
14657
|
+
case "notifications/resources/list_changed":
|
|
14658
|
+
await this.onResourcesListChanged();
|
|
14659
|
+
break;
|
|
14660
|
+
case "notifications/prompts/list_changed":
|
|
14661
|
+
await this.onPromptsListChanged();
|
|
14662
|
+
break;
|
|
14663
|
+
}
|
|
14664
|
+
for (const handler of this.notificationHandlers) {
|
|
14665
|
+
try {
|
|
14666
|
+
await handler({
|
|
14667
|
+
method: data2.method,
|
|
14668
|
+
params: data2.params
|
|
14669
|
+
});
|
|
14670
|
+
} catch (err) {
|
|
14671
|
+
logger.error("Error in notification handler:", err);
|
|
14672
|
+
}
|
|
14673
|
+
}
|
|
14674
|
+
}
|
|
14675
|
+
/**
|
|
14676
|
+
* Auto-refresh tools cache when server sends tools/list_changed notification
|
|
14677
|
+
* Override to use WebSocket-specific listTools method
|
|
14678
|
+
*/
|
|
14679
|
+
async refreshToolsCache() {
|
|
14680
|
+
try {
|
|
14681
|
+
logger.debug(
|
|
14682
|
+
"[Auto] Refreshing tools cache due to list_changed notification"
|
|
14683
|
+
);
|
|
14684
|
+
const tools = await this.listTools();
|
|
14685
|
+
this.toolsCache = tools.map((t) => t);
|
|
14686
|
+
logger.debug(
|
|
14687
|
+
`[Auto] Refreshed tools cache: ${this.toolsCache.length} tools`
|
|
14688
|
+
);
|
|
14689
|
+
} catch (err) {
|
|
14690
|
+
logger.warn("[Auto] Failed to refresh tools cache:", err);
|
|
14691
|
+
}
|
|
14692
|
+
}
|
|
14435
14693
|
async initialize() {
|
|
14436
14694
|
logger.debug("Initializing MCP session over WebSocket");
|
|
14437
14695
|
const result = await this.sendRequest("initialize");
|
|
@@ -14480,8 +14738,8 @@ var WebSocketConnector = (_j = class extends BaseConnector {
|
|
|
14480
14738
|
url: this.url
|
|
14481
14739
|
};
|
|
14482
14740
|
}
|
|
14483
|
-
}, __name(
|
|
14484
|
-
var BrowserOAuthClientProvider = (
|
|
14741
|
+
}, __name(_i, "WebSocketConnector"), _i);
|
|
14742
|
+
var BrowserOAuthClientProvider = (_j = class {
|
|
14485
14743
|
serverUrl;
|
|
14486
14744
|
storageKeyPrefix;
|
|
14487
14745
|
serverUrlHash;
|
|
@@ -14689,7 +14947,7 @@ var BrowserOAuthClientProvider = (_k = class {
|
|
|
14689
14947
|
getKey(keySuffix) {
|
|
14690
14948
|
return `${this.storageKeyPrefix}_${this.serverUrlHash}_${keySuffix}`;
|
|
14691
14949
|
}
|
|
14692
|
-
}, __name(
|
|
14950
|
+
}, __name(_j, "BrowserOAuthClientProvider"), _j);
|
|
14693
14951
|
async function onMcpAuthorization() {
|
|
14694
14952
|
const queryParams = new URLSearchParams(window.location.search);
|
|
14695
14953
|
const code = queryParams.get("code");
|
|
@@ -14816,7 +15074,7 @@ async function onMcpAuthorization() {
|
|
|
14816
15074
|
}
|
|
14817
15075
|
}
|
|
14818
15076
|
__name(onMcpAuthorization, "onMcpAuthorization");
|
|
14819
|
-
var BaseMCPClient = (
|
|
15077
|
+
var BaseMCPClient = (_k = class {
|
|
14820
15078
|
config = {};
|
|
14821
15079
|
sessions = {};
|
|
14822
15080
|
activeSessions = [];
|
|
@@ -14927,20 +15185,29 @@ var BaseMCPClient = (_l = class {
|
|
|
14927
15185
|
logger.debug("All sessions closed successfully");
|
|
14928
15186
|
}
|
|
14929
15187
|
}
|
|
14930
|
-
}, __name(
|
|
14931
|
-
var BrowserMCPClient = (
|
|
15188
|
+
}, __name(_k, "BaseMCPClient"), _k);
|
|
15189
|
+
var BrowserMCPClient = (_l = class extends BaseMCPClient {
|
|
14932
15190
|
constructor(config) {
|
|
14933
15191
|
super(config);
|
|
14934
15192
|
}
|
|
14935
15193
|
static fromDict(cfg) {
|
|
14936
|
-
return new
|
|
15194
|
+
return new _l(cfg);
|
|
14937
15195
|
}
|
|
14938
15196
|
/**
|
|
14939
15197
|
* Create a connector from server configuration (Browser version)
|
|
14940
15198
|
* Supports HTTP and WebSocket connectors only
|
|
14941
15199
|
*/
|
|
14942
15200
|
createConnectorFromConfig(serverConfig) {
|
|
14943
|
-
const {
|
|
15201
|
+
const {
|
|
15202
|
+
url,
|
|
15203
|
+
transport,
|
|
15204
|
+
headers,
|
|
15205
|
+
authToken,
|
|
15206
|
+
authProvider,
|
|
15207
|
+
wrapTransport,
|
|
15208
|
+
clientOptions,
|
|
15209
|
+
samplingCallback
|
|
15210
|
+
} = serverConfig;
|
|
14944
15211
|
if (!url) {
|
|
14945
15212
|
throw new Error("Server URL is required");
|
|
14946
15213
|
}
|
|
@@ -14949,9 +15216,23 @@ var BrowserMCPClient = (_m = class extends BaseMCPClient {
|
|
|
14949
15216
|
authToken,
|
|
14950
15217
|
authProvider,
|
|
14951
15218
|
// ← Pass OAuth provider to connector
|
|
14952
|
-
wrapTransport
|
|
15219
|
+
wrapTransport,
|
|
14953
15220
|
// ← Pass transport wrapper if provided
|
|
15221
|
+
clientOptions,
|
|
15222
|
+
// ← Pass client options (capabilities, etc.) to connector
|
|
15223
|
+
samplingCallback
|
|
15224
|
+
// ← Pass sampling callback to connector
|
|
14954
15225
|
};
|
|
15226
|
+
if (clientOptions) {
|
|
15227
|
+
console.log(
|
|
15228
|
+
"[BrowserMCPClient] Passing clientOptions to connector:",
|
|
15229
|
+
JSON.stringify(clientOptions, null, 2)
|
|
15230
|
+
);
|
|
15231
|
+
} else {
|
|
15232
|
+
console.warn(
|
|
15233
|
+
"[BrowserMCPClient] No clientOptions provided to connector!"
|
|
15234
|
+
);
|
|
15235
|
+
}
|
|
14955
15236
|
if (transport === "websocket" || url.startsWith("ws://") || url.startsWith("wss://")) {
|
|
14956
15237
|
return new WebSocketConnector(url, connectorOptions);
|
|
14957
15238
|
} else if (transport === "http" || url.startsWith("http://") || url.startsWith("https://")) {
|
|
@@ -14960,7 +15241,7 @@ var BrowserMCPClient = (_m = class extends BaseMCPClient {
|
|
|
14960
15241
|
return new HttpConnector(url, connectorOptions);
|
|
14961
15242
|
}
|
|
14962
15243
|
}
|
|
14963
|
-
}, __name(
|
|
15244
|
+
}, __name(_l, "BrowserMCPClient"), _l);
|
|
14964
15245
|
var react = { exports: {} };
|
|
14965
15246
|
var react_production = {};
|
|
14966
15247
|
var hasRequiredReact_production;
|
|
@@ -17675,7 +17956,9 @@ function useMcp(options) {
|
|
|
17675
17956
|
// 30 seconds default for connection timeout
|
|
17676
17957
|
sseReadTimeout = 3e5,
|
|
17677
17958
|
// 5 minutes default for SSE read timeout
|
|
17678
|
-
wrapTransport
|
|
17959
|
+
wrapTransport,
|
|
17960
|
+
onNotification,
|
|
17961
|
+
samplingCallback
|
|
17679
17962
|
} = options;
|
|
17680
17963
|
const [state, setState] = reactExports.useState("discovering");
|
|
17681
17964
|
const [tools, setTools] = reactExports.useState([]);
|
|
@@ -17828,6 +18111,10 @@ function useMcp(options) {
|
|
|
17828
18111
|
...serverConfig,
|
|
17829
18112
|
authProvider: authProviderRef.current,
|
|
17830
18113
|
// ← SDK handles OAuth automatically!
|
|
18114
|
+
clientOptions: clientConfig,
|
|
18115
|
+
// ← Pass client config to connector
|
|
18116
|
+
samplingCallback,
|
|
18117
|
+
// ← Pass sampling callback to connector
|
|
17831
18118
|
wrapTransport: wrapTransport ? (transport) => {
|
|
17832
18119
|
console.log(
|
|
17833
18120
|
"[useMcp] Applying transport wrapper for server:",
|
|
@@ -17838,7 +18125,13 @@ function useMcp(options) {
|
|
|
17838
18125
|
return wrapTransport(transport, url);
|
|
17839
18126
|
} : void 0
|
|
17840
18127
|
});
|
|
17841
|
-
const session = await clientRef.current.createSession(
|
|
18128
|
+
const session = await clientRef.current.createSession(
|
|
18129
|
+
serverName,
|
|
18130
|
+
false
|
|
18131
|
+
);
|
|
18132
|
+
if (onNotification) {
|
|
18133
|
+
session.on("notification", onNotification);
|
|
18134
|
+
}
|
|
17842
18135
|
await session.initialize();
|
|
17843
18136
|
addLog("info", "✅ Successfully connected to MCP server");
|
|
17844
18137
|
addLog("info", "Server info:", session.connector.serverInfo);
|
|
@@ -18249,7 +18542,7 @@ function useMcp(options) {
|
|
|
18249
18542
|
};
|
|
18250
18543
|
}
|
|
18251
18544
|
__name(useMcp, "useMcp");
|
|
18252
|
-
var ErrorBoundary = (
|
|
18545
|
+
var ErrorBoundary = (_m = class extends re$1.Component {
|
|
18253
18546
|
constructor(props2) {
|
|
18254
18547
|
super(props2);
|
|
18255
18548
|
this.state = { hasError: false, error: null };
|
|
@@ -18266,7 +18559,7 @@ var ErrorBoundary = (_n = class extends re$1.Component {
|
|
|
18266
18559
|
}
|
|
18267
18560
|
return this.props.children;
|
|
18268
18561
|
}
|
|
18269
|
-
}, __name(
|
|
18562
|
+
}, __name(_m, "ErrorBoundary"), _m);
|
|
18270
18563
|
var SET_GLOBALS_EVENT_TYPE = "openai:set_globals";
|
|
18271
18564
|
function useOpenAiGlobal(key) {
|
|
18272
18565
|
return reactExports.useSyncExternalStore(
|
|
@@ -40376,7 +40669,7 @@ class MCPToolSavedEvent {
|
|
|
40376
40669
|
function getPackageVersion() {
|
|
40377
40670
|
try {
|
|
40378
40671
|
if (true) {
|
|
40379
|
-
return "0.7.0";
|
|
40672
|
+
return "0.7.1-canary.0";
|
|
40380
40673
|
}
|
|
40381
40674
|
return "0.0.0";
|
|
40382
40675
|
} catch {
|
|
@@ -40667,6 +40960,55 @@ function McpConnectionWrapper({
|
|
|
40667
40960
|
return wrapTransportRef.current(transport, actualServerId);
|
|
40668
40961
|
};
|
|
40669
40962
|
}, [wrapTransportReady, url]);
|
|
40963
|
+
const NOTIFICATIONS_STORAGE_KEY = `mcp-inspector-notifications-${url}`;
|
|
40964
|
+
const MAX_NOTIFICATIONS = 500;
|
|
40965
|
+
const [notifications, setNotifications] = reactExports.useState([]);
|
|
40966
|
+
reactExports.useEffect(() => {
|
|
40967
|
+
try {
|
|
40968
|
+
const saved = localStorage.getItem(NOTIFICATIONS_STORAGE_KEY);
|
|
40969
|
+
if (saved) {
|
|
40970
|
+
const parsed = JSON.parse(saved);
|
|
40971
|
+
if (Array.isArray(parsed)) {
|
|
40972
|
+
setNotifications(parsed);
|
|
40973
|
+
}
|
|
40974
|
+
}
|
|
40975
|
+
} catch (e) {
|
|
40976
|
+
console.error("Failed to load notifications from localStorage:", e);
|
|
40977
|
+
}
|
|
40978
|
+
}, [NOTIFICATIONS_STORAGE_KEY]);
|
|
40979
|
+
reactExports.useEffect(() => {
|
|
40980
|
+
try {
|
|
40981
|
+
localStorage.setItem(
|
|
40982
|
+
NOTIFICATIONS_STORAGE_KEY,
|
|
40983
|
+
JSON.stringify(notifications)
|
|
40984
|
+
);
|
|
40985
|
+
} catch (e) {
|
|
40986
|
+
console.error("Failed to save notifications to localStorage:", e);
|
|
40987
|
+
}
|
|
40988
|
+
}, [notifications, NOTIFICATIONS_STORAGE_KEY]);
|
|
40989
|
+
const markNotificationRead = reactExports.useCallback((id2) => {
|
|
40990
|
+
setNotifications(
|
|
40991
|
+
(prev) => prev.map((n2) => n2.id === id2 ? { ...n2, read: true } : n2)
|
|
40992
|
+
);
|
|
40993
|
+
}, []);
|
|
40994
|
+
const markAllNotificationsRead = reactExports.useCallback(() => {
|
|
40995
|
+
setNotifications((prev) => prev.map((n2) => ({ ...n2, read: true })));
|
|
40996
|
+
}, []);
|
|
40997
|
+
const clearNotifications = reactExports.useCallback(() => {
|
|
40998
|
+
setNotifications([]);
|
|
40999
|
+
}, []);
|
|
41000
|
+
const onNotificationReceived = reactExports.useCallback(
|
|
41001
|
+
(notification) => {
|
|
41002
|
+
setNotifications((prev) => {
|
|
41003
|
+
const updated = [notification, ...prev];
|
|
41004
|
+
if (updated.length > MAX_NOTIFICATIONS) {
|
|
41005
|
+
return updated.slice(0, MAX_NOTIFICATIONS);
|
|
41006
|
+
}
|
|
41007
|
+
return updated;
|
|
41008
|
+
});
|
|
41009
|
+
},
|
|
41010
|
+
[]
|
|
41011
|
+
);
|
|
40670
41012
|
const mcpHook = useMcp({
|
|
40671
41013
|
url: finalUrl,
|
|
40672
41014
|
callbackUrl,
|
|
@@ -40675,7 +41017,16 @@ function McpConnectionWrapper({
|
|
|
40675
41017
|
// Default to 'http' for Streamable HTTP
|
|
40676
41018
|
enabled: wrapTransportReady,
|
|
40677
41019
|
// Only connect when wrapper is ready
|
|
40678
|
-
wrapTransport: wrapTransportFn
|
|
41020
|
+
wrapTransport: wrapTransportFn,
|
|
41021
|
+
onNotification: (notification) => {
|
|
41022
|
+
onNotificationReceived({
|
|
41023
|
+
id: globalThis.crypto.randomUUID(),
|
|
41024
|
+
method: notification.method,
|
|
41025
|
+
params: notification.params,
|
|
41026
|
+
timestamp: Date.now(),
|
|
41027
|
+
read: false
|
|
41028
|
+
});
|
|
41029
|
+
}
|
|
40679
41030
|
});
|
|
40680
41031
|
const onUpdateRef = reactExports.useRef(onUpdate);
|
|
40681
41032
|
const prevConnectionRef = reactExports.useRef(null);
|
|
@@ -40691,6 +41042,7 @@ function McpConnectionWrapper({
|
|
|
40691
41042
|
mcpHook.serverInfo
|
|
40692
41043
|
);
|
|
40693
41044
|
}
|
|
41045
|
+
const unreadCount = notifications.filter((n2) => !n2.read).length;
|
|
40694
41046
|
const connection = {
|
|
40695
41047
|
id: url,
|
|
40696
41048
|
url,
|
|
@@ -40707,6 +41059,11 @@ function McpConnectionWrapper({
|
|
|
40707
41059
|
proxyConfig,
|
|
40708
41060
|
serverInfo: mcpHook.serverInfo,
|
|
40709
41061
|
capabilities: mcpHook.capabilities,
|
|
41062
|
+
notifications,
|
|
41063
|
+
unreadNotificationCount: unreadCount,
|
|
41064
|
+
markNotificationRead,
|
|
41065
|
+
markAllNotificationsRead,
|
|
41066
|
+
clearNotifications,
|
|
40710
41067
|
callTool: mcpHook.callTool,
|
|
40711
41068
|
readResource: mcpHook.readResource,
|
|
40712
41069
|
listPrompts: mcpHook.listPrompts,
|
|
@@ -40717,12 +41074,13 @@ function McpConnectionWrapper({
|
|
|
40717
41074
|
client: mcpHook.client
|
|
40718
41075
|
};
|
|
40719
41076
|
const prev = prevConnectionRef.current;
|
|
40720
|
-
if (!prev || prev.state !== connection.state || prev.error !== connection.error || prev.authUrl !== connection.authUrl || prev.name !== connection.name || prev.tools.length !== connection.tools.length || prev.resources.length !== connection.resources.length || prev.prompts.length !== connection.prompts.length || prev.serverInfo !== connection.serverInfo || prev.capabilities !== connection.capabilities || !prev.client) {
|
|
41077
|
+
if (!prev || prev.state !== connection.state || prev.error !== connection.error || prev.authUrl !== connection.authUrl || prev.name !== connection.name || prev.tools.length !== connection.tools.length || prev.resources.length !== connection.resources.length || prev.prompts.length !== connection.prompts.length || prev.serverInfo !== connection.serverInfo || prev.capabilities !== connection.capabilities || prev.notifications.length !== connection.notifications.length || prev.unreadNotificationCount !== connection.unreadNotificationCount || !prev.client) {
|
|
40721
41078
|
prevConnectionRef.current = connection;
|
|
40722
41079
|
onUpdateRef.current(connection);
|
|
40723
41080
|
}
|
|
40724
41081
|
});
|
|
40725
41082
|
} else {
|
|
41083
|
+
const unreadCount = notifications.filter((n2) => !n2.read).length;
|
|
40726
41084
|
const connection = {
|
|
40727
41085
|
id: url,
|
|
40728
41086
|
url,
|
|
@@ -40739,6 +41097,11 @@ function McpConnectionWrapper({
|
|
|
40739
41097
|
proxyConfig,
|
|
40740
41098
|
serverInfo: mcpHook.serverInfo,
|
|
40741
41099
|
capabilities: mcpHook.capabilities,
|
|
41100
|
+
notifications,
|
|
41101
|
+
unreadNotificationCount: unreadCount,
|
|
41102
|
+
markNotificationRead,
|
|
41103
|
+
markAllNotificationsRead,
|
|
41104
|
+
clearNotifications,
|
|
40742
41105
|
callTool: mcpHook.callTool,
|
|
40743
41106
|
readResource: mcpHook.readResource,
|
|
40744
41107
|
listPrompts: mcpHook.listPrompts,
|
|
@@ -40749,7 +41112,7 @@ function McpConnectionWrapper({
|
|
|
40749
41112
|
client: mcpHook.client
|
|
40750
41113
|
};
|
|
40751
41114
|
const prev = prevConnectionRef.current;
|
|
40752
|
-
if (!prev || prev.state !== connection.state || prev.error !== connection.error || prev.authUrl !== connection.authUrl || prev.name !== connection.name || prev.tools.length !== connection.tools.length || prev.resources.length !== connection.resources.length || prev.prompts.length !== connection.prompts.length || prev.serverInfo !== connection.serverInfo || prev.capabilities !== connection.capabilities || !prev.client) {
|
|
41115
|
+
if (!prev || prev.state !== connection.state || prev.error !== connection.error || prev.authUrl !== connection.authUrl || prev.name !== connection.name || prev.tools.length !== connection.tools.length || prev.resources.length !== connection.resources.length || prev.prompts.length !== connection.prompts.length || prev.serverInfo !== connection.serverInfo || prev.capabilities !== connection.capabilities || prev.notifications.length !== connection.notifications.length || prev.unreadNotificationCount !== connection.unreadNotificationCount || !prev.client) {
|
|
40753
41116
|
prevConnectionRef.current = connection;
|
|
40754
41117
|
onUpdateRef.current(connection);
|
|
40755
41118
|
}
|
|
@@ -40770,6 +41133,10 @@ function McpConnectionWrapper({
|
|
|
40770
41133
|
mcpHook.serverInfo,
|
|
40771
41134
|
mcpHook.capabilities,
|
|
40772
41135
|
mcpHook.client,
|
|
41136
|
+
notifications,
|
|
41137
|
+
markNotificationRead,
|
|
41138
|
+
markAllNotificationsRead,
|
|
41139
|
+
clearNotifications,
|
|
40773
41140
|
// Stable functions don't strictly need to be here but good practice
|
|
40774
41141
|
mcpHook.callTool,
|
|
40775
41142
|
mcpHook.readResource,
|
|
@@ -40807,6 +41174,14 @@ function McpProvider({ children }) {
|
|
|
40807
41174
|
customHeaders: config.proxyConfig?.customHeaders,
|
|
40808
41175
|
transportType: config.transportType,
|
|
40809
41176
|
proxyConfig: config.proxyConfig,
|
|
41177
|
+
notifications: [],
|
|
41178
|
+
unreadNotificationCount: 0,
|
|
41179
|
+
markNotificationRead: () => {
|
|
41180
|
+
},
|
|
41181
|
+
markAllNotificationsRead: () => {
|
|
41182
|
+
},
|
|
41183
|
+
clearNotifications: () => {
|
|
41184
|
+
},
|
|
40810
41185
|
callTool: async () => {
|
|
40811
41186
|
},
|
|
40812
41187
|
readResource: async () => {
|
|
@@ -40877,6 +41252,14 @@ function McpProvider({ children }) {
|
|
|
40877
41252
|
customHeaders: proxyConfig?.customHeaders,
|
|
40878
41253
|
transportType,
|
|
40879
41254
|
proxyConfig,
|
|
41255
|
+
notifications: [],
|
|
41256
|
+
unreadNotificationCount: 0,
|
|
41257
|
+
markNotificationRead: () => {
|
|
41258
|
+
},
|
|
41259
|
+
markAllNotificationsRead: () => {
|
|
41260
|
+
},
|
|
41261
|
+
clearNotifications: () => {
|
|
41262
|
+
},
|
|
40880
41263
|
callTool: async () => {
|
|
40881
41264
|
},
|
|
40882
41265
|
readResource: async () => {
|
|
@@ -40947,7 +41330,7 @@ function McpProvider({ children }) {
|
|
|
40947
41330
|
const index2 = prev.findIndex((c2) => c2.id === updatedConnection.id);
|
|
40948
41331
|
if (index2 === -1) return prev;
|
|
40949
41332
|
const current = prev[index2];
|
|
40950
|
-
if (current.state === updatedConnection.state && current.tools === updatedConnection.tools && current.resources === updatedConnection.resources && current.prompts === updatedConnection.prompts && current.error === updatedConnection.error && current.serverInfo === updatedConnection.serverInfo && current.client === updatedConnection.client) {
|
|
41333
|
+
if (current.state === updatedConnection.state && current.tools === updatedConnection.tools && current.resources === updatedConnection.resources && current.prompts === updatedConnection.prompts && current.error === updatedConnection.error && current.serverInfo === updatedConnection.serverInfo && current.client === updatedConnection.client && current.notifications === updatedConnection.notifications && current.unreadNotificationCount === updatedConnection.unreadNotificationCount) {
|
|
40951
41334
|
return prev;
|
|
40952
41335
|
}
|
|
40953
41336
|
const newConnections = [...prev];
|
|
@@ -41075,23 +41458,34 @@ const createLucideIcon = (iconName, iconNode) => {
|
|
|
41075
41458
|
Component.displayName = toPascalCase(iconName);
|
|
41076
41459
|
return Component;
|
|
41077
41460
|
};
|
|
41078
|
-
const __iconNode$
|
|
41461
|
+
const __iconNode$V = [
|
|
41079
41462
|
["path", { d: "M12 17V3", key: "1cwfxf" }],
|
|
41080
41463
|
["path", { d: "m6 11 6 6 6-6", key: "12ii2o" }],
|
|
41081
41464
|
["path", { d: "M19 21H5", key: "150jfl" }]
|
|
41082
41465
|
];
|
|
41083
|
-
const ArrowDownToLine = createLucideIcon("arrow-down-to-line", __iconNode$
|
|
41084
|
-
const __iconNode$
|
|
41466
|
+
const ArrowDownToLine = createLucideIcon("arrow-down-to-line", __iconNode$V);
|
|
41467
|
+
const __iconNode$U = [
|
|
41085
41468
|
["path", { d: "m18 9-6-6-6 6", key: "kcunyi" }],
|
|
41086
41469
|
["path", { d: "M12 3v14", key: "7cf3v8" }],
|
|
41087
41470
|
["path", { d: "M5 21h14", key: "11awu3" }]
|
|
41088
41471
|
];
|
|
41089
|
-
const ArrowUpFromLine = createLucideIcon("arrow-up-from-line", __iconNode$
|
|
41090
|
-
const __iconNode$
|
|
41472
|
+
const ArrowUpFromLine = createLucideIcon("arrow-up-from-line", __iconNode$U);
|
|
41473
|
+
const __iconNode$T = [
|
|
41091
41474
|
["path", { d: "m5 12 7-7 7 7", key: "hav0vg" }],
|
|
41092
41475
|
["path", { d: "M12 19V5", key: "x0mq9r" }]
|
|
41093
41476
|
];
|
|
41094
|
-
const ArrowUp = createLucideIcon("arrow-up", __iconNode$
|
|
41477
|
+
const ArrowUp = createLucideIcon("arrow-up", __iconNode$T);
|
|
41478
|
+
const __iconNode$S = [
|
|
41479
|
+
["path", { d: "M10.268 21a2 2 0 0 0 3.464 0", key: "vwvbt9" }],
|
|
41480
|
+
[
|
|
41481
|
+
"path",
|
|
41482
|
+
{
|
|
41483
|
+
d: "M3.262 15.326A1 1 0 0 0 4 17h16a1 1 0 0 0 .74-1.673C19.41 13.956 18 12.499 18 8A6 6 0 0 0 6 8c0 4.499-1.411 5.956-2.738 7.326",
|
|
41484
|
+
key: "11g9vi"
|
|
41485
|
+
}
|
|
41486
|
+
]
|
|
41487
|
+
];
|
|
41488
|
+
const Bell = createLucideIcon("bell", __iconNode$S);
|
|
41095
41489
|
const __iconNode$R = [
|
|
41096
41490
|
["path", { d: "m11 10 3 3", key: "fzmg1i" }],
|
|
41097
41491
|
[
|
|
@@ -82563,6 +82957,12 @@ function OpenAIComponentRendererBase({
|
|
|
82563
82957
|
if (iframeRef.current?.contentWindow) {
|
|
82564
82958
|
try {
|
|
82565
82959
|
const iframeWindow = iframeRef.current.contentWindow;
|
|
82960
|
+
const iframeDocument = iframeRef.current.contentDocument;
|
|
82961
|
+
if (updates.theme !== void 0 && iframeDocument) {
|
|
82962
|
+
const htmlElement = iframeDocument.documentElement;
|
|
82963
|
+
htmlElement.setAttribute("data-theme", updates.theme);
|
|
82964
|
+
htmlElement.style.colorScheme = updates.theme;
|
|
82965
|
+
}
|
|
82566
82966
|
if (iframeWindow.openai) {
|
|
82567
82967
|
if (updates.displayMode !== void 0) {
|
|
82568
82968
|
iframeWindow.openai.displayMode = updates.displayMode;
|
|
@@ -82869,6 +83269,14 @@ function OpenAIComponentRendererBase({
|
|
|
82869
83269
|
updateIframeGlobals,
|
|
82870
83270
|
useDevMode
|
|
82871
83271
|
]);
|
|
83272
|
+
reactExports.useEffect(() => {
|
|
83273
|
+
if (!iframeRef.current?.contentDocument || !isReady) return;
|
|
83274
|
+
const iframeDoc = iframeRef.current.contentDocument;
|
|
83275
|
+
const htmlElement = iframeDoc.documentElement;
|
|
83276
|
+
htmlElement.setAttribute("data-theme", resolvedTheme);
|
|
83277
|
+
htmlElement.style.colorScheme = resolvedTheme;
|
|
83278
|
+
updateIframeGlobals({ theme: resolvedTheme });
|
|
83279
|
+
}, [resolvedTheme, isReady, updateIframeGlobals]);
|
|
82872
83280
|
reactExports.useEffect(() => {
|
|
82873
83281
|
if (!widgetUrl) return;
|
|
82874
83282
|
const measure = () => {
|
|
@@ -86425,7 +86833,7 @@ function useChatMessagesClientSide({
|
|
|
86425
86833
|
let llm;
|
|
86426
86834
|
if (llmConfig.provider === "openai") {
|
|
86427
86835
|
const { ChatOpenAI } = await __vitePreload(async () => {
|
|
86428
|
-
const { ChatOpenAI: ChatOpenAI2 } = await import("./index-
|
|
86836
|
+
const { ChatOpenAI: ChatOpenAI2 } = await import("./index-DIp48bR6.js");
|
|
86429
86837
|
return { ChatOpenAI: ChatOpenAI2 };
|
|
86430
86838
|
}, true ? __vite__mapDeps([4,5,6,2,7]) : void 0);
|
|
86431
86839
|
llm = new ChatOpenAI({
|
|
@@ -86434,7 +86842,7 @@ function useChatMessagesClientSide({
|
|
|
86434
86842
|
});
|
|
86435
86843
|
} else if (llmConfig.provider === "anthropic") {
|
|
86436
86844
|
const { ChatAnthropic } = await __vitePreload(async () => {
|
|
86437
|
-
const { ChatAnthropic: ChatAnthropic2 } = await import("./index-
|
|
86845
|
+
const { ChatAnthropic: ChatAnthropic2 } = await import("./index-SW6h169v.js");
|
|
86438
86846
|
return { ChatAnthropic: ChatAnthropic2 };
|
|
86439
86847
|
}, true ? __vite__mapDeps([8,5,6,2]) : void 0);
|
|
86440
86848
|
llm = new ChatAnthropic({
|
|
@@ -86443,7 +86851,7 @@ function useChatMessagesClientSide({
|
|
|
86443
86851
|
});
|
|
86444
86852
|
} else if (llmConfig.provider === "google") {
|
|
86445
86853
|
const { ChatGoogleGenerativeAI } = await __vitePreload(async () => {
|
|
86446
|
-
const { ChatGoogleGenerativeAI: ChatGoogleGenerativeAI2 } = await import("./index-
|
|
86854
|
+
const { ChatGoogleGenerativeAI: ChatGoogleGenerativeAI2 } = await import("./index-fTSANe1E.js");
|
|
86447
86855
|
return { ChatGoogleGenerativeAI: ChatGoogleGenerativeAI2 };
|
|
86448
86856
|
}, true ? __vite__mapDeps([9,5,6,2,7]) : void 0);
|
|
86449
86857
|
llm = new ChatGoogleGenerativeAI({
|
|
@@ -86462,7 +86870,7 @@ function useChatMessagesClientSide({
|
|
|
86462
86870
|
}
|
|
86463
86871
|
if (!agentRef.current || agentRef.current.llm !== llmRef.current.instance) {
|
|
86464
86872
|
const { MCPAgent } = await __vitePreload(async () => {
|
|
86465
|
-
const { MCPAgent: MCPAgent2 } = await import("./browser-
|
|
86873
|
+
const { MCPAgent: MCPAgent2 } = await import("./browser-C03pLkVq.js");
|
|
86466
86874
|
return { MCPAgent: MCPAgent2 };
|
|
86467
86875
|
}, true ? __vite__mapDeps([10,6,2,1,3]) : void 0);
|
|
86468
86876
|
agentRef.current = new MCPAgent({
|
|
@@ -89165,6 +89573,86 @@ function ResizableHandle({
|
|
|
89165
89573
|
}
|
|
89166
89574
|
);
|
|
89167
89575
|
}
|
|
89576
|
+
function Kbd({ className, ...props2 }) {
|
|
89577
|
+
return /* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
89578
|
+
"kbd",
|
|
89579
|
+
{
|
|
89580
|
+
"data-slot": "kbd",
|
|
89581
|
+
className: cn$1(
|
|
89582
|
+
"bg-muted text-muted-foreground pointer-events-none inline-flex h-5 w-fit min-w-5 items-center justify-center gap-1 rounded-sm px-1 font-sans text-xs font-medium select-none",
|
|
89583
|
+
"[&_svg:not([class*='size-'])]:size-3",
|
|
89584
|
+
"[[data-slot=tooltip-content]_&]:bg-background/20 [[data-slot=tooltip-content]_&]:text-background dark:[[data-slot=tooltip-content]_&]:bg-background/10",
|
|
89585
|
+
className
|
|
89586
|
+
),
|
|
89587
|
+
...props2
|
|
89588
|
+
}
|
|
89589
|
+
);
|
|
89590
|
+
}
|
|
89591
|
+
function NotificationsTabHeader({
|
|
89592
|
+
isSearchExpanded,
|
|
89593
|
+
searchQuery,
|
|
89594
|
+
filteredNotificationsCount,
|
|
89595
|
+
notificationsCount,
|
|
89596
|
+
onSearchExpand,
|
|
89597
|
+
onSearchChange,
|
|
89598
|
+
onSearchBlur,
|
|
89599
|
+
onClearAll,
|
|
89600
|
+
searchInputRef
|
|
89601
|
+
}) {
|
|
89602
|
+
return /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex items-center justify-between p-4 py-3", children: [
|
|
89603
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "flex items-center gap-2 flex-1", children: !isSearchExpanded ? /* @__PURE__ */ jsxRuntimeExports.jsxs(jsxRuntimeExports.Fragment, { children: [
|
|
89604
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("h2", { className: "text-lg font-medium text-gray-900 dark:text-gray-100", children: "Notifications" }),
|
|
89605
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
89606
|
+
Badge,
|
|
89607
|
+
{
|
|
89608
|
+
className: "bg-zinc-500/20 text-zinc-600 dark:text-zinc-400 border-transparent",
|
|
89609
|
+
variant: "outline",
|
|
89610
|
+
children: filteredNotificationsCount
|
|
89611
|
+
}
|
|
89612
|
+
),
|
|
89613
|
+
/* @__PURE__ */ jsxRuntimeExports.jsxs(Tooltip, { children: [
|
|
89614
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx(TooltipTrigger, { asChild: true, children: /* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
89615
|
+
Button,
|
|
89616
|
+
{
|
|
89617
|
+
variant: "ghost",
|
|
89618
|
+
size: "sm",
|
|
89619
|
+
onClick: onSearchExpand,
|
|
89620
|
+
className: "h-8 w-8 p-0",
|
|
89621
|
+
children: /* @__PURE__ */ jsxRuntimeExports.jsx(Search, { className: "h-4 w-4" })
|
|
89622
|
+
}
|
|
89623
|
+
) }),
|
|
89624
|
+
/* @__PURE__ */ jsxRuntimeExports.jsxs(TooltipContent, { side: "bottom", className: "flex gap-2", children: [
|
|
89625
|
+
"Search",
|
|
89626
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx(Kbd, { children: "F" })
|
|
89627
|
+
] })
|
|
89628
|
+
] })
|
|
89629
|
+
] }) : /* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
89630
|
+
Input,
|
|
89631
|
+
{
|
|
89632
|
+
ref: searchInputRef,
|
|
89633
|
+
placeholder: "Search notifications...",
|
|
89634
|
+
value: searchQuery,
|
|
89635
|
+
onChange: (e) => onSearchChange(e.target.value),
|
|
89636
|
+
onBlur: onSearchBlur,
|
|
89637
|
+
className: "h-8 border-gray-300 dark:border-zinc-600"
|
|
89638
|
+
}
|
|
89639
|
+
) }),
|
|
89640
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "flex items-center gap-2", children: /* @__PURE__ */ jsxRuntimeExports.jsxs(Tooltip, { children: [
|
|
89641
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx(TooltipTrigger, { asChild: true, children: /* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
89642
|
+
Button,
|
|
89643
|
+
{
|
|
89644
|
+
variant: "ghost",
|
|
89645
|
+
size: "sm",
|
|
89646
|
+
onClick: onClearAll,
|
|
89647
|
+
disabled: notificationsCount === 0,
|
|
89648
|
+
className: "h-8 w-8 p-0",
|
|
89649
|
+
children: /* @__PURE__ */ jsxRuntimeExports.jsx(Trash2, { className: "h-4 w-4" })
|
|
89650
|
+
}
|
|
89651
|
+
) }),
|
|
89652
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx(TooltipContent, { side: "bottom", children: "Clear all" })
|
|
89653
|
+
] }) })
|
|
89654
|
+
] });
|
|
89655
|
+
}
|
|
89168
89656
|
function ListItem({
|
|
89169
89657
|
id: id2,
|
|
89170
89658
|
isSelected,
|
|
@@ -89189,7 +89677,7 @@ function ListItem({
|
|
|
89189
89677
|
className
|
|
89190
89678
|
),
|
|
89191
89679
|
children: /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex items-start gap-2 sm:gap-3", children: [
|
|
89192
|
-
/* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "flex-shrink-0 mt-1", children: /* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
89680
|
+
icon && /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "flex-shrink-0 mt-1", children: /* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
89193
89681
|
"div",
|
|
89194
89682
|
{
|
|
89195
89683
|
className: cn$1(
|
|
@@ -89207,20 +89695,381 @@ function ListItem({
|
|
|
89207
89695
|
}
|
|
89208
89696
|
);
|
|
89209
89697
|
}
|
|
89210
|
-
function
|
|
89211
|
-
|
|
89212
|
-
|
|
89213
|
-
|
|
89214
|
-
|
|
89215
|
-
|
|
89216
|
-
|
|
89217
|
-
|
|
89218
|
-
|
|
89219
|
-
|
|
89220
|
-
),
|
|
89221
|
-
|
|
89698
|
+
function NotificationsList({
|
|
89699
|
+
notifications,
|
|
89700
|
+
selectedNotification,
|
|
89701
|
+
onNotificationSelect,
|
|
89702
|
+
focusedIndex,
|
|
89703
|
+
formatRelativeTime: formatRelativeTime2,
|
|
89704
|
+
listRef
|
|
89705
|
+
}) {
|
|
89706
|
+
if (notifications.length === 0) {
|
|
89707
|
+
return /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex flex-col items-center justify-center h-full p-4 text-center", children: [
|
|
89708
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx(Bell, { className: "h-12 w-12 text-gray-400 dark:text-gray-600 mb-3" }),
|
|
89709
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("p", { className: "text-gray-500 dark:text-gray-400", children: "No notifications yet" })
|
|
89710
|
+
] });
|
|
89711
|
+
}
|
|
89712
|
+
return /* @__PURE__ */ jsxRuntimeExports.jsx("div", { ref: listRef, className: "overflow-y-auto flex-1 overscroll-contain", children: notifications.map((notification, index2) => {
|
|
89713
|
+
return /* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
89714
|
+
ListItem,
|
|
89715
|
+
{
|
|
89716
|
+
id: `notification-${notification.id}`,
|
|
89717
|
+
isSelected: selectedNotification?.id === notification.id,
|
|
89718
|
+
isFocused: focusedIndex === index2,
|
|
89719
|
+
title: /* @__PURE__ */ jsxRuntimeExports.jsxs("span", { className: "flex items-center gap-3", children: [
|
|
89720
|
+
notification.method,
|
|
89721
|
+
!notification.read && /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "size-1.5 block rounded-full bg-orange-500" })
|
|
89722
|
+
] }),
|
|
89723
|
+
description: (() => {
|
|
89724
|
+
const timeStr = formatRelativeTime2(notification.timestamp);
|
|
89725
|
+
const paramCount = notification.params && Object.keys(notification.params).length > 0 ? Object.keys(notification.params).length : 0;
|
|
89726
|
+
const paramStr = paramCount > 0 ? ` | ${paramCount} param${paramCount > 1 ? "s" : ""}` : "";
|
|
89727
|
+
return timeStr + paramStr;
|
|
89728
|
+
})(),
|
|
89729
|
+
onClick: () => onNotificationSelect(notification)
|
|
89730
|
+
},
|
|
89731
|
+
notification.id
|
|
89732
|
+
);
|
|
89733
|
+
}) });
|
|
89734
|
+
}
|
|
89735
|
+
function NotificationResultDisplay({
|
|
89736
|
+
notification,
|
|
89737
|
+
previewMode,
|
|
89738
|
+
onTogglePreview,
|
|
89739
|
+
onCopy,
|
|
89740
|
+
onDownload,
|
|
89741
|
+
onFullscreen,
|
|
89742
|
+
isCopied = false,
|
|
89743
|
+
onClose
|
|
89744
|
+
}) {
|
|
89745
|
+
if (!notification) {
|
|
89746
|
+
return /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex flex-col items-center justify-center h-full p-4 text-center", children: [
|
|
89747
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx(Bell, { className: "h-12 w-12 text-gray-400 dark:text-gray-600 mb-3" }),
|
|
89748
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("p", { className: "text-gray-500 dark:text-gray-400", children: "Select a notification to view details" })
|
|
89749
|
+
] });
|
|
89750
|
+
}
|
|
89751
|
+
return /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex flex-col h-full", children: [
|
|
89752
|
+
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex-shrink-0 px-4 py-3 border-b border-gray-200 dark:border-zinc-700 flex items-center justify-between", children: [
|
|
89753
|
+
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex items-center gap-2", children: [
|
|
89754
|
+
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex items-center gap-1", children: [
|
|
89755
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx(Clock, { className: "h-3 w-3 text-gray-400" }),
|
|
89756
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "text-xs text-gray-500 dark:text-gray-400", children: new Date(notification.timestamp).toLocaleTimeString() })
|
|
89757
|
+
] }),
|
|
89758
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "text-xs text-gray-500 dark:text-gray-400", children: notification.formatRelativeTime(notification.timestamp) })
|
|
89759
|
+
] }),
|
|
89760
|
+
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex items-center gap-1", children: [
|
|
89761
|
+
/* @__PURE__ */ jsxRuntimeExports.jsxs(
|
|
89762
|
+
Button,
|
|
89763
|
+
{
|
|
89764
|
+
variant: "ghost",
|
|
89765
|
+
size: "sm",
|
|
89766
|
+
onClick: onTogglePreview,
|
|
89767
|
+
className: !previewMode ? "text-purple-600 dark:text-purple-400" : "",
|
|
89768
|
+
children: [
|
|
89769
|
+
previewMode ? /* @__PURE__ */ jsxRuntimeExports.jsx(Code, { className: "h-4 w-4 mr-1" }) : /* @__PURE__ */ jsxRuntimeExports.jsx(Brush, { className: "h-4 w-4 mr-1" }),
|
|
89770
|
+
previewMode ? "JSON" : "Formatted"
|
|
89771
|
+
]
|
|
89772
|
+
}
|
|
89773
|
+
),
|
|
89774
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx(Button, { variant: "ghost", size: "sm", onClick: onCopy, children: isCopied ? /* @__PURE__ */ jsxRuntimeExports.jsx(Check, { className: "h-4 w-4" }) : /* @__PURE__ */ jsxRuntimeExports.jsx(Copy, { className: "h-4 w-4" }) }),
|
|
89775
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx(Button, { variant: "ghost", size: "sm", onClick: onDownload, children: /* @__PURE__ */ jsxRuntimeExports.jsx(Download, { className: "h-4 w-4" }) }),
|
|
89776
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx(Button, { variant: "ghost", size: "sm", onClick: onFullscreen, children: /* @__PURE__ */ jsxRuntimeExports.jsx(Maximize, { className: "h-4 w-4" }) }),
|
|
89777
|
+
onClose && /* @__PURE__ */ jsxRuntimeExports.jsx(Button, { variant: "ghost", size: "sm", onClick: onClose, children: /* @__PURE__ */ jsxRuntimeExports.jsx(X$3, { className: "h-4 w-4" }) })
|
|
89778
|
+
] })
|
|
89779
|
+
] }),
|
|
89780
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "flex-1 overflow-y-auto", children: /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "px-4 pt-4", children: /* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
89781
|
+
JSONDisplay,
|
|
89782
|
+
{
|
|
89783
|
+
data: {
|
|
89784
|
+
method: notification.method,
|
|
89785
|
+
timestamp: notification.timestamp,
|
|
89786
|
+
read: notification.read,
|
|
89787
|
+
params: notification.params
|
|
89788
|
+
},
|
|
89789
|
+
filename: `notification-${notification.method.replace(/[^a-zA-Z0-9]/g, "-")}-${Date.now()}.json`
|
|
89790
|
+
}
|
|
89791
|
+
) }) })
|
|
89792
|
+
] });
|
|
89793
|
+
}
|
|
89794
|
+
function formatRelativeTime(timestamp) {
|
|
89795
|
+
const now2 = Date.now();
|
|
89796
|
+
const diff = now2 - timestamp;
|
|
89797
|
+
const seconds = Math.floor(diff / 1e3);
|
|
89798
|
+
const minutes = Math.floor(seconds / 60);
|
|
89799
|
+
const hours = Math.floor(minutes / 60);
|
|
89800
|
+
const days = Math.floor(hours / 24);
|
|
89801
|
+
if (seconds < 60) {
|
|
89802
|
+
return "just now";
|
|
89803
|
+
} else if (minutes < 60) {
|
|
89804
|
+
return `${minutes}m ago`;
|
|
89805
|
+
} else if (hours < 24) {
|
|
89806
|
+
return `${hours}h ago`;
|
|
89807
|
+
} else if (days < 7) {
|
|
89808
|
+
return `${days}d ago`;
|
|
89809
|
+
} else {
|
|
89810
|
+
return new Date(timestamp).toLocaleDateString();
|
|
89811
|
+
}
|
|
89812
|
+
}
|
|
89813
|
+
function NotificationsTab({
|
|
89814
|
+
notifications,
|
|
89815
|
+
unreadCount: _unreadCount,
|
|
89816
|
+
markNotificationRead,
|
|
89817
|
+
markAllNotificationsRead: _markAllNotificationsRead,
|
|
89818
|
+
clearNotifications,
|
|
89819
|
+
serverId: _serverId,
|
|
89820
|
+
isConnected
|
|
89821
|
+
}) {
|
|
89822
|
+
const [selectedNotification, setSelectedNotification] = reactExports.useState(null);
|
|
89823
|
+
const [searchQuery, setSearchQuery] = reactExports.useState("");
|
|
89824
|
+
const [focusedIndex, setFocusedIndex] = reactExports.useState(-1);
|
|
89825
|
+
const [autoScroll, setAutoScroll] = reactExports.useState(true);
|
|
89826
|
+
const [isSearchExpanded, setIsSearchExpanded] = reactExports.useState(false);
|
|
89827
|
+
const [previewMode, setPreviewMode] = reactExports.useState(true);
|
|
89828
|
+
const [isCopied, setIsCopied] = reactExports.useState(false);
|
|
89829
|
+
const listRef = reactExports.useRef(null);
|
|
89830
|
+
const notificationDisplayRef = reactExports.useRef(null);
|
|
89831
|
+
const searchInputRef = reactExports.useRef(null);
|
|
89832
|
+
const userHasScrolledRef = reactExports.useRef(false);
|
|
89833
|
+
reactExports.useEffect(() => {
|
|
89834
|
+
if (autoScroll && notifications.length > 0 && listRef.current && !userHasScrolledRef.current) {
|
|
89835
|
+
listRef.current.scrollTop = 0;
|
|
89222
89836
|
}
|
|
89837
|
+
}, [notifications.length, autoScroll]);
|
|
89838
|
+
reactExports.useEffect(() => {
|
|
89839
|
+
const listElement = listRef.current;
|
|
89840
|
+
if (!listElement) return;
|
|
89841
|
+
const handleScroll2 = () => {
|
|
89842
|
+
if (listElement.scrollTop > 0) {
|
|
89843
|
+
userHasScrolledRef.current = true;
|
|
89844
|
+
setAutoScroll(false);
|
|
89845
|
+
}
|
|
89846
|
+
};
|
|
89847
|
+
listElement.addEventListener("scroll", handleScroll2);
|
|
89848
|
+
return () => listElement.removeEventListener("scroll", handleScroll2);
|
|
89849
|
+
}, []);
|
|
89850
|
+
reactExports.useEffect(() => {
|
|
89851
|
+
if (notifications.length === 0) {
|
|
89852
|
+
userHasScrolledRef.current = false;
|
|
89853
|
+
setAutoScroll(true);
|
|
89854
|
+
}
|
|
89855
|
+
}, [notifications.length]);
|
|
89856
|
+
reactExports.useEffect(() => {
|
|
89857
|
+
if (selectedNotification && !selectedNotification.read) {
|
|
89858
|
+
markNotificationRead(selectedNotification.id);
|
|
89859
|
+
}
|
|
89860
|
+
}, [selectedNotification, markNotificationRead]);
|
|
89861
|
+
reactExports.useEffect(() => {
|
|
89862
|
+
if (isSearchExpanded && searchInputRef.current) {
|
|
89863
|
+
searchInputRef.current.focus();
|
|
89864
|
+
}
|
|
89865
|
+
}, [isSearchExpanded]);
|
|
89866
|
+
const handleSearchBlur = reactExports.useCallback(() => {
|
|
89867
|
+
if (!searchQuery.trim()) {
|
|
89868
|
+
setIsSearchExpanded(false);
|
|
89869
|
+
}
|
|
89870
|
+
}, [searchQuery]);
|
|
89871
|
+
const filteredNotifications = reactExports.useMemo(() => {
|
|
89872
|
+
if (!searchQuery.trim()) return notifications;
|
|
89873
|
+
const query = searchQuery.toLowerCase();
|
|
89874
|
+
return notifications.filter(
|
|
89875
|
+
(notification) => notification.method.toLowerCase().includes(query) || JSON.stringify(notification.params || {}).toLowerCase().includes(query)
|
|
89876
|
+
);
|
|
89877
|
+
}, [notifications, searchQuery]);
|
|
89878
|
+
reactExports.useEffect(() => {
|
|
89879
|
+
setFocusedIndex(-1);
|
|
89880
|
+
}, [searchQuery]);
|
|
89881
|
+
reactExports.useEffect(() => {
|
|
89882
|
+
const handleKeyDown = (e) => {
|
|
89883
|
+
const target = e.target;
|
|
89884
|
+
const isInputFocused = target.tagName === "INPUT" || target.tagName === "TEXTAREA" || target.contentEditable === "true";
|
|
89885
|
+
if (isInputFocused || e.metaKey || e.ctrlKey || e.altKey) {
|
|
89886
|
+
return;
|
|
89887
|
+
}
|
|
89888
|
+
const items2 = filteredNotifications;
|
|
89889
|
+
if (e.key === "ArrowDown") {
|
|
89890
|
+
e.preventDefault();
|
|
89891
|
+
setFocusedIndex((prev) => {
|
|
89892
|
+
const next = prev + 1;
|
|
89893
|
+
return next >= items2.length ? 0 : next;
|
|
89894
|
+
});
|
|
89895
|
+
} else if (e.key === "ArrowUp") {
|
|
89896
|
+
e.preventDefault();
|
|
89897
|
+
setFocusedIndex((prev) => {
|
|
89898
|
+
const next = prev - 1;
|
|
89899
|
+
return next < 0 ? items2.length - 1 : next;
|
|
89900
|
+
});
|
|
89901
|
+
} else if (e.key === "Enter" && focusedIndex >= 0) {
|
|
89902
|
+
e.preventDefault();
|
|
89903
|
+
const notification = filteredNotifications[focusedIndex];
|
|
89904
|
+
if (notification) {
|
|
89905
|
+
handleNotificationSelect(notification);
|
|
89906
|
+
}
|
|
89907
|
+
}
|
|
89908
|
+
};
|
|
89909
|
+
document.addEventListener("keydown", handleKeyDown);
|
|
89910
|
+
return () => document.removeEventListener("keydown", handleKeyDown);
|
|
89911
|
+
}, [focusedIndex, filteredNotifications]);
|
|
89912
|
+
reactExports.useEffect(() => {
|
|
89913
|
+
if (focusedIndex >= 0) {
|
|
89914
|
+
const itemId = `notification-${filteredNotifications[focusedIndex]?.id}`;
|
|
89915
|
+
const element = document.getElementById(itemId);
|
|
89916
|
+
if (element) {
|
|
89917
|
+
element.scrollIntoView({ behavior: "smooth", block: "nearest" });
|
|
89918
|
+
}
|
|
89919
|
+
}
|
|
89920
|
+
}, [focusedIndex, filteredNotifications]);
|
|
89921
|
+
const handleNotificationSelect = reactExports.useCallback(
|
|
89922
|
+
(notification) => {
|
|
89923
|
+
setSelectedNotification(notification);
|
|
89924
|
+
},
|
|
89925
|
+
[]
|
|
89223
89926
|
);
|
|
89927
|
+
const handleClearAll = reactExports.useCallback(() => {
|
|
89928
|
+
if (window.confirm(
|
|
89929
|
+
"Are you sure you want to clear all notifications? This cannot be undone."
|
|
89930
|
+
)) {
|
|
89931
|
+
clearNotifications();
|
|
89932
|
+
setSelectedNotification(null);
|
|
89933
|
+
}
|
|
89934
|
+
}, [clearNotifications]);
|
|
89935
|
+
const handleCopy = reactExports.useCallback(async () => {
|
|
89936
|
+
if (!selectedNotification) return;
|
|
89937
|
+
try {
|
|
89938
|
+
await navigator.clipboard.writeText(
|
|
89939
|
+
JSON.stringify(
|
|
89940
|
+
{
|
|
89941
|
+
method: selectedNotification.method,
|
|
89942
|
+
timestamp: selectedNotification.timestamp,
|
|
89943
|
+
read: selectedNotification.read,
|
|
89944
|
+
params: selectedNotification.params
|
|
89945
|
+
},
|
|
89946
|
+
null,
|
|
89947
|
+
2
|
|
89948
|
+
)
|
|
89949
|
+
);
|
|
89950
|
+
setIsCopied(true);
|
|
89951
|
+
setTimeout(() => setIsCopied(false), 2e3);
|
|
89952
|
+
} catch (error) {
|
|
89953
|
+
console.error("[NotificationsTab] Failed to copy notification:", error);
|
|
89954
|
+
}
|
|
89955
|
+
}, [selectedNotification]);
|
|
89956
|
+
const handleDownload = reactExports.useCallback(() => {
|
|
89957
|
+
if (!selectedNotification) return;
|
|
89958
|
+
try {
|
|
89959
|
+
const blob = new globalThis.Blob(
|
|
89960
|
+
[
|
|
89961
|
+
JSON.stringify(
|
|
89962
|
+
{
|
|
89963
|
+
method: selectedNotification.method,
|
|
89964
|
+
timestamp: selectedNotification.timestamp,
|
|
89965
|
+
read: selectedNotification.read,
|
|
89966
|
+
params: selectedNotification.params
|
|
89967
|
+
},
|
|
89968
|
+
null,
|
|
89969
|
+
2
|
|
89970
|
+
)
|
|
89971
|
+
],
|
|
89972
|
+
{
|
|
89973
|
+
type: "application/json"
|
|
89974
|
+
}
|
|
89975
|
+
);
|
|
89976
|
+
const url = URL.createObjectURL(blob);
|
|
89977
|
+
const a2 = document.createElement("a");
|
|
89978
|
+
a2.href = url;
|
|
89979
|
+
a2.download = `notification-${Date.now()}.json`;
|
|
89980
|
+
document.body.appendChild(a2);
|
|
89981
|
+
a2.click();
|
|
89982
|
+
document.body.removeChild(a2);
|
|
89983
|
+
URL.revokeObjectURL(url);
|
|
89984
|
+
} catch (error) {
|
|
89985
|
+
console.error(
|
|
89986
|
+
"[NotificationsTab] Failed to download notification:",
|
|
89987
|
+
error
|
|
89988
|
+
);
|
|
89989
|
+
}
|
|
89990
|
+
}, [selectedNotification]);
|
|
89991
|
+
const handleFullscreen = reactExports.useCallback(async () => {
|
|
89992
|
+
if (!notificationDisplayRef.current) return;
|
|
89993
|
+
try {
|
|
89994
|
+
if (!document.fullscreenElement) {
|
|
89995
|
+
await notificationDisplayRef.current.requestFullscreen();
|
|
89996
|
+
} else {
|
|
89997
|
+
await document.exitFullscreen();
|
|
89998
|
+
}
|
|
89999
|
+
} catch (error) {
|
|
90000
|
+
console.error("[NotificationsTab] Failed to toggle fullscreen:", error);
|
|
90001
|
+
}
|
|
90002
|
+
}, []);
|
|
90003
|
+
const notificationResult = selectedNotification ? {
|
|
90004
|
+
method: selectedNotification.method,
|
|
90005
|
+
params: selectedNotification.params,
|
|
90006
|
+
timestamp: selectedNotification.timestamp,
|
|
90007
|
+
read: selectedNotification.read,
|
|
90008
|
+
formatRelativeTime
|
|
90009
|
+
} : null;
|
|
90010
|
+
if (!isConnected) {
|
|
90011
|
+
return /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex flex-col items-center justify-center h-full p-4 text-center", children: [
|
|
90012
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx(Bell, { className: "h-12 w-12 text-gray-400 dark:text-gray-600 mb-3" }),
|
|
90013
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("p", { className: "text-gray-500 dark:text-gray-400", children: "Not connected to server" })
|
|
90014
|
+
] });
|
|
90015
|
+
}
|
|
90016
|
+
return /* @__PURE__ */ jsxRuntimeExports.jsxs(ResizablePanelGroup, { direction: "horizontal", className: "h-full", children: [
|
|
90017
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx(ResizablePanel, { defaultSize: 40, minSize: 30, children: /* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
90018
|
+
ResizablePanelGroup,
|
|
90019
|
+
{
|
|
90020
|
+
direction: "vertical",
|
|
90021
|
+
className: "h-full border-r dark:border-zinc-700",
|
|
90022
|
+
children: /* @__PURE__ */ jsxRuntimeExports.jsxs(ResizablePanel, { defaultSize: 75, minSize: 30, children: [
|
|
90023
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
90024
|
+
NotificationsTabHeader,
|
|
90025
|
+
{
|
|
90026
|
+
isSearchExpanded,
|
|
90027
|
+
searchQuery,
|
|
90028
|
+
filteredNotificationsCount: filteredNotifications.length,
|
|
90029
|
+
notificationsCount: notifications.length,
|
|
90030
|
+
onSearchExpand: () => setIsSearchExpanded(true),
|
|
90031
|
+
onSearchChange: setSearchQuery,
|
|
90032
|
+
onSearchBlur: handleSearchBlur,
|
|
90033
|
+
onClearAll: handleClearAll,
|
|
90034
|
+
searchInputRef
|
|
90035
|
+
}
|
|
90036
|
+
),
|
|
90037
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "flex flex-col h-full", children: /* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
90038
|
+
NotificationsList,
|
|
90039
|
+
{
|
|
90040
|
+
notifications: filteredNotifications,
|
|
90041
|
+
selectedNotification,
|
|
90042
|
+
onNotificationSelect: handleNotificationSelect,
|
|
90043
|
+
focusedIndex,
|
|
90044
|
+
formatRelativeTime,
|
|
90045
|
+
listRef
|
|
90046
|
+
}
|
|
90047
|
+
) })
|
|
90048
|
+
] })
|
|
90049
|
+
}
|
|
90050
|
+
) }),
|
|
90051
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx(ResizableHandle, {}),
|
|
90052
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx(ResizablePanel, { defaultSize: 60, minSize: 40, children: /* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
90053
|
+
"div",
|
|
90054
|
+
{
|
|
90055
|
+
ref: notificationDisplayRef,
|
|
90056
|
+
className: "h-full bg-white dark:bg-zinc-900",
|
|
90057
|
+
children: /* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
90058
|
+
NotificationResultDisplay,
|
|
90059
|
+
{
|
|
90060
|
+
notification: notificationResult,
|
|
90061
|
+
previewMode,
|
|
90062
|
+
onTogglePreview: () => setPreviewMode(!previewMode),
|
|
90063
|
+
onCopy: handleCopy,
|
|
90064
|
+
onDownload: handleDownload,
|
|
90065
|
+
onFullscreen: handleFullscreen,
|
|
90066
|
+
onClose: () => setSelectedNotification(null),
|
|
90067
|
+
isCopied
|
|
90068
|
+
}
|
|
90069
|
+
)
|
|
90070
|
+
}
|
|
90071
|
+
) })
|
|
90072
|
+
] });
|
|
89224
90073
|
}
|
|
89225
90074
|
function ListTabHeader({
|
|
89226
90075
|
activeTab,
|
|
@@ -90300,7 +91149,7 @@ function PromptsTab({
|
|
|
90300
91149
|
defaultSize: 0,
|
|
90301
91150
|
collapsible: true,
|
|
90302
91151
|
minSize: 5,
|
|
90303
|
-
collapsedSize:
|
|
91152
|
+
collapsedSize: 6,
|
|
90304
91153
|
onCollapse: () => setRpcPanelCollapsed(true),
|
|
90305
91154
|
onExpand: () => setRpcPanelCollapsed(false),
|
|
90306
91155
|
className: "flex flex-col border-t dark:border-zinc-700",
|
|
@@ -91116,7 +91965,7 @@ function ResourcesTab({
|
|
|
91116
91965
|
defaultSize: 0,
|
|
91117
91966
|
collapsible: true,
|
|
91118
91967
|
minSize: 5,
|
|
91119
|
-
collapsedSize:
|
|
91968
|
+
collapsedSize: 6,
|
|
91120
91969
|
onCollapse: () => setRpcPanelCollapsed(true),
|
|
91121
91970
|
onExpand: () => setRpcPanelCollapsed(false),
|
|
91122
91971
|
className: "flex flex-col border-t dark:border-zinc-700",
|
|
@@ -92694,7 +93543,7 @@ function ToolsTab({
|
|
|
92694
93543
|
defaultSize: 0,
|
|
92695
93544
|
collapsible: true,
|
|
92696
93545
|
minSize: 5,
|
|
92697
|
-
collapsedSize:
|
|
93546
|
+
collapsedSize: 6,
|
|
92698
93547
|
onCollapse: () => {
|
|
92699
93548
|
setRpcPanelCollapsed(true);
|
|
92700
93549
|
},
|
|
@@ -92872,6 +93721,19 @@ function LayoutContent({
|
|
|
92872
93721
|
},
|
|
92873
93722
|
selectedServer.id
|
|
92874
93723
|
);
|
|
93724
|
+
case "notifications":
|
|
93725
|
+
return /* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
93726
|
+
NotificationsTab,
|
|
93727
|
+
{
|
|
93728
|
+
notifications: selectedServer.notifications,
|
|
93729
|
+
unreadCount: selectedServer.unreadNotificationCount,
|
|
93730
|
+
markNotificationRead: selectedServer.markNotificationRead,
|
|
93731
|
+
markAllNotificationsRead: selectedServer.markAllNotificationsRead,
|
|
93732
|
+
clearNotifications: selectedServer.clearNotifications,
|
|
93733
|
+
serverId: selectedServer.id,
|
|
93734
|
+
isConnected: selectedServer.state === "ready"
|
|
93735
|
+
}
|
|
93736
|
+
);
|
|
92875
93737
|
default:
|
|
92876
93738
|
return /* @__PURE__ */ jsxRuntimeExports.jsx(jsxRuntimeExports.Fragment, { children });
|
|
92877
93739
|
}
|
|
@@ -93968,7 +94830,8 @@ const tabs = [
|
|
|
93968
94830
|
{ id: "tools", label: "Tools", icon: Wrench },
|
|
93969
94831
|
{ id: "prompts", label: "Prompts", icon: MessageSquare },
|
|
93970
94832
|
{ id: "resources", label: "Resources", icon: FolderOpen },
|
|
93971
|
-
{ id: "chat", label: "Chat", icon: MessageCircle }
|
|
94833
|
+
{ id: "chat", label: "Chat", icon: MessageCircle },
|
|
94834
|
+
{ id: "notifications", label: "Notifications", icon: Bell }
|
|
93972
94835
|
];
|
|
93973
94836
|
function LayoutHeader({
|
|
93974
94837
|
connections,
|
|
@@ -94038,13 +94901,15 @@ function LayoutHeader({
|
|
|
94038
94901
|
count2 = selectedServer.prompts.length;
|
|
94039
94902
|
} else if (tab.id === "resources") {
|
|
94040
94903
|
count2 = selectedServer.resources.length;
|
|
94904
|
+
} else if (tab.id === "notifications") {
|
|
94905
|
+
count2 = selectedServer.unreadNotificationCount;
|
|
94041
94906
|
}
|
|
94042
94907
|
return /* @__PURE__ */ jsxRuntimeExports.jsxs(
|
|
94043
94908
|
TabsTrigger,
|
|
94044
94909
|
{
|
|
94045
94910
|
value: tab.id,
|
|
94046
94911
|
icon: tab.icon,
|
|
94047
|
-
className: "[&>svg]:mr-0 flex-1 flex-row gap-2",
|
|
94912
|
+
className: "[&>svg]:mr-0 flex-1 flex-row gap-2 relative",
|
|
94048
94913
|
children: [
|
|
94049
94914
|
count2 > 0 && /* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
94050
94915
|
"span",
|
|
@@ -94089,13 +94954,15 @@ function LayoutHeader({
|
|
|
94089
94954
|
count2 = selectedServer.prompts.length;
|
|
94090
94955
|
} else if (tab.id === "resources") {
|
|
94091
94956
|
count2 = selectedServer.resources.length;
|
|
94957
|
+
} else if (tab.id === "notifications") {
|
|
94958
|
+
count2 = selectedServer.unreadNotificationCount;
|
|
94092
94959
|
}
|
|
94093
94960
|
return /* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
94094
94961
|
TabsTrigger,
|
|
94095
94962
|
{
|
|
94096
94963
|
value: tab.id,
|
|
94097
94964
|
icon: tab.icon,
|
|
94098
|
-
className: "[&>svg]:mr-0 lg:[&>svg]:mr-2",
|
|
94965
|
+
className: "[&>svg]:mr-0 lg:[&>svg]:mr-2 relative",
|
|
94099
94966
|
children: /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "items-center gap-2 hidden lg:flex", children: [
|
|
94100
94967
|
tab.label,
|
|
94101
94968
|
count2 > 0 && /* @__PURE__ */ jsxRuntimeExports.jsx(
|