@mcpjam/inspector 0.3.4 → 0.3.6

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.
@@ -22663,7 +22663,7 @@ function createChatConfig(options = {}) {
22663
22663
  "Explain a concept to me"
22664
22664
  ];
22665
22665
  const config = {
22666
- title: `Chat`,
22666
+ title: "LLM Playground",
22667
22667
  suggestions: [...baseSuggestions, ...options.additionalSuggestions || []]
22668
22668
  };
22669
22669
  if (options.subtitle) {
@@ -26843,6 +26843,13 @@ const ChevronLeft = createLucideIcon("ChevronLeft", [
26843
26843
  const ChevronRight = createLucideIcon("ChevronRight", [
26844
26844
  ["path", { d: "m9 18 6-6-6-6", key: "mthhwq" }]
26845
26845
  ]);
26846
+ /**
26847
+ * @license lucide-react v0.447.0 - ISC
26848
+ *
26849
+ * This source code is licensed under the ISC license.
26850
+ * See the LICENSE file in the root directory of this source tree.
26851
+ */
26852
+ const ChevronUp = createLucideIcon("ChevronUp", [["path", { d: "m18 15-6-6-6 6", key: "153udz" }]]);
26846
26853
  /**
26847
26854
  * @license lucide-react v0.447.0 - ISC
26848
26855
  *
@@ -27125,17 +27132,6 @@ const Hash = createLucideIcon("Hash", [
27125
27132
  ["line", { x1: "10", x2: "8", y1: "3", y2: "21", key: "1ggp8o" }],
27126
27133
  ["line", { x1: "16", x2: "14", y1: "3", y2: "21", key: "weycgp" }]
27127
27134
  ]);
27128
- /**
27129
- * @license lucide-react v0.447.0 - ISC
27130
- *
27131
- * This source code is licensed under the ISC license.
27132
- * See the LICENSE file in the root directory of this source tree.
27133
- */
27134
- const History = createLucideIcon("History", [
27135
- ["path", { d: "M3 12a9 9 0 1 0 9-9 9.75 9.75 0 0 0-6.74 2.74L3 8", key: "1357e3" }],
27136
- ["path", { d: "M3 3v5h5", key: "1xhq8a" }],
27137
- ["path", { d: "M12 7v5l4 2", key: "1fdv2h" }]
27138
- ]);
27139
27135
  /**
27140
27136
  * @license lucide-react v0.447.0 - ISC
27141
27137
  *
@@ -28099,12 +28095,8 @@ const ActivityHeader = ({
28099
28095
  ] })
28100
28096
  ] });
28101
28097
  const CompactHeader = ({
28102
- requestHistory,
28103
- onClearHistory
28104
- }) => /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex items-center justify-between mb-6", children: [
28105
- /* @__PURE__ */ jsxRuntimeExports.jsx(RequestCountBadge, { count: requestHistory.length }),
28106
- /* @__PURE__ */ jsxRuntimeExports.jsx(ClearHistoryButton, { onClick: onClearHistory })
28107
- ] });
28098
+ requestHistory
28099
+ }) => /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "flex items-center justify-between mb-6", children: /* @__PURE__ */ jsxRuntimeExports.jsx(RequestCountBadge, { count: requestHistory.length }) });
28108
28100
  const EmptyState$1 = () => /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex flex-col items-center justify-center py-12 text-center", children: [
28109
28101
  /* @__PURE__ */ jsxRuntimeExports.jsx(Activity, { className: "w-12 h-12 text-muted-foreground/40 mb-4" }),
28110
28102
  /* @__PURE__ */ jsxRuntimeExports.jsx("p", { className: "text-muted-foreground text-lg font-medium mb-2", children: "No activity yet" }),
@@ -28141,13 +28133,7 @@ const ActivityTab = ({
28141
28133
  }
28142
28134
  ),
28143
28135
  requestHistory.length === 0 ? /* @__PURE__ */ jsxRuntimeExports.jsx(EmptyState$1, {}) : /* @__PURE__ */ jsxRuntimeExports.jsxs(jsxRuntimeExports.Fragment, { children: [
28144
- !showHeader && requestHistory.length > 0 && /* @__PURE__ */ jsxRuntimeExports.jsx(
28145
- CompactHeader,
28146
- {
28147
- requestHistory,
28148
- onClearHistory
28149
- }
28150
- ),
28136
+ !showHeader && requestHistory.length > 0 && /* @__PURE__ */ jsxRuntimeExports.jsx(CompactHeader, { requestHistory }),
28151
28137
  /* @__PURE__ */ jsxRuntimeExports.jsx(RequestHistoryList, { requestHistory })
28152
28138
  ] })
28153
28139
  ]
@@ -29174,9 +29160,29 @@ const ResultsTab = ({
29174
29160
  ] }) : /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "bg-gradient-to-br from-background/80 to-background/60 backdrop-blur-sm p-4 rounded-xl border border-border/30", children: /* @__PURE__ */ jsxRuntimeExports.jsx(ToolResult, { toolResult }) })
29175
29161
  ] });
29176
29162
  };
29163
+ function CopyIcon({ value }) {
29164
+ const [copied, setCopied] = reactExports.useState(false);
29165
+ const handleCopy = async () => {
29166
+ await navigator.clipboard.writeText(value);
29167
+ setCopied(true);
29168
+ };
29169
+ reactExports.useEffect(() => {
29170
+ let timeoutId;
29171
+ if (copied) {
29172
+ timeoutId = setTimeout(() => {
29173
+ setCopied(false);
29174
+ }, 500);
29175
+ }
29176
+ return () => {
29177
+ if (timeoutId) {
29178
+ clearTimeout(timeoutId);
29179
+ }
29180
+ };
29181
+ }, [copied]);
29182
+ return /* @__PURE__ */ jsxRuntimeExports.jsx(Button, { size: "icon", variant: "ghost", className: "size-4", onClick: handleCopy, children: copied ? /* @__PURE__ */ jsxRuntimeExports.jsx(CheckCheck, {}) : /* @__PURE__ */ jsxRuntimeExports.jsx(Copy, {}) });
29183
+ }
29177
29184
  const ClientLogsTab = ({
29178
29185
  clientLogs,
29179
- onClearLogs,
29180
29186
  showHeader = true
29181
29187
  }) => {
29182
29188
  const reversedClientLogs = [...clientLogs].reverse();
@@ -29236,11 +29242,11 @@ const ClientLogsTab = ({
29236
29242
  return /* @__PURE__ */ jsxRuntimeExports.jsxs(
29237
29243
  "div",
29238
29244
  {
29239
- className: `flex items-start space-x-3 p-3 rounded-lg border ${config.bgColor} ${config.borderColor} hover:shadow-sm transition-all duration-200`,
29245
+ className: `group flex items-start space-x-3 p-3 rounded-lg border ${config.bgColor} ${config.borderColor} hover:shadow-sm transition-all duration-200`,
29240
29246
  children: [
29241
29247
  /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: `flex-shrink-0 mt-0.5 ${config.iconColor}`, children: /* @__PURE__ */ jsxRuntimeExports.jsx(IconComponent, { className: "w-4 h-4" }) }),
29242
29248
  /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex-1 min-w-0", children: [
29243
- /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex items-center space-x-2 mb-1", children: [
29249
+ /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex items-center mb-1 space-x-2", children: [
29244
29250
  /* @__PURE__ */ jsxRuntimeExports.jsx(
29245
29251
  "span",
29246
29252
  {
@@ -29248,36 +29254,26 @@ const ClientLogsTab = ({
29248
29254
  children: config.label
29249
29255
  }
29250
29256
  ),
29251
- /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "text-xs text-muted-foreground font-mono", children: formatTimestamp(log.timestamp) })
29257
+ /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "font-mono text-xs text-muted-foreground", children: formatTimestamp(log.timestamp) })
29252
29258
  ] }),
29253
29259
  /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: `text-sm ${config.textColor} font-mono break-words`, children: log.message })
29254
- ] })
29260
+ ] }),
29261
+ /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "flex-shrink-0 mt-0.5 opacity-0 group-hover:opacity-100 transition-opacity duration-200", children: /* @__PURE__ */ jsxRuntimeExports.jsx(CopyIcon, { value: log.message }) })
29255
29262
  ]
29256
29263
  }
29257
29264
  );
29258
29265
  };
29259
- return /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "h-full flex flex-col", children: [
29260
- !showHeader && clientLogs.length > 0 && /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex items-center justify-between mb-6", children: [
29261
- /* @__PURE__ */ jsxRuntimeExports.jsxs("span", { className: "text-sm text-muted-foreground bg-muted/50 px-3 py-1 rounded-full", children: [
29262
- clientLogs.length,
29263
- " log",
29264
- clientLogs.length !== 1 ? "s" : ""
29265
- ] }),
29266
- /* @__PURE__ */ jsxRuntimeExports.jsx(
29267
- "button",
29268
- {
29269
- onClick: onClearLogs,
29270
- className: "p-2 rounded-lg hover:bg-destructive/10 hover:text-destructive transition-all duration-200 group",
29271
- title: "Clear all activity",
29272
- children: /* @__PURE__ */ jsxRuntimeExports.jsx(Trash2, { className: "w-4 h-4 text-muted-foreground group-hover:text-destructive" })
29273
- }
29274
- )
29275
- ] }),
29276
- /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "flex-1 overflow-hidden", children: clientLogs.length === 0 ? /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex flex-col items-center justify-center h-full text-center p-8", children: [
29277
- /* @__PURE__ */ jsxRuntimeExports.jsx(Bug, { className: "w-12 h-12 text-muted-foreground/50 mb-4" }),
29278
- /* @__PURE__ */ jsxRuntimeExports.jsx("h3", { className: "text-lg font-medium text-muted-foreground mb-2", children: "No logs yet" }),
29279
- /* @__PURE__ */ jsxRuntimeExports.jsx("p", { className: "text-sm text-muted-foreground/70 max-w-sm", children: "Client logs will appear here when you perform operations. Logs include info, warnings, errors, and debug messages." })
29280
- ] }) : /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "h-full overflow-y-auto p-4 space-y-2", children: reversedClientLogs.map((log, index2) => /* @__PURE__ */ jsxRuntimeExports.jsx(LogEntry, { log }, `${log.timestamp}-${index2}`)) }) })
29266
+ return /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex flex-col h-full", children: [
29267
+ !showHeader && clientLogs.length > 0 && /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "flex items-center justify-between mb-6", children: /* @__PURE__ */ jsxRuntimeExports.jsxs("span", { className: "px-3 py-1 text-sm rounded-full text-muted-foreground bg-muted/50", children: [
29268
+ clientLogs.length,
29269
+ " log",
29270
+ clientLogs.length !== 1 ? "s" : ""
29271
+ ] }) }),
29272
+ /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "flex-1 overflow-hidden", children: clientLogs.length === 0 ? /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex flex-col items-center justify-center h-full p-8 text-center", children: [
29273
+ /* @__PURE__ */ jsxRuntimeExports.jsx(Bug, { className: "w-12 h-12 mb-4 text-muted-foreground/50" }),
29274
+ /* @__PURE__ */ jsxRuntimeExports.jsx("h3", { className: "mb-2 text-lg font-medium text-muted-foreground", children: "No logs yet" }),
29275
+ /* @__PURE__ */ jsxRuntimeExports.jsx("p", { className: "max-w-sm text-sm text-muted-foreground/70", children: "Client logs will appear here when you perform operations. Logs include info, warnings, errors, and debug messages." })
29276
+ ] }) : /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "h-full p-4 space-y-2 overflow-y-auto", children: reversedClientLogs.map((log, index2) => /* @__PURE__ */ jsxRuntimeExports.jsx(LogEntry, { log }, `${log.timestamp}-${index2}`)) }) })
29281
29277
  ] });
29282
29278
  };
29283
29279
  const TabbedHistoryPanel = ({
@@ -29286,16 +29282,38 @@ const TabbedHistoryPanel = ({
29286
29282
  clientLogs,
29287
29283
  onClearHistory,
29288
29284
  onClearLogs,
29289
- onToggleCollapse
29285
+ onToggleCollapse,
29286
+ activeTab,
29287
+ setActiveTab
29290
29288
  }) => {
29291
- const [activeTab, setActiveTab] = reactExports.useState("activity");
29292
29289
  const [isToolResultError, setIsToolResultError] = reactExports.useState(false);
29290
+ const { toast: toast2 } = useToast();
29293
29291
  reactExports.useEffect(() => {
29294
29292
  if (toolResult) {
29295
29293
  setIsToolResultError(toolResult.isError === true);
29296
- setActiveTab("results");
29297
29294
  }
29298
29295
  }, [toolResult]);
29296
+ const handleCopyLogs = async () => {
29297
+ if (clientLogs.length === 0) return;
29298
+ try {
29299
+ const logsText = clientLogs.map((log) => {
29300
+ const timestamp = new Date(log.timestamp).toISOString();
29301
+ return `[${timestamp}] ${log.level.toUpperCase()}: ${log.message}`;
29302
+ }).join("\n");
29303
+ await navigator.clipboard.writeText(logsText);
29304
+ toast2({
29305
+ title: "Logs copied to clipboard",
29306
+ description: `Successfully copied ${clientLogs.length} log entries to clipboard`
29307
+ });
29308
+ } catch (err) {
29309
+ console.error("Failed to copy logs to clipboard:", err);
29310
+ toast2({
29311
+ title: "Failed to copy logs",
29312
+ description: "Could not copy logs to clipboard. Please try again.",
29313
+ variant: "destructive"
29314
+ });
29315
+ }
29316
+ };
29299
29317
  reactExports.useEffect(() => {
29300
29318
  if (clientLogs.length > 0) {
29301
29319
  const isLastLogError = clientLogs[clientLogs.length - 1].level === "error";
@@ -29306,7 +29324,7 @@ const TabbedHistoryPanel = ({
29306
29324
  setActiveTab("logs");
29307
29325
  }
29308
29326
  }
29309
- }, [clientLogs]);
29327
+ }, [clientLogs, setActiveTab]);
29310
29328
  const renderActivityTabButton = () => {
29311
29329
  return /* @__PURE__ */ jsxRuntimeExports.jsxs(
29312
29330
  "button",
@@ -29375,18 +29393,43 @@ const TabbedHistoryPanel = ({
29375
29393
  case "results":
29376
29394
  return /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "h-full overflow-y-auto p-6", children: /* @__PURE__ */ jsxRuntimeExports.jsx(ResultsTab, { toolResult, showHeader: false }) });
29377
29395
  case "logs":
29378
- return /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "h-full overflow-y-auto p-6", children: /* @__PURE__ */ jsxRuntimeExports.jsx(
29379
- ClientLogsTab,
29380
- {
29381
- clientLogs,
29382
- onClearLogs,
29383
- showHeader: false
29384
- }
29385
- ) });
29396
+ return /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "h-full overflow-y-auto p-6", children: /* @__PURE__ */ jsxRuntimeExports.jsx(ClientLogsTab, { clientLogs, showHeader: false }) });
29386
29397
  default:
29387
29398
  return null;
29388
29399
  }
29389
29400
  };
29401
+ const ClearHistoryButton2 = ({
29402
+ onClick,
29403
+ count: count2
29404
+ }) => {
29405
+ if (count2 > 0) {
29406
+ return /* @__PURE__ */ jsxRuntimeExports.jsx(
29407
+ "button",
29408
+ {
29409
+ onClick,
29410
+ className: "p-2 rounded-lg hover:bg-destructive/10 hover:text-destructive transition-all duration-200 group",
29411
+ title: "Clear all activity",
29412
+ children: /* @__PURE__ */ jsxRuntimeExports.jsx(Trash2, { className: "w-5 h-5 text-muted-foreground group-hover:text-destructive" })
29413
+ }
29414
+ );
29415
+ }
29416
+ };
29417
+ const CopyLogsButton = ({
29418
+ onClick,
29419
+ count: count2
29420
+ }) => {
29421
+ if (count2 > 0) {
29422
+ return /* @__PURE__ */ jsxRuntimeExports.jsx(
29423
+ "button",
29424
+ {
29425
+ onClick,
29426
+ className: "p-2 rounded-lg hover:bg-accent/50 hover:text-foreground transition-all duration-200 group",
29427
+ title: "Copy all logs to clipboard",
29428
+ children: /* @__PURE__ */ jsxRuntimeExports.jsx(Copy, { className: "w-5 h-5 text-muted-foreground group-hover:text-foreground" })
29429
+ }
29430
+ );
29431
+ }
29432
+ };
29390
29433
  return /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "bg-transparent flex flex-col h-full", children: [
29391
29434
  /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex items-center justify-between border-b border-border/20 px-6 py-3", children: [
29392
29435
  /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex space-x-1", children: [
@@ -29394,18 +29437,48 @@ const TabbedHistoryPanel = ({
29394
29437
  renderResultsTabButton(),
29395
29438
  renderLogsTabButton()
29396
29439
  ] }),
29397
- /* @__PURE__ */ jsxRuntimeExports.jsx(
29398
- "button",
29399
- {
29400
- onClick: onToggleCollapse,
29401
- className: "p-2 rounded-lg hover:bg-accent/50 transition-all duration-200",
29402
- children: /* @__PURE__ */ jsxRuntimeExports.jsx(ChevronDown, { className: "w-5 h-5 text-muted-foreground hover:text-foreground" })
29403
- }
29404
- )
29440
+ /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex items-center", children: [
29441
+ activeTab === "activity" && /* @__PURE__ */ jsxRuntimeExports.jsx(
29442
+ ClearHistoryButton2,
29443
+ {
29444
+ onClick: onClearHistory,
29445
+ count: requestHistory.length
29446
+ }
29447
+ ),
29448
+ activeTab === "logs" && /* @__PURE__ */ jsxRuntimeExports.jsxs(jsxRuntimeExports.Fragment, { children: [
29449
+ /* @__PURE__ */ jsxRuntimeExports.jsx(
29450
+ CopyLogsButton,
29451
+ {
29452
+ onClick: handleCopyLogs,
29453
+ count: clientLogs.length
29454
+ }
29455
+ ),
29456
+ /* @__PURE__ */ jsxRuntimeExports.jsx(
29457
+ ClearHistoryButton2,
29458
+ {
29459
+ onClick: onClearLogs,
29460
+ count: clientLogs.length
29461
+ }
29462
+ )
29463
+ ] }),
29464
+ /* @__PURE__ */ jsxRuntimeExports.jsx(
29465
+ "button",
29466
+ {
29467
+ onClick: onToggleCollapse,
29468
+ className: "p-2 rounded-lg hover:bg-accent/50 transition-all duration-200",
29469
+ children: /* @__PURE__ */ jsxRuntimeExports.jsx(ChevronDown, { className: "w-5 h-5 text-muted-foreground hover:text-foreground" })
29470
+ }
29471
+ )
29472
+ ] })
29405
29473
  ] }),
29406
29474
  /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "flex-1 overflow-hidden", children: renderTabContent() })
29407
29475
  ] });
29408
29476
  };
29477
+ const TAB_CONFIG = [
29478
+ { key: "activity", label: "History" },
29479
+ { key: "results", label: "Results" },
29480
+ { key: "logs", label: "Logs" }
29481
+ ];
29409
29482
  const HistoryAndNotifications = ({
29410
29483
  requestHistory,
29411
29484
  toolResult,
@@ -29413,109 +29486,113 @@ const HistoryAndNotifications = ({
29413
29486
  onClearHistory,
29414
29487
  onClearLogs
29415
29488
  }) => {
29416
- const [isHistoryCollapsed, setIsHistoryCollapsed] = reactExports.useState(true);
29417
- const {
29418
- height: historyPaneHeight,
29419
- isDragging,
29420
- handleDragStart,
29421
- resetHeight,
29422
- setCustomHeight
29423
- } = useDraggablePane(500, "historyPaneHeight");
29489
+ const [isCollapsed, setIsCollapsed] = reactExports.useState(true);
29490
+ const [activeTab, setActiveTab] = reactExports.useState(null);
29491
+ const { height, isDragging, handleDragStart, resetHeight, setCustomHeight } = useDraggablePane(500, "historyPaneHeight");
29424
29492
  const toggleCollapse = reactExports.useCallback(() => {
29425
- setIsHistoryCollapsed(!isHistoryCollapsed);
29426
- }, [isHistoryCollapsed]);
29493
+ setIsCollapsed((collapsed) => {
29494
+ const next = !collapsed;
29495
+ if (next) setActiveTab(null);
29496
+ return next;
29497
+ });
29498
+ }, []);
29427
29499
  const handleDoubleClick = reactExports.useCallback(() => {
29428
- if (!isHistoryCollapsed) {
29429
- resetHeight();
29430
- }
29431
- }, [isHistoryCollapsed, resetHeight]);
29500
+ if (!isCollapsed) resetHeight();
29501
+ }, [isCollapsed, resetHeight]);
29432
29502
  reactExports.useEffect(() => {
29433
- const handleKeyDown = (e) => {
29434
- var _a2, _b, _c, _d;
29435
- if (isHistoryCollapsed || ((_b = (_a2 = e.target) == null ? void 0 : _a2.tagName) == null ? void 0 : _b.toLowerCase()) === "input" || ((_d = (_c = e.target) == null ? void 0 : _c.tagName) == null ? void 0 : _d.toLowerCase()) === "textarea") {
29436
- return;
29437
- }
29438
- if (e.altKey && (e.key === "ArrowUp" || e.key === "ArrowDown")) {
29439
- e.preventDefault();
29440
- const increment = e.shiftKey ? 50 : 25;
29441
- const newHeight = e.key === "ArrowUp" ? historyPaneHeight + increment : historyPaneHeight - increment;
29442
- setCustomHeight(newHeight);
29443
- }
29444
- if (e.altKey && e.key === "r") {
29445
- e.preventDefault();
29446
- resetHeight();
29447
- }
29448
- };
29449
- window.addEventListener("keydown", handleKeyDown);
29450
- return () => window.removeEventListener("keydown", handleKeyDown);
29451
- }, [isHistoryCollapsed, historyPaneHeight, setCustomHeight, resetHeight]);
29503
+ }, [isCollapsed, height, setCustomHeight, resetHeight]);
29452
29504
  reactExports.useEffect(() => {
29453
29505
  if (toolResult) {
29454
- setIsHistoryCollapsed(false);
29506
+ setActiveTab("results");
29507
+ setIsCollapsed(false);
29455
29508
  }
29456
29509
  }, [toolResult]);
29457
29510
  reactExports.useEffect(() => {
29458
- if (clientLogs.length > 0) {
29459
- const isLastError = clientLogs[clientLogs.length - 1].level === "error";
29460
- if (isLastError) {
29461
- setIsHistoryCollapsed(false);
29462
- }
29511
+ if (clientLogs.length > 0 && clientLogs[clientLogs.length - 1].level === "error") {
29512
+ setActiveTab("logs");
29513
+ setIsCollapsed(false);
29463
29514
  }
29464
29515
  }, [clientLogs]);
29516
+ reactExports.useEffect(() => {
29517
+ if (requestHistory.length === 0) return;
29518
+ const last = requestHistory[requestHistory.length - 1];
29519
+ if (!last.request) return;
29520
+ try {
29521
+ const parsed = JSON.parse(last.request);
29522
+ if (parsed.method === "ping") {
29523
+ setActiveTab("activity");
29524
+ setIsCollapsed(false);
29525
+ }
29526
+ } catch {
29527
+ }
29528
+ }, [requestHistory]);
29529
+ const counts = {
29530
+ activity: requestHistory.length,
29531
+ results: toolResult ? 1 : 0,
29532
+ logs: clientLogs.length
29533
+ };
29465
29534
  return /* @__PURE__ */ jsxRuntimeExports.jsxs(
29466
29535
  "div",
29467
29536
  {
29468
- className: `relative bg-gradient-to-r from-card/95 via-card to-card/95 backdrop-blur-md border-t border-border/30 transition-all duration-500 ease-out ${isHistoryCollapsed ? "shadow-lg shadow-black/5" : "shadow-2xl shadow-black/10"}`,
29469
- style: {
29470
- height: `${isHistoryCollapsed ? 60 : historyPaneHeight}px`
29471
- },
29537
+ className: `relative bg-card backdrop-blur-md border-t border-border/30 transition-shadow duration-300 ${isCollapsed ? "shadow-md" : "shadow-xl"}`,
29538
+ style: { height: isCollapsed ? 40 : height },
29472
29539
  children: [
29473
29540
  /* @__PURE__ */ jsxRuntimeExports.jsx(
29474
29541
  "div",
29475
29542
  {
29476
- className: `absolute w-full h-3 -top-1.5 cursor-row-resize group flex items-center justify-center ${isDragging ? "bg-primary/20" : "hover:bg-border/20"} transition-all duration-200`,
29543
+ className: `absolute w-full h-3 -top-1.5 cursor-row-resize flex items-center justify-center ${isDragging ? "bg-primary/20" : "hover:bg-border/20"} transition-all duration-200`,
29477
29544
  onMouseDown: handleDragStart,
29478
29545
  onDoubleClick: handleDoubleClick,
29479
- title: "Drag to resize • Double-click to reset • Alt+↑/↓ to adjust • Alt+R to reset",
29546
+ title: "Drag to resize • Doubleclick to reset • Alt+↑↓ to adjust • Alt+R to reset",
29480
29547
  children: /* @__PURE__ */ jsxRuntimeExports.jsx(
29481
- "div",
29548
+ GripHorizontal,
29482
29549
  {
29483
- className: `flex items-center space-x-1 opacity-0 group-hover:opacity-100 transition-opacity duration-200 ${isDragging ? "opacity-100" : ""}`,
29484
- children: /* @__PURE__ */ jsxRuntimeExports.jsx(GripHorizontal, { className: "w-4 h-4 text-muted-foreground" })
29550
+ className: `w-4 h-4 text-muted-foreground transition-opacity duration-200 ${isDragging ? "opacity-100" : "opacity-0 group-hover:opacity-100"}`
29485
29551
  }
29486
29552
  )
29487
29553
  }
29488
29554
  ),
29489
- /* @__PURE__ */ jsxRuntimeExports.jsx(
29490
- "div",
29491
- {
29492
- className: `absolute w-full h-0.5 -top-0.5 transition-all duration-200 ${isDragging ? "bg-primary" : "bg-border/50"}`
29493
- }
29494
- ),
29495
- /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "h-full overflow-hidden", children: !isHistoryCollapsed ? /* @__PURE__ */ jsxRuntimeExports.jsx(
29496
- TabbedHistoryPanel,
29497
- {
29498
- requestHistory,
29499
- toolResult,
29500
- clientLogs,
29501
- onClearHistory,
29502
- onClearLogs,
29503
- onToggleCollapse: toggleCollapse
29504
- }
29505
- ) : /* @__PURE__ */ jsxRuntimeExports.jsx(
29506
- "div",
29507
- {
29508
- className: "h-full flex items-center justify-center bg-gradient-to-r from-muted/20 via-muted/30 to-muted/20 cursor-pointer hover:bg-gradient-to-r hover:from-muted/30 hover:via-muted/40 hover:to-muted/30 transition-all duration-200",
29509
- onClick: toggleCollapse,
29510
- children: /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex items-center space-x-4 text-muted-foreground", children: [
29511
- /* @__PURE__ */ jsxRuntimeExports.jsx(History, { className: "w-5 h-5" }),
29512
- /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "text-sm font-medium", children: "History & Results" }),
29513
- requestHistory.length > 0 && /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "px-2 py-1 text-xs bg-primary/10 text-primary rounded-full", children: requestHistory.length }),
29514
- clientLogs.length > 0 && /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "px-2 py-1 text-xs bg-blue-500/10 text-blue-500 rounded-full", children: clientLogs.length }),
29515
- /* @__PURE__ */ jsxRuntimeExports.jsx(ChevronDown, { className: "w-4 h-4 rotate-180" })
29516
- ] })
29517
- }
29518
- ) })
29555
+ isCollapsed ? (
29556
+ /* Collapsed: tab bar */
29557
+ /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "h-full flex items-center", children: [
29558
+ TAB_CONFIG.map(({ key, label }) => /* @__PURE__ */ jsxRuntimeExports.jsxs(
29559
+ "button",
29560
+ {
29561
+ onClick: () => {
29562
+ setActiveTab(key);
29563
+ setIsCollapsed(false);
29564
+ },
29565
+ className: `flex items-center h-full px-4 text-sm font-medium transition-colors duration-200 ${activeTab === key ? "border-b-2 border-primary text-foreground" : "text-muted-foreground hover:text-foreground"}`,
29566
+ children: [
29567
+ label,
29568
+ counts[key] > 0 && /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "ml-1 px-1 rounded bg-muted/30 text-xs", children: counts[key] })
29569
+ ]
29570
+ },
29571
+ key
29572
+ )),
29573
+ /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "ml-auto pr-3 cursor-pointer", onClick: toggleCollapse, children: /* @__PURE__ */ jsxRuntimeExports.jsx(
29574
+ ChevronDown,
29575
+ {
29576
+ className: `w-5 h-5 transform transition-transform duration-200 ${isCollapsed ? "rotate-180" : "rotate-0"}`
29577
+ }
29578
+ ) })
29579
+ ] })
29580
+ ) : (
29581
+ /* Expanded: full panel */
29582
+ /* @__PURE__ */ jsxRuntimeExports.jsx(
29583
+ TabbedHistoryPanel,
29584
+ {
29585
+ requestHistory,
29586
+ toolResult,
29587
+ clientLogs,
29588
+ onClearHistory,
29589
+ onClearLogs,
29590
+ onToggleCollapse: toggleCollapse,
29591
+ activeTab,
29592
+ setActiveTab
29593
+ }
29594
+ )
29595
+ )
29519
29596
  ]
29520
29597
  }
29521
29598
  );
@@ -33971,8 +34048,8 @@ const SelectSeparator = reactExports.forwardRef(({ className, ...props }, ref2)
33971
34048
  SelectSeparator.displayName = Separator$1.displayName;
33972
34049
  const useTheme = () => {
33973
34050
  const [theme, setTheme] = reactExports.useState(() => {
33974
- const savedTheme = localStorage.getItem("theme");
33975
- return savedTheme || "system";
34051
+ const savedTheme2 = localStorage.getItem("theme");
34052
+ return savedTheme2 || "system";
33976
34053
  });
33977
34054
  reactExports.useEffect(() => {
33978
34055
  const darkModeMediaQuery = window.matchMedia(
@@ -33999,7 +34076,10 @@ const useTheme = () => {
33999
34076
  const setThemeWithSideEffect = reactExports.useCallback((newTheme) => {
34000
34077
  setTheme(newTheme);
34001
34078
  localStorage.setItem("theme", newTheme);
34002
- if (newTheme !== "system") {
34079
+ if (newTheme === "system") {
34080
+ const isDark = window.matchMedia("(prefers-color-scheme: dark)").matches;
34081
+ document.documentElement.classList.toggle("dark", isDark);
34082
+ } else {
34003
34083
  document.documentElement.classList.toggle("dark", newTheme === "dark");
34004
34084
  }
34005
34085
  }, []);
@@ -34008,7 +34088,7 @@ const useTheme = () => {
34008
34088
  [theme, setThemeWithSideEffect]
34009
34089
  );
34010
34090
  };
34011
- const version$1 = "0.3.4";
34091
+ const version$1 = "0.3.6";
34012
34092
  var [createTooltipContext, createTooltipScope] = createContextScope("Tooltip", [
34013
34093
  createPopperScope
34014
34094
  ]);
@@ -34491,124 +34571,59 @@ const TooltipContent = reactExports.forwardRef(({ className, sideOffset = 4, ...
34491
34571
  }
34492
34572
  ));
34493
34573
  TooltipContent.displayName = Content2$1.displayName;
34494
- const Sidebar = ({
34495
- mcpAgent,
34574
+ class StringUtil {
34575
+ static shorten(str2, maxLength = 30) {
34576
+ return str2.length > maxLength ? str2.substring(0, maxLength - 3) + "..." : str2;
34577
+ }
34578
+ }
34579
+ const getConnectionStatusIcon = (status) => {
34580
+ switch (status) {
34581
+ case "connected":
34582
+ return /* @__PURE__ */ jsxRuntimeExports.jsx(Wifi, { className: "w-4 h-4 text-green-500" });
34583
+ case "disconnected":
34584
+ return /* @__PURE__ */ jsxRuntimeExports.jsx(WifiOff, { className: "w-4 h-4 text-gray-400" });
34585
+ case "error":
34586
+ case "error-connecting-to-proxy":
34587
+ return /* @__PURE__ */ jsxRuntimeExports.jsx(CircleAlert, { className: "w-4 h-4 text-red-500" });
34588
+ default:
34589
+ return /* @__PURE__ */ jsxRuntimeExports.jsx(WifiOff, { className: "w-4 h-4 text-gray-400" });
34590
+ }
34591
+ };
34592
+ const getConnectionStatusColor = (status) => {
34593
+ switch (status) {
34594
+ case "connected":
34595
+ return "text-green-600 dark:text-green-400";
34596
+ case "disconnected":
34597
+ return "text-gray-500 dark:text-gray-400";
34598
+ case "error":
34599
+ case "error-connecting-to-proxy":
34600
+ return "text-red-600 dark:text-red-400";
34601
+ default:
34602
+ return "text-gray-500 dark:text-gray-400";
34603
+ }
34604
+ };
34605
+ const getConnectionDisplayText = (connection) => {
34606
+ var _a2;
34607
+ if (connection.config.transportType === "stdio" && "command" in connection.config) {
34608
+ return `${connection.config.command} ${((_a2 = connection.config.args) == null ? void 0 : _a2.join(" ")) || ""}`;
34609
+ }
34610
+ if ("url" in connection.config && connection.config.url) {
34611
+ return StringUtil.shorten(connection.config.url.toString());
34612
+ }
34613
+ return "Unknown configuration";
34614
+ };
34615
+ const ConnectionItem = ({
34616
+ connection,
34496
34617
  selectedServerName,
34497
34618
  onServerSelect,
34619
+ onEditClient,
34498
34620
  onRemoveServer,
34499
34621
  onConnectServer,
34500
34622
  onDisconnectServer,
34501
- onCreateClient,
34502
- onEditClient,
34503
- updateTrigger,
34504
- isExpanded,
34505
- onToggleExpanded
34623
+ shouldDisableConnection,
34624
+ getConnectTooltipMessage
34506
34625
  }) => {
34507
- const [theme, setTheme] = useTheme();
34508
- const serverConnections = React.useMemo(() => {
34509
- return mcpAgent ? mcpAgent.getAllConnectionInfo() : [];
34510
- }, [mcpAgent, updateTrigger]);
34511
- const getLogoSrc = () => {
34512
- if (theme === "dark") {
34513
- return "/mcp_jam_dark.png";
34514
- } else if (theme === "light") {
34515
- return "/mcp_jam_light.png";
34516
- } else {
34517
- const isDarkMode = document.documentElement.classList.contains("dark");
34518
- return isDarkMode ? "/mcp_jam_dark.png" : "/mcp_jam_light.png";
34519
- }
34520
- };
34521
- const getConnectionStatusIcon = (status) => {
34522
- switch (status) {
34523
- case "connected":
34524
- return /* @__PURE__ */ jsxRuntimeExports.jsx(Wifi, { className: "w-4 h-4 text-green-500" });
34525
- case "disconnected":
34526
- return /* @__PURE__ */ jsxRuntimeExports.jsx(WifiOff, { className: "w-4 h-4 text-gray-400" });
34527
- case "error":
34528
- case "error-connecting-to-proxy":
34529
- return /* @__PURE__ */ jsxRuntimeExports.jsx(CircleAlert, { className: "w-4 h-4 text-red-500" });
34530
- default:
34531
- return /* @__PURE__ */ jsxRuntimeExports.jsx(WifiOff, { className: "w-4 h-4 text-gray-400" });
34532
- }
34533
- };
34534
- const getConnectionStatusColor = (status) => {
34535
- switch (status) {
34536
- case "connected":
34537
- return "text-green-600 dark:text-green-400";
34538
- case "disconnected":
34539
- return "text-gray-500 dark:text-gray-400";
34540
- case "error":
34541
- case "error-connecting-to-proxy":
34542
- return "text-red-600 dark:text-red-400";
34543
- default:
34544
- return "text-gray-500 dark:text-gray-400";
34545
- }
34546
- };
34547
- const shouldDisableConnection = () => {
34548
- return false;
34549
- };
34550
- const getConnectTooltipMessage = () => {
34551
- return "Connect to this server";
34552
- };
34553
- const getConnectionDisplayText = (connection) => {
34554
- var _a2;
34555
- if (connection.config.transportType === "stdio" && "command" in connection.config) {
34556
- return `${connection.config.command} ${((_a2 = connection.config.args) == null ? void 0 : _a2.join(" ")) || ""}`;
34557
- }
34558
- if ("url" in connection.config && connection.config.url) {
34559
- return connection.config.url.toString();
34560
- }
34561
- return "Unknown configuration";
34562
- };
34563
- const renderHeader = () => /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "p-4 border-b border-gray-200 dark:border-gray-800", children: /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex flex-col items-center space-y-2", children: [
34564
- /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "w-full flex justify-center", children: /* @__PURE__ */ jsxRuntimeExports.jsx(
34565
- "img",
34566
- {
34567
- src: getLogoSrc(),
34568
- alt: "MCP Jam",
34569
- className: "h-6 w-auto object-contain transition-opacity duration-200",
34570
- onError: (e) => {
34571
- console.warn("Failed to load MCP Jam logo");
34572
- e.currentTarget.style.display = "none";
34573
- }
34574
- }
34575
- ) }),
34576
- /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "text-center", children: /* @__PURE__ */ jsxRuntimeExports.jsxs("p", { className: "text-xs text-muted-foreground opacity-70", children: [
34577
- "v",
34578
- version$1
34579
- ] }) })
34580
- ] }) });
34581
- const renderConnectionsHeader = () => /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "p-3 border-b border-border/50", children: /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex items-center justify-between", children: [
34582
- /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex items-center space-x-2", children: [
34583
- /* @__PURE__ */ jsxRuntimeExports.jsx(Server, { className: "w-4 h-4 text-muted-foreground" }),
34584
- /* @__PURE__ */ jsxRuntimeExports.jsx("h3", { className: "text-sm font-medium text-foreground", children: "Connections" }),
34585
- /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "text-xs text-muted-foreground bg-muted px-1.5 py-0.5 rounded", children: serverConnections.length })
34586
- ] }),
34587
- /* @__PURE__ */ jsxRuntimeExports.jsxs(Tooltip, { children: [
34588
- /* @__PURE__ */ jsxRuntimeExports.jsx(TooltipTrigger, { asChild: true, children: /* @__PURE__ */ jsxRuntimeExports.jsx(
34589
- Button,
34590
- {
34591
- onClick: onCreateClient,
34592
- size: "sm",
34593
- variant: "ghost",
34594
- className: "h-7 w-7 p-0 hover:bg-primary/20 hover:text-primary",
34595
- title: "Create new client",
34596
- children: /* @__PURE__ */ jsxRuntimeExports.jsx(Plus, { className: "w-4 h-4" })
34597
- }
34598
- ) }),
34599
- /* @__PURE__ */ jsxRuntimeExports.jsx(TooltipContent, { children: (mcpAgent == null ? void 0 : mcpAgent.hasConnectedRemoteServer()) ? "Note: Creating a remote client will disconnect the current remote connection" : "Create new client" })
34600
- ] })
34601
- ] }) });
34602
- const renderEmptyState = () => /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "p-4 text-center", children: /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "py-8", children: [
34603
- /* @__PURE__ */ jsxRuntimeExports.jsx(Server, { className: "w-12 h-12 text-muted-foreground mx-auto mb-4" }),
34604
- /* @__PURE__ */ jsxRuntimeExports.jsx("h3", { className: "text-sm font-medium mb-2", children: "No connections" }),
34605
- /* @__PURE__ */ jsxRuntimeExports.jsx("p", { className: "text-xs text-muted-foreground mb-4", children: "Create your first MCP connection to get started" }),
34606
- /* @__PURE__ */ jsxRuntimeExports.jsxs(Button, { onClick: onCreateClient, size: "sm", className: "w-full", children: [
34607
- /* @__PURE__ */ jsxRuntimeExports.jsx(Plus, { className: "w-4 h-4 mr-2" }),
34608
- "Create Connection"
34609
- ] })
34610
- ] }) });
34611
- const renderConnectionActions = (connection) => /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex space-x-1", children: [
34626
+ const renderConnectionActions = () => /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex space-x-1", children: [
34612
34627
  /* @__PURE__ */ jsxRuntimeExports.jsx(
34613
34628
  Button,
34614
34629
  {
@@ -34636,7 +34651,7 @@ const Sidebar = ({
34636
34651
  }
34637
34652
  )
34638
34653
  ] });
34639
- const renderConnectionButton = (connection) => {
34654
+ const renderConnectionButton = () => {
34640
34655
  if (connection.connectionStatus === "connected") {
34641
34656
  return /* @__PURE__ */ jsxRuntimeExports.jsx(
34642
34657
  Button,
@@ -34670,7 +34685,7 @@ const Sidebar = ({
34670
34685
  /* @__PURE__ */ jsxRuntimeExports.jsx(TooltipContent, { children: getConnectTooltipMessage() })
34671
34686
  ] });
34672
34687
  };
34673
- const renderConnectionItem = (connection) => /* @__PURE__ */ jsxRuntimeExports.jsx(
34688
+ return /* @__PURE__ */ jsxRuntimeExports.jsx(
34674
34689
  "div",
34675
34690
  {
34676
34691
  className: `p-3 rounded-lg border cursor-pointer transition-all hover:bg-muted/50 ${selectedServerName === connection.name ? "border-primary bg-primary/10" : "border-border"}`,
@@ -34681,10 +34696,10 @@ const Sidebar = ({
34681
34696
  getConnectionStatusIcon(connection.connectionStatus),
34682
34697
  /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { children: [
34683
34698
  /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "font-medium text-sm", children: connection.name }),
34684
- /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "text-xs text-muted-foreground", children: getConnectionDisplayText(connection) })
34699
+ /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: `text-xs text-muted-foreground break-all`, children: getConnectionDisplayText(connection) })
34685
34700
  ] })
34686
34701
  ] }),
34687
- renderConnectionActions(connection)
34702
+ renderConnectionActions()
34688
34703
  ] }),
34689
34704
  /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex items-center justify-between", children: [
34690
34705
  /* @__PURE__ */ jsxRuntimeExports.jsx(
@@ -34694,12 +34709,93 @@ const Sidebar = ({
34694
34709
  children: connection.connectionStatus
34695
34710
  }
34696
34711
  ),
34697
- /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "flex space-x-1", children: renderConnectionButton(connection) })
34712
+ /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "flex space-x-1", children: renderConnectionButton() })
34698
34713
  ] })
34699
34714
  ] })
34700
- },
34701
- connection.name
34715
+ }
34702
34716
  );
34717
+ };
34718
+ const Sidebar = ({
34719
+ mcpAgent,
34720
+ selectedServerName,
34721
+ onServerSelect,
34722
+ onRemoveServer,
34723
+ onConnectServer,
34724
+ onDisconnectServer,
34725
+ onCreateClient,
34726
+ onEditClient,
34727
+ updateTrigger,
34728
+ isExpanded,
34729
+ onToggleExpanded
34730
+ }) => {
34731
+ const [theme, setTheme] = useTheme();
34732
+ const serverConnections = React.useMemo(() => {
34733
+ return mcpAgent ? mcpAgent.getAllConnectionInfo() : [];
34734
+ }, [mcpAgent, updateTrigger]);
34735
+ const getLogoSrc = () => {
34736
+ if (theme === "dark") {
34737
+ return "/mcp_jam_dark.png";
34738
+ } else if (theme === "light") {
34739
+ return "/mcp_jam_light.png";
34740
+ } else {
34741
+ const isDarkMode = document.documentElement.classList.contains("dark");
34742
+ return isDarkMode ? "/mcp_jam_dark.png" : "/mcp_jam_light.png";
34743
+ }
34744
+ };
34745
+ const shouldDisableConnection = () => {
34746
+ return false;
34747
+ };
34748
+ const getConnectTooltipMessage = () => {
34749
+ return "Connect to this server";
34750
+ };
34751
+ const renderHeader = () => /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "p-4 border-b border-gray-200 dark:border-gray-800", children: /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex flex-col items-center space-y-2", children: [
34752
+ /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "w-full flex justify-center", children: /* @__PURE__ */ jsxRuntimeExports.jsx(
34753
+ "img",
34754
+ {
34755
+ src: getLogoSrc(),
34756
+ alt: "MCP Jam",
34757
+ className: "h-6 w-auto object-contain transition-opacity duration-200",
34758
+ onError: (e) => {
34759
+ console.warn("Failed to load MCP Jam logo");
34760
+ e.currentTarget.style.display = "none";
34761
+ }
34762
+ }
34763
+ ) }),
34764
+ /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "text-center", children: /* @__PURE__ */ jsxRuntimeExports.jsxs("p", { className: "text-xs text-muted-foreground opacity-70", children: [
34765
+ "v",
34766
+ version$1
34767
+ ] }) })
34768
+ ] }) });
34769
+ const renderConnectionsHeader = () => /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "p-3 border-b border-border/50", children: /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex items-center justify-between", children: [
34770
+ /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex items-center space-x-2", children: [
34771
+ /* @__PURE__ */ jsxRuntimeExports.jsx(Server, { className: "w-4 h-4 text-muted-foreground" }),
34772
+ /* @__PURE__ */ jsxRuntimeExports.jsx("h3", { className: "text-sm font-medium text-foreground", children: "Connections" }),
34773
+ /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "text-xs text-muted-foreground bg-muted px-1.5 py-0.5 rounded", children: serverConnections.length })
34774
+ ] }),
34775
+ /* @__PURE__ */ jsxRuntimeExports.jsxs(Tooltip, { children: [
34776
+ /* @__PURE__ */ jsxRuntimeExports.jsx(TooltipTrigger, { asChild: true, children: /* @__PURE__ */ jsxRuntimeExports.jsx(
34777
+ Button,
34778
+ {
34779
+ onClick: onCreateClient,
34780
+ size: "sm",
34781
+ variant: "ghost",
34782
+ className: "h-7 w-7 p-0 hover:bg-primary/20 hover:text-primary",
34783
+ title: "Create new connection",
34784
+ children: /* @__PURE__ */ jsxRuntimeExports.jsx(Plus, { className: "w-4 h-4" })
34785
+ }
34786
+ ) }),
34787
+ /* @__PURE__ */ jsxRuntimeExports.jsx(TooltipContent, { children: (mcpAgent == null ? void 0 : mcpAgent.hasConnectedRemoteServer()) ? "Note: Creating a remote connection will disconnect the current remote connection" : "Create new connection" })
34788
+ ] })
34789
+ ] }) });
34790
+ const renderEmptyState = () => /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "p-4 text-center", children: /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "py-8", children: [
34791
+ /* @__PURE__ */ jsxRuntimeExports.jsx(Server, { className: "w-12 h-12 text-muted-foreground mx-auto mb-4" }),
34792
+ /* @__PURE__ */ jsxRuntimeExports.jsx("h3", { className: "text-sm font-medium mb-2", children: "No connections" }),
34793
+ /* @__PURE__ */ jsxRuntimeExports.jsx("p", { className: "text-xs text-muted-foreground mb-4", children: "Create your first MCP connection to get started" }),
34794
+ /* @__PURE__ */ jsxRuntimeExports.jsxs(Button, { onClick: onCreateClient, size: "sm", className: "w-full", children: [
34795
+ /* @__PURE__ */ jsxRuntimeExports.jsx(Plus, { className: "w-4 h-4 mr-2" }),
34796
+ "Create Connection"
34797
+ ] })
34798
+ ] }) });
34703
34799
  const renderThemeSelector = () => /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "p-4 border-t", children: /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex items-center justify-between", children: [
34704
34800
  /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex items-center space-x-2", children: [
34705
34801
  /* @__PURE__ */ jsxRuntimeExports.jsxs(Tooltip, { children: [
@@ -34779,7 +34875,21 @@ const Sidebar = ({
34779
34875
  renderConnectionsHeader(),
34780
34876
  /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "flex-1 overflow-hidden flex flex-col", children: /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "flex-1 flex flex-col min-h-0", children: /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex-1 overflow-y-auto", children: [
34781
34877
  shouldShowCreatePrompt && renderEmptyState(),
34782
- serverConnections.length > 0 && /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "p-3 space-y-2", children: serverConnections.map(renderConnectionItem) })
34878
+ serverConnections.length > 0 && /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "p-3 space-y-2", children: serverConnections.map((connection) => /* @__PURE__ */ jsxRuntimeExports.jsx(
34879
+ ConnectionItem,
34880
+ {
34881
+ connection,
34882
+ selectedServerName,
34883
+ onServerSelect,
34884
+ onEditClient,
34885
+ onRemoveServer,
34886
+ onConnectServer,
34887
+ onDisconnectServer,
34888
+ shouldDisableConnection,
34889
+ getConnectTooltipMessage
34890
+ },
34891
+ connection.name
34892
+ )) })
34783
34893
  ] }) }) }),
34784
34894
  renderThemeSelector()
34785
34895
  ] });
@@ -34811,7 +34921,7 @@ const Sidebar = ({
34811
34921
  children: /* @__PURE__ */ jsxRuntimeExports.jsx(Plus, { className: "w-4 h-4" })
34812
34922
  }
34813
34923
  ) }),
34814
- /* @__PURE__ */ jsxRuntimeExports.jsx(TooltipContent, { side: "right", children: "Create new client" })
34924
+ /* @__PURE__ */ jsxRuntimeExports.jsx(TooltipContent, { side: "right", children: "Create new connection" })
34815
34925
  ] })
34816
34926
  ] }) });
34817
34927
  };
@@ -34847,7 +34957,7 @@ const Tabs = ({
34847
34957
  },
34848
34958
  {
34849
34959
  id: "chat",
34850
- label: "Chat",
34960
+ label: "Playground",
34851
34961
  icon: Bot,
34852
34962
  disabled: shouldDisableAll
34853
34963
  },
@@ -36448,6 +36558,48 @@ const ConnectionSection = ({
36448
36558
  )
36449
36559
  ] });
36450
36560
  };
36561
+ function configToDisplayStrings(config) {
36562
+ var _a2, _b;
36563
+ const argsString = config.transportType === "stdio" && "args" in config ? ((_a2 = config.args) == null ? void 0 : _a2.join(" ")) || "" : "";
36564
+ const urlString = config.transportType !== "stdio" && "url" in config ? ((_b = config.url) == null ? void 0 : _b.toString()) || "" : "";
36565
+ return { argsString, urlString };
36566
+ }
36567
+ function createStdioConfig(command, args = [], env = {}) {
36568
+ return {
36569
+ transportType: "stdio",
36570
+ command,
36571
+ args,
36572
+ env
36573
+ };
36574
+ }
36575
+ function createHttpConfig(url, transportType = "sse") {
36576
+ return {
36577
+ transportType,
36578
+ url
36579
+ };
36580
+ }
36581
+ function updateConfigFromStrings(config, argsString) {
36582
+ if (config.transportType === "stdio") {
36583
+ return {
36584
+ ...config,
36585
+ args: argsString.trim() ? argsString.split(/\s+/) : []
36586
+ };
36587
+ } else {
36588
+ return config;
36589
+ }
36590
+ }
36591
+ function createDefaultStdioConfig() {
36592
+ return createStdioConfig("npx", ["@modelcontextprotocol/server-everything"]);
36593
+ }
36594
+ function createDefaultHttpConfig(transportType = "sse") {
36595
+ return createHttpConfig(new URL("https://example.com"), transportType);
36596
+ }
36597
+ function isStdioConfig(config) {
36598
+ return config.transportType === "stdio";
36599
+ }
36600
+ function isHttpConfig(config) {
36601
+ return config.transportType !== "stdio";
36602
+ }
36451
36603
  var NAME = "Label";
36452
36604
  var Label$1 = reactExports.forwardRef((props, forwardedRef) => {
36453
36605
  return /* @__PURE__ */ jsxRuntimeExports.jsx(
@@ -36571,10 +36723,7 @@ function Badge({ className, variant, ...props }) {
36571
36723
  const ClientFormSection = ({
36572
36724
  isCreating,
36573
36725
  editingClientName,
36574
- clientFormName,
36575
- setClientFormName,
36576
- clientFormConfig,
36577
- setClientFormConfig,
36726
+ initialClient,
36578
36727
  config,
36579
36728
  setConfig,
36580
36729
  bearerToken,
@@ -36583,78 +36732,95 @@ const ClientFormSection = ({
36583
36732
  setHeaderName,
36584
36733
  onSave,
36585
36734
  onCancel,
36586
- onImportMultipleServers,
36587
- onSaveMultiple
36735
+ onImportMultipleServers
36588
36736
  }) => {
36589
- const [argsString, setArgsString] = reactExports.useState("");
36590
- const [sseUrlString, setSseUrlString] = reactExports.useState("");
36591
- const [multipleClients, setMultipleClients] = reactExports.useState([]);
36592
- const [isMultipleMode, setIsMultipleMode] = reactExports.useState(false);
36593
- const [isManualConfigExpanded, setIsManualConfigExpanded] = reactExports.useState(false);
36737
+ const [multipleClients, setMultipleClients] = reactExports.useState(() => {
36738
+ if (initialClient) {
36739
+ return [
36740
+ {
36741
+ id: "editing-client",
36742
+ name: initialClient.name,
36743
+ config: initialClient.config
36744
+ }
36745
+ ];
36746
+ } else {
36747
+ return [
36748
+ {
36749
+ id: "new-client",
36750
+ name: "",
36751
+ config: createDefaultStdioConfig()
36752
+ }
36753
+ ];
36754
+ }
36755
+ });
36756
+ console.log("🔧 multipleClients", multipleClients);
36757
+ const [isManualConfigExpanded, setIsManualConfigExpanded] = reactExports.useState(true);
36594
36758
  const { toast: toast2 } = useToast();
36595
36759
  const [showImportDialog, setShowImportDialog] = reactExports.useState(false);
36596
36760
  const [nameError, setNameError] = reactExports.useState("");
36761
+ const [isNameTouched, setIsNameTouched] = reactExports.useState(false);
36762
+ const scrollContainerRef = reactExports.useRef(null);
36763
+ const isMultipleMode = multipleClients.length > 1;
36764
+ const currentClient = multipleClients[0] || {
36765
+ id: "default",
36766
+ name: "",
36767
+ config: createDefaultStdioConfig()
36768
+ };
36769
+ const handleUpdateCurrentClient = (updates) => {
36770
+ setMultipleClients(
36771
+ (prev) => prev.map(
36772
+ (client2) => client2.id === currentClient.id ? { ...client2, ...updates } : client2
36773
+ )
36774
+ );
36775
+ };
36597
36776
  reactExports.useEffect(() => {
36598
- var _a2, _b;
36599
- if (clientFormConfig.transportType === "stdio" && "args" in clientFormConfig) {
36600
- setArgsString(((_a2 = clientFormConfig.args) == null ? void 0 : _a2.join(" ")) || "");
36601
- setSseUrlString("");
36602
- } else if (clientFormConfig.transportType !== "stdio" && "url" in clientFormConfig) {
36603
- setArgsString("");
36604
- setSseUrlString(((_b = clientFormConfig.url) == null ? void 0 : _b.toString()) || "");
36605
- }
36606
- }, [clientFormConfig]);
36607
- reactExports.useEffect(() => {
36608
- if (clientFormName.trim()) {
36777
+ if (!isNameTouched) return;
36778
+ if (currentClient.name.trim()) {
36609
36779
  setNameError("");
36610
36780
  } else {
36611
36781
  setNameError("Client name is required");
36612
36782
  }
36613
- }, [clientFormName]);
36783
+ }, [currentClient.name, isNameTouched]);
36614
36784
  const handleArgsChange = (newArgsString) => {
36615
- setArgsString(newArgsString);
36616
- if (clientFormConfig.transportType === "stdio") {
36617
- setClientFormConfig({
36618
- ...clientFormConfig,
36619
- args: newArgsString.trim() ? newArgsString.split(/\s+/) : []
36620
- });
36785
+ if (isStdioConfig(currentClient.config)) {
36786
+ const updatedConfig = updateConfigFromStrings(
36787
+ currentClient.config,
36788
+ newArgsString
36789
+ );
36790
+ handleUpdateCurrentClient({ config: updatedConfig });
36621
36791
  }
36622
36792
  };
36623
36793
  const handleSseUrlChange = (newSseUrlString) => {
36624
- setSseUrlString(newSseUrlString);
36794
+ if (isHttpConfig(currentClient.config)) {
36795
+ try {
36796
+ const newUrl = new URL(newSseUrlString || "https://example.com");
36797
+ handleUpdateCurrentClient({
36798
+ config: { ...currentClient.config, url: newUrl }
36799
+ });
36800
+ } catch {
36801
+ }
36802
+ }
36625
36803
  };
36626
36804
  const handleImportServers = (servers) => {
36627
- var _a2, _b;
36628
36805
  if (servers.length > 1) {
36629
- const clients = servers.map((server, index2) => {
36630
- var _a3, _b2;
36631
- return {
36632
- id: `client-${Date.now()}-${index2}`,
36633
- name: server.name,
36634
- config: server.config,
36635
- argsString: server.config.transportType === "stdio" && "args" in server.config ? ((_a3 = server.config.args) == null ? void 0 : _a3.join(" ")) || "" : "",
36636
- sseUrlString: server.config.transportType !== "stdio" && "url" in server.config ? ((_b2 = server.config.url) == null ? void 0 : _b2.toString()) || "" : ""
36637
- };
36638
- });
36806
+ const clients = servers.map((server, index2) => ({
36807
+ id: `client-${Date.now()}-${index2}`,
36808
+ name: server.name,
36809
+ config: server.config
36810
+ }));
36639
36811
  setMultipleClients(clients);
36640
- setIsMultipleMode(true);
36641
36812
  toast2({
36642
36813
  title: "Multiple servers imported",
36643
36814
  description: `Imported ${servers.length} server configurations. Configure each client below.`
36644
36815
  });
36645
36816
  } else if (servers.length === 1) {
36646
36817
  const firstServer = servers[0];
36647
- setClientFormConfig(firstServer.config);
36648
- if (!clientFormName.trim()) {
36649
- setClientFormName(firstServer.name);
36650
- }
36651
- if (firstServer.config.transportType === "stdio" && "args" in firstServer.config) {
36652
- setArgsString(((_a2 = firstServer.config.args) == null ? void 0 : _a2.join(" ")) || "");
36653
- setSseUrlString("");
36654
- } else if (firstServer.config.transportType !== "stdio" && "url" in firstServer.config) {
36655
- setArgsString("");
36656
- setSseUrlString(((_b = firstServer.config.url) == null ? void 0 : _b.toString()) || "");
36657
- }
36818
+ const updatedClient = {
36819
+ ...currentClient,
36820
+ name: currentClient.name.trim() || firstServer.name,
36821
+ config: firstServer.config
36822
+ };
36823
+ setMultipleClients([updatedClient]);
36658
36824
  toast2({
36659
36825
  title: "Configuration imported",
36660
36826
  description: `Imported configuration for "${firstServer.name}".`
@@ -36663,6 +36829,14 @@ const ClientFormSection = ({
36663
36829
  if (onImportMultipleServers) {
36664
36830
  onImportMultipleServers(servers);
36665
36831
  }
36832
+ setTimeout(() => {
36833
+ if (scrollContainerRef.current) {
36834
+ scrollContainerRef.current.scrollTo({
36835
+ top: scrollContainerRef.current.scrollHeight,
36836
+ behavior: "smooth"
36837
+ });
36838
+ }
36839
+ }, 100);
36666
36840
  };
36667
36841
  const handleUpdateClient = (clientId, updates) => {
36668
36842
  setMultipleClients(
@@ -36680,39 +36854,12 @@ const ClientFormSection = ({
36680
36854
  const newClient = {
36681
36855
  id: `client-${Date.now()}`,
36682
36856
  name: "",
36683
- config: {
36684
- transportType: "stdio",
36685
- command: "npx",
36686
- args: ["@modelcontextprotocol/server-everything"],
36687
- env: {}
36688
- },
36689
- argsString: "@modelcontextprotocol/server-everything",
36690
- sseUrlString: ""
36857
+ config: createDefaultStdioConfig()
36691
36858
  };
36692
36859
  setMultipleClients((prev) => [...prev, newClient]);
36693
36860
  };
36694
- const handleSingleSave = () => {
36695
- let configToSave = { ...clientFormConfig };
36696
- if (configToSave.transportType !== "stdio") {
36697
- try {
36698
- const url = new URL(sseUrlString);
36699
- configToSave = {
36700
- ...configToSave,
36701
- url
36702
- };
36703
- } catch {
36704
- toast2({
36705
- title: "Invalid URL",
36706
- description: "Please enter a valid URL for the client.",
36707
- variant: "destructive"
36708
- });
36709
- return;
36710
- }
36711
- }
36712
- onSave(configToSave);
36713
- };
36714
- const handleSaveAll = async () => {
36715
- if (!onSaveMultiple) return;
36861
+ const handleSave = async () => {
36862
+ var _a2;
36716
36863
  const validClients = multipleClients.filter((c) => c.name.trim());
36717
36864
  if (validClients.length === 0) {
36718
36865
  toast2({
@@ -36722,438 +36869,478 @@ const ClientFormSection = ({
36722
36869
  });
36723
36870
  return;
36724
36871
  }
36725
- const clientsToSave = validClients.map((client2) => {
36726
- let configToSave = { ...client2.config };
36727
- if (configToSave.transportType !== "stdio") {
36872
+ const clientsToSave = [];
36873
+ const configErrors = [];
36874
+ for (const client2 of validClients) {
36875
+ if (isHttpConfig(client2.config)) {
36876
+ if (!client2.config.url) {
36877
+ configErrors.push(
36878
+ `${client2.name}: URL is required for HTTP connections`
36879
+ );
36880
+ continue;
36881
+ }
36728
36882
  try {
36729
- const url = new URL(client2.sseUrlString);
36730
- configToSave = {
36731
- ...configToSave,
36732
- url
36733
- };
36883
+ new URL(client2.config.url.toString());
36734
36884
  } catch {
36735
- throw new Error(`Invalid URL for client "${client2.name}"`);
36885
+ configErrors.push(`${client2.name}: Invalid URL format`);
36886
+ continue;
36736
36887
  }
36737
36888
  }
36738
- return {
36889
+ if (isStdioConfig(client2.config)) {
36890
+ if (!((_a2 = client2.config.command) == null ? void 0 : _a2.trim())) {
36891
+ configErrors.push(
36892
+ `${client2.name}: Command is required for stdio connections`
36893
+ );
36894
+ continue;
36895
+ }
36896
+ }
36897
+ clientsToSave.push({
36739
36898
  name: client2.name,
36740
- config: configToSave
36741
- };
36742
- });
36899
+ config: client2.config
36900
+ });
36901
+ }
36902
+ if (configErrors.length > 0) {
36903
+ toast2({
36904
+ title: "Configuration errors",
36905
+ description: `Please fix the following errors: ${configErrors.join(", ")}`,
36906
+ variant: "destructive"
36907
+ });
36908
+ return;
36909
+ }
36910
+ console.log("🔧 clientsToSave", clientsToSave);
36743
36911
  try {
36744
- const result = await onSaveMultiple(clientsToSave);
36912
+ const result = await onSave(clientsToSave);
36745
36913
  if (result.success.length > 0) {
36746
36914
  toast2({
36747
- title: "Clients created successfully",
36748
- description: `Successfully created ${result.success.length} connection(s).`
36915
+ title: "Clients saved successfully",
36916
+ description: `Successfully saved ${result.success.length} connection(s).`
36749
36917
  });
36750
36918
  }
36751
36919
  if (result.failed.length > 0) {
36752
36920
  toast2({
36753
- title: "Some clients failed to create",
36754
- description: `${result.failed.length} connection(s) failed to create. Check the console for details.`,
36921
+ title: "Some clients failed to save",
36922
+ description: `${result.failed.length} connection(s) failed to save. Check the console for details.`,
36755
36923
  variant: "destructive"
36756
36924
  });
36757
36925
  }
36758
36926
  } catch (error) {
36759
36927
  toast2({
36760
- title: "Error creating clients",
36928
+ title: "Error saving clients",
36761
36929
  description: error instanceof Error ? error.message : "An unexpected error occurred.",
36762
36930
  variant: "destructive"
36763
36931
  });
36764
36932
  }
36765
36933
  };
36766
36934
  const handleBackToSingle = () => {
36767
- setIsMultipleMode(false);
36768
- setMultipleClients([]);
36935
+ setMultipleClients([
36936
+ {
36937
+ id: "new-client",
36938
+ name: "",
36939
+ config: createDefaultStdioConfig()
36940
+ }
36941
+ ]);
36769
36942
  };
36770
36943
  if (isMultipleMode) {
36771
- return /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "flex-1 flex flex-col overflow-auto bg-gradient-to-br from-background to-muted/20", children: /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "max-w-7xl mx-auto w-full p-6 space-y-6", children: [
36772
- /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex items-center gap-3", children: [
36773
- /* @__PURE__ */ jsxRuntimeExports.jsx(
36774
- Button,
36775
- {
36776
- variant: "ghost",
36777
- size: "sm",
36778
- onClick: handleBackToSingle,
36779
- className: "h-8 w-8 p-0",
36780
- children: /* @__PURE__ */ jsxRuntimeExports.jsx(ArrowLeft, { className: "h-4 w-4" })
36781
- }
36782
- ),
36783
- /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { children: [
36784
- /* @__PURE__ */ jsxRuntimeExports.jsx("h1", { className: "text-3xl font-bold tracking-tight", children: "Create Multiple Clients" }),
36785
- /* @__PURE__ */ jsxRuntimeExports.jsx("p", { className: "text-muted-foreground mt-1", children: "Configure each imported server as a separate client" })
36786
- ] }),
36787
- /* @__PURE__ */ jsxRuntimeExports.jsxs(Badge, { variant: "secondary", className: "ml-auto", children: [
36788
- /* @__PURE__ */ jsxRuntimeExports.jsx(Users, { className: "h-3 w-3 mr-1" }),
36789
- multipleClients.length,
36790
- " clients"
36791
- ] })
36792
- ] }),
36793
- /* @__PURE__ */ jsxRuntimeExports.jsx(Separator, {}),
36794
- /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "grid gap-6", children: [
36795
- multipleClients.map((client2, index2) => /* @__PURE__ */ jsxRuntimeExports.jsxs(
36796
- Card,
36797
- {
36798
- className: "border-2 border-border/50 hover:border-border transition-colors",
36799
- children: [
36800
- /* @__PURE__ */ jsxRuntimeExports.jsx(CardHeader, { className: "pb-4", children: /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex items-center justify-between", children: [
36801
- /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex items-center gap-3", children: [
36802
- /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "flex items-center justify-center w-8 h-8 rounded-full bg-primary/10 text-primary font-semibold text-sm", children: index2 + 1 }),
36803
- /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { children: [
36804
- /* @__PURE__ */ jsxRuntimeExports.jsxs(CardTitle, { className: "text-lg", children: [
36805
- "Client ",
36806
- index2 + 1
36944
+ return /* @__PURE__ */ jsxRuntimeExports.jsx(
36945
+ "div",
36946
+ {
36947
+ ref: scrollContainerRef,
36948
+ className: "flex-1 flex flex-col overflow-auto bg-gradient-to-br from-background to-muted/20",
36949
+ children: /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "max-w-7xl mx-auto w-full p-6 space-y-6", children: [
36950
+ /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex items-center gap-3", children: [
36951
+ /* @__PURE__ */ jsxRuntimeExports.jsx(
36952
+ Button,
36953
+ {
36954
+ variant: "ghost",
36955
+ size: "sm",
36956
+ onClick: handleBackToSingle,
36957
+ className: "h-8 w-8 p-0",
36958
+ children: /* @__PURE__ */ jsxRuntimeExports.jsx(ArrowLeft, { className: "h-4 w-4" })
36959
+ }
36960
+ ),
36961
+ /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { children: [
36962
+ /* @__PURE__ */ jsxRuntimeExports.jsx("h1", { className: "text-3xl font-bold tracking-tight", children: "Create Multiple Clients" }),
36963
+ /* @__PURE__ */ jsxRuntimeExports.jsx("p", { className: "text-muted-foreground mt-1", children: "Configure each imported server as a separate client" })
36964
+ ] }),
36965
+ /* @__PURE__ */ jsxRuntimeExports.jsxs(Badge, { variant: "secondary", className: "ml-auto", children: [
36966
+ /* @__PURE__ */ jsxRuntimeExports.jsx(Users, { className: "h-3 w-3 mr-1" }),
36967
+ multipleClients.length,
36968
+ " clients"
36969
+ ] })
36970
+ ] }),
36971
+ /* @__PURE__ */ jsxRuntimeExports.jsx(Separator, {}),
36972
+ /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "grid gap-6", children: [
36973
+ multipleClients.map((client2, index2) => /* @__PURE__ */ jsxRuntimeExports.jsxs(
36974
+ Card,
36975
+ {
36976
+ className: "border-2 border-border/50 hover:border-border transition-colors",
36977
+ children: [
36978
+ /* @__PURE__ */ jsxRuntimeExports.jsx(CardHeader, { className: "pb-4", children: /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex items-center justify-between", children: [
36979
+ /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex items-center gap-3", children: [
36980
+ /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "flex items-center justify-center w-8 h-8 rounded-full bg-primary/10 text-primary font-semibold text-sm", children: index2 + 1 }),
36981
+ /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { children: [
36982
+ /* @__PURE__ */ jsxRuntimeExports.jsxs(CardTitle, { className: "text-lg", children: [
36983
+ "Client ",
36984
+ index2 + 1
36985
+ ] }),
36986
+ /* @__PURE__ */ jsxRuntimeExports.jsx(CardDescription, { children: client2.name || "Unnamed client" })
36987
+ ] })
36988
+ ] }),
36989
+ /* @__PURE__ */ jsxRuntimeExports.jsx(
36990
+ Button,
36991
+ {
36992
+ variant: "ghost",
36993
+ size: "sm",
36994
+ onClick: () => handleRemoveClient(client2.id),
36995
+ className: "h-8 w-8 p-0 text-muted-foreground hover:text-destructive",
36996
+ children: /* @__PURE__ */ jsxRuntimeExports.jsx(X$1, { className: "h-4 w-4" })
36997
+ }
36998
+ )
36999
+ ] }) }),
37000
+ /* @__PURE__ */ jsxRuntimeExports.jsxs(CardContent, { className: "space-y-6", children: [
37001
+ /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "space-y-2", children: [
37002
+ /* @__PURE__ */ jsxRuntimeExports.jsx(
37003
+ Label,
37004
+ {
37005
+ htmlFor: `client-name-${client2.id}`,
37006
+ className: "text-sm font-medium",
37007
+ children: "Client Name"
37008
+ }
37009
+ ),
37010
+ /* @__PURE__ */ jsxRuntimeExports.jsx(
37011
+ Input,
37012
+ {
37013
+ id: `client-name-${client2.id}`,
37014
+ value: client2.name,
37015
+ onChange: (e) => handleUpdateClient(client2.id, { name: e.target.value }),
37016
+ placeholder: "Enter a descriptive name for this client",
37017
+ className: "max-w-md"
37018
+ }
37019
+ )
36807
37020
  ] }),
36808
- /* @__PURE__ */ jsxRuntimeExports.jsx(CardDescription, { children: client2.name || "Unnamed client" })
37021
+ /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "space-y-3", children: [
37022
+ /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex items-center gap-2", children: [
37023
+ /* @__PURE__ */ jsxRuntimeExports.jsx(Settings, { className: "h-4 w-4 text-muted-foreground" }),
37024
+ /* @__PURE__ */ jsxRuntimeExports.jsx(Label, { className: "text-sm font-medium", children: "Connection Settings" })
37025
+ ] }),
37026
+ /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "border border-border/50 rounded-lg p-4 bg-muted/30", children: /* @__PURE__ */ jsxRuntimeExports.jsx(
37027
+ ConnectionSection,
37028
+ {
37029
+ connectionStatus: "disconnected",
37030
+ transportType: client2.config.transportType,
37031
+ setTransportType: (type2) => {
37032
+ const newConfig = type2 === "stdio" ? createDefaultStdioConfig() : createDefaultHttpConfig(type2);
37033
+ handleUpdateClient(client2.id, {
37034
+ config: newConfig
37035
+ });
37036
+ },
37037
+ command: isStdioConfig(client2.config) ? client2.config.command || "" : "",
37038
+ setCommand: (command) => {
37039
+ if (isStdioConfig(client2.config)) {
37040
+ handleUpdateClient(client2.id, {
37041
+ config: {
37042
+ ...client2.config,
37043
+ command
37044
+ }
37045
+ });
37046
+ }
37047
+ },
37048
+ args: configToDisplayStrings(client2.config).argsString,
37049
+ setArgs: (newArgsString) => {
37050
+ if (isStdioConfig(client2.config)) {
37051
+ const updatedConfig = updateConfigFromStrings(
37052
+ client2.config,
37053
+ newArgsString
37054
+ );
37055
+ handleUpdateClient(client2.id, {
37056
+ config: updatedConfig
37057
+ });
37058
+ }
37059
+ },
37060
+ sseUrl: configToDisplayStrings(client2.config).urlString,
37061
+ setSseUrl: (url) => {
37062
+ if (isHttpConfig(client2.config)) {
37063
+ try {
37064
+ const newUrl = new URL(
37065
+ url || "https://example.com"
37066
+ );
37067
+ handleUpdateClient(client2.id, {
37068
+ config: {
37069
+ ...client2.config,
37070
+ url: newUrl
37071
+ }
37072
+ });
37073
+ } catch {
37074
+ }
37075
+ }
37076
+ },
37077
+ env: isStdioConfig(client2.config) ? client2.config.env || {} : {},
37078
+ setEnv: (env) => {
37079
+ if (isStdioConfig(client2.config)) {
37080
+ handleUpdateClient(client2.id, {
37081
+ config: {
37082
+ ...client2.config,
37083
+ env
37084
+ }
37085
+ });
37086
+ }
37087
+ },
37088
+ config,
37089
+ setConfig,
37090
+ bearerToken,
37091
+ setBearerToken,
37092
+ headerName,
37093
+ setHeaderName,
37094
+ onConnect: () => {
37095
+ },
37096
+ onDisconnect: () => {
37097
+ },
37098
+ stdErrNotifications: [],
37099
+ clearStdErrNotifications: () => {
37100
+ },
37101
+ logLevel: "debug",
37102
+ sendLogLevelRequest: async () => {
37103
+ },
37104
+ loggingSupported: false,
37105
+ hideActionButtons: true
37106
+ }
37107
+ ) })
37108
+ ] })
36809
37109
  ] })
37110
+ ]
37111
+ },
37112
+ client2.id
37113
+ )),
37114
+ /* @__PURE__ */ jsxRuntimeExports.jsx(Card, { className: "border-2 border-dashed border-border/50 hover:border-border transition-colors", children: /* @__PURE__ */ jsxRuntimeExports.jsx(CardContent, { className: "p-6", children: /* @__PURE__ */ jsxRuntimeExports.jsxs(
37115
+ Button,
37116
+ {
37117
+ variant: "ghost",
37118
+ onClick: handleAddClient,
37119
+ className: "w-full h-16 text-muted-foreground hover:text-foreground",
37120
+ children: [
37121
+ /* @__PURE__ */ jsxRuntimeExports.jsx(Plus, { className: "h-5 w-5 mr-2" }),
37122
+ "Add Another Client"
37123
+ ]
37124
+ }
37125
+ ) }) })
37126
+ ] }),
37127
+ /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "sticky bottom-0 bg-background/95 backdrop-blur supports-[backdrop-filter]:bg-background/60 border-t pt-4", children: /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex items-center justify-between gap-4", children: [
37128
+ /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "flex items-center gap-2 text-sm text-muted-foreground", children: multipleClients.some((c) => !c.name.trim()) && /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex items-center gap-2 text-amber-600", children: [
37129
+ /* @__PURE__ */ jsxRuntimeExports.jsx(CircleAlert, { className: "h-4 w-4" }),
37130
+ /* @__PURE__ */ jsxRuntimeExports.jsx("span", { children: "Some clients need names" })
37131
+ ] }) }),
37132
+ /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex items-center gap-3", children: [
37133
+ /* @__PURE__ */ jsxRuntimeExports.jsx(Button, { variant: "outline", onClick: onCancel, children: "Cancel" }),
37134
+ /* @__PURE__ */ jsxRuntimeExports.jsxs(
37135
+ Button,
37136
+ {
37137
+ onClick: handleSave,
37138
+ disabled: multipleClients.filter((c) => c.name.trim()).length === 0,
37139
+ className: "min-w-[200px]",
37140
+ children: [
37141
+ /* @__PURE__ */ jsxRuntimeExports.jsx(Save, { className: "h-4 w-4 mr-2" }),
37142
+ isCreating ? "Create" : "Update",
37143
+ " ",
37144
+ multipleClients.filter((c) => c.name.trim()).length,
37145
+ " ",
37146
+ "Connection(s)"
37147
+ ]
37148
+ }
37149
+ )
37150
+ ] })
37151
+ ] }) })
37152
+ ] })
37153
+ }
37154
+ );
37155
+ }
37156
+ return /* @__PURE__ */ jsxRuntimeExports.jsx(
37157
+ "div",
37158
+ {
37159
+ ref: scrollContainerRef,
37160
+ className: "flex-1 flex flex-col overflow-auto bg-gradient-to-br from-background to-muted/20",
37161
+ children: /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "max-w-5xl mx-auto w-full p-6 space-y-8", children: [
37162
+ isCreating && /* @__PURE__ */ jsxRuntimeExports.jsxs(Card, { className: "border-2 border-primary/20 bg-gradient-to-r from-primary/5 to-primary/10", children: [
37163
+ /* @__PURE__ */ jsxRuntimeExports.jsx(CardHeader, { children: /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex items-center gap-3", children: [
37164
+ /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "p-2 bg-primary/10 rounded-lg", children: /* @__PURE__ */ jsxRuntimeExports.jsx(Upload, { className: "h-5 w-5 text-primary" }) }),
37165
+ /* @__PURE__ */ jsxRuntimeExports.jsx("div", { children: /* @__PURE__ */ jsxRuntimeExports.jsx(CardTitle, { className: "text-lg", children: "Quick Import" }) }),
37166
+ /* @__PURE__ */ jsxRuntimeExports.jsxs(Badge, { variant: "secondary", className: "ml-auto", children: [
37167
+ /* @__PURE__ */ jsxRuntimeExports.jsx(Sparkles, { className: "h-3 w-3 mr-1" }),
37168
+ "Recommended"
37169
+ ] })
37170
+ ] }) }),
37171
+ /* @__PURE__ */ jsxRuntimeExports.jsxs(CardContent, { children: [
37172
+ /* @__PURE__ */ jsxRuntimeExports.jsx("p", { className: "text-sm text-muted-foreground mb-4", children: "Supports the same format used by Claude Desktop and Cursor." }),
37173
+ /* @__PURE__ */ jsxRuntimeExports.jsxs(
37174
+ Button,
37175
+ {
37176
+ onClick: () => setShowImportDialog(true),
37177
+ className: "w-full sm:w-auto",
37178
+ children: [
37179
+ /* @__PURE__ */ jsxRuntimeExports.jsx(Upload, { className: "w-4 h-4 mr-2" }),
37180
+ "Import from Configuration File"
37181
+ ]
37182
+ }
37183
+ )
37184
+ ] })
37185
+ ] }),
37186
+ isCreating && /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "flex items-center justify-center", children: /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex items-center gap-4", children: [
37187
+ /* @__PURE__ */ jsxRuntimeExports.jsx(Separator, { className: "w-16" }),
37188
+ /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "text-sm font-medium text-muted-foreground", children: "or" }),
37189
+ /* @__PURE__ */ jsxRuntimeExports.jsx(Separator, { className: "w-16" })
37190
+ ] }) }),
37191
+ /* @__PURE__ */ jsxRuntimeExports.jsxs(Card, { className: "border-2 border-border/50", children: [
37192
+ /* @__PURE__ */ jsxRuntimeExports.jsx(
37193
+ CardHeader,
37194
+ {
37195
+ className: "cursor-pointer",
37196
+ onClick: () => setIsManualConfigExpanded(!isManualConfigExpanded),
37197
+ children: /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex items-center justify-between", children: [
37198
+ /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex items-center gap-3", children: [
37199
+ /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "p-2 bg-muted rounded-lg", children: /* @__PURE__ */ jsxRuntimeExports.jsx(Settings, { className: "h-5 w-5 text-muted-foreground" }) }),
37200
+ /* @__PURE__ */ jsxRuntimeExports.jsx("div", { children: /* @__PURE__ */ jsxRuntimeExports.jsx(CardTitle, { className: "text-lg", children: isCreating ? "Manual Setup" : `Edit: ${editingClientName}` }) })
36810
37201
  ] }),
36811
37202
  /* @__PURE__ */ jsxRuntimeExports.jsx(
36812
37203
  Button,
36813
37204
  {
36814
37205
  variant: "ghost",
36815
37206
  size: "sm",
36816
- onClick: () => handleRemoveClient(client2.id),
36817
- className: "h-8 w-8 p-0 text-muted-foreground hover:text-destructive",
36818
- children: /* @__PURE__ */ jsxRuntimeExports.jsx(X$1, { className: "h-4 w-4" })
37207
+ className: "h-8 w-8 p-0",
37208
+ onClick: (e) => {
37209
+ e.stopPropagation();
37210
+ setIsManualConfigExpanded(!isManualConfigExpanded);
37211
+ },
37212
+ children: isManualConfigExpanded ? /* @__PURE__ */ jsxRuntimeExports.jsx(ChevronDown, { className: "h-4 w-4" }) : /* @__PURE__ */ jsxRuntimeExports.jsx(ChevronRight, { className: "h-4 w-4" })
36819
37213
  }
36820
37214
  )
36821
- ] }) }),
36822
- /* @__PURE__ */ jsxRuntimeExports.jsxs(CardContent, { className: "space-y-6", children: [
36823
- /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "space-y-2", children: [
36824
- /* @__PURE__ */ jsxRuntimeExports.jsx(
36825
- Label,
36826
- {
36827
- htmlFor: `client-name-${client2.id}`,
36828
- className: "text-sm font-medium",
36829
- children: "Client Name"
36830
- }
36831
- ),
36832
- /* @__PURE__ */ jsxRuntimeExports.jsx(
36833
- Input,
37215
+ ] })
37216
+ }
37217
+ ),
37218
+ isManualConfigExpanded && /* @__PURE__ */ jsxRuntimeExports.jsxs(CardContent, { className: "space-y-6", children: [
37219
+ /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "space-y-2", children: [
37220
+ /* @__PURE__ */ jsxRuntimeExports.jsx(Label, { htmlFor: "client-name", className: "text-sm font-medium", children: "Name*" }),
37221
+ /* @__PURE__ */ jsxRuntimeExports.jsx(
37222
+ Input,
37223
+ {
37224
+ id: "client-name",
37225
+ value: currentClient.name,
37226
+ onChange: (e) => handleUpdateCurrentClient({ name: e.target.value }),
37227
+ onBlur: () => setIsNameTouched(true),
37228
+ placeholder: "Enter client name",
37229
+ className: `max-w-md ${nameError ? "border-red-500 focus:border-red-500 focus:ring-red-500" : ""}`
37230
+ }
37231
+ ),
37232
+ nameError && /* @__PURE__ */ jsxRuntimeExports.jsxs("p", { className: "text-sm text-red-500 flex items-center gap-1", children: [
37233
+ /* @__PURE__ */ jsxRuntimeExports.jsx(TooltipProvider, { children: /* @__PURE__ */ jsxRuntimeExports.jsxs(Tooltip, { children: [
37234
+ /* @__PURE__ */ jsxRuntimeExports.jsx(TooltipTrigger, { asChild: true, children: /* @__PURE__ */ jsxRuntimeExports.jsx(CircleAlert, { className: "h-4 w-4 cursor-help" }) }),
37235
+ /* @__PURE__ */ jsxRuntimeExports.jsxs(
37236
+ TooltipContent,
36834
37237
  {
36835
- id: `client-name-${client2.id}`,
36836
- value: client2.name,
36837
- onChange: (e) => handleUpdateClient(client2.id, { name: e.target.value }),
36838
- placeholder: "Enter a descriptive name for this client",
36839
- className: "max-w-md"
37238
+ side: "top",
37239
+ className: "max-w-sm p-2 text-xs leading-relaxed",
37240
+ children: [
37241
+ "A client name is required to help you identify and manage your MCP connections.",
37242
+ /* @__PURE__ */ jsxRuntimeExports.jsx("br", {}),
37243
+ "It ensures clarity when debugging or switching between multiple clients. Leaving it blank makes the connection untraceable within the tool."
37244
+ ]
36840
37245
  }
36841
37246
  )
36842
- ] }),
36843
- /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "space-y-3", children: [
36844
- /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex items-center gap-2", children: [
36845
- /* @__PURE__ */ jsxRuntimeExports.jsx(Settings, { className: "h-4 w-4 text-muted-foreground" }),
36846
- /* @__PURE__ */ jsxRuntimeExports.jsx(Label, { className: "text-sm font-medium", children: "Connection Settings" })
36847
- ] }),
36848
- /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "border border-border/50 rounded-lg p-4 bg-muted/30", children: /* @__PURE__ */ jsxRuntimeExports.jsx(
36849
- ConnectionSection,
36850
- {
36851
- connectionStatus: "disconnected",
36852
- transportType: client2.config.transportType,
36853
- setTransportType: (type2) => {
36854
- let newConfig;
36855
- let newArgsString = "";
36856
- if (type2 === "stdio") {
36857
- newConfig = {
36858
- transportType: type2,
36859
- command: "npx",
36860
- args: ["@modelcontextprotocol/server-everything"],
36861
- env: {}
36862
- };
36863
- newArgsString = "@modelcontextprotocol/server-everything";
36864
- } else {
36865
- newConfig = {
36866
- transportType: type2,
36867
- url: new URL("https://example.com")
36868
- };
36869
- }
36870
- handleUpdateClient(client2.id, {
36871
- config: newConfig,
36872
- argsString: newArgsString,
36873
- sseUrlString: newConfig.transportType !== "stdio" && "url" in newConfig && newConfig.url ? newConfig.url.toString() : ""
36874
- });
36875
- },
36876
- command: client2.config.transportType === "stdio" && "command" in client2.config ? client2.config.command || "" : "",
36877
- setCommand: (command) => {
36878
- if (client2.config.transportType === "stdio") {
36879
- handleUpdateClient(client2.id, {
36880
- config: {
36881
- ...client2.config,
36882
- command
36883
- }
36884
- });
36885
- }
36886
- },
36887
- args: client2.argsString,
36888
- setArgs: (newArgsString) => {
36889
- if (client2.config.transportType === "stdio") {
36890
- handleUpdateClient(client2.id, {
36891
- argsString: newArgsString,
36892
- config: {
36893
- ...client2.config,
36894
- args: newArgsString.trim() ? newArgsString.split(/\s+/) : []
36895
- }
36896
- });
37247
+ ] }) }),
37248
+ nameError
37249
+ ] })
37250
+ ] }),
37251
+ /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "space-y-3", children: [
37252
+ /* @__PURE__ */ jsxRuntimeExports.jsx(Label, { className: "text-sm font-medium", children: "Connection" }),
37253
+ /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "border border-border/50 rounded-lg p-4 bg-muted/30", children: /* @__PURE__ */ jsxRuntimeExports.jsx(
37254
+ ConnectionSection,
37255
+ {
37256
+ connectionStatus: "disconnected",
37257
+ transportType: currentClient.config.transportType,
37258
+ setTransportType: (type2) => {
37259
+ const newConfig = type2 === "stdio" ? createDefaultStdioConfig() : createDefaultHttpConfig(type2);
37260
+ handleUpdateCurrentClient({ config: newConfig });
37261
+ },
37262
+ command: isStdioConfig(currentClient.config) ? currentClient.config.command || "" : "",
37263
+ setCommand: (command) => {
37264
+ if (isStdioConfig(currentClient.config)) {
37265
+ handleUpdateCurrentClient({
37266
+ config: {
37267
+ ...currentClient.config,
37268
+ command
36897
37269
  }
36898
- },
36899
- sseUrl: client2.sseUrlString,
36900
- setSseUrl: (url) => {
36901
- handleUpdateClient(client2.id, { sseUrlString: url });
36902
- },
36903
- env: client2.config.transportType === "stdio" && "env" in client2.config ? client2.config.env || {} : {},
36904
- setEnv: (env) => {
36905
- if (client2.config.transportType === "stdio") {
36906
- handleUpdateClient(client2.id, {
36907
- config: {
36908
- ...client2.config,
36909
- env
36910
- }
36911
- });
37270
+ });
37271
+ }
37272
+ },
37273
+ args: configToDisplayStrings(currentClient.config).argsString,
37274
+ setArgs: handleArgsChange,
37275
+ sseUrl: configToDisplayStrings(currentClient.config).urlString,
37276
+ setSseUrl: handleSseUrlChange,
37277
+ env: isStdioConfig(currentClient.config) ? currentClient.config.env || {} : {},
37278
+ setEnv: (env) => {
37279
+ if (isStdioConfig(currentClient.config)) {
37280
+ handleUpdateCurrentClient({
37281
+ config: {
37282
+ ...currentClient.config,
37283
+ env
36912
37284
  }
36913
- },
36914
- config,
36915
- setConfig,
36916
- bearerToken,
36917
- setBearerToken,
36918
- headerName,
36919
- setHeaderName,
36920
- onConnect: () => {
36921
- },
36922
- onDisconnect: () => {
36923
- },
36924
- stdErrNotifications: [],
36925
- clearStdErrNotifications: () => {
36926
- },
36927
- logLevel: "debug",
36928
- sendLogLevelRequest: async () => {
36929
- },
36930
- loggingSupported: false,
36931
- hideActionButtons: true
37285
+ });
36932
37286
  }
36933
- ) })
36934
- ] })
36935
- ] })
36936
- ]
36937
- },
36938
- client2.id
36939
- )),
36940
- /* @__PURE__ */ jsxRuntimeExports.jsx(Card, { className: "border-2 border-dashed border-border/50 hover:border-border transition-colors", children: /* @__PURE__ */ jsxRuntimeExports.jsx(CardContent, { className: "p-6", children: /* @__PURE__ */ jsxRuntimeExports.jsxs(
36941
- Button,
36942
- {
36943
- variant: "ghost",
36944
- onClick: handleAddClient,
36945
- className: "w-full h-16 text-muted-foreground hover:text-foreground",
36946
- children: [
36947
- /* @__PURE__ */ jsxRuntimeExports.jsx(Plus, { className: "h-5 w-5 mr-2" }),
36948
- "Add Another Client"
36949
- ]
36950
- }
36951
- ) }) })
36952
- ] }),
36953
- /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "sticky bottom-0 bg-background/95 backdrop-blur supports-[backdrop-filter]:bg-background/60 border-t pt-4", children: /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex items-center justify-between gap-4", children: [
36954
- /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "flex items-center gap-2 text-sm text-muted-foreground", children: multipleClients.some((c) => !c.name.trim()) && /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex items-center gap-2 text-amber-600", children: [
36955
- /* @__PURE__ */ jsxRuntimeExports.jsx(CircleAlert, { className: "h-4 w-4" }),
36956
- /* @__PURE__ */ jsxRuntimeExports.jsx("span", { children: "Some clients need names" })
36957
- ] }) }),
36958
- /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex items-center gap-3", children: [
36959
- /* @__PURE__ */ jsxRuntimeExports.jsx(Button, { variant: "outline", onClick: onCancel, children: "Cancel" }),
37287
+ },
37288
+ config,
37289
+ setConfig,
37290
+ bearerToken,
37291
+ setBearerToken,
37292
+ headerName,
37293
+ setHeaderName,
37294
+ onConnect: () => {
37295
+ },
37296
+ onDisconnect: () => {
37297
+ },
37298
+ stdErrNotifications: [],
37299
+ clearStdErrNotifications: () => {
37300
+ },
37301
+ logLevel: "debug",
37302
+ sendLogLevelRequest: async () => {
37303
+ },
37304
+ loggingSupported: false,
37305
+ hideActionButtons: true
37306
+ }
37307
+ ) })
37308
+ ] })
37309
+ ] })
37310
+ ] }),
37311
+ /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex flex-col items-center gap-3 pt-4", children: [
36960
37312
  /* @__PURE__ */ jsxRuntimeExports.jsxs(
36961
37313
  Button,
36962
37314
  {
36963
- onClick: handleSaveAll,
36964
- disabled: multipleClients.filter((c) => c.name.trim()).length === 0,
36965
- className: "min-w-[200px]",
37315
+ onClick: handleSave,
37316
+ disabled: !currentClient.name.trim(),
37317
+ className: "min-w-[180px] h-12 text-base font-semibold bg-primary hover:bg-primary/90 shadow-lg hover:shadow-xl transition-all duration-200 border-2 border-primary/20",
36966
37318
  children: [
36967
- /* @__PURE__ */ jsxRuntimeExports.jsx(Save, { className: "h-4 w-4 mr-2" }),
36968
- "Create ",
36969
- multipleClients.filter((c) => c.name.trim()).length,
36970
- " ",
36971
- "Connection(s)"
37319
+ /* @__PURE__ */ jsxRuntimeExports.jsx(CircleCheck, { className: "h-5 w-5 mr-2" }),
37320
+ isCreating ? "Create Connection" : "Update Connection"
36972
37321
  ]
36973
37322
  }
36974
- )
36975
- ] })
36976
- ] }) })
36977
- ] }) });
36978
- }
36979
- return /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "flex-1 flex flex-col overflow-auto bg-gradient-to-br from-background to-muted/20", children: /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "max-w-5xl mx-auto w-full p-6 space-y-8", children: [
36980
- isCreating && /* @__PURE__ */ jsxRuntimeExports.jsxs(Card, { className: "border-2 border-primary/20 bg-gradient-to-r from-primary/5 to-primary/10", children: [
36981
- /* @__PURE__ */ jsxRuntimeExports.jsx(CardHeader, { children: /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex items-center gap-3", children: [
36982
- /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "p-2 bg-primary/10 rounded-lg", children: /* @__PURE__ */ jsxRuntimeExports.jsx(Upload, { className: "h-5 w-5 text-primary" }) }),
36983
- /* @__PURE__ */ jsxRuntimeExports.jsx("div", { children: /* @__PURE__ */ jsxRuntimeExports.jsx(CardTitle, { className: "text-lg", children: "Quick Import" }) }),
36984
- /* @__PURE__ */ jsxRuntimeExports.jsxs(Badge, { variant: "secondary", className: "ml-auto", children: [
36985
- /* @__PURE__ */ jsxRuntimeExports.jsx(Sparkles, { className: "h-3 w-3 mr-1" }),
36986
- "Recommended"
36987
- ] })
36988
- ] }) }),
36989
- /* @__PURE__ */ jsxRuntimeExports.jsxs(CardContent, { children: [
36990
- /* @__PURE__ */ jsxRuntimeExports.jsx("p", { className: "text-sm text-muted-foreground mb-4", children: "Supports the same format used by Claude Desktop and Cursor." }),
36991
- /* @__PURE__ */ jsxRuntimeExports.jsxs(
36992
- Button,
36993
- {
36994
- onClick: () => setShowImportDialog(true),
36995
- className: "w-full sm:w-auto",
36996
- children: [
36997
- /* @__PURE__ */ jsxRuntimeExports.jsx(Upload, { className: "w-4 h-4 mr-2" }),
36998
- "Import from Configuration File"
36999
- ]
37000
- }
37001
- )
37002
- ] })
37003
- ] }),
37004
- isCreating && /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "flex items-center justify-center", children: /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex items-center gap-4", children: [
37005
- /* @__PURE__ */ jsxRuntimeExports.jsx(Separator, { className: "w-16" }),
37006
- /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "text-sm font-medium text-muted-foreground", children: "or" }),
37007
- /* @__PURE__ */ jsxRuntimeExports.jsx(Separator, { className: "w-16" })
37008
- ] }) }),
37009
- /* @__PURE__ */ jsxRuntimeExports.jsxs(Card, { className: "border-2 border-border/50", children: [
37010
- /* @__PURE__ */ jsxRuntimeExports.jsx(
37011
- CardHeader,
37012
- {
37013
- className: "cursor-pointer",
37014
- onClick: () => setIsManualConfigExpanded(!isManualConfigExpanded),
37015
- children: /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex items-center justify-between", children: [
37016
- /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex items-center gap-3", children: [
37017
- /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "p-2 bg-muted rounded-lg", children: /* @__PURE__ */ jsxRuntimeExports.jsx(Settings, { className: "h-5 w-5 text-muted-foreground" }) }),
37018
- /* @__PURE__ */ jsxRuntimeExports.jsx("div", { children: /* @__PURE__ */ jsxRuntimeExports.jsx(CardTitle, { className: "text-lg", children: isCreating ? "Manual Setup" : `Edit: ${editingClientName}` }) })
37019
- ] }),
37020
- /* @__PURE__ */ jsxRuntimeExports.jsx(
37021
- Button,
37022
- {
37023
- variant: "ghost",
37024
- size: "sm",
37025
- className: "h-8 w-8 p-0",
37026
- onClick: (e) => {
37027
- e.stopPropagation();
37028
- setIsManualConfigExpanded(!isManualConfigExpanded);
37029
- },
37030
- children: isManualConfigExpanded ? /* @__PURE__ */ jsxRuntimeExports.jsx(ChevronDown, { className: "h-4 w-4" }) : /* @__PURE__ */ jsxRuntimeExports.jsx(ChevronRight, { className: "h-4 w-4" })
37031
- }
37032
- )
37033
- ] })
37034
- }
37035
- ),
37036
- isManualConfigExpanded && /* @__PURE__ */ jsxRuntimeExports.jsxs(CardContent, { className: "space-y-6", children: [
37037
- /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "space-y-2", children: [
37038
- /* @__PURE__ */ jsxRuntimeExports.jsx(Label, { htmlFor: "client-name", className: "text-sm font-medium", children: "Name" }),
37323
+ ),
37039
37324
  /* @__PURE__ */ jsxRuntimeExports.jsx(
37040
- Input,
37325
+ "button",
37041
37326
  {
37042
- id: "client-name",
37043
- value: clientFormName,
37044
- onChange: (e) => setClientFormName(e.target.value),
37045
- placeholder: "Enter client name",
37046
- className: `max-w-md ${nameError ? "border-red-500 focus:border-red-500 focus:ring-red-500" : ""}`
37327
+ onClick: onCancel,
37328
+ className: "text-sm text-muted-foreground hover:text-foreground transition-colors underline-offset-4 hover:underline",
37329
+ children: "Cancel"
37047
37330
  }
37048
- ),
37049
- nameError && /* @__PURE__ */ jsxRuntimeExports.jsxs("p", { className: "text-sm text-red-500 flex items-center gap-1", children: [
37050
- /* @__PURE__ */ jsxRuntimeExports.jsx(CircleAlert, { className: "h-3 w-3" }),
37051
- nameError
37052
- ] })
37331
+ )
37053
37332
  ] }),
37054
- /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "space-y-3", children: [
37055
- /* @__PURE__ */ jsxRuntimeExports.jsx(Label, { className: "text-sm font-medium", children: "Connection" }),
37056
- /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "border border-border/50 rounded-lg p-4 bg-muted/30", children: /* @__PURE__ */ jsxRuntimeExports.jsx(
37057
- ConnectionSection,
37058
- {
37059
- connectionStatus: "disconnected",
37060
- transportType: clientFormConfig.transportType,
37061
- setTransportType: (type2) => {
37062
- if (type2 === "stdio") {
37063
- const newConfig = {
37064
- transportType: type2,
37065
- command: "npx",
37066
- args: ["@modelcontextprotocol/server-everything"],
37067
- env: {}
37068
- };
37069
- setClientFormConfig(newConfig);
37070
- setArgsString(
37071
- "@modelcontextprotocol/server-everything"
37072
- );
37073
- } else {
37074
- setClientFormConfig({
37075
- transportType: type2,
37076
- url: new URL("https://example.com")
37077
- });
37078
- setArgsString("");
37079
- }
37080
- },
37081
- command: clientFormConfig.transportType === "stdio" && "command" in clientFormConfig ? clientFormConfig.command || "" : "",
37082
- setCommand: (command) => {
37083
- if (clientFormConfig.transportType === "stdio") {
37084
- setClientFormConfig({
37085
- ...clientFormConfig,
37086
- command
37087
- });
37088
- }
37089
- },
37090
- args: argsString,
37091
- setArgs: handleArgsChange,
37092
- sseUrl: sseUrlString,
37093
- setSseUrl: handleSseUrlChange,
37094
- env: clientFormConfig.transportType === "stdio" && "env" in clientFormConfig ? clientFormConfig.env || {} : {},
37095
- setEnv: (env) => {
37096
- if (clientFormConfig.transportType === "stdio") {
37097
- setClientFormConfig({
37098
- ...clientFormConfig,
37099
- env
37100
- });
37101
- }
37102
- },
37103
- config,
37104
- setConfig,
37105
- bearerToken,
37106
- setBearerToken,
37107
- headerName,
37108
- setHeaderName,
37109
- onConnect: () => {
37110
- },
37111
- onDisconnect: () => {
37112
- },
37113
- stdErrNotifications: [],
37114
- clearStdErrNotifications: () => {
37115
- },
37116
- logLevel: "debug",
37117
- sendLogLevelRequest: async () => {
37118
- },
37119
- loggingSupported: false,
37120
- hideActionButtons: true
37121
- }
37122
- ) })
37123
- ] })
37333
+ /* @__PURE__ */ jsxRuntimeExports.jsx(
37334
+ ConfigImportDialog,
37335
+ {
37336
+ open: showImportDialog,
37337
+ onOpenChange: setShowImportDialog,
37338
+ onImportServers: handleImportServers
37339
+ }
37340
+ )
37124
37341
  ] })
37125
- ] }),
37126
- /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex flex-col items-center gap-3 pt-4", children: [
37127
- /* @__PURE__ */ jsxRuntimeExports.jsxs(
37128
- Button,
37129
- {
37130
- onClick: handleSingleSave,
37131
- disabled: !clientFormName.trim(),
37132
- className: "min-w-[180px] h-12 text-base font-semibold bg-primary hover:bg-primary/90 shadow-lg hover:shadow-xl transition-all duration-200 border-2 border-primary/20",
37133
- children: [
37134
- /* @__PURE__ */ jsxRuntimeExports.jsx(CircleCheck, { className: "h-5 w-5 mr-2" }),
37135
- isCreating ? "Create Connection" : "Update Connection"
37136
- ]
37137
- }
37138
- ),
37139
- /* @__PURE__ */ jsxRuntimeExports.jsx(
37140
- "button",
37141
- {
37142
- onClick: onCancel,
37143
- className: "text-sm text-muted-foreground hover:text-foreground transition-colors underline-offset-4 hover:underline",
37144
- children: "Cancel"
37145
- }
37146
- )
37147
- ] }),
37148
- /* @__PURE__ */ jsxRuntimeExports.jsx(
37149
- ConfigImportDialog,
37150
- {
37151
- open: showImportDialog,
37152
- onOpenChange: setShowImportDialog,
37153
- onImportServers: handleImportServers
37154
- }
37155
- )
37156
- ] }) });
37342
+ }
37343
+ );
37157
37344
  };
37158
37345
  const StarGitHubModal = ({
37159
37346
  isOpen,
@@ -37293,6 +37480,7 @@ objectType({
37293
37480
  const SESSION_KEYS = {
37294
37481
  CODE_VERIFIER: "mcp_code_verifier",
37295
37482
  SERVER_URL: "mcp_server_url",
37483
+ TRANSPORT_TYPE: "mcp_transport_type",
37296
37484
  TOKENS: "mcp_tokens",
37297
37485
  CLIENT_INFORMATION: "mcp_client_information",
37298
37486
  SERVER_METADATA: "mcp_server_metadata"
@@ -37325,9 +37513,17 @@ const DEFAULT_INSPECTOR_CONFIG = {
37325
37513
  }
37326
37514
  };
37327
37515
  class InspectorOAuthClientProvider {
37328
- constructor(serverUrl) {
37516
+ constructor(serverUrl, transportType) {
37329
37517
  this.serverUrl = serverUrl;
37518
+ this.transportType = transportType;
37330
37519
  sessionStorage.setItem(SESSION_KEYS.SERVER_URL, serverUrl);
37520
+ if (transportType) {
37521
+ const transportKey = getServerSpecificKey(
37522
+ SESSION_KEYS.TRANSPORT_TYPE,
37523
+ serverUrl
37524
+ );
37525
+ sessionStorage.setItem(transportKey, transportType);
37526
+ }
37331
37527
  }
37332
37528
  get redirectUrl() {
37333
37529
  return window.location.origin + "/oauth/callback";
@@ -37403,6 +37599,9 @@ class InspectorOAuthClientProvider {
37403
37599
  sessionStorage.removeItem(
37404
37600
  getServerSpecificKey(SESSION_KEYS.CODE_VERIFIER, this.serverUrl)
37405
37601
  );
37602
+ sessionStorage.removeItem(
37603
+ getServerSpecificKey(SESSION_KEYS.TRANSPORT_TYPE, this.serverUrl)
37604
+ );
37406
37605
  }
37407
37606
  }
37408
37607
  class DebugInspectorOAuthClientProvider extends InspectorOAuthClientProvider {
@@ -39253,7 +39452,7 @@ const ListPane = ({
39253
39452
  " items"
39254
39453
  ] })
39255
39454
  ] }),
39256
- /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "p-4", children: /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "space-y-2 overflow-y-auto max-h-96", children: filteredItems.length > 0 ? filteredItems.map((item, index2) => /* @__PURE__ */ jsxRuntimeExports.jsx(
39455
+ /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "p-4", children: /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "space-y-4 overflow-y-auto max-h-[calc(100vh-300px)]", children: filteredItems.length > 0 ? filteredItems.map((item, index2) => /* @__PURE__ */ jsxRuntimeExports.jsx(
39257
39456
  "div",
39258
39457
  {
39259
39458
  className: "cursor-pointer",
@@ -43297,48 +43496,54 @@ const ToolsTab = ({
43297
43496
  ] }),
43298
43497
  /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex items-center space-x-1", children: [
43299
43498
  request.isFavorite && /* @__PURE__ */ jsxRuntimeExports.jsx(Star, { className: "w-3 h-3 text-yellow-500 fill-current" }),
43300
- /* @__PURE__ */ jsxRuntimeExports.jsx(
43301
- Button,
43302
- {
43303
- onClick: (e) => {
43304
- e.stopPropagation();
43305
- handleRenameRequest(request.id, request.name);
43306
- },
43307
- size: "sm",
43308
- variant: "ghost",
43309
- className: "h-6 w-6 p-0 hover:bg-primary/20 hover:text-primary opacity-0 group-hover:opacity-100 transition-opacity",
43310
- title: "Rename request",
43311
- children: /* @__PURE__ */ jsxRuntimeExports.jsx(Pen, { className: "w-3 h-3" })
43312
- }
43313
- ),
43314
- /* @__PURE__ */ jsxRuntimeExports.jsx(
43315
- Button,
43316
- {
43317
- onClick: (e) => {
43318
- e.stopPropagation();
43319
- handleDuplicateRequest(request);
43320
- },
43321
- size: "sm",
43322
- variant: "ghost",
43323
- className: "h-6 w-6 p-0 hover:bg-blue-500/20 hover:text-blue-500 opacity-0 group-hover:opacity-100 transition-opacity",
43324
- title: "Duplicate request",
43325
- children: /* @__PURE__ */ jsxRuntimeExports.jsx(CopyPlus, { className: "w-3 h-3" })
43326
- }
43327
- ),
43328
- /* @__PURE__ */ jsxRuntimeExports.jsx(
43329
- Button,
43330
- {
43331
- onClick: (e) => {
43332
- e.stopPropagation();
43333
- handleDeleteRequest(request.id);
43334
- },
43335
- size: "sm",
43336
- variant: "ghost",
43337
- className: "h-6 w-6 p-0 hover:bg-destructive/20 hover:text-destructive opacity-0 group-hover:opacity-100 transition-opacity",
43338
- title: "Delete request",
43339
- children: /* @__PURE__ */ jsxRuntimeExports.jsx(Trash2, { className: "w-3 h-3" })
43340
- }
43341
- )
43499
+ /* @__PURE__ */ jsxRuntimeExports.jsxs(Tooltip, { children: [
43500
+ /* @__PURE__ */ jsxRuntimeExports.jsx(TooltipTrigger, { asChild: true, children: /* @__PURE__ */ jsxRuntimeExports.jsx(
43501
+ Button,
43502
+ {
43503
+ onClick: (e) => {
43504
+ e.stopPropagation();
43505
+ handleRenameRequest(request.id, request.name);
43506
+ },
43507
+ size: "sm",
43508
+ variant: "ghost",
43509
+ className: "h-6 w-6 p-0 hover:bg-primary/20 hover:text-primary opacity-0 group-hover:opacity-100 transition-opacity",
43510
+ children: /* @__PURE__ */ jsxRuntimeExports.jsx(Pen, { className: "w-3 h-3" })
43511
+ }
43512
+ ) }),
43513
+ /* @__PURE__ */ jsxRuntimeExports.jsx(TooltipContent, { side: "top", children: "Rename" })
43514
+ ] }),
43515
+ /* @__PURE__ */ jsxRuntimeExports.jsxs(Tooltip, { children: [
43516
+ /* @__PURE__ */ jsxRuntimeExports.jsx(TooltipTrigger, { asChild: true, children: /* @__PURE__ */ jsxRuntimeExports.jsx(
43517
+ Button,
43518
+ {
43519
+ onClick: (e) => {
43520
+ e.stopPropagation();
43521
+ handleDuplicateRequest(request);
43522
+ },
43523
+ size: "sm",
43524
+ variant: "ghost",
43525
+ className: "h-6 w-6 p-0 hover:bg-blue-500/20 hover:text-blue-500 opacity-0 group-hover:opacity-100 transition-opacity",
43526
+ children: /* @__PURE__ */ jsxRuntimeExports.jsx(CopyPlus, { className: "w-3 h-3" })
43527
+ }
43528
+ ) }),
43529
+ /* @__PURE__ */ jsxRuntimeExports.jsx(TooltipContent, { side: "top", children: "Duplicate" })
43530
+ ] }),
43531
+ /* @__PURE__ */ jsxRuntimeExports.jsxs(Tooltip, { children: [
43532
+ /* @__PURE__ */ jsxRuntimeExports.jsx(TooltipTrigger, { asChild: true, children: /* @__PURE__ */ jsxRuntimeExports.jsx(
43533
+ Button,
43534
+ {
43535
+ onClick: (e) => {
43536
+ e.stopPropagation();
43537
+ handleDeleteRequest(request.id);
43538
+ },
43539
+ size: "sm",
43540
+ variant: "ghost",
43541
+ className: "h-6 w-6 p-0 hover:bg-destructive/20 hover:text-destructive opacity-0 group-hover:opacity-100 transition-opacity",
43542
+ children: /* @__PURE__ */ jsxRuntimeExports.jsx(Trash2, { className: "w-3 h-3" })
43543
+ }
43544
+ ) }),
43545
+ /* @__PURE__ */ jsxRuntimeExports.jsx(TooltipContent, { side: "top", children: "Delete" })
43546
+ ] })
43342
43547
  ] })
43343
43548
  ] }),
43344
43549
  request.description && /* @__PURE__ */ jsxRuntimeExports.jsx("p", { className: "text-xs text-muted-foreground/80 mb-1.5 line-clamp-2", children: request.description }),
@@ -43372,7 +43577,7 @@ const ToolsTab = ({
43372
43577
  return /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "bg-white dark:bg-gray-900 rounded-lg p-3 shadow-sm border border-gray-100 dark:border-gray-800 hover:shadow-md hover:border-blue-200 dark:hover:border-blue-800 transition-all duration-200 group", children: /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex flex-col space-y-2.5", children: [
43373
43578
  /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex items-center justify-between", children: [
43374
43579
  /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex items-center space-x-2", children: [
43375
- /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "text-lg", children: "🛠️" }),
43580
+ /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "text-lg", children: /* @__PURE__ */ jsxRuntimeExports.jsx(Hammer, { className: "w-5 h-5 text-muted-foreground" }) }),
43376
43581
  /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "font-mono text-xs bg-gradient-to-r from-slate-100 to-gray-100 dark:from-slate-800 dark:to-gray-800 px-2.5 py-1 rounded-md border border-slate-300 dark:border-slate-600 text-slate-800 dark:text-slate-200 font-medium shadow-sm", children: tool.name })
43377
43582
  ] }),
43378
43583
  parameters.length > 0 && /* @__PURE__ */ jsxRuntimeExports.jsxs("span", { className: "text-xs text-gray-400 dark:text-gray-600 font-medium", children: [
@@ -43451,6 +43656,12 @@ const ToolCallMessage = ({
43451
43656
  toolCall
43452
43657
  }) => {
43453
43658
  const { type: type2, toolName, args, error, message, result } = toolCall;
43659
+ const [isCollapsed, setIsCollapsed] = reactExports.useState(true);
43660
+ const shouldBeCollapsible = reactExports.useMemo(() => {
43661
+ if (type2 !== "tool_result" || !result) return false;
43662
+ return result.length > 200;
43663
+ }, [result, type2]);
43664
+ const toggleCollapse = () => setIsCollapsed((prev) => !prev);
43454
43665
  const getIcon = () => {
43455
43666
  switch (type2) {
43456
43667
  case "tool_call":
@@ -43514,9 +43725,10 @@ const ToolCallMessage = ({
43514
43725
  /* @__PURE__ */ jsxRuntimeExports.jsx("pre", { className: "text-xs bg-black/10 dark:bg-white/10 rounded p-2 overflow-x-auto whitespace-pre-wrap", children: error })
43515
43726
  ] }),
43516
43727
  type2 === "tool_warning" && message && /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "mt-2", children: /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "text-xs bg-black/10 dark:bg-white/10 rounded p-2", children: message }) }),
43517
- type2 === "tool_result" && result && /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "mt-2", children: [
43728
+ type2 === "tool_result" && result && /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "mt-2 relative", children: [
43518
43729
  /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "text-xs opacity-75 mb-1", children: "Result:" }),
43519
- /* @__PURE__ */ jsxRuntimeExports.jsx("pre", { className: "text-xs bg-black/10 dark:bg-white/10 rounded p-2 overflow-x-auto whitespace-pre-wrap", children: result })
43730
+ /* @__PURE__ */ jsxRuntimeExports.jsx("pre", { className: "text-xs bg-black/10 dark:bg-white/10 rounded p-2 overflow-x-auto whitespace-pre-wrap", children: shouldBeCollapsible && isCollapsed ? result.slice(0, 200) + "..." : result }),
43731
+ shouldBeCollapsible && /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "flex justify-center mt-1", children: /* @__PURE__ */ jsxRuntimeExports.jsx("button", { onClick: toggleCollapse, className: "p-1", children: isCollapsed ? /* @__PURE__ */ jsxRuntimeExports.jsx(ChevronDown, { className: "w-4 h-4" }) : /* @__PURE__ */ jsxRuntimeExports.jsx(ChevronUp, { className: "w-4 h-4" }) }) })
43520
43732
  ] })
43521
43733
  ]
43522
43734
  }
@@ -43810,13 +44022,13 @@ const ToolCallApproval = ({
43810
44022
  onApprove,
43811
44023
  onReject
43812
44024
  }) => {
43813
- return /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex gap-4 p-4 border border-amber-200 dark:border-amber-800 rounded-xl bg-amber-50 dark:bg-amber-900/30 mb-2", children: [
44025
+ return /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex gap-4 p-4 border border-slate-200 dark:border-slate-700 rounded-xl bg-slate-50 dark:bg-slate-800 mb-2", children: [
43814
44026
  /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex-1", children: [
43815
- /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "text-sm font-medium text-amber-800 dark:text-amber-200 mb-1", children: [
44027
+ /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "text-sm font-medium text-slate-800 dark:text-slate-200 mb-1", children: [
43816
44028
  "Approve tool call: ",
43817
44029
  toolCall.name
43818
44030
  ] }),
43819
- /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "text-xs text-amber-700 dark:text-amber-300 bg-amber-100 dark:bg-amber-900/50 p-2 rounded font-mono overflow-auto max-h-28", children: JSON.stringify(toolCall.input, null, 2) })
44031
+ /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "text-xs text-slate-700 dark:text-slate-300 bg-slate-100 dark:bg-slate-700 p-2 rounded font-mono overflow-auto max-h-28", children: JSON.stringify(toolCall.input, null, 2) })
43820
44032
  ] }),
43821
44033
  /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex flex-col justify-center gap-2", children: [
43822
44034
  /* @__PURE__ */ jsxRuntimeExports.jsx(
@@ -43854,11 +44066,15 @@ const ToolSelector = ({
43854
44066
  loading = false
43855
44067
  }) => {
43856
44068
  const [showSelector, setShowSelector] = reactExports.useState(false);
44069
+ const [expandedServers, setExpandedServers] = reactExports.useState(
44070
+ /* @__PURE__ */ new Set()
44071
+ );
43857
44072
  const selectorRef = reactExports.useRef(null);
43858
- const totalTools = tools.length;
44073
+ const availableTools = serverInfo.filter((server) => toolSelection.enabledServers.has(server.name)).flatMap((server) => server.tools);
44074
+ const totalAvailableTools = availableTools.length;
43859
44075
  const enabledToolCount = toolSelection.enabledTools.size;
43860
- const allToolsEnabled = enabledToolCount === totalTools;
43861
- const someToolsDisabled = enabledToolCount < totalTools;
44076
+ const allAvailableToolsEnabled = enabledToolCount === totalAvailableTools && totalAvailableTools > 0;
44077
+ const someToolsDisabled = enabledToolCount < totalAvailableTools;
43862
44078
  const toggleServer = (serverName, enabled) => {
43863
44079
  var _a2;
43864
44080
  const newEnabledServers = new Set(toolSelection.enabledServers);
@@ -43889,6 +44105,17 @@ const ToolSelector = ({
43889
44105
  enabledServers: toolSelection.enabledServers
43890
44106
  });
43891
44107
  };
44108
+ const toggleExpandedServer = (serverName) => {
44109
+ setExpandedServers((prev) => {
44110
+ const newSet = new Set(prev);
44111
+ if (newSet.has(serverName)) {
44112
+ newSet.delete(serverName);
44113
+ } else {
44114
+ newSet.add(serverName);
44115
+ }
44116
+ return newSet;
44117
+ });
44118
+ };
43892
44119
  const toggleAllServers = (enabled) => {
43893
44120
  const newEnabledServers = new Set(serverInfo.map((s) => s.name));
43894
44121
  const newEnabledTools = new Set(tools.map((t) => t.name));
@@ -43919,12 +44146,12 @@ const ToolSelector = ({
43919
44146
  ),
43920
44147
  disabled: loading,
43921
44148
  children: [
43922
- /* @__PURE__ */ jsxRuntimeExports.jsx(Settings, { className: "w-3 h-3 text-slate-400" }),
44149
+ /* @__PURE__ */ jsxRuntimeExports.jsx(Wrench, { className: "w-3 h-3 text-slate-400" }),
43923
44150
  /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "text-slate-700 dark:text-slate-200 font-medium", children: "Tools" }),
43924
44151
  someToolsDisabled && /* @__PURE__ */ jsxRuntimeExports.jsxs("span", { className: "text-xs px-1.5 py-0.5 bg-amber-100 dark:bg-amber-900/50 text-amber-600 dark:text-amber-400 rounded", children: [
43925
44152
  enabledToolCount,
43926
44153
  "/",
43927
- totalTools
44154
+ totalAvailableTools
43928
44155
  ] }),
43929
44156
  /* @__PURE__ */ jsxRuntimeExports.jsx(ChevronDown, { className: "w-3 h-3 text-slate-400" })
43930
44157
  ]
@@ -43938,7 +44165,7 @@ const ToolSelector = ({
43938
44165
  {
43939
44166
  onClick: () => toggleAllServers(),
43940
44167
  className: "text-xs px-2 py-1 bg-slate-100 dark:bg-slate-800 hover:bg-slate-200 dark:hover:bg-slate-700 rounded text-slate-600 dark:text-slate-300",
43941
- disabled: allToolsEnabled,
44168
+ disabled: allAvailableToolsEnabled,
43942
44169
  children: "All"
43943
44170
  }
43944
44171
  ) })
@@ -43947,44 +44174,55 @@ const ToolSelector = ({
43947
44174
  const serverEnabled = toolSelection.enabledServers.has(
43948
44175
  server.name
43949
44176
  );
44177
+ const serverExpanded = expandedServers.has(server.name);
43950
44178
  const serverTools = server.tools;
43951
44179
  const enabledServerToolCount = serverTools.filter(
43952
44180
  (tool) => toolSelection.enabledTools.has(tool.name)
43953
44181
  ).length;
43954
44182
  const allServerToolsEnabled = enabledServerToolCount === serverTools.length;
43955
44183
  return /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "mb-2", children: [
43956
- /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "px-4 py-2 hover:bg-slate-50 dark:hover:bg-slate-800/50", children: /* @__PURE__ */ jsxRuntimeExports.jsxs("label", { className: "flex items-center gap-3 cursor-pointer", children: [
43957
- /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "relative", children: [
43958
- /* @__PURE__ */ jsxRuntimeExports.jsx(
43959
- "input",
43960
- {
43961
- type: "checkbox",
43962
- checked: serverEnabled,
43963
- onChange: (e) => toggleServer(server.name, e.target.checked),
43964
- className: "w-4 h-4 text-blue-600 bg-gray-100 border-gray-300 rounded focus:ring-blue-500 dark:focus:ring-blue-600 dark:ring-offset-gray-800 focus:ring-2 dark:bg-gray-700 dark:border-gray-600"
43965
- }
43966
- ),
43967
- serverEnabled && allServerToolsEnabled && /* @__PURE__ */ jsxRuntimeExports.jsx(Check, { className: "w-3 h-3 text-blue-600 absolute top-0.5 left-0.5 pointer-events-none" })
43968
- ] }),
43969
- /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex-1", children: [
43970
- /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "text-sm font-medium text-slate-900 dark:text-slate-100", children: server.name }),
43971
- /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "text-xs text-slate-500 dark:text-slate-400", children: [
43972
- enabledServerToolCount,
43973
- "/",
43974
- serverTools.length,
43975
- " tools"
44184
+ /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "relative", children: [
44185
+ /* @__PURE__ */ jsxRuntimeExports.jsxs("label", { className: "flex items-center gap-3 pl-4 pr-12 py-2 min-w-0 cursor-pointer hover:bg-slate-50 dark:hover:bg-slate-800/50", children: [
44186
+ /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "relative", children: [
44187
+ /* @__PURE__ */ jsxRuntimeExports.jsx(
44188
+ "input",
44189
+ {
44190
+ type: "checkbox",
44191
+ checked: serverEnabled,
44192
+ onChange: (e) => toggleServer(server.name, e.target.checked),
44193
+ className: "w-4 h-4 text-blue-600 bg-gray-100 border-gray-300 rounded focus:ring-blue-500 dark:focus:ring-blue-600 dark:ring-offset-gray-800 focus:ring-2 dark:bg-gray-700 dark:border-gray-600"
44194
+ }
44195
+ ),
44196
+ serverEnabled && allServerToolsEnabled && /* @__PURE__ */ jsxRuntimeExports.jsx(Check, { className: "w-3 h-3 text-blue-600 absolute top-0.5 left-0.5 pointer-events-none" })
44197
+ ] }),
44198
+ /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "min-w-0", children: [
44199
+ /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "text-sm font-medium break-words text-slate-900 dark:text-slate-100", children: server.name }),
44200
+ /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "text-xs text-slate-500 dark:text-slate-400", children: [
44201
+ enabledServerToolCount,
44202
+ "/",
44203
+ serverTools.length,
44204
+ " tools"
44205
+ ] })
43976
44206
  ] })
43977
- ] })
43978
- ] }) }),
43979
- serverEnabled && /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "ml-8 space-y-1", children: serverTools.map((tool) => {
44207
+ ] }),
44208
+ /* @__PURE__ */ jsxRuntimeExports.jsx(
44209
+ "button",
44210
+ {
44211
+ onClick: () => toggleExpandedServer(server.name),
44212
+ className: "absolute top-1/2 right-3 -translate-y-1/2 text-xs p-2 hover:bg-slate-100 dark:hover:bg-slate-800 rounded text-slate-600 dark:text-slate-300",
44213
+ children: serverExpanded ? /* @__PURE__ */ jsxRuntimeExports.jsx(ChevronDown, { className: "w-3 h-3 text-slate-400" }) : /* @__PURE__ */ jsxRuntimeExports.jsx(ChevronRight, { className: "w-3 h-3 text-slate-400" })
44214
+ }
44215
+ )
44216
+ ] }),
44217
+ serverExpanded && /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "space-y-1", children: serverTools.map((tool) => {
43980
44218
  const toolEnabled = toolSelection.enabledTools.has(
43981
44219
  tool.name
43982
44220
  );
43983
44221
  return /* @__PURE__ */ jsxRuntimeExports.jsx(
43984
44222
  "div",
43985
44223
  {
43986
- className: "px-4 py-1.5 hover:bg-slate-50 dark:hover:bg-slate-800/50",
43987
- children: /* @__PURE__ */ jsxRuntimeExports.jsxs("label", { className: "flex items-center gap-3 cursor-pointer", children: [
44224
+ className: "hover:bg-slate-50 dark:hover:bg-slate-800/50",
44225
+ children: /* @__PURE__ */ jsxRuntimeExports.jsxs("label", { className: "pl-12 pr-4 py-1.5 flex items-center gap-3 cursor-pointer", children: [
43988
44226
  /* @__PURE__ */ jsxRuntimeExports.jsx(
43989
44227
  "input",
43990
44228
  {
@@ -44014,6 +44252,365 @@ const ToolSelector = ({
44014
44252
  ] })
44015
44253
  ] });
44016
44254
  };
44255
+ function commonjsRequire(path2) {
44256
+ throw new Error('Could not dynamically require "' + path2 + '". Please configure the dynamicRequireTargets or/and ignoreDynamicRequires option of @rollup/plugin-commonjs appropriately for this require call to work.');
44257
+ }
44258
+ var pluralize$2 = { exports: {} };
44259
+ var pluralize$1 = pluralize$2.exports;
44260
+ var hasRequiredPluralize;
44261
+ function requirePluralize() {
44262
+ if (hasRequiredPluralize) return pluralize$2.exports;
44263
+ hasRequiredPluralize = 1;
44264
+ (function(module, exports) {
44265
+ (function(root, pluralize2) {
44266
+ if (typeof commonjsRequire === "function" && true && true) {
44267
+ module.exports = pluralize2();
44268
+ } else {
44269
+ root.pluralize = pluralize2();
44270
+ }
44271
+ })(pluralize$1, function() {
44272
+ var pluralRules = [];
44273
+ var singularRules = [];
44274
+ var uncountables = {};
44275
+ var irregularPlurals = {};
44276
+ var irregularSingles = {};
44277
+ function sanitizeRule(rule) {
44278
+ if (typeof rule === "string") {
44279
+ return new RegExp("^" + rule + "$", "i");
44280
+ }
44281
+ return rule;
44282
+ }
44283
+ function restoreCase(word, token) {
44284
+ if (word === token) return token;
44285
+ if (word === word.toLowerCase()) return token.toLowerCase();
44286
+ if (word === word.toUpperCase()) return token.toUpperCase();
44287
+ if (word[0] === word[0].toUpperCase()) {
44288
+ return token.charAt(0).toUpperCase() + token.substr(1).toLowerCase();
44289
+ }
44290
+ return token.toLowerCase();
44291
+ }
44292
+ function interpolate(str2, args) {
44293
+ return str2.replace(/\$(\d{1,2})/g, function(match, index2) {
44294
+ return args[index2] || "";
44295
+ });
44296
+ }
44297
+ function replace(word, rule) {
44298
+ return word.replace(rule[0], function(match, index2) {
44299
+ var result = interpolate(rule[1], arguments);
44300
+ if (match === "") {
44301
+ return restoreCase(word[index2 - 1], result);
44302
+ }
44303
+ return restoreCase(match, result);
44304
+ });
44305
+ }
44306
+ function sanitizeWord(token, word, rules2) {
44307
+ if (!token.length || uncountables.hasOwnProperty(token)) {
44308
+ return word;
44309
+ }
44310
+ var len = rules2.length;
44311
+ while (len--) {
44312
+ var rule = rules2[len];
44313
+ if (rule[0].test(word)) return replace(word, rule);
44314
+ }
44315
+ return word;
44316
+ }
44317
+ function replaceWord(replaceMap, keepMap, rules2) {
44318
+ return function(word) {
44319
+ var token = word.toLowerCase();
44320
+ if (keepMap.hasOwnProperty(token)) {
44321
+ return restoreCase(word, token);
44322
+ }
44323
+ if (replaceMap.hasOwnProperty(token)) {
44324
+ return restoreCase(word, replaceMap[token]);
44325
+ }
44326
+ return sanitizeWord(token, word, rules2);
44327
+ };
44328
+ }
44329
+ function checkWord(replaceMap, keepMap, rules2, bool) {
44330
+ return function(word) {
44331
+ var token = word.toLowerCase();
44332
+ if (keepMap.hasOwnProperty(token)) return true;
44333
+ if (replaceMap.hasOwnProperty(token)) return false;
44334
+ return sanitizeWord(token, token, rules2) === token;
44335
+ };
44336
+ }
44337
+ function pluralize2(word, count2, inclusive) {
44338
+ var pluralized = count2 === 1 ? pluralize2.singular(word) : pluralize2.plural(word);
44339
+ return (inclusive ? count2 + " " : "") + pluralized;
44340
+ }
44341
+ pluralize2.plural = replaceWord(
44342
+ irregularSingles,
44343
+ irregularPlurals,
44344
+ pluralRules
44345
+ );
44346
+ pluralize2.isPlural = checkWord(
44347
+ irregularSingles,
44348
+ irregularPlurals,
44349
+ pluralRules
44350
+ );
44351
+ pluralize2.singular = replaceWord(
44352
+ irregularPlurals,
44353
+ irregularSingles,
44354
+ singularRules
44355
+ );
44356
+ pluralize2.isSingular = checkWord(
44357
+ irregularPlurals,
44358
+ irregularSingles,
44359
+ singularRules
44360
+ );
44361
+ pluralize2.addPluralRule = function(rule, replacement) {
44362
+ pluralRules.push([sanitizeRule(rule), replacement]);
44363
+ };
44364
+ pluralize2.addSingularRule = function(rule, replacement) {
44365
+ singularRules.push([sanitizeRule(rule), replacement]);
44366
+ };
44367
+ pluralize2.addUncountableRule = function(word) {
44368
+ if (typeof word === "string") {
44369
+ uncountables[word.toLowerCase()] = true;
44370
+ return;
44371
+ }
44372
+ pluralize2.addPluralRule(word, "$0");
44373
+ pluralize2.addSingularRule(word, "$0");
44374
+ };
44375
+ pluralize2.addIrregularRule = function(single, plural) {
44376
+ plural = plural.toLowerCase();
44377
+ single = single.toLowerCase();
44378
+ irregularSingles[single] = plural;
44379
+ irregularPlurals[plural] = single;
44380
+ };
44381
+ [
44382
+ // Pronouns.
44383
+ ["I", "we"],
44384
+ ["me", "us"],
44385
+ ["he", "they"],
44386
+ ["she", "they"],
44387
+ ["them", "them"],
44388
+ ["myself", "ourselves"],
44389
+ ["yourself", "yourselves"],
44390
+ ["itself", "themselves"],
44391
+ ["herself", "themselves"],
44392
+ ["himself", "themselves"],
44393
+ ["themself", "themselves"],
44394
+ ["is", "are"],
44395
+ ["was", "were"],
44396
+ ["has", "have"],
44397
+ ["this", "these"],
44398
+ ["that", "those"],
44399
+ // Words ending in with a consonant and `o`.
44400
+ ["echo", "echoes"],
44401
+ ["dingo", "dingoes"],
44402
+ ["volcano", "volcanoes"],
44403
+ ["tornado", "tornadoes"],
44404
+ ["torpedo", "torpedoes"],
44405
+ // Ends with `us`.
44406
+ ["genus", "genera"],
44407
+ ["viscus", "viscera"],
44408
+ // Ends with `ma`.
44409
+ ["stigma", "stigmata"],
44410
+ ["stoma", "stomata"],
44411
+ ["dogma", "dogmata"],
44412
+ ["lemma", "lemmata"],
44413
+ ["schema", "schemata"],
44414
+ ["anathema", "anathemata"],
44415
+ // Other irregular rules.
44416
+ ["ox", "oxen"],
44417
+ ["axe", "axes"],
44418
+ ["die", "dice"],
44419
+ ["yes", "yeses"],
44420
+ ["foot", "feet"],
44421
+ ["eave", "eaves"],
44422
+ ["goose", "geese"],
44423
+ ["tooth", "teeth"],
44424
+ ["quiz", "quizzes"],
44425
+ ["human", "humans"],
44426
+ ["proof", "proofs"],
44427
+ ["carve", "carves"],
44428
+ ["valve", "valves"],
44429
+ ["looey", "looies"],
44430
+ ["thief", "thieves"],
44431
+ ["groove", "grooves"],
44432
+ ["pickaxe", "pickaxes"],
44433
+ ["passerby", "passersby"]
44434
+ ].forEach(function(rule) {
44435
+ return pluralize2.addIrregularRule(rule[0], rule[1]);
44436
+ });
44437
+ [
44438
+ [/s?$/i, "s"],
44439
+ [/[^\u0000-\u007F]$/i, "$0"],
44440
+ [/([^aeiou]ese)$/i, "$1"],
44441
+ [/(ax|test)is$/i, "$1es"],
44442
+ [/(alias|[^aou]us|t[lm]as|gas|ris)$/i, "$1es"],
44443
+ [/(e[mn]u)s?$/i, "$1s"],
44444
+ [/([^l]ias|[aeiou]las|[ejzr]as|[iu]am)$/i, "$1"],
44445
+ [/(alumn|syllab|vir|radi|nucle|fung|cact|stimul|termin|bacill|foc|uter|loc|strat)(?:us|i)$/i, "$1i"],
44446
+ [/(alumn|alg|vertebr)(?:a|ae)$/i, "$1ae"],
44447
+ [/(seraph|cherub)(?:im)?$/i, "$1im"],
44448
+ [/(her|at|gr)o$/i, "$1oes"],
44449
+ [/(agend|addend|millenni|dat|extrem|bacteri|desiderat|strat|candelabr|errat|ov|symposi|curricul|automat|quor)(?:a|um)$/i, "$1a"],
44450
+ [/(apheli|hyperbat|periheli|asyndet|noumen|phenomen|criteri|organ|prolegomen|hedr|automat)(?:a|on)$/i, "$1a"],
44451
+ [/sis$/i, "ses"],
44452
+ [/(?:(kni|wi|li)fe|(ar|l|ea|eo|oa|hoo)f)$/i, "$1$2ves"],
44453
+ [/([^aeiouy]|qu)y$/i, "$1ies"],
44454
+ [/([^ch][ieo][ln])ey$/i, "$1ies"],
44455
+ [/(x|ch|ss|sh|zz)$/i, "$1es"],
44456
+ [/(matr|cod|mur|sil|vert|ind|append)(?:ix|ex)$/i, "$1ices"],
44457
+ [/\b((?:tit)?m|l)(?:ice|ouse)$/i, "$1ice"],
44458
+ [/(pe)(?:rson|ople)$/i, "$1ople"],
44459
+ [/(child)(?:ren)?$/i, "$1ren"],
44460
+ [/eaux$/i, "$0"],
44461
+ [/m[ae]n$/i, "men"],
44462
+ ["thou", "you"]
44463
+ ].forEach(function(rule) {
44464
+ return pluralize2.addPluralRule(rule[0], rule[1]);
44465
+ });
44466
+ [
44467
+ [/s$/i, ""],
44468
+ [/(ss)$/i, "$1"],
44469
+ [/(wi|kni|(?:after|half|high|low|mid|non|night|[^\w]|^)li)ves$/i, "$1fe"],
44470
+ [/(ar|(?:wo|[ae])l|[eo][ao])ves$/i, "$1f"],
44471
+ [/ies$/i, "y"],
44472
+ [/\b([pl]|zomb|(?:neck|cross)?t|coll|faer|food|gen|goon|group|lass|talk|goal|cut)ies$/i, "$1ie"],
44473
+ [/\b(mon|smil)ies$/i, "$1ey"],
44474
+ [/\b((?:tit)?m|l)ice$/i, "$1ouse"],
44475
+ [/(seraph|cherub)im$/i, "$1"],
44476
+ [/(x|ch|ss|sh|zz|tto|go|cho|alias|[^aou]us|t[lm]as|gas|(?:her|at|gr)o|[aeiou]ris)(?:es)?$/i, "$1"],
44477
+ [/(analy|diagno|parenthe|progno|synop|the|empha|cri|ne)(?:sis|ses)$/i, "$1sis"],
44478
+ [/(movie|twelve|abuse|e[mn]u)s$/i, "$1"],
44479
+ [/(test)(?:is|es)$/i, "$1is"],
44480
+ [/(alumn|syllab|vir|radi|nucle|fung|cact|stimul|termin|bacill|foc|uter|loc|strat)(?:us|i)$/i, "$1us"],
44481
+ [/(agend|addend|millenni|dat|extrem|bacteri|desiderat|strat|candelabr|errat|ov|symposi|curricul|quor)a$/i, "$1um"],
44482
+ [/(apheli|hyperbat|periheli|asyndet|noumen|phenomen|criteri|organ|prolegomen|hedr|automat)a$/i, "$1on"],
44483
+ [/(alumn|alg|vertebr)ae$/i, "$1a"],
44484
+ [/(cod|mur|sil|vert|ind)ices$/i, "$1ex"],
44485
+ [/(matr|append)ices$/i, "$1ix"],
44486
+ [/(pe)(rson|ople)$/i, "$1rson"],
44487
+ [/(child)ren$/i, "$1"],
44488
+ [/(eau)x?$/i, "$1"],
44489
+ [/men$/i, "man"]
44490
+ ].forEach(function(rule) {
44491
+ return pluralize2.addSingularRule(rule[0], rule[1]);
44492
+ });
44493
+ [
44494
+ // Singular words with no plurals.
44495
+ "adulthood",
44496
+ "advice",
44497
+ "agenda",
44498
+ "aid",
44499
+ "aircraft",
44500
+ "alcohol",
44501
+ "ammo",
44502
+ "analytics",
44503
+ "anime",
44504
+ "athletics",
44505
+ "audio",
44506
+ "bison",
44507
+ "blood",
44508
+ "bream",
44509
+ "buffalo",
44510
+ "butter",
44511
+ "carp",
44512
+ "cash",
44513
+ "chassis",
44514
+ "chess",
44515
+ "clothing",
44516
+ "cod",
44517
+ "commerce",
44518
+ "cooperation",
44519
+ "corps",
44520
+ "debris",
44521
+ "diabetes",
44522
+ "digestion",
44523
+ "elk",
44524
+ "energy",
44525
+ "equipment",
44526
+ "excretion",
44527
+ "expertise",
44528
+ "firmware",
44529
+ "flounder",
44530
+ "fun",
44531
+ "gallows",
44532
+ "garbage",
44533
+ "graffiti",
44534
+ "hardware",
44535
+ "headquarters",
44536
+ "health",
44537
+ "herpes",
44538
+ "highjinks",
44539
+ "homework",
44540
+ "housework",
44541
+ "information",
44542
+ "jeans",
44543
+ "justice",
44544
+ "kudos",
44545
+ "labour",
44546
+ "literature",
44547
+ "machinery",
44548
+ "mackerel",
44549
+ "mail",
44550
+ "media",
44551
+ "mews",
44552
+ "moose",
44553
+ "music",
44554
+ "mud",
44555
+ "manga",
44556
+ "news",
44557
+ "only",
44558
+ "personnel",
44559
+ "pike",
44560
+ "plankton",
44561
+ "pliers",
44562
+ "police",
44563
+ "pollution",
44564
+ "premises",
44565
+ "rain",
44566
+ "research",
44567
+ "rice",
44568
+ "salmon",
44569
+ "scissors",
44570
+ "series",
44571
+ "sewage",
44572
+ "shambles",
44573
+ "shrimp",
44574
+ "software",
44575
+ "species",
44576
+ "staff",
44577
+ "swine",
44578
+ "tennis",
44579
+ "traffic",
44580
+ "transportation",
44581
+ "trout",
44582
+ "tuna",
44583
+ "wealth",
44584
+ "welfare",
44585
+ "whiting",
44586
+ "wildebeest",
44587
+ "wildlife",
44588
+ "you",
44589
+ /pok[eé]mon$/i,
44590
+ // Regexes.
44591
+ /[^aeiou]ese$/i,
44592
+ // "chinese", "japanese"
44593
+ /deer$/i,
44594
+ // "deer", "reindeer"
44595
+ /fish$/i,
44596
+ // "fish", "blowfish", "angelfish"
44597
+ /measles$/i,
44598
+ /o[iu]s$/i,
44599
+ // "carnivorous"
44600
+ /pox$/i,
44601
+ // "chickpox", "smallpox"
44602
+ /sheep$/i
44603
+ ].forEach(pluralize2.addUncountableRule);
44604
+ return pluralize2;
44605
+ });
44606
+ })(pluralize$2);
44607
+ return pluralize$2.exports;
44608
+ }
44609
+ var pluralizeExports = requirePluralize();
44610
+ const pluralize = /* @__PURE__ */ getDefaultExportFromCjs(pluralizeExports);
44611
+ function formatPlural(count2, word) {
44612
+ return `${count2} ${pluralize(word, count2)}`;
44613
+ }
44017
44614
  const Chat2 = ({
44018
44615
  provider,
44019
44616
  config,
@@ -44366,7 +44963,7 @@ const Chat2 = ({
44366
44963
  ) }),
44367
44964
  /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { children: [
44368
44965
  /* @__PURE__ */ jsxRuntimeExports.jsx("h1", { className: "text-base font-semibold text-slate-900 dark:text-slate-100", children: config.title }),
44369
- /* @__PURE__ */ jsxRuntimeExports.jsx("p", { className: "text-xs text-slate-500 dark:text-slate-400", children: hasApiKey ? `${serversCount} servers • ${toolSelection.enabledTools.size}/${toolsCount} tools` : "API key required" })
44966
+ /* @__PURE__ */ jsxRuntimeExports.jsx("p", { className: "text-xs text-slate-500 dark:text-slate-400", children: hasApiKey ? `${formatPlural(serversCount, "server")} • ${toolSelection.enabledTools.size}/${formatPlural(toolsCount, "tool")}` : "API key required" })
44370
44967
  ] })
44371
44968
  ] }),
44372
44969
  hasApiKey && /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex items-center gap-2", children: [
@@ -44481,18 +45078,15 @@ const Chat2 = ({
44481
45078
  },
44482
45079
  idx
44483
45080
  )),
44484
- hasPendingToolCalls && /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "px-6 mb-2", children: [
44485
- /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "mb-2 text-sm text-amber-600 dark:text-amber-400 font-medium", children: "Pending Tool Calls:" }),
44486
- Array.from(pendingToolCalls.values()).map((toolCall) => /* @__PURE__ */ jsxRuntimeExports.jsx(
44487
- ToolCallApproval,
44488
- {
44489
- toolCall,
44490
- onApprove: handleApproveToolCall,
44491
- onReject: handleRejectToolCall
44492
- },
44493
- toolCall.id
44494
- ))
44495
- ] }),
45081
+ hasPendingToolCalls && /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "px-6 mb-2", children: Array.from(pendingToolCalls.values()).map((toolCall) => /* @__PURE__ */ jsxRuntimeExports.jsx(
45082
+ ToolCallApproval,
45083
+ {
45084
+ toolCall,
45085
+ onApprove: handleApproveToolCall,
45086
+ onReject: handleRejectToolCall
45087
+ },
45088
+ toolCall.id
45089
+ )) }),
44496
45090
  loading && /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex gap-3 px-6 py-4", children: [
44497
45091
  /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "flex-shrink-0 w-8 h-8 rounded-full bg-slate-100 dark:bg-slate-800 flex items-center justify-center", children: /* @__PURE__ */ jsxRuntimeExports.jsx(
44498
45092
  ProviderLogo,
@@ -44567,7 +45161,7 @@ const Chat2 = ({
44567
45161
  };
44568
45162
  const ChatTab = ({ mcpAgent, updateTrigger }) => {
44569
45163
  const config = createChatConfig({
44570
- subtitle: "Chat with access to tools from all connected servers",
45164
+ subtitle: "LLM Playground with access to tools from all connected servers",
44571
45165
  additionalSuggestions: ["What tools do you have access to?"]
44572
45166
  });
44573
45167
  const getServersCount = () => {
@@ -44597,245 +45191,167 @@ const ChatTab = ({ mcpAgent, updateTrigger }) => {
44597
45191
  }
44598
45192
  );
44599
45193
  };
44600
- const ProviderSection = ({
44601
- providerName,
45194
+ const ProviderCard = ({
45195
+ provider,
44602
45196
  config,
44603
- keyData,
44604
- isCollapsed,
45197
+ data: data2,
44605
45198
  disabled = false,
44606
- onApiKeyChange,
44607
- onClearApiKey,
44608
- onToggleShowKey,
44609
- onToggleCollapse
45199
+ onChange,
45200
+ onClear,
45201
+ onToggleShow
44610
45202
  }) => {
44611
- console.log("providerName", providerName);
44612
- console.log("keyData", keyData);
44613
- const renderCollapsedView = () => {
44614
- return /* @__PURE__ */ jsxRuntimeExports.jsx(
44615
- "div",
44616
- {
44617
- className: "p-3 bg-green-50/80 dark:bg-green-900/20 backdrop-blur-sm rounded-lg border border-green-200/60 dark:border-green-700/60 shadow-sm",
44618
- children: /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex items-center justify-between", children: [
44619
- /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex items-center gap-2", children: [
44620
- /* @__PURE__ */ jsxRuntimeExports.jsx(Key, { className: "w-4 h-4 text-green-600 dark:text-green-400" }),
44621
- /* @__PURE__ */ jsxRuntimeExports.jsx(CircleCheckBig, { className: "w-4 h-4 text-green-600 dark:text-green-400" }),
44622
- /* @__PURE__ */ jsxRuntimeExports.jsxs("span", { className: "text-sm font-medium text-green-700 dark:text-green-300", children: [
44623
- config.displayName,
44624
- " API Key Configured"
44625
- ] })
44626
- ] }),
44627
- /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "flex items-center gap-2", children: /* @__PURE__ */ jsxRuntimeExports.jsxs(
44628
- Button,
44629
- {
44630
- variant: "ghost",
44631
- size: "sm",
44632
- onClick: () => onToggleCollapse(providerName),
44633
- disabled,
44634
- className: "h-7 px-2 text-green-700 dark:text-green-300 hover:bg-green-100/50 dark:hover:bg-green-800/30",
44635
- children: [
44636
- /* @__PURE__ */ jsxRuntimeExports.jsx(ChevronRight, { className: "w-4 h-4" }),
44637
- /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "ml-1 text-xs", children: "Manage" })
44638
- ]
44639
- }
44640
- ) })
44641
- ] })
44642
- },
44643
- providerName
44644
- );
44645
- };
44646
- const renderExpandedView = () => {
44647
- return /* @__PURE__ */ jsxRuntimeExports.jsxs(
44648
- "div",
44649
- {
44650
- className: "p-4 bg-white/60 dark:bg-slate-800/60 backdrop-blur-sm rounded-xl border border-slate-200/60 dark:border-slate-700/60 shadow-lg",
44651
- children: [
44652
- /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "flex items-center justify-between mb-3", children: /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex items-center gap-2", children: [
44653
- /* @__PURE__ */ jsxRuntimeExports.jsx(Key, { className: "w-5 h-5 text-blue-600 dark:text-blue-400" }),
44654
- /* @__PURE__ */ jsxRuntimeExports.jsx("h3", { className: "text-lg font-semibold text-slate-800 dark:text-slate-200", children: config.displayName }),
44655
- keyData.isValid && /* @__PURE__ */ jsxRuntimeExports.jsx(CircleCheckBig, { className: "w-5 h-5 text-green-600 dark:text-green-400" }),
44656
- keyData.key.length > 0 && !keyData.isValid && /* @__PURE__ */ jsxRuntimeExports.jsx(CircleAlert, { className: "w-5 h-5 text-red-600 dark:text-red-400" })
44657
- ] }) }),
44658
- /* @__PURE__ */ jsxRuntimeExports.jsx("p", { className: "text-sm text-slate-600 dark:text-slate-400 mb-4", children: config.description }),
44659
- /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "space-y-3", children: [
44660
- /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex gap-2", children: [
44661
- /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex-1 relative", children: [
44662
- /* @__PURE__ */ jsxRuntimeExports.jsx(
44663
- Input,
44664
- {
44665
- type: keyData.showKey ? "text" : "password",
44666
- placeholder: config.placeholder,
44667
- value: keyData.key,
44668
- onChange: (e) => onApiKeyChange(providerName, e.target.value),
44669
- disabled,
44670
- className: `font-mono pr-10 ${keyData.key.length > 0 ? keyData.isValid ? "border-green-500 dark:border-green-400" : "border-red-500 dark:border-red-400" : ""}`
44671
- }
44672
- ),
44673
- /* @__PURE__ */ jsxRuntimeExports.jsx(
44674
- Button,
44675
- {
44676
- type: "button",
44677
- variant: "ghost",
44678
- size: "icon",
44679
- className: "absolute right-1 top-1/2 transform -translate-y-1/2 h-8 w-8",
44680
- onClick: () => onToggleShowKey(providerName),
44681
- disabled,
44682
- children: keyData.showKey ? /* @__PURE__ */ jsxRuntimeExports.jsx(EyeOff, { className: "h-4 w-4" }) : /* @__PURE__ */ jsxRuntimeExports.jsx(Eye, { className: "h-4 w-4" })
44683
- }
44684
- )
44685
- ] }),
44686
- keyData.key.length > 0 && /* @__PURE__ */ jsxRuntimeExports.jsx(
44687
- Button,
44688
- {
44689
- variant: "outline",
44690
- onClick: () => onClearApiKey(providerName),
44691
- disabled,
44692
- className: "bg-white/70 dark:bg-slate-800/70 backdrop-blur-sm border-slate-300/60 dark:border-slate-600/60 hover:border-red-400/60 dark:hover:border-red-500/60 hover:bg-red-50/80 dark:hover:bg-red-900/20",
44693
- children: "Clear"
44694
- }
44695
- )
44696
- ] }),
44697
- keyData.key.length > 0 && !keyData.isValid && /* @__PURE__ */ jsxRuntimeExports.jsxs("p", { className: "text-sm text-red-600 dark:text-red-400", children: [
44698
- "Please enter a valid ",
44699
- config.displayName,
44700
- " API key with the correct format"
44701
- ] }),
44702
- !keyData.key.length && /* @__PURE__ */ jsxRuntimeExports.jsxs("p", { className: "text-sm text-slate-600 dark:text-slate-400", children: [
44703
- "Enter your ",
44704
- config.displayName,
44705
- " API key to enable related functionality. Your key will be securely stored in your browser's local storage."
44706
- ] }),
44707
- keyData.isValid && /* @__PURE__ */ jsxRuntimeExports.jsxs("p", { className: "text-sm text-green-600 dark:text-green-400", children: [
44708
- "✓ Valid ",
44709
- config.displayName,
44710
- " API key configured."
44711
- ] })
44712
- ] })
44713
- ]
44714
- },
44715
- providerName
44716
- );
44717
- };
44718
- return isCollapsed ? renderCollapsedView() : renderExpandedView();
45203
+ return /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "bg-white dark:bg-gray-800 rounded-xl shadow hover:shadow-lg transition p-6 flex flex-col", children: [
45204
+ /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex items-center mb-4 -ml-1", children: [
45205
+ /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "w-8 h-8 flex items-center justify-center bg-white rounded-md", children: /* @__PURE__ */ jsxRuntimeExports.jsx(
45206
+ "img",
45207
+ {
45208
+ src: config.logo,
45209
+ alt: `${config.displayName} logo`,
45210
+ className: "w-5 h-5"
45211
+ }
45212
+ ) }),
45213
+ /* @__PURE__ */ jsxRuntimeExports.jsx("h3", { className: "text-xl font-semibold text-gray-900 dark:text-gray-100", children: config.displayName })
45214
+ ] }),
45215
+ /* @__PURE__ */ jsxRuntimeExports.jsx("p", { className: "text-gray-600 dark:text-gray-400 mb-4 text-sm", children: config.description }),
45216
+ /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "space-y-4", children: [
45217
+ /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "relative", children: [
45218
+ /* @__PURE__ */ jsxRuntimeExports.jsx(
45219
+ "input",
45220
+ {
45221
+ type: data2.showKey ? "text" : "password",
45222
+ value: data2.key,
45223
+ placeholder: config.placeholder,
45224
+ disabled,
45225
+ onChange: (e) => onChange(provider, e.target.value),
45226
+ className: "w-full pr-10 p-2 text-sm border rounded-lg bg-white dark:bg-gray-700 focus:outline-none focus:ring-2 focus:ring-indigo-400"
45227
+ }
45228
+ ),
45229
+ /* @__PURE__ */ jsxRuntimeExports.jsx(
45230
+ "button",
45231
+ {
45232
+ onClick: () => onToggleShow(provider),
45233
+ className: "absolute right-2 top-1/2 -translate-y-1/2 text-gray-400 hover:text-gray-600 dark:hover:text-gray-300",
45234
+ disabled: disabled || !data2.key,
45235
+ children: data2.showKey ? /* @__PURE__ */ jsxRuntimeExports.jsx(EyeOff, { size: 16 }) : /* @__PURE__ */ jsxRuntimeExports.jsx(Eye, { size: 16 })
45236
+ }
45237
+ )
45238
+ ] }),
45239
+ /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex space-x-2", children: [
45240
+ /* @__PURE__ */ jsxRuntimeExports.jsx(
45241
+ "button",
45242
+ {
45243
+ onClick: () => onChange(provider, data2.key),
45244
+ disabled: disabled || !data2.key,
45245
+ className: "flex-1 bg-gray-600 hover:bg-gray-700 text-white text-sm py-1 rounded transition disabled:opacity-50",
45246
+ children: "Save"
45247
+ }
45248
+ ),
45249
+ /* @__PURE__ */ jsxRuntimeExports.jsx(
45250
+ "button",
45251
+ {
45252
+ onClick: () => onClear(provider),
45253
+ disabled: disabled || !data2.key,
45254
+ className: "flex-1 border border-gray-400 hover:border-gray-500 text-gray-400 hover:text-gray-600 text-sm py-1 rounded transition disabled:opacity-50",
45255
+ children: "Clear"
45256
+ }
45257
+ )
45258
+ ] })
45259
+ ] })
45260
+ ] });
44719
45261
  };
45262
+ const ClaudeLogo = "data:image/svg+xml,%3csvg%20xmlns='http://www.w3.org/2000/svg'%20shape-rendering='geometricPrecision'%20text-rendering='geometricPrecision'%20image-rendering='optimizeQuality'%20fill-rule='evenodd'%20clip-rule='evenodd'%20viewBox='0%200%20512%20509.64'%3e%3cpath%20fill='%23D77655'%20d='M115.612%200h280.775C459.974%200%20512%2052.026%20512%20115.612v278.415c0%2063.587-52.026%20115.612-115.613%20115.612H115.612C52.026%20509.639%200%20457.614%200%20394.027V115.612C0%2052.026%2052.026%200%20115.612%200z'/%3e%3cpath%20fill='%23FCF2EE'%20fill-rule='nonzero'%20d='M142.27%20316.619l73.655-41.326%201.238-3.589-1.238-1.996-3.589-.001-12.31-.759-42.084-1.138-36.498-1.516-35.361-1.896-8.897-1.895-8.34-10.995.859-5.484%207.482-5.03%2010.717.935%2023.683%201.617%2035.537%202.452%2025.782%201.517%2038.193%203.968h6.064l.86-2.451-2.073-1.517-1.618-1.517-36.776-24.922-39.81-26.338-20.852-15.166-11.273-7.683-5.687-7.204-2.451-15.721%2010.237-11.273%2013.75.935%203.513.936%2013.928%2010.716%2029.749%2023.027%2038.848%2028.612%205.687%204.727%202.275-1.617.278-1.138-2.553-4.271-21.13-38.193-22.546-38.848-10.035-16.101-2.654-9.655c-.935-3.968-1.617-7.304-1.617-11.374l11.652-15.823%206.445-2.073%2015.545%202.073%206.547%205.687%209.655%2022.092%2015.646%2034.78%2024.265%2047.291%207.103%2014.028%203.791%2012.992%201.416%203.968%202.449-.001v-2.275l1.997-26.641%203.69-32.707%203.589-42.084%201.239-11.854%205.863-14.206%2011.652-7.683%209.099%204.348%207.482%2010.716-1.036%206.926-4.449%2028.915-8.72%2045.294-5.687%2030.331h3.313l3.792-3.791%2015.342-20.372%2025.782-32.227%2011.374-12.789%2013.27-14.129%208.517-6.724%2016.1-.001%2011.854%2017.617-5.307%2018.199-16.581%2021.029-13.75%2017.819-19.716%2026.54-12.309%2021.231%201.138%201.694%202.932-.278%2044.536-9.479%2024.062-4.347%2028.714-4.928%2012.992%206.066%201.416%206.167-5.106%2012.613-30.71%207.583-36.018%207.204-53.636%2012.689-.657.48.758.935%2024.164%202.275%2010.337.556h25.301l47.114%203.514%2012.309%208.139%207.381%209.959-1.238%207.583-18.957%209.655-25.579-6.066-59.702-14.205-20.474-5.106-2.83-.001v1.694l17.061%2016.682%2031.266%2028.233%2039.152%2036.397%201.997%208.999-5.03%207.102-5.307-.758-34.401-25.883-13.27-11.651-30.053-25.302-1.996-.001v2.654l6.926%2010.136%2036.574%2054.975%201.895%2016.859-2.653%205.485-9.479%203.311-10.414-1.895-21.408-30.054-22.092-33.844-17.819-30.331-2.173%201.238-10.515%20113.261-4.929%205.788-11.374%204.348-9.478-7.204-5.03-11.652%205.03-23.027%206.066-30.052%204.928-23.886%204.449-29.674%202.654-9.858-.177-.657-2.173.278-22.37%2030.71-34.021%2045.977-26.919%2028.815-6.445%202.553-11.173-5.789%201.037-10.337%206.243-9.2%2037.257-47.392%2022.47-29.371%2014.508-16.961-.101-2.451h-.859l-98.954%2064.251-17.618%202.275-7.583-7.103.936-11.652%203.589-3.791%2029.749-20.474-.101.102.024.101z'/%3e%3c/svg%3e";
45263
+ const OpenAILogo = "data:image/svg+xml,%3csvg%20viewBox='0%200%20512%20512'%20xmlns='http://www.w3.org/2000/svg'%20fill-rule='evenodd'%20clip-rule='evenodd'%20stroke-linejoin='round'%20stroke-miterlimit='2'%3e%3cpath%20d='M474.123%20209.81c11.525-34.577%207.569-72.423-10.838-103.904-27.696-48.168-83.433-72.94-137.794-61.414a127.14%20127.14%200%2000-95.475-42.49c-55.564%200-104.936%2035.781-122.139%2088.593-35.781%207.397-66.574%2029.76-84.637%2061.414-27.868%2048.167-21.503%20108.72%2015.826%20150.007-11.525%2034.578-7.569%2072.424%2010.838%20103.733%2027.696%2048.34%2083.433%2073.111%20137.966%2061.585%2024.084%2027.18%2058.833%2042.835%2095.303%2042.663%2055.564%200%20104.936-35.782%20122.139-88.594%2035.782-7.397%2066.574-29.76%2084.465-61.413%2028.04-48.168%2021.676-108.722-15.654-150.008v-.172zm-39.567-87.218c11.01%2019.267%2015.139%2041.803%2011.354%2063.65-.688-.516-2.064-1.204-2.924-1.72l-101.152-58.49a16.965%2016.965%200%2000-16.687%200L206.621%20194.5v-50.232l97.883-56.597c45.587-26.32%20103.732-10.666%20130.052%2034.921zm-227.935%20104.42l49.888-28.9%2049.887%2028.9v57.63l-49.887%2028.9-49.888-28.9v-57.63zm23.223-191.81c22.364%200%2043.867%207.742%2061.07%2022.02-.688.344-2.064%201.204-3.097%201.72L186.666%20117.26c-5.161%202.925-8.258%208.43-8.258%2014.45v136.934l-43.523-25.116V130.333c0-52.64%2042.491-95.13%2095.131-95.302l-.172.172zM52.14%20168.697c11.182-19.268%2028.557-34.062%2049.544-41.803V247.14c0%206.02%203.097%2011.354%208.258%2014.45l118.354%2068.295-43.695%2025.288-97.711-56.425c-45.415-26.32-61.07-84.465-34.75-130.052zm26.665%20220.71c-11.182-19.095-15.139-41.802-11.354-63.65.688.516%202.064%201.204%202.924%201.72l101.152%2058.49a16.965%2016.965%200%200016.687%200l118.354-68.467v50.232l-97.883%2056.425c-45.587%2026.148-103.732%2010.665-130.052-34.75h.172zm204.54%2087.39c-22.192%200-43.867-7.741-60.898-22.02a62.439%2062.439%200%20003.097-1.72l101.152-58.317c5.16-2.924%208.429-8.43%208.257-14.45V243.527l43.523%2025.116v113.022c0%2052.64-42.663%2095.303-95.131%2095.303v-.172zM461.22%20343.303c-11.182%2019.267-28.729%2034.061-49.544%2041.63V264.687c0-6.021-3.097-11.526-8.257-14.45L284.893%20181.77l43.523-25.116%2097.883%2056.424c45.587%2026.32%2061.07%2084.466%2034.75%20130.053l.172.172z'%20fill-rule='nonzero'/%3e%3c/svg%3e";
45264
+ const OllamaLogo = "data:image/svg+xml,%3csvg%20fill='currentColor'%20fill-rule='evenodd'%20height='1em'%20style='flex:none;line-height:1'%20viewBox='0%200%2024%2024'%20width='1em'%20xmlns='http://www.w3.org/2000/svg'%3e%3ctitle%3eOllama%3c/title%3e%3cpath%20d='M7.905%201.09c.216.085.411.225.588.41.295.306.544.744.734%201.263.191.522.315%201.1.362%201.68a5.054%205.054%200%20012.049-.636l.051-.004c.87-.07%201.73.087%202.48.474.101.053.2.11.297.17.05-.569.172-1.134.36-1.644.19-.52.439-.957.733-1.264a1.67%201.67%200%2001.589-.41c.257-.1.53-.118.796-.042.401.114.745.368%201.016.737.248.337.434.769.561%201.287.23.934.27%202.163.115%203.645l.053.04.026.019c.757.576%201.284%201.397%201.563%202.35.435%201.487.216%203.155-.534%204.088l-.018.021.002.003c.417.762.67%201.567.724%202.4l.002.03c.064%201.065-.2%202.137-.814%203.19l-.007.01.01.024c.472%201.157.62%202.322.438%203.486l-.006.039a.651.651%200%2001-.747.536.648.648%200%2001-.54-.742c.167-1.033.01-2.069-.48-3.123a.643.643%200%2001.04-.617l.004-.006c.604-.924.854-1.83.8-2.72-.046-.779-.325-1.544-.8-2.273a.644.644%200%2001.18-.886l.009-.006c.243-.159.467-.565.58-1.12a4.229%204.229%200%2000-.095-1.974c-.205-.7-.58-1.284-1.105-1.683-.595-.454-1.383-.673-2.38-.61a.653.653%200%2001-.632-.371c-.314-.665-.772-1.141-1.343-1.436a3.288%203.288%200%2000-1.772-.332c-1.245.099-2.343.801-2.67%201.686a.652.652%200%2001-.61.425c-1.067.002-1.893.252-2.497.703-.522.39-.878.935-1.066%201.588a4.07%204.07%200%2000-.068%201.886c.112.558.331%201.02.582%201.269l.008.007c.212.207.257.53.109.785-.36.622-.629%201.549-.673%202.44-.05%201.018.186%201.902.719%202.536l.016.019a.643.643%200%2001.095.69c-.576%201.236-.753%202.252-.562%203.052a.652.652%200%2001-1.269.298c-.243-1.018-.078-2.184.473-3.498l.014-.035-.008-.012a4.339%204.339%200%2001-.598-1.309l-.005-.019a5.764%205.764%200%2001-.177-1.785c.044-.91.278-1.842.622-2.59l.012-.026-.002-.002c-.293-.418-.51-.953-.63-1.545l-.005-.024a5.352%205.352%200%2001.093-2.49c.262-.915.777-1.701%201.536-2.269.06-.045.123-.09.186-.132-.159-1.493-.119-2.73.112-3.67.127-.518.314-.95.562-1.287.27-.368.614-.622%201.015-.737.266-.076.54-.059.797.042zm4.116%209.09c.936%200%201.8.313%202.446.855.63.527%201.005%201.235%201.005%201.94%200%20.888-.406%201.58-1.133%202.022-.62.375-1.451.557-2.403.557-1.009%200-1.871-.259-2.493-.734-.617-.47-.963-1.13-.963-1.845%200-.707.398-1.417%201.056-1.946.668-.537%201.55-.849%202.485-.849zm0%20.896a3.07%203.07%200%2000-1.916.65c-.461.37-.722.835-.722%201.25%200%20.428.21.829.61%201.134.455.347%201.124.548%201.943.548.799%200%201.473-.147%201.932-.426.463-.28.7-.686.7-1.257%200-.423-.246-.89-.683-1.256-.484-.405-1.14-.643-1.864-.643zm.662%201.21l.004.004c.12.151.095.37-.056.49l-.292.23v.446a.375.375%200%2001-.376.373.375.375%200%2001-.376-.373v-.46l-.271-.218a.347.347%200%2001-.052-.49.353.353%200%2001.494-.051l.215.172.22-.174a.353.353%200%2001.49.051zm-5.04-1.919c.478%200%20.867.39.867.871a.87.87%200%2001-.868.871.87.87%200%2001-.867-.87.87.87%200%2001.867-.872zm8.706%200c.48%200%20.868.39.868.871a.87.87%200%2001-.868.871.87.87%200%2001-.867-.87.87.87%200%2001.867-.872zM7.44%202.3l-.003.002a.659.659%200%2000-.285.238l-.005.006c-.138.189-.258.467-.348.832-.17.692-.216%201.631-.124%202.782.43-.128.899-.208%201.404-.237l.01-.001.019-.034c.046-.082.095-.161.148-.239.123-.771.022-1.692-.253-2.444-.134-.364-.297-.65-.453-.813a.628.628%200%2000-.107-.09L7.44%202.3zm9.174.04l-.002.001a.628.628%200%2000-.107.09c-.156.163-.32.45-.453.814-.29.794-.387%201.776-.23%202.572l.058.097.008.014h.03a5.184%205.184%200%20011.466.212c.086-1.124.038-2.043-.128-2.722-.09-.365-.21-.643-.349-.832l-.004-.006a.659.659%200%2000-.285-.239h-.004z'%3e%3c/path%3e%3c/svg%3e";
44720
45265
  const PROVIDERS = {
44721
45266
  anthropic: {
44722
45267
  name: "anthropic",
44723
45268
  displayName: "Anthropic (Claude)",
44724
- placeholder: "Enter your Claude API key (sk-ant-api03-...)",
44725
- description: "Required for Claude AI chat functionality"
45269
+ placeholder: "sk-ant-…",
45270
+ description: "Enable Claude AI chat functionality",
45271
+ logo: ClaudeLogo
44726
45272
  },
44727
45273
  openai: {
44728
45274
  name: "openai",
44729
45275
  displayName: "OpenAI",
44730
- placeholder: "Enter your OpenAI API key (sk-...)",
44731
- description: "Required for GPT models and OpenAI features"
45276
+ placeholder: "sk-…",
45277
+ description: "Enable GPT models & OpenAI features",
45278
+ logo: OpenAILogo
44732
45279
  },
44733
45280
  ollama: {
44734
45281
  name: "ollama",
44735
45282
  displayName: "Ollama",
44736
- placeholder: "Enter Ollama host URL (optional, defaults to http://127.0.0.1:11434)",
44737
- description: "Local Ollama installation - requires Ollama to be running. 📥 Download from https://ollama.com/download • 🔧 Pull tool-calling models from https://ollama.com/search?c=tools • 🔄 Models appear dynamically in chat"
45283
+ placeholder: "http://127.0.0.1:11434",
45284
+ description: "Local Ollamarequires Ollama running. Models load dynamically.",
45285
+ logo: OllamaLogo
44738
45286
  }
44739
45287
  };
44740
45288
  const SettingsTab = ({ disabled = false }) => {
44741
- const [apiKeys, setApiKeys] = reactExports.useState({
44742
- anthropic: { key: "", isValid: false, showKey: false },
44743
- openai: { key: "", isValid: false, showKey: false },
44744
- ollama: { key: "", isValid: false, showKey: false }
44745
- });
44746
- const [collapsedSections, setCollapsedSections] = reactExports.useState({});
44747
- const { toast: toast2 } = useToast();
44748
- reactExports.useEffect(() => {
44749
- const newApiKeys = { ...apiKeys };
44750
- Object.keys(PROVIDERS).forEach((providerName) => {
44751
- const provider = providerName;
44752
- const apiKey = providerManager.getApiKey(provider);
44753
- const isValid2 = providerManager.isProviderReady(provider);
44754
- newApiKeys[provider] = {
44755
- key: apiKey,
44756
- isValid: isValid2,
45289
+ const [apiKeys, setApiKeys] = reactExports.useState(
45290
+ () => Object.keys(PROVIDERS).reduce((acc, p2) => {
45291
+ acc[p2] = {
45292
+ key: "",
45293
+ isValid: false,
44757
45294
  showKey: false
44758
45295
  };
44759
- if (isValid2) {
44760
- setCollapsedSections((prev) => ({ ...prev, [providerName]: true }));
44761
- }
45296
+ return acc;
45297
+ }, {})
45298
+ );
45299
+ const { toast: toast2 } = useToast();
45300
+ reactExports.useEffect(() => {
45301
+ Object.keys(PROVIDERS).forEach((prov) => {
45302
+ const provider = prov;
45303
+ const key = providerManager.getApiKey(provider);
45304
+ const valid = providerManager.isProviderReady(provider);
45305
+ setApiKeys((prev) => ({
45306
+ ...prev,
45307
+ [provider]: { key, isValid: valid, showKey: false }
45308
+ }));
44762
45309
  });
44763
- setApiKeys(newApiKeys);
44764
45310
  }, []);
44765
- const handleApiKeyChange = (providerName, value) => {
44766
- const config = PROVIDERS[providerName];
44767
- const isValid2 = providerManager.setApiKey(providerName, value);
45311
+ const handleApiKeyChange = (provider, value) => {
45312
+ const cfg = PROVIDERS[provider];
45313
+ const valid = providerManager.setApiKey(provider, value);
44768
45314
  setApiKeys((prev) => ({
44769
45315
  ...prev,
44770
- [providerName]: {
44771
- ...prev[providerName],
44772
- key: value,
44773
- isValid: isValid2
44774
- }
45316
+ [provider]: { ...prev[provider], key: value, isValid: valid }
44775
45317
  }));
44776
- if (isValid2) {
44777
- setCollapsedSections((prev) => ({ ...prev, [providerName]: true }));
44778
- toast2({
44779
- title: "API Key Set",
44780
- description: `Your ${config.displayName} API key has been saved and configured successfully.`,
44781
- variant: "default"
44782
- });
44783
- } else {
44784
- setCollapsedSections((prev) => ({ ...prev, [providerName]: false }));
44785
- }
44786
- };
44787
- const clearApiKey = (providerName) => {
44788
- const config = PROVIDERS[providerName];
44789
- providerManager.clearApiKey(providerName);
44790
- setApiKeys((prev) => ({
44791
- ...prev,
44792
- [providerName]: {
44793
- ...prev[providerName],
44794
- key: "",
44795
- isValid: false
44796
- }
44797
- }));
44798
- setCollapsedSections((prev) => ({ ...prev, [providerName]: false }));
44799
45318
  toast2({
44800
- title: "API Key Cleared",
44801
- description: `Your ${config.displayName} API key has been removed from storage.`,
44802
- variant: "default"
45319
+ title: valid ? `${cfg.displayName} key saved` : `${cfg.displayName} key invalid`,
45320
+ description: valid ? `Your ${cfg.displayName} API key was saved successfully.` : `Unable to validate your ${cfg.displayName} key.`
44803
45321
  });
44804
45322
  };
44805
- const toggleShowKey = (providerName) => {
44806
- setApiKeys((prev) => ({
44807
- ...prev,
44808
- [providerName]: {
44809
- ...prev[providerName],
44810
- showKey: !prev[providerName].showKey
44811
- }
45323
+ const handleClear = (provider) => {
45324
+ const cfg = PROVIDERS[provider];
45325
+ providerManager.clearApiKey(provider);
45326
+ setApiKeys((p2) => ({
45327
+ ...p2,
45328
+ [provider]: { ...p2[provider], key: "", isValid: false }
44812
45329
  }));
45330
+ toast2({ title: `${cfg.displayName} key cleared` });
44813
45331
  };
44814
- const toggleCollapse = (providerName) => {
44815
- setCollapsedSections((prev) => ({
44816
- ...prev,
44817
- [providerName]: !prev[providerName]
45332
+ const toggleShow = (provider) => {
45333
+ setApiKeys((p2) => ({
45334
+ ...p2,
45335
+ [provider]: { ...p2[provider], showKey: !p2[provider].showKey }
44818
45336
  }));
44819
45337
  };
44820
- return /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "space-y-6 p-6", children: /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "space-y-4", children: [
44821
- /* @__PURE__ */ jsxRuntimeExports.jsx("h2", { className: "text-2xl font-bold text-slate-800 dark:text-slate-200 mb-6", children: "API Key Management" }),
44822
- /* @__PURE__ */ jsxRuntimeExports.jsx("p", { className: "text-slate-600 dark:text-slate-400 mb-6", children: "Configure your API keys for different AI providers. Keys are stored securely in your browser's local storage." }),
44823
- Object.entries(PROVIDERS).map(([providerName, config]) => /* @__PURE__ */ jsxRuntimeExports.jsx(
44824
- ProviderSection,
45338
+ return /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "space-y-8 p-8", children: [
45339
+ /* @__PURE__ */ jsxRuntimeExports.jsx("h2", { className: "text-3xl font-bold text-gray-900 dark:text-gray-100", children: "API Key Management" }),
45340
+ /* @__PURE__ */ jsxRuntimeExports.jsx("p", { className: "text-gray-600 dark:text-gray-400 max-w-2xl", children: "Enter your API keys below. They’re stored securely in local storage." }),
45341
+ /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "grid gap-6 md:grid-cols-2 lg:grid-cols-3", children: Object.entries(PROVIDERS).map(([prov, cfg]) => /* @__PURE__ */ jsxRuntimeExports.jsx(
45342
+ ProviderCard,
44825
45343
  {
44826
- providerName,
44827
- config,
44828
- keyData: apiKeys[providerName],
44829
- isCollapsed: collapsedSections[providerName] && apiKeys[providerName].isValid,
45344
+ provider: prov,
45345
+ config: cfg,
45346
+ data: apiKeys[prov],
44830
45347
  disabled,
44831
- onApiKeyChange: handleApiKeyChange,
44832
- onClearApiKey: clearApiKey,
44833
- onToggleShowKey: toggleShowKey,
44834
- onToggleCollapse: toggleCollapse
45348
+ onChange: handleApiKeyChange,
45349
+ onClear: handleClear,
45350
+ onToggleShow: toggleShow
44835
45351
  },
44836
- providerName
44837
- ))
44838
- ] }) });
45352
+ prov
45353
+ )) })
45354
+ ] });
44839
45355
  };
44840
45356
  const McpClientContext = reactExports.createContext(null);
44841
45357
  const SERVER_CONFIGS_STORAGE_KEY = "mcpServerConfigs_v1";
@@ -44916,13 +45432,6 @@ const useServerState = () => {
44916
45432
  const [editingClientName, setEditingClientName] = reactExports.useState(
44917
45433
  null
44918
45434
  );
44919
- const [clientFormConfig, setClientFormConfig] = reactExports.useState({
44920
- transportType: "stdio",
44921
- command: "npx",
44922
- args: ["@modelcontextprotocol/server-everything"],
44923
- env: {}
44924
- });
44925
- const [clientFormName, setClientFormName] = reactExports.useState("");
44926
45435
  reactExports.useEffect(() => {
44927
45436
  try {
44928
45437
  if (Object.keys(serverConfigs).length > 0) {
@@ -44961,27 +45470,14 @@ const useServerState = () => {
44961
45470
  const handleCreateClient = reactExports.useCallback(() => {
44962
45471
  setIsCreatingClient(true);
44963
45472
  setEditingClientName(null);
44964
- setClientFormName("");
44965
- setClientFormConfig({
44966
- transportType: "stdio",
44967
- command: "npx",
44968
- args: ["@modelcontextprotocol/server-everything"],
44969
- env: {}
44970
- });
44971
45473
  }, []);
44972
- const handleEditClient = reactExports.useCallback(
44973
- (serverName, config) => {
44974
- setIsCreatingClient(false);
44975
- setEditingClientName(serverName);
44976
- setClientFormName(serverName);
44977
- setClientFormConfig(config);
44978
- },
44979
- []
44980
- );
45474
+ const handleEditClient = reactExports.useCallback((serverName) => {
45475
+ setIsCreatingClient(false);
45476
+ setEditingClientName(serverName);
45477
+ }, []);
44981
45478
  const handleCancelClientForm = reactExports.useCallback(() => {
44982
45479
  setIsCreatingClient(false);
44983
45480
  setEditingClientName(null);
44984
- setClientFormName("");
44985
45481
  }, []);
44986
45482
  return {
44987
45483
  serverConfigs,
@@ -44990,10 +45486,6 @@ const useServerState = () => {
44990
45486
  setSelectedServerName,
44991
45487
  isCreatingClient,
44992
45488
  editingClientName,
44993
- clientFormConfig,
44994
- setClientFormConfig,
44995
- clientFormName,
44996
- setClientFormName,
44997
45489
  updateServerConfig,
44998
45490
  removeServerConfig,
44999
45491
  handleCreateClient,
@@ -51609,7 +52101,7 @@ class Client extends Protocol {
51609
52101
  return this.notification({ method: "notifications/roots/list_changed" });
51610
52102
  }
51611
52103
  }
51612
- const version = "0.3.4";
52104
+ const version = "0.3.6";
51613
52105
  const packageJson = {
51614
52106
  version
51615
52107
  };
@@ -52931,7 +53423,10 @@ class MCPJamClient extends Client {
52931
53423
  */
52932
53424
  createAuthProvider() {
52933
53425
  if (this.serverConfig.transportType !== "stdio" && "url" in this.serverConfig && this.serverConfig.url) {
52934
- return new InspectorOAuthClientProvider(this.serverConfig.url.toString());
53426
+ return new InspectorOAuthClientProvider(
53427
+ this.serverConfig.url.toString(),
53428
+ this.serverConfig.transportType
53429
+ );
52935
53430
  }
52936
53431
  return null;
52937
53432
  }
@@ -53014,7 +53509,8 @@ class MCPJamClient extends Client {
53014
53509
  "debug"
53015
53510
  );
53016
53511
  const serverAuthProvider = new InspectorOAuthClientProvider(
53017
- this.serverConfig.url.toString()
53512
+ this.serverConfig.url.toString(),
53513
+ this.serverConfig.transportType
53018
53514
  );
53019
53515
  const token = this.bearerToken || ((_a2 = await serverAuthProvider.tokens()) == null ? void 0 : _a2.access_token);
53020
53516
  if (token) {
@@ -53270,7 +53766,8 @@ class MCPJamClient extends Client {
53270
53766
  this.connectionStatus = "disconnected";
53271
53767
  if (this.serverConfig.transportType !== "stdio") {
53272
53768
  const authProvider = new InspectorOAuthClientProvider(
53273
- this.serverConfig.url.toString()
53769
+ this.serverConfig.url.toString(),
53770
+ this.serverConfig.transportType
53274
53771
  );
53275
53772
  authProvider.clear();
53276
53773
  this.addClientLog("OAuth tokens cleared", "debug");
@@ -54663,7 +55160,7 @@ const useConnectionState = (addRequestHistory, addClientLog) => {
54663
55160
  const updateServer = reactExports.useCallback(
54664
55161
  async (serverName, config) => {
54665
55162
  if (!mcpAgent) return;
54666
- await mcpAgent.disconnectFromServer(serverName);
55163
+ await mcpAgent.removeServer(serverName);
54667
55164
  mcpAgent.addServer(serverName, config);
54668
55165
  try {
54669
55166
  await mcpAgent.connectToServer(serverName);
@@ -61617,6 +62114,24 @@ function requireAjv() {
61617
62114
  }
61618
62115
  var ajvExports = requireAjv();
61619
62116
  const Ajv = /* @__PURE__ */ getDefaultExportFromCjs(ajvExports);
62117
+ function stripEnumNames(schema) {
62118
+ if (Array.isArray(schema)) {
62119
+ return schema.map(stripEnumNames);
62120
+ }
62121
+ if (typeof schema !== "object" || schema === null) return schema;
62122
+ const { properties: properties2, items: items2, ...rest } = schema;
62123
+ const cleaned = { ...rest };
62124
+ if (properties2) {
62125
+ cleaned.properties = {};
62126
+ for (const key in properties2) {
62127
+ cleaned.properties[key] = stripEnumNames(properties2[key]);
62128
+ }
62129
+ }
62130
+ if (items2) {
62131
+ cleaned.items = stripEnumNames(items2);
62132
+ }
62133
+ return cleaned;
62134
+ }
61620
62135
  const ElicitationModal = ({ request, onClose }) => {
61621
62136
  const [formData, setFormData] = reactExports.useState({});
61622
62137
  const [validationError, setValidationError] = reactExports.useState(null);
@@ -61662,7 +62177,8 @@ const ElicitationModal = ({ request, onClose }) => {
61662
62177
  return;
61663
62178
  }
61664
62179
  const ajv2 = new Ajv();
61665
- const validate2 = ajv2.compile(request.requestedSchema);
62180
+ const cleanedSchema = stripEnumNames(request.requestedSchema);
62181
+ const validate2 = ajv2.compile(cleanedSchema);
61666
62182
  const isValid2 = validate2(formData);
61667
62183
  if (!isValid2) {
61668
62184
  const errorMessage = ajv2.errorsText(validate2.errors);
@@ -61681,7 +62197,7 @@ const ElicitationModal = ({ request, onClose }) => {
61681
62197
  }
61682
62198
  };
61683
62199
  const handleReject = () => {
61684
- request.resolve({ action: "reject" });
62200
+ request.resolve({ action: "decline" });
61685
62201
  onClose();
61686
62202
  };
61687
62203
  const handleCancel = () => {
@@ -61824,14 +62340,9 @@ const useServerManagement = (serverState, connectionState, configState, mcpOpera
61824
62340
  );
61825
62341
  const handleEditClient = reactExports.useCallback(
61826
62342
  (serverName) => {
61827
- const serverConnections = connectionState.mcpAgent ? connectionState.mcpAgent.getAllConnectionInfo() : [];
61828
- const connection = serverConnections.find(
61829
- (conn) => conn.name === serverName
61830
- );
61831
- if (!connection) return;
61832
- serverState.handleEditClient(serverName, connection.config);
62343
+ serverState.handleEditClient(serverName);
61833
62344
  },
61834
- [connectionState.mcpAgent, serverState]
62345
+ [serverState]
61835
62346
  );
61836
62347
  const handleConnectServer = reactExports.useCallback(
61837
62348
  async (serverName) => {
@@ -61839,47 +62350,7 @@ const useServerManagement = (serverState, connectionState, configState, mcpOpera
61839
62350
  },
61840
62351
  [connectionState]
61841
62352
  );
61842
- const handleSaveClient = reactExports.useCallback(
61843
- async (config) => {
61844
- if (!serverState.clientFormName.trim()) return;
61845
- try {
61846
- if (serverState.isCreatingClient) {
61847
- await handleAddServer(serverState.clientFormName, config, {
61848
- autoConnect: true
61849
- });
61850
- } else if (serverState.editingClientName) {
61851
- const oldServerName = serverState.editingClientName;
61852
- const newServerName = serverState.clientFormName.trim();
61853
- if (oldServerName !== newServerName) {
61854
- addClientLog(
61855
- `🔄 Server name changed from "${oldServerName}" to "${newServerName}"`,
61856
- "info"
61857
- );
61858
- await handleRemoveServer(oldServerName);
61859
- await handleAddServer(newServerName, config, {
61860
- autoConnect: true
61861
- });
61862
- if (serverState.selectedServerName === oldServerName) {
61863
- serverState.setSelectedServerName(newServerName);
61864
- }
61865
- } else {
61866
- await handleUpdateServer(serverState.editingClientName, config);
61867
- }
61868
- }
61869
- serverState.handleCancelClientForm();
61870
- } catch (error) {
61871
- console.error("Failed to save client:", error);
61872
- }
61873
- },
61874
- [
61875
- serverState,
61876
- handleAddServer,
61877
- handleUpdateServer,
61878
- handleRemoveServer,
61879
- addClientLog
61880
- ]
61881
- );
61882
- const handleSaveMultiple = reactExports.useCallback(
62353
+ const saveClients = reactExports.useCallback(
61883
62354
  async (clients) => {
61884
62355
  const results = {
61885
62356
  success: [],
@@ -61887,19 +62358,43 @@ const useServerManagement = (serverState, connectionState, configState, mcpOpera
61887
62358
  };
61888
62359
  for (const client2 of clients) {
61889
62360
  try {
61890
- console.log(`🔧 Creating client: "${client2.name}"`);
61891
- await handleAddServer(client2.name, client2.config, {
61892
- autoConnect: false
61893
- });
62361
+ if (serverState.editingClientName && clients.length === 1) {
62362
+ const oldServerName = serverState.editingClientName;
62363
+ const newServerName = client2.name.trim();
62364
+ if (oldServerName !== newServerName) {
62365
+ addClientLog(
62366
+ `🔄 Server name changed from "${oldServerName}" to "${newServerName}"`,
62367
+ "info"
62368
+ );
62369
+ await handleRemoveServer(oldServerName);
62370
+ await handleAddServer(newServerName, client2.config, {
62371
+ autoConnect: true
62372
+ });
62373
+ if (serverState.selectedServerName === oldServerName) {
62374
+ serverState.setSelectedServerName(newServerName);
62375
+ }
62376
+ } else {
62377
+ await handleUpdateServer(
62378
+ serverState.editingClientName,
62379
+ client2.config
62380
+ );
62381
+ }
62382
+ } else {
62383
+ console.log(`🔧 Creating client: "${client2.name}"`);
62384
+ await handleAddServer(client2.name, client2.config, {
62385
+ autoConnect: clients.length === 1
62386
+ // Auto-connect only for single client
62387
+ });
62388
+ }
61894
62389
  results.success.push(client2.name);
61895
62390
  addClientLog(
61896
- `✅ Successfully created client: "${client2.name}"`,
62391
+ `✅ Successfully ${serverState.editingClientName ? "updated" : "created"} client: "${client2.name}"`,
61897
62392
  "info"
61898
62393
  );
61899
62394
  } catch (error) {
61900
62395
  const errorMessage = error instanceof Error ? error.message : String(error);
61901
62396
  addClientLog(
61902
- `❌ Failed to create client "${client2.name}": ${errorMessage}`,
62397
+ `❌ Failed to ${serverState.editingClientName ? "update" : "create"} client "${client2.name}": ${errorMessage}`,
61903
62398
  "error"
61904
62399
  );
61905
62400
  results.failed.push({ name: client2.name, error: errorMessage });
@@ -61908,19 +62403,25 @@ const useServerManagement = (serverState, connectionState, configState, mcpOpera
61908
62403
  serverState.handleCancelClientForm();
61909
62404
  if (results.success.length > 0) {
61910
62405
  addClientLog(
61911
- `✅ Successfully created ${results.success.length} client(s): ${results.success.join(", ")}`,
62406
+ `✅ Successfully ${serverState.editingClientName ? "updated" : "created"} ${results.success.length} client(s): ${results.success.join(", ")}`,
61912
62407
  "info"
61913
62408
  );
61914
62409
  }
61915
62410
  if (results.failed.length > 0) {
61916
62411
  addClientLog(
61917
- `❌ Failed to create ${results.failed.length} client(s): ${results.failed.map(({ name, error }) => `${name}: ${error}`).join(", ")}`,
62412
+ `❌ Failed to ${serverState.editingClientName ? "update" : "create"} ${results.failed.length} client(s): ${results.failed.map(({ name, error }) => `${name}: ${error}`).join(", ")}`,
61918
62413
  "error"
61919
62414
  );
61920
62415
  }
61921
62416
  return results;
61922
62417
  },
61923
- [handleAddServer, serverState, addClientLog]
62418
+ [
62419
+ handleAddServer,
62420
+ handleUpdateServer,
62421
+ handleRemoveServer,
62422
+ serverState,
62423
+ addClientLog
62424
+ ]
61924
62425
  );
61925
62426
  return {
61926
62427
  handleAddServer,
@@ -61928,8 +62429,7 @@ const useServerManagement = (serverState, connectionState, configState, mcpOpera
61928
62429
  handleUpdateServer,
61929
62430
  handleEditClient,
61930
62431
  handleConnectServer,
61931
- handleSaveClient,
61932
- handleSaveMultiple
62432
+ saveClients
61933
62433
  };
61934
62434
  };
61935
62435
  const loadOAuthTokens = async (serverUrl, updateAuthState) => {
@@ -61991,8 +62491,14 @@ const useOAuthHandlers = (serverState, configState, handleAddServer) => {
61991
62491
  }
61992
62492
  }
61993
62493
  const finalServerName = existingServerName || serverName;
62494
+ const transportKey = getServerSpecificKey(
62495
+ SESSION_KEYS.TRANSPORT_TYPE,
62496
+ serverUrl
62497
+ );
62498
+ const storedTransportType = sessionStorage.getItem(transportKey);
62499
+ const transportType = storedTransportType || "sse";
61994
62500
  const serverConfig = {
61995
- transportType: "sse",
62501
+ transportType,
61996
62502
  url: new URL(serverUrl)
61997
62503
  };
61998
62504
  try {
@@ -62114,15 +62620,73 @@ const useAppEffects = (serverState, connectionState, configState, mcpOperations,
62114
62620
  const proxyAddress = await getMCPProxyAddressAsync(configState.config);
62115
62621
  const response = await fetch(`${proxyAddress}/config`);
62116
62622
  const data2 = await response.json();
62117
- const currentConfig = serverState.serverConfigs[serverState.selectedServerName];
62118
- if ((currentConfig == null ? void 0 : currentConfig.transportType) === "stdio") {
62119
- serverState.setServerConfigs((prev) => ({
62120
- ...prev,
62121
- [serverState.selectedServerName]: {
62122
- ...prev[serverState.selectedServerName],
62123
- env: data2.defaultEnvironment || {}
62623
+ if (data2.serverConfigs && Object.keys(data2.serverConfigs).length > 0) {
62624
+ console.log("📡 Found CLI server configurations, loading...");
62625
+ const convertedConfigs = {};
62626
+ for (const [serverName, cliConfig] of Object.entries(
62627
+ data2.serverConfigs
62628
+ )) {
62629
+ const config = cliConfig;
62630
+ if (config.type === "sse" && config.url) {
62631
+ convertedConfigs[serverName] = {
62632
+ transportType: "sse",
62633
+ url: new URL(config.url),
62634
+ name: serverName
62635
+ };
62636
+ } else if (config.command) {
62637
+ convertedConfigs[serverName] = {
62638
+ transportType: "stdio",
62639
+ command: config.command,
62640
+ args: config.args || [],
62641
+ env: {
62642
+ ...data2.defaultEnvironment || {},
62643
+ ...config.env || {}
62644
+ },
62645
+ name: serverName
62646
+ };
62647
+ } else if (config.url) {
62648
+ convertedConfigs[serverName] = {
62649
+ transportType: "sse",
62650
+ url: new URL(config.url),
62651
+ name: serverName
62652
+ };
62653
+ }
62654
+ }
62655
+ if (Object.keys(convertedConfigs).length > 0) {
62656
+ const existingConfigs = serverState.serverConfigs;
62657
+ const hasExistingConfigs = Object.keys(existingConfigs).length > 0;
62658
+ const mergedConfigs = { ...convertedConfigs, ...existingConfigs };
62659
+ console.log(
62660
+ `✅ Loading ${Object.keys(convertedConfigs).length} servers from CLI config`
62661
+ );
62662
+ if (hasExistingConfigs) {
62663
+ console.log(
62664
+ `📦 Merging with ${Object.keys(existingConfigs).length} existing localStorage servers`
62665
+ );
62124
62666
  }
62125
- }));
62667
+ serverState.setServerConfigs(mergedConfigs);
62668
+ if (!serverState.selectedServerName || !mergedConfigs[serverState.selectedServerName]) {
62669
+ const firstServerName = Object.keys(convertedConfigs)[0];
62670
+ serverState.setSelectedServerName(firstServerName);
62671
+ }
62672
+ const totalServers = Object.keys(mergedConfigs).length;
62673
+ const cliServers = Object.keys(convertedConfigs).length;
62674
+ addClientLog(
62675
+ `Loaded ${cliServers} servers from CLI configuration (${totalServers} total)`,
62676
+ "info"
62677
+ );
62678
+ }
62679
+ } else {
62680
+ const currentConfig = serverState.serverConfigs[serverState.selectedServerName];
62681
+ if ((currentConfig == null ? void 0 : currentConfig.transportType) === "stdio") {
62682
+ serverState.setServerConfigs((prev) => ({
62683
+ ...prev,
62684
+ [serverState.selectedServerName]: {
62685
+ ...prev[serverState.selectedServerName],
62686
+ env: data2.defaultEnvironment || {}
62687
+ }
62688
+ }));
62689
+ }
62126
62690
  }
62127
62691
  } catch (error) {
62128
62692
  console.error("Error fetching default environment:", error);
@@ -62225,7 +62789,7 @@ const __vitePreload = function preload(baseModule, deps, importerUrl) {
62225
62789
  });
62226
62790
  };
62227
62791
  const renderOAuthCallback = (onOAuthConnect) => {
62228
- const OAuthCallback = React.lazy(() => __vitePreload(() => import("./OAuthCallback-59IQqASq.js"), true ? [] : void 0));
62792
+ const OAuthCallback = React.lazy(() => __vitePreload(() => import("./OAuthCallback-Bgz6lAmx.js"), true ? [] : void 0));
62229
62793
  return /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "min-h-screen bg-gradient-to-br from-slate-50 to-slate-100 dark:from-slate-900 dark:to-slate-800 flex items-center justify-center", children: /* @__PURE__ */ jsxRuntimeExports.jsx(
62230
62794
  reactExports.Suspense,
62231
62795
  {
@@ -62239,7 +62803,7 @@ const renderOAuthCallback = (onOAuthConnect) => {
62239
62803
  };
62240
62804
  const renderOAuthDebugCallback = (onOAuthDebugConnect) => {
62241
62805
  const OAuthDebugCallback = React.lazy(
62242
- () => __vitePreload(() => import("./OAuthDebugCallback-Bm010sVQ.js"), true ? [] : void 0)
62806
+ () => __vitePreload(() => import("./OAuthDebugCallback-Gd08QO37.js"), true ? [] : void 0)
62243
62807
  );
62244
62808
  return /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "min-h-screen bg-gradient-to-br from-slate-50 to-slate-100 dark:from-slate-900 dark:to-slate-800 flex items-center justify-center", children: /* @__PURE__ */ jsxRuntimeExports.jsx(
62245
62809
  reactExports.Suspense,
@@ -62288,6 +62852,7 @@ const App = () => {
62288
62852
  mcpOperations.addClientLog
62289
62853
  );
62290
62854
  const configState = useConfigState();
62855
+ console.log("🔧 serverState", serverState);
62291
62856
  const rootsRef = reactExports.useRef(mcpOperations.roots);
62292
62857
  const nextRequestId = reactExports.useRef(0);
62293
62858
  const [currentPage, setCurrentPage] = reactExports.useState(() => {
@@ -62352,8 +62917,7 @@ const App = () => {
62352
62917
  handleRemoveServer,
62353
62918
  handleEditClient,
62354
62919
  handleConnectServer,
62355
- handleSaveClient,
62356
- handleSaveMultiple,
62920
+ saveClients,
62357
62921
  handleAddServer
62358
62922
  } = useServerManagement(
62359
62923
  serverState,
@@ -62647,23 +63211,23 @@ const App = () => {
62647
63211
  }
62648
63212
  const renderTabs = () => {
62649
63213
  if (serverState.isCreatingClient || serverState.editingClientName) {
63214
+ const initialClient = serverState.editingClientName ? {
63215
+ name: serverState.editingClientName,
63216
+ config: serverState.serverConfigs[serverState.editingClientName]
63217
+ } : void 0;
62650
63218
  return /* @__PURE__ */ jsxRuntimeExports.jsx(
62651
63219
  ClientFormSection,
62652
63220
  {
62653
63221
  isCreating: serverState.isCreatingClient,
62654
63222
  editingClientName: serverState.editingClientName,
62655
- clientFormName: serverState.clientFormName,
62656
- setClientFormName: serverState.setClientFormName,
62657
- clientFormConfig: serverState.clientFormConfig,
62658
- setClientFormConfig: serverState.setClientFormConfig,
63223
+ initialClient,
62659
63224
  config: configState.config,
62660
63225
  setConfig: configState.setConfig,
62661
63226
  bearerToken: configState.bearerToken,
62662
63227
  setBearerToken: configState.setBearerToken,
62663
63228
  headerName: configState.headerName,
62664
63229
  setHeaderName: configState.setHeaderName,
62665
- onSave: handleSaveClient,
62666
- onSaveMultiple: handleSaveMultiple,
63230
+ onSave: saveClients,
62667
63231
  onCancel: serverState.handleCancelClientForm
62668
63232
  }
62669
63233
  );
@@ -62695,7 +63259,10 @@ const App = () => {
62695
63259
  Tabs,
62696
63260
  {
62697
63261
  currentPage,
62698
- onPageChange: setCurrentPage,
63262
+ onPageChange: (page) => {
63263
+ setCurrentPage(page);
63264
+ serverState.handleCancelClientForm();
63265
+ },
62699
63266
  serverCapabilities,
62700
63267
  pendingSampleRequests: mcpOperations.pendingSampleRequests,
62701
63268
  shouldDisableAll: !connectionState.mcpAgent
@@ -62724,6 +63291,15 @@ const App = () => {
62724
63291
  /* @__PURE__ */ jsxRuntimeExports.jsx(StarGitHubModal, { isOpen: showStarModal, onClose: handleCloseStarModal })
62725
63292
  ] });
62726
63293
  };
63294
+ const savedTheme = localStorage.getItem("theme");
63295
+ if (savedTheme === "dark") {
63296
+ document.documentElement.classList.add("dark");
63297
+ } else if (savedTheme === "light") {
63298
+ document.documentElement.classList.remove("dark");
63299
+ } else {
63300
+ const isDark = window.matchMedia("(prefers-color-scheme: dark)").matches;
63301
+ document.documentElement.classList.toggle("dark", isDark);
63302
+ }
62727
63303
  clientExports.createRoot(document.getElementById("root")).render(
62728
63304
  /* @__PURE__ */ jsxRuntimeExports.jsxs(reactExports.StrictMode, { children: [
62729
63305
  /* @__PURE__ */ jsxRuntimeExports.jsx(TooltipProvider, { children: /* @__PURE__ */ jsxRuntimeExports.jsx(App, {}) }),