@mcpjam/inspector 0.2.3 → 0.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,4 +1,4 @@
1
- const __vite__mapDeps=(i,m=__vite__mapDeps,d=(m.f||(m.f=["assets/OAuthCallback-CfsBsNUt.js","assets/oauthUtils-DTcoXpSP.js","assets/OAuthDebugCallback-DuorYCq_.js"])))=>i.map(i=>d[i]);
1
+ const __vite__mapDeps=(i,m=__vite__mapDeps,d=(m.f||(m.f=["assets/OAuthCallback-CdxuZKBm.js","assets/oauthUtils-DTcoXpSP.js","assets/OAuthDebugCallback-BJaIMNT8.js"])))=>i.map(i=>d[i]);
2
2
  var __defProp = Object.defineProperty;
3
3
  var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
4
4
  var __publicField = (obj, key, value) => __defNormalProp(obj, typeof key !== "symbol" ? key + "" : key, value);
@@ -16041,6 +16041,16 @@ const Activity = createLucideIcon("Activity", [
16041
16041
  }
16042
16042
  ]
16043
16043
  ]);
16044
+ /**
16045
+ * @license lucide-react v0.447.0 - ISC
16046
+ *
16047
+ * This source code is licensed under the ISC license.
16048
+ * See the LICENSE file in the root directory of this source tree.
16049
+ */
16050
+ const ArrowLeft = createLucideIcon("ArrowLeft", [
16051
+ ["path", { d: "m12 19-7-7 7-7", key: "1l729n" }],
16052
+ ["path", { d: "M19 12H5", key: "x3x0zl" }]
16053
+ ]);
16044
16054
  /**
16045
16055
  * @license lucide-react v0.447.0 - ISC
16046
16056
  *
@@ -16074,6 +16084,31 @@ const Bot = createLucideIcon("Bot", [
16074
16084
  ["path", { d: "M15 13v2", key: "1xurst" }],
16075
16085
  ["path", { d: "M9 13v2", key: "rq6x2g" }]
16076
16086
  ]);
16087
+ /**
16088
+ * @license lucide-react v0.447.0 - ISC
16089
+ *
16090
+ * This source code is licensed under the ISC license.
16091
+ * See the LICENSE file in the root directory of this source tree.
16092
+ */
16093
+ const Bug = createLucideIcon("Bug", [
16094
+ ["path", { d: "m8 2 1.88 1.88", key: "fmnt4t" }],
16095
+ ["path", { d: "M14.12 3.88 16 2", key: "qol33r" }],
16096
+ ["path", { d: "M9 7.13v-1a3.003 3.003 0 1 1 6 0v1", key: "d7y7pr" }],
16097
+ [
16098
+ "path",
16099
+ {
16100
+ d: "M12 20c-3.3 0-6-2.7-6-6v-3a4 4 0 0 1 4-4h4a4 4 0 0 1 4 4v3c0 3.3-2.7 6-6 6",
16101
+ key: "xs1cw7"
16102
+ }
16103
+ ],
16104
+ ["path", { d: "M12 20v-9", key: "1qisl0" }],
16105
+ ["path", { d: "M6.53 9C4.6 8.8 3 7.1 3 5", key: "32zzws" }],
16106
+ ["path", { d: "M6 13H2", key: "82j7cp" }],
16107
+ ["path", { d: "M3 21c0-2.1 1.7-3.9 3.8-4", key: "4p0ekp" }],
16108
+ ["path", { d: "M20.97 5c0 2.1-1.6 3.8-3.5 4", key: "18gb23" }],
16109
+ ["path", { d: "M22 13h-4", key: "1jl80f" }],
16110
+ ["path", { d: "M17.2 17c2.1.1 3.8 1.9 3.8 4", key: "k3fwyw" }]
16111
+ ]);
16077
16112
  /**
16078
16113
  * @license lucide-react v0.447.0 - ISC
16079
16114
  *
@@ -16212,6 +16247,18 @@ const CodeXml = createLucideIcon("CodeXml", [
16212
16247
  ["path", { d: "m6 8-4 4 4 4", key: "15zrgr" }],
16213
16248
  ["path", { d: "m14.5 4-5 16", key: "e7oirm" }]
16214
16249
  ]);
16250
+ /**
16251
+ * @license lucide-react v0.447.0 - ISC
16252
+ *
16253
+ * This source code is licensed under the ISC license.
16254
+ * See the LICENSE file in the root directory of this source tree.
16255
+ */
16256
+ const CopyPlus = createLucideIcon("CopyPlus", [
16257
+ ["line", { x1: "15", x2: "15", y1: "12", y2: "18", key: "1p7wdc" }],
16258
+ ["line", { x1: "12", x2: "18", y1: "15", y2: "15", key: "1nscbv" }],
16259
+ ["rect", { width: "14", height: "14", x: "8", y: "8", rx: "2", ry: "2", key: "17jyea" }],
16260
+ ["path", { d: "M4 16c-1.1 0-2-.9-2-2V4c0-1.1.9-2 2-2h10c1.1 0 2 .9 2 2", key: "zix9uf" }]
16261
+ ]);
16215
16262
  /**
16216
16263
  * @license lucide-react v0.447.0 - ISC
16217
16264
  *
@@ -16377,6 +16424,17 @@ const History = createLucideIcon("History", [
16377
16424
  ["path", { d: "M3 3v5h5", key: "1xhq8a" }],
16378
16425
  ["path", { d: "M12 7v5l4 2", key: "1fdv2h" }]
16379
16426
  ]);
16427
+ /**
16428
+ * @license lucide-react v0.447.0 - ISC
16429
+ *
16430
+ * This source code is licensed under the ISC license.
16431
+ * See the LICENSE file in the root directory of this source tree.
16432
+ */
16433
+ const Info = createLucideIcon("Info", [
16434
+ ["circle", { cx: "12", cy: "12", r: "10", key: "1mglay" }],
16435
+ ["path", { d: "M12 16v-4", key: "1dtifu" }],
16436
+ ["path", { d: "M12 8h.01", key: "e9boi3" }]
16437
+ ]);
16380
16438
  /**
16381
16439
  * @license lucide-react v0.447.0 - ISC
16382
16440
  *
@@ -16563,6 +16621,25 @@ const Settings = createLucideIcon("Settings", [
16563
16621
  ],
16564
16622
  ["circle", { cx: "12", cy: "12", r: "3", key: "1v7zrd" }]
16565
16623
  ]);
16624
+ /**
16625
+ * @license lucide-react v0.447.0 - ISC
16626
+ *
16627
+ * This source code is licensed under the ISC license.
16628
+ * See the LICENSE file in the root directory of this source tree.
16629
+ */
16630
+ const Sparkles = createLucideIcon("Sparkles", [
16631
+ [
16632
+ "path",
16633
+ {
16634
+ d: "M9.937 15.5A2 2 0 0 0 8.5 14.063l-6.135-1.582a.5.5 0 0 1 0-.962L8.5 9.936A2 2 0 0 0 9.937 8.5l1.582-6.135a.5.5 0 0 1 .963 0L14.063 8.5A2 2 0 0 0 15.5 9.937l6.135 1.581a.5.5 0 0 1 0 .964L15.5 14.063a2 2 0 0 0-1.437 1.437l-1.582 6.135a.5.5 0 0 1-.963 0z",
16635
+ key: "4pj2yx"
16636
+ }
16637
+ ],
16638
+ ["path", { d: "M20 3v4", key: "1olli1" }],
16639
+ ["path", { d: "M22 5h-4", key: "1gvqau" }],
16640
+ ["path", { d: "M4 17v2", key: "vumght" }],
16641
+ ["path", { d: "M5 18H3", key: "zchphs" }]
16642
+ ]);
16566
16643
  /**
16567
16644
  * @license lucide-react v0.447.0 - ISC
16568
16645
  *
@@ -16608,6 +16685,17 @@ const TriangleAlert = createLucideIcon("TriangleAlert", [
16608
16685
  ["path", { d: "M12 9v4", key: "juzpu7" }],
16609
16686
  ["path", { d: "M12 17h.01", key: "p32p05" }]
16610
16687
  ]);
16688
+ /**
16689
+ * @license lucide-react v0.447.0 - ISC
16690
+ *
16691
+ * This source code is licensed under the ISC license.
16692
+ * See the LICENSE file in the root directory of this source tree.
16693
+ */
16694
+ const Upload = createLucideIcon("Upload", [
16695
+ ["path", { d: "M21 15v4a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2v-4", key: "ih7n3h" }],
16696
+ ["polyline", { points: "17 8 12 3 7 8", key: "t8dd8p" }],
16697
+ ["line", { x1: "12", x2: "12", y1: "3", y2: "15", key: "widbto" }]
16698
+ ]);
16611
16699
  /**
16612
16700
  * @license lucide-react v0.447.0 - ISC
16613
16701
  *
@@ -16618,6 +16706,18 @@ const User = createLucideIcon("User", [
16618
16706
  ["path", { d: "M19 21v-2a4 4 0 0 0-4-4H9a4 4 0 0 0-4 4v2", key: "975kel" }],
16619
16707
  ["circle", { cx: "12", cy: "7", r: "4", key: "17ys0d" }]
16620
16708
  ]);
16709
+ /**
16710
+ * @license lucide-react v0.447.0 - ISC
16711
+ *
16712
+ * This source code is licensed under the ISC license.
16713
+ * See the LICENSE file in the root directory of this source tree.
16714
+ */
16715
+ const Users = createLucideIcon("Users", [
16716
+ ["path", { d: "M16 21v-2a4 4 0 0 0-4-4H6a4 4 0 0 0-4 4v2", key: "1yyitq" }],
16717
+ ["circle", { cx: "9", cy: "7", r: "4", key: "nufk8" }],
16718
+ ["path", { d: "M22 21v-2a4 4 0 0 0-3-3.87", key: "kshegd" }],
16719
+ ["path", { d: "M16 3.13a4 4 0 0 1 0 7.75", key: "1da9ce" }]
16720
+ ]);
16621
16721
  /**
16622
16722
  * @license lucide-react v0.447.0 - ISC
16623
16723
  *
@@ -16965,11 +17065,6 @@ class DebugInspectorOAuthClientProvider extends InspectorOAuthClientProvider {
16965
17065
  );
16966
17066
  }
16967
17067
  }
16968
- const auth$1 = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({
16969
- __proto__: null,
16970
- DebugInspectorOAuthClientProvider,
16971
- InspectorOAuthClientProvider
16972
- }, Symbol.toStringTag, { value: "Module" }));
16973
17068
  const OAuthStepDetails = ({
16974
17069
  label,
16975
17070
  isComplete,
@@ -17648,6 +17743,7 @@ const AuthDebugger = ({
17648
17743
  authState,
17649
17744
  updateAuthState
17650
17745
  }) => {
17746
+ const [showFullToken, setShowFullToken] = reactExports.useState(false);
17651
17747
  const startOAuthFlow = reactExports.useCallback(() => {
17652
17748
  if (!serverUrl) {
17653
17749
  updateAuthState({
@@ -17772,9 +17868,19 @@ const AuthDebugger = ({
17772
17868
  authState.loading ? /* @__PURE__ */ jsxRuntimeExports.jsx("p", { children: "Loading authentication status..." }) : /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "space-y-4", children: [
17773
17869
  authState.oauthTokens && /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "space-y-2", children: [
17774
17870
  /* @__PURE__ */ jsxRuntimeExports.jsx("p", { className: "text-sm font-medium", children: "Access Token:" }),
17775
- /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "bg-muted p-2 rounded-md text-xs overflow-x-auto", children: [
17776
- authState.oauthTokens.access_token.substring(0, 25),
17777
- "..."
17871
+ /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "relative", children: [
17872
+ /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "bg-muted p-2 rounded-md text-xs overflow-x-auto pr-10", children: showFullToken ? authState.oauthTokens.access_token : "********************************" }),
17873
+ /* @__PURE__ */ jsxRuntimeExports.jsx(
17874
+ Button,
17875
+ {
17876
+ variant: "ghost",
17877
+ size: "sm",
17878
+ className: "absolute right-1 top-1 h-6 w-6 p-0 hover:bg-muted-foreground/10",
17879
+ onClick: () => setShowFullToken(!showFullToken),
17880
+ title: showFullToken ? "Hide token" : "Show full token",
17881
+ children: showFullToken ? /* @__PURE__ */ jsxRuntimeExports.jsx(EyeOff, { className: "h-3 w-3" }) : /* @__PURE__ */ jsxRuntimeExports.jsx(Eye, { className: "h-3 w-3" })
17882
+ }
17883
+ )
17778
17884
  ] })
17779
17885
  ] }),
17780
17886
  /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex gap-4", children: [
@@ -17813,299 +17919,6 @@ const AuthDebugger = ({
17813
17919
  ] });
17814
17920
  };
17815
17921
  const ConsoleTab = () => /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "bg-gray-900 text-gray-100 p-4 rounded-lg h-full font-mono text-sm overflow-auto", children: /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "opacity-50", children: "Welcome to MCP Client Console" }) });
17816
- function getDataType(value) {
17817
- if (Array.isArray(value)) return "array";
17818
- if (value === null) return "null";
17819
- return typeof value;
17820
- }
17821
- function tryParseJson(str) {
17822
- const trimmed = str.trim();
17823
- if (!(trimmed.startsWith("{") && trimmed.endsWith("}")) && !(trimmed.startsWith("[") && trimmed.endsWith("]"))) {
17824
- return { success: false, data: str };
17825
- }
17826
- try {
17827
- return { success: true, data: JSON.parse(str) };
17828
- } catch {
17829
- return { success: false, data: str };
17830
- }
17831
- }
17832
- function updateValueAtPath(obj, path2, value) {
17833
- if (path2.length === 0) return value;
17834
- if (obj === null || obj === void 0) {
17835
- obj = !isNaN(Number(path2[0])) ? [] : {};
17836
- }
17837
- if (Array.isArray(obj)) {
17838
- return updateArray(obj, path2, value);
17839
- } else if (typeof obj === "object" && obj !== null) {
17840
- return updateObject(obj, path2, value);
17841
- } else {
17842
- console.error(
17843
- `Cannot update path ${path2.join(".")} in non-object/array value:`,
17844
- obj
17845
- );
17846
- return obj;
17847
- }
17848
- }
17849
- function updateArray(array, path2, value) {
17850
- const [index2, ...restPath] = path2;
17851
- const arrayIndex = Number(index2);
17852
- if (isNaN(arrayIndex)) {
17853
- console.error(`Invalid array index: ${index2}`);
17854
- return array;
17855
- }
17856
- if (arrayIndex < 0) {
17857
- console.error(`Array index out of bounds: ${arrayIndex} < 0`);
17858
- return array;
17859
- }
17860
- let newArray = [];
17861
- for (let i = 0; i < array.length; i++) {
17862
- newArray[i] = i in array ? array[i] : null;
17863
- }
17864
- if (arrayIndex >= newArray.length) {
17865
- const extendedArray = new Array(arrayIndex).fill(null);
17866
- for (let i = 0; i < newArray.length; i++) {
17867
- extendedArray[i] = newArray[i];
17868
- }
17869
- newArray = extendedArray;
17870
- }
17871
- if (restPath.length === 0) {
17872
- newArray[arrayIndex] = value;
17873
- } else {
17874
- newArray[arrayIndex] = updateValueAtPath(
17875
- newArray[arrayIndex],
17876
- restPath,
17877
- value
17878
- );
17879
- }
17880
- return newArray;
17881
- }
17882
- function updateObject(obj, path2, value) {
17883
- const [key, ...restPath] = path2;
17884
- if (typeof key !== "string") {
17885
- console.error(`Invalid object key: ${key}`);
17886
- return obj;
17887
- }
17888
- const newObj = { ...obj };
17889
- if (restPath.length === 0) {
17890
- newObj[key] = value;
17891
- } else {
17892
- if (!(key in newObj)) {
17893
- newObj[key] = {};
17894
- }
17895
- newObj[key] = updateValueAtPath(newObj[key], restPath, value);
17896
- }
17897
- return newObj;
17898
- }
17899
- const JsonView = reactExports.memo(
17900
- ({
17901
- data: data2,
17902
- name,
17903
- initialExpandDepth = 3,
17904
- className,
17905
- withCopyButton = true,
17906
- isError = false
17907
- }) => {
17908
- const { toast: toast2 } = useToast();
17909
- const [copied, setCopied] = reactExports.useState(false);
17910
- reactExports.useEffect(() => {
17911
- let timeoutId;
17912
- if (copied) {
17913
- timeoutId = setTimeout(() => {
17914
- setCopied(false);
17915
- }, 500);
17916
- }
17917
- return () => {
17918
- if (timeoutId) {
17919
- clearTimeout(timeoutId);
17920
- }
17921
- };
17922
- }, [copied]);
17923
- const normalizedData = reactExports.useMemo(() => {
17924
- return typeof data2 === "string" ? tryParseJson(data2).success ? tryParseJson(data2).data : data2 : data2;
17925
- }, [data2]);
17926
- const handleCopy = reactExports.useCallback(() => {
17927
- try {
17928
- navigator.clipboard.writeText(
17929
- typeof normalizedData === "string" ? normalizedData : JSON.stringify(normalizedData, null, 2)
17930
- );
17931
- setCopied(true);
17932
- } catch (error) {
17933
- toast2({
17934
- title: "Error",
17935
- description: `There was an error coping result into the clipboard: ${error instanceof Error ? error.message : String(error)}`,
17936
- variant: "destructive"
17937
- });
17938
- }
17939
- }, [toast2, normalizedData]);
17940
- return /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: clsx("p-4 border rounded relative", className), children: [
17941
- withCopyButton && /* @__PURE__ */ jsxRuntimeExports.jsx(
17942
- Button,
17943
- {
17944
- size: "icon",
17945
- variant: "ghost",
17946
- className: "absolute top-2 right-2",
17947
- onClick: handleCopy,
17948
- children: copied ? /* @__PURE__ */ jsxRuntimeExports.jsx(CheckCheck, { className: "size-4 dark:text-green-700 text-green-600" }) : /* @__PURE__ */ jsxRuntimeExports.jsx(Copy, { className: "size-4 text-foreground" })
17949
- }
17950
- ),
17951
- /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "font-mono text-sm transition-all duration-300", children: /* @__PURE__ */ jsxRuntimeExports.jsx(
17952
- JsonNode,
17953
- {
17954
- data: normalizedData,
17955
- name,
17956
- depth: 0,
17957
- initialExpandDepth,
17958
- isError
17959
- }
17960
- ) })
17961
- ] });
17962
- }
17963
- );
17964
- JsonView.displayName = "JsonView";
17965
- const JsonNode = reactExports.memo(
17966
- ({
17967
- data: data2,
17968
- name,
17969
- depth = 0,
17970
- initialExpandDepth,
17971
- isError = false
17972
- }) => {
17973
- const [isExpanded, setIsExpanded] = reactExports.useState(depth < initialExpandDepth);
17974
- const [typeStyleMap] = reactExports.useState({
17975
- number: "text-blue-600",
17976
- boolean: "text-amber-600",
17977
- null: "text-purple-600",
17978
- undefined: "text-gray-600",
17979
- string: "text-green-600 group-hover:text-green-500",
17980
- error: "text-red-600 group-hover:text-red-500",
17981
- default: "text-gray-700"
17982
- });
17983
- const dataType = getDataType(data2);
17984
- const renderCollapsible = (isArray2) => {
17985
- const items2 = isArray2 ? data2 : Object.entries(data2);
17986
- const itemCount = items2.length;
17987
- const isEmpty = itemCount === 0;
17988
- const symbolMap = {
17989
- open: isArray2 ? "[" : "{",
17990
- close: isArray2 ? "]" : "}",
17991
- collapsed: isArray2 ? "[ ... ]" : "{ ... }",
17992
- empty: isArray2 ? "[]" : "{}"
17993
- };
17994
- if (isEmpty) {
17995
- return /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex items-center", children: [
17996
- name && /* @__PURE__ */ jsxRuntimeExports.jsxs("span", { className: "mr-1 text-gray-600 dark:text-gray-400", children: [
17997
- name,
17998
- ":"
17999
- ] }),
18000
- /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "text-gray-500", children: symbolMap.empty })
18001
- ] });
18002
- }
18003
- return /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex flex-col", children: [
18004
- /* @__PURE__ */ jsxRuntimeExports.jsxs(
18005
- "div",
18006
- {
18007
- className: "flex items-center mr-1 rounded cursor-pointer group hover:bg-gray-800/10 dark:hover:bg-gray-800/20",
18008
- onClick: () => setIsExpanded(!isExpanded),
18009
- children: [
18010
- name && /* @__PURE__ */ jsxRuntimeExports.jsxs("span", { className: "mr-1 text-gray-600 dark:text-gray-400 dark:group-hover:text-gray-100 group-hover:text-gray-400", children: [
18011
- name,
18012
- ":"
18013
- ] }),
18014
- isExpanded ? /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "text-gray-600 dark:text-gray-400 dark:group-hover:text-gray-100 group-hover:text-gray-400", children: symbolMap.open }) : /* @__PURE__ */ jsxRuntimeExports.jsxs(jsxRuntimeExports.Fragment, { children: [
18015
- /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "text-gray-600 dark:group-hover:text-gray-100 group-hover:text-gray-400", children: symbolMap.collapsed }),
18016
- /* @__PURE__ */ jsxRuntimeExports.jsxs("span", { className: "ml-1 text-gray-700 dark:group-hover:text-gray-100 group-hover:text-gray-400", children: [
18017
- itemCount,
18018
- " ",
18019
- itemCount === 1 ? "item" : "items"
18020
- ] })
18021
- ] })
18022
- ]
18023
- }
18024
- ),
18025
- isExpanded && /* @__PURE__ */ jsxRuntimeExports.jsxs(jsxRuntimeExports.Fragment, { children: [
18026
- /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "pl-2 ml-4 border-l border-gray-200 dark:border-gray-800", children: isArray2 ? items2.map((item, index2) => /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "my-1", children: /* @__PURE__ */ jsxRuntimeExports.jsx(
18027
- JsonNode,
18028
- {
18029
- data: item,
18030
- name: `${index2}`,
18031
- depth: depth + 1,
18032
- initialExpandDepth
18033
- }
18034
- ) }, index2)) : items2.map(([key, value]) => /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "my-1", children: /* @__PURE__ */ jsxRuntimeExports.jsx(
18035
- JsonNode,
18036
- {
18037
- data: value,
18038
- name: key,
18039
- depth: depth + 1,
18040
- initialExpandDepth
18041
- }
18042
- ) }, key)) }),
18043
- /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "text-gray-600 dark:text-gray-400", children: symbolMap.close })
18044
- ] })
18045
- ] });
18046
- };
18047
- const renderString = (value) => {
18048
- const maxLength = 100;
18049
- const isTooLong = value.length > maxLength;
18050
- if (!isTooLong) {
18051
- return /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex mr-1 rounded hover:bg-gray-800/20", children: [
18052
- name && /* @__PURE__ */ jsxRuntimeExports.jsxs("span", { className: "mr-1 text-gray-600 dark:text-gray-400", children: [
18053
- name,
18054
- ":"
18055
- ] }),
18056
- /* @__PURE__ */ jsxRuntimeExports.jsxs(
18057
- "pre",
18058
- {
18059
- className: clsx(
18060
- isError ? typeStyleMap.error : typeStyleMap.string,
18061
- "break-all whitespace-pre-wrap"
18062
- ),
18063
- children: [
18064
- '"',
18065
- value,
18066
- '"'
18067
- ]
18068
- }
18069
- )
18070
- ] });
18071
- }
18072
- return /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex mr-1 rounded group hover:bg-gray-800/20", children: [
18073
- name && /* @__PURE__ */ jsxRuntimeExports.jsxs("span", { className: "mr-1 text-gray-600 dark:text-gray-400 dark:group-hover:text-gray-100 group-hover:text-gray-400", children: [
18074
- name,
18075
- ":"
18076
- ] }),
18077
- /* @__PURE__ */ jsxRuntimeExports.jsx(
18078
- "pre",
18079
- {
18080
- className: clsx(
18081
- isError ? typeStyleMap.error : typeStyleMap.string,
18082
- "cursor-pointer break-all whitespace-pre-wrap"
18083
- ),
18084
- onClick: () => setIsExpanded(!isExpanded),
18085
- title: isExpanded ? "Click to collapse" : "Click to expand",
18086
- children: isExpanded ? `"${value}"` : `"${value.slice(0, maxLength)}..."`
18087
- }
18088
- )
18089
- ] });
18090
- };
18091
- switch (dataType) {
18092
- case "object":
18093
- case "array":
18094
- return renderCollapsible(dataType === "array");
18095
- case "string":
18096
- return renderString(data2);
18097
- default:
18098
- return /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex items-center mr-1 rounded hover:bg-gray-800/20", children: [
18099
- name && /* @__PURE__ */ jsxRuntimeExports.jsxs("span", { className: "mr-1 text-gray-600 dark:text-gray-400", children: [
18100
- name,
18101
- ":"
18102
- ] }),
18103
- /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: typeStyleMap[dataType] || typeStyleMap.default, children: data2 === null ? "null" : String(data2) })
18104
- ] });
18105
- }
18106
- }
18107
- );
18108
- JsonNode.displayName = "JsonNode";
18109
17922
  function useDraggablePane(initialHeight) {
18110
17923
  const [height, setHeight] = reactExports.useState(initialHeight);
18111
17924
  const [isDragging, setIsDragging] = reactExports.useState(false);
@@ -18161,78 +17974,836 @@ function useDraggablePane(initialHeight) {
18161
17974
  resetHeight
18162
17975
  };
18163
17976
  }
17977
+ function getDataType(value) {
17978
+ if (Array.isArray(value)) return "array";
17979
+ if (value === null) return "null";
17980
+ return typeof value;
17981
+ }
17982
+ function tryParseJson(str) {
17983
+ const trimmed = str.trim();
17984
+ if (!(trimmed.startsWith("{") && trimmed.endsWith("}")) && !(trimmed.startsWith("[") && trimmed.endsWith("]"))) {
17985
+ return { success: false, data: str };
17986
+ }
17987
+ try {
17988
+ return { success: true, data: JSON.parse(str) };
17989
+ } catch {
17990
+ return { success: false, data: str };
17991
+ }
17992
+ }
17993
+ function updateValueAtPath(obj, path2, value) {
17994
+ if (path2.length === 0) return value;
17995
+ if (obj === null || obj === void 0) {
17996
+ obj = !isNaN(Number(path2[0])) ? [] : {};
17997
+ }
17998
+ if (Array.isArray(obj)) {
17999
+ return updateArray(obj, path2, value);
18000
+ } else if (typeof obj === "object" && obj !== null) {
18001
+ return updateObject(obj, path2, value);
18002
+ } else {
18003
+ console.error(
18004
+ `Cannot update path ${path2.join(".")} in non-object/array value:`,
18005
+ obj
18006
+ );
18007
+ return obj;
18008
+ }
18009
+ }
18010
+ function updateArray(array, path2, value) {
18011
+ const [index2, ...restPath] = path2;
18012
+ const arrayIndex = Number(index2);
18013
+ if (isNaN(arrayIndex)) {
18014
+ console.error(`Invalid array index: ${index2}`);
18015
+ return array;
18016
+ }
18017
+ if (arrayIndex < 0) {
18018
+ console.error(`Array index out of bounds: ${arrayIndex} < 0`);
18019
+ return array;
18020
+ }
18021
+ let newArray = [];
18022
+ for (let i = 0; i < array.length; i++) {
18023
+ newArray[i] = i in array ? array[i] : null;
18024
+ }
18025
+ if (arrayIndex >= newArray.length) {
18026
+ const extendedArray = new Array(arrayIndex).fill(null);
18027
+ for (let i = 0; i < newArray.length; i++) {
18028
+ extendedArray[i] = newArray[i];
18029
+ }
18030
+ newArray = extendedArray;
18031
+ }
18032
+ if (restPath.length === 0) {
18033
+ newArray[arrayIndex] = value;
18034
+ } else {
18035
+ newArray[arrayIndex] = updateValueAtPath(
18036
+ newArray[arrayIndex],
18037
+ restPath,
18038
+ value
18039
+ );
18040
+ }
18041
+ return newArray;
18042
+ }
18043
+ function updateObject(obj, path2, value) {
18044
+ const [key, ...restPath] = path2;
18045
+ if (typeof key !== "string") {
18046
+ console.error(`Invalid object key: ${key}`);
18047
+ return obj;
18048
+ }
18049
+ const newObj = { ...obj };
18050
+ if (restPath.length === 0) {
18051
+ newObj[key] = value;
18052
+ } else {
18053
+ if (!(key in newObj)) {
18054
+ newObj[key] = {};
18055
+ }
18056
+ newObj[key] = updateValueAtPath(newObj[key], restPath, value);
18057
+ }
18058
+ return newObj;
18059
+ }
18060
+ const JsonView = reactExports.memo(
18061
+ ({
18062
+ data: data2,
18063
+ name,
18064
+ initialExpandDepth = 3,
18065
+ className,
18066
+ withCopyButton = true,
18067
+ isError = false
18068
+ }) => {
18069
+ const { toast: toast2 } = useToast();
18070
+ const [copied, setCopied] = reactExports.useState(false);
18071
+ reactExports.useEffect(() => {
18072
+ let timeoutId;
18073
+ if (copied) {
18074
+ timeoutId = setTimeout(() => {
18075
+ setCopied(false);
18076
+ }, 500);
18077
+ }
18078
+ return () => {
18079
+ if (timeoutId) {
18080
+ clearTimeout(timeoutId);
18081
+ }
18082
+ };
18083
+ }, [copied]);
18084
+ const normalizedData = reactExports.useMemo(() => {
18085
+ return typeof data2 === "string" ? tryParseJson(data2).success ? tryParseJson(data2).data : data2 : data2;
18086
+ }, [data2]);
18087
+ const handleCopy = reactExports.useCallback(() => {
18088
+ try {
18089
+ navigator.clipboard.writeText(
18090
+ typeof normalizedData === "string" ? normalizedData : JSON.stringify(normalizedData, null, 2)
18091
+ );
18092
+ setCopied(true);
18093
+ } catch (error) {
18094
+ toast2({
18095
+ title: "Error",
18096
+ description: `There was an error coping result into the clipboard: ${error instanceof Error ? error.message : String(error)}`,
18097
+ variant: "destructive"
18098
+ });
18099
+ }
18100
+ }, [toast2, normalizedData]);
18101
+ return /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: clsx("p-4 border rounded relative", className), children: [
18102
+ withCopyButton && /* @__PURE__ */ jsxRuntimeExports.jsx(
18103
+ Button,
18104
+ {
18105
+ size: "icon",
18106
+ variant: "ghost",
18107
+ className: "absolute top-2 right-2",
18108
+ onClick: handleCopy,
18109
+ children: copied ? /* @__PURE__ */ jsxRuntimeExports.jsx(CheckCheck, { className: "size-4 dark:text-green-700 text-green-600" }) : /* @__PURE__ */ jsxRuntimeExports.jsx(Copy, { className: "size-4 text-foreground" })
18110
+ }
18111
+ ),
18112
+ /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "font-mono text-sm transition-all duration-300", children: /* @__PURE__ */ jsxRuntimeExports.jsx(
18113
+ JsonNode,
18114
+ {
18115
+ data: normalizedData,
18116
+ name,
18117
+ depth: 0,
18118
+ initialExpandDepth,
18119
+ isError
18120
+ }
18121
+ ) })
18122
+ ] });
18123
+ }
18124
+ );
18125
+ JsonView.displayName = "JsonView";
18126
+ const JsonNode = reactExports.memo(
18127
+ ({
18128
+ data: data2,
18129
+ name,
18130
+ depth = 0,
18131
+ initialExpandDepth,
18132
+ isError = false
18133
+ }) => {
18134
+ const [isExpanded, setIsExpanded] = reactExports.useState(depth < initialExpandDepth);
18135
+ const [typeStyleMap] = reactExports.useState({
18136
+ number: "text-blue-600",
18137
+ boolean: "text-amber-600",
18138
+ null: "text-purple-600",
18139
+ undefined: "text-gray-600",
18140
+ string: "text-green-600 group-hover:text-green-500",
18141
+ error: "text-red-600 group-hover:text-red-500",
18142
+ default: "text-gray-700"
18143
+ });
18144
+ const dataType = getDataType(data2);
18145
+ const renderCollapsible = (isArray2) => {
18146
+ const items2 = isArray2 ? data2 : Object.entries(data2);
18147
+ const itemCount = items2.length;
18148
+ const isEmpty = itemCount === 0;
18149
+ const symbolMap = {
18150
+ open: isArray2 ? "[" : "{",
18151
+ close: isArray2 ? "]" : "}",
18152
+ collapsed: isArray2 ? "[ ... ]" : "{ ... }",
18153
+ empty: isArray2 ? "[]" : "{}"
18154
+ };
18155
+ if (isEmpty) {
18156
+ return /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex items-center", children: [
18157
+ name && /* @__PURE__ */ jsxRuntimeExports.jsxs("span", { className: "mr-1 text-gray-600 dark:text-gray-400", children: [
18158
+ name,
18159
+ ":"
18160
+ ] }),
18161
+ /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "text-gray-500", children: symbolMap.empty })
18162
+ ] });
18163
+ }
18164
+ return /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex flex-col", children: [
18165
+ /* @__PURE__ */ jsxRuntimeExports.jsxs(
18166
+ "div",
18167
+ {
18168
+ className: "flex items-center mr-1 rounded cursor-pointer group hover:bg-gray-800/10 dark:hover:bg-gray-800/20",
18169
+ onClick: () => setIsExpanded(!isExpanded),
18170
+ children: [
18171
+ name && /* @__PURE__ */ jsxRuntimeExports.jsxs("span", { className: "mr-1 text-gray-600 dark:text-gray-400 dark:group-hover:text-gray-100 group-hover:text-gray-400", children: [
18172
+ name,
18173
+ ":"
18174
+ ] }),
18175
+ isExpanded ? /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "text-gray-600 dark:text-gray-400 dark:group-hover:text-gray-100 group-hover:text-gray-400", children: symbolMap.open }) : /* @__PURE__ */ jsxRuntimeExports.jsxs(jsxRuntimeExports.Fragment, { children: [
18176
+ /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "text-gray-600 dark:group-hover:text-gray-100 group-hover:text-gray-400", children: symbolMap.collapsed }),
18177
+ /* @__PURE__ */ jsxRuntimeExports.jsxs("span", { className: "ml-1 text-gray-700 dark:group-hover:text-gray-100 group-hover:text-gray-400", children: [
18178
+ itemCount,
18179
+ " ",
18180
+ itemCount === 1 ? "item" : "items"
18181
+ ] })
18182
+ ] })
18183
+ ]
18184
+ }
18185
+ ),
18186
+ isExpanded && /* @__PURE__ */ jsxRuntimeExports.jsxs(jsxRuntimeExports.Fragment, { children: [
18187
+ /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "pl-2 ml-4 border-l border-gray-200 dark:border-gray-800", children: isArray2 ? items2.map((item, index2) => /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "my-1", children: /* @__PURE__ */ jsxRuntimeExports.jsx(
18188
+ JsonNode,
18189
+ {
18190
+ data: item,
18191
+ name: `${index2}`,
18192
+ depth: depth + 1,
18193
+ initialExpandDepth
18194
+ }
18195
+ ) }, index2)) : items2.map(([key, value]) => /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "my-1", children: /* @__PURE__ */ jsxRuntimeExports.jsx(
18196
+ JsonNode,
18197
+ {
18198
+ data: value,
18199
+ name: key,
18200
+ depth: depth + 1,
18201
+ initialExpandDepth
18202
+ }
18203
+ ) }, key)) }),
18204
+ /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "text-gray-600 dark:text-gray-400", children: symbolMap.close })
18205
+ ] })
18206
+ ] });
18207
+ };
18208
+ const renderString = (value) => {
18209
+ const maxLength = 100;
18210
+ const isTooLong = value.length > maxLength;
18211
+ if (!isTooLong) {
18212
+ return /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex mr-1 rounded hover:bg-gray-800/20", children: [
18213
+ name && /* @__PURE__ */ jsxRuntimeExports.jsxs("span", { className: "mr-1 text-gray-600 dark:text-gray-400", children: [
18214
+ name,
18215
+ ":"
18216
+ ] }),
18217
+ /* @__PURE__ */ jsxRuntimeExports.jsxs(
18218
+ "pre",
18219
+ {
18220
+ className: clsx(
18221
+ isError ? typeStyleMap.error : typeStyleMap.string,
18222
+ "break-all whitespace-pre-wrap"
18223
+ ),
18224
+ children: [
18225
+ '"',
18226
+ value,
18227
+ '"'
18228
+ ]
18229
+ }
18230
+ )
18231
+ ] });
18232
+ }
18233
+ return /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex mr-1 rounded group hover:bg-gray-800/20", children: [
18234
+ name && /* @__PURE__ */ jsxRuntimeExports.jsxs("span", { className: "mr-1 text-gray-600 dark:text-gray-400 dark:group-hover:text-gray-100 group-hover:text-gray-400", children: [
18235
+ name,
18236
+ ":"
18237
+ ] }),
18238
+ /* @__PURE__ */ jsxRuntimeExports.jsx(
18239
+ "pre",
18240
+ {
18241
+ className: clsx(
18242
+ isError ? typeStyleMap.error : typeStyleMap.string,
18243
+ "cursor-pointer break-all whitespace-pre-wrap"
18244
+ ),
18245
+ onClick: () => setIsExpanded(!isExpanded),
18246
+ title: isExpanded ? "Click to collapse" : "Click to expand",
18247
+ children: isExpanded ? `"${value}"` : `"${value.slice(0, maxLength)}..."`
18248
+ }
18249
+ )
18250
+ ] });
18251
+ };
18252
+ switch (dataType) {
18253
+ case "object":
18254
+ case "array":
18255
+ return renderCollapsible(dataType === "array");
18256
+ case "string":
18257
+ return renderString(data2);
18258
+ default:
18259
+ return /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex items-center mr-1 rounded hover:bg-gray-800/20", children: [
18260
+ name && /* @__PURE__ */ jsxRuntimeExports.jsxs("span", { className: "mr-1 text-gray-600 dark:text-gray-400", children: [
18261
+ name,
18262
+ ":"
18263
+ ] }),
18264
+ /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: typeStyleMap[dataType] || typeStyleMap.default, children: data2 === null ? "null" : String(data2) })
18265
+ ] });
18266
+ }
18267
+ }
18268
+ );
18269
+ JsonNode.displayName = "JsonNode";
18270
+ const RequestHistoryItem = ({ request, index: index2, totalRequests }) => {
18271
+ const [isExpanded, setIsExpanded] = reactExports.useState(false);
18272
+ const toggleExpansion = () => {
18273
+ setIsExpanded(!isExpanded);
18274
+ };
18275
+ const requestData = JSON.parse(request.request);
18276
+ const requestNumber = totalRequests - index2;
18277
+ const formatTimestamp = (timestamp) => {
18278
+ const date = new Date(timestamp);
18279
+ return date.toLocaleTimeString("en-US", {
18280
+ hour12: true,
18281
+ hour: "2-digit",
18282
+ minute: "2-digit",
18283
+ second: "2-digit"
18284
+ });
18285
+ };
18286
+ const formatLatency = (latency) => {
18287
+ if (latency === void 0) return void 0;
18288
+ return `${latency}ms`;
18289
+ };
18290
+ return /* @__PURE__ */ jsxRuntimeExports.jsxs("article", { className: "text-sm bg-gradient-to-r from-secondary/50 via-secondary/70 to-secondary/50 backdrop-blur-sm p-4 rounded-xl border border-border/30 hover:border-border/60 transition-all duration-200 hover:shadow-lg", children: [
18291
+ /* @__PURE__ */ jsxRuntimeExports.jsx(
18292
+ RequestHeader,
18293
+ {
18294
+ requestNumber,
18295
+ method: requestData.method,
18296
+ server: requestData.server,
18297
+ timestamp: formatTimestamp(request.timestamp),
18298
+ latency: formatLatency(request.latency),
18299
+ isExpanded,
18300
+ onToggle: toggleExpansion
18301
+ }
18302
+ ),
18303
+ isExpanded && /* @__PURE__ */ jsxRuntimeExports.jsx(
18304
+ RequestDetails,
18305
+ {
18306
+ requestData: request.request,
18307
+ responseData: request.response
18308
+ }
18309
+ )
18310
+ ] });
18311
+ };
18312
+ const RequestHeader = ({ requestNumber, method, server, timestamp, latency, isExpanded, onToggle }) => /* @__PURE__ */ jsxRuntimeExports.jsxs(
18313
+ "header",
18314
+ {
18315
+ className: "flex justify-between items-center cursor-pointer group",
18316
+ onClick: onToggle,
18317
+ role: "button",
18318
+ tabIndex: 0,
18319
+ onKeyDown: (e) => {
18320
+ if (e.key === "Enter" || e.key === " ") {
18321
+ e.preventDefault();
18322
+ onToggle();
18323
+ }
18324
+ },
18325
+ "aria-expanded": isExpanded,
18326
+ "aria-label": `Request ${requestNumber}: ${method}`,
18327
+ children: [
18328
+ /* @__PURE__ */ jsxRuntimeExports.jsx(RequestInfo, { requestNumber, method, server, timestamp, latency }),
18329
+ /* @__PURE__ */ jsxRuntimeExports.jsx(ExpandIcon, { isExpanded })
18330
+ ]
18331
+ }
18332
+ );
18333
+ const RequestInfo = ({ requestNumber, method, server, timestamp, latency }) => /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex items-center space-x-3", children: [
18334
+ /* @__PURE__ */ jsxRuntimeExports.jsx(RequestBadge, { number: requestNumber }),
18335
+ /* @__PURE__ */ jsxRuntimeExports.jsx(TimeStamp, { timestamp }),
18336
+ /* @__PURE__ */ jsxRuntimeExports.jsx(MethodLabel, { method, server }),
18337
+ latency && /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "text-xs text-muted-foreground font-mono", children: latency })
18338
+ ] });
18339
+ const RequestBadge = ({ number }) => /* @__PURE__ */ jsxRuntimeExports.jsx(
18340
+ "span",
18341
+ {
18342
+ className: "flex items-center justify-center w-6 h-6 bg-primary/10 text-primary text-xs font-bold rounded-full",
18343
+ "aria-label": `Request number ${number}`,
18344
+ children: number
18345
+ }
18346
+ );
18347
+ const TimeStamp = ({ timestamp }) => /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "text-xs text-muted-foreground font-mono", children: timestamp });
18348
+ const MethodLabel = ({ method, server }) => /* @__PURE__ */ jsxRuntimeExports.jsxs("span", { className: "font-mono font-semibold text-foreground", children: [
18349
+ method,
18350
+ server && ` (${server})`
18351
+ ] });
18352
+ const ExpandIcon = ({ isExpanded }) => /* @__PURE__ */ jsxRuntimeExports.jsx(
18353
+ "span",
18354
+ {
18355
+ className: "text-muted-foreground group-hover:text-foreground transition-colors duration-200",
18356
+ "aria-hidden": "true",
18357
+ children: isExpanded ? "▼" : "▶"
18358
+ }
18359
+ );
18360
+ const RequestDetails = ({ requestData, responseData }) => /* @__PURE__ */ jsxRuntimeExports.jsxs("section", { className: "mt-4 space-y-4", "aria-label": "Request and response details", children: [
18361
+ /* @__PURE__ */ jsxRuntimeExports.jsx(RequestSection, { title: "Request", data: requestData }),
18362
+ responseData && /* @__PURE__ */ jsxRuntimeExports.jsx(RequestSection, { title: "Response", data: responseData })
18363
+ ] });
18364
+ const RequestSection = ({ title: title2, data: data2 }) => /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { children: [
18365
+ /* @__PURE__ */ jsxRuntimeExports.jsx(SectionHeader, { title: title2 }),
18366
+ /* @__PURE__ */ jsxRuntimeExports.jsx(
18367
+ JsonView,
18368
+ {
18369
+ data: data2,
18370
+ className: "bg-background/80 backdrop-blur-sm border border-border/20 rounded-lg"
18371
+ }
18372
+ )
18373
+ ] });
18374
+ const SectionHeader = ({ title: title2 }) => /* @__PURE__ */ jsxRuntimeExports.jsx("h3", { className: "flex items-center mb-2", children: /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "font-semibold text-foreground text-sm", children: title2 }) });
18375
+ const formatRequestCount = (count2) => {
18376
+ return `${count2} request${count2 !== 1 ? "s" : ""}`;
18377
+ };
18378
+ const ClearHistoryButton = ({ onClick }) => /* @__PURE__ */ jsxRuntimeExports.jsx(
18379
+ "button",
18380
+ {
18381
+ onClick,
18382
+ className: "p-2 rounded-lg hover:bg-destructive/10 hover:text-destructive transition-all duration-200 group",
18383
+ title: "Clear all activity",
18384
+ children: /* @__PURE__ */ jsxRuntimeExports.jsx(Trash2, { className: "w-4 h-4 text-muted-foreground group-hover:text-destructive" })
18385
+ }
18386
+ );
18387
+ const RequestCountBadge = ({ count: count2 }) => /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "text-sm text-muted-foreground bg-muted/50 px-3 py-1 rounded-full", children: formatRequestCount(count2) });
18388
+ const CollapseToggleButton = ({ onClick }) => /* @__PURE__ */ jsxRuntimeExports.jsx(
18389
+ "button",
18390
+ {
18391
+ onClick,
18392
+ className: "p-2 rounded-lg hover:bg-accent/50 transition-all duration-200",
18393
+ children: /* @__PURE__ */ jsxRuntimeExports.jsx(ChevronDown, { className: "w-5 h-5 text-muted-foreground hover:text-foreground" })
18394
+ }
18395
+ );
18396
+ const ActivityHeader = ({
18397
+ requestHistory,
18398
+ onClearHistory,
18399
+ onToggleCollapse
18400
+ }) => /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex items-center justify-between mb-6", children: [
18401
+ /* @__PURE__ */ jsxRuntimeExports.jsxs("h2", { className: "text-lg font-bold text-foreground flex items-center space-x-2", children: [
18402
+ /* @__PURE__ */ jsxRuntimeExports.jsx(Activity, { className: "w-5 h-5 text-primary" }),
18403
+ /* @__PURE__ */ jsxRuntimeExports.jsx("span", { children: "All Activity" })
18404
+ ] }),
18405
+ /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex items-center space-x-3", children: [
18406
+ requestHistory.length > 0 && /* @__PURE__ */ jsxRuntimeExports.jsxs(jsxRuntimeExports.Fragment, { children: [
18407
+ /* @__PURE__ */ jsxRuntimeExports.jsx(RequestCountBadge, { count: requestHistory.length }),
18408
+ /* @__PURE__ */ jsxRuntimeExports.jsx(ClearHistoryButton, { onClick: onClearHistory })
18409
+ ] }),
18410
+ onToggleCollapse && /* @__PURE__ */ jsxRuntimeExports.jsx(CollapseToggleButton, { onClick: onToggleCollapse })
18411
+ ] })
18412
+ ] });
18413
+ const CompactHeader = ({
18414
+ requestHistory,
18415
+ onClearHistory
18416
+ }) => /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex items-center justify-between mb-6", children: [
18417
+ /* @__PURE__ */ jsxRuntimeExports.jsx(RequestCountBadge, { count: requestHistory.length }),
18418
+ /* @__PURE__ */ jsxRuntimeExports.jsx(ClearHistoryButton, { onClick: onClearHistory })
18419
+ ] });
18420
+ const EmptyState$1 = () => /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex flex-col items-center justify-center py-12 text-center", children: [
18421
+ /* @__PURE__ */ jsxRuntimeExports.jsx(Activity, { className: "w-12 h-12 text-muted-foreground/40 mb-4" }),
18422
+ /* @__PURE__ */ jsxRuntimeExports.jsx("p", { className: "text-muted-foreground text-lg font-medium mb-2", children: "No activity yet" }),
18423
+ /* @__PURE__ */ jsxRuntimeExports.jsx("p", { className: "text-muted-foreground/60 text-sm", children: "MCP requests and responses will appear here" })
18424
+ ] });
18425
+ const RequestHistoryList = ({
18426
+ requestHistory
18427
+ }) => /* @__PURE__ */ jsxRuntimeExports.jsx("ul", { className: "space-y-4", children: requestHistory.slice().reverse().map((request, index2) => /* @__PURE__ */ jsxRuntimeExports.jsx(
18428
+ RequestHistoryItem,
18429
+ {
18430
+ request,
18431
+ index: index2,
18432
+ totalRequests: requestHistory.length
18433
+ },
18434
+ index2
18435
+ )) });
18436
+ const ActivityTab = ({
18437
+ requestHistory,
18438
+ onClearHistory,
18439
+ onToggleCollapse,
18440
+ showHeader = true
18441
+ }) => {
18442
+ return /* @__PURE__ */ jsxRuntimeExports.jsxs(
18443
+ "div",
18444
+ {
18445
+ className: `flex-1 overflow-y-auto ${showHeader ? "p-6 border-r border-border/20" : ""}`,
18446
+ children: [
18447
+ showHeader && /* @__PURE__ */ jsxRuntimeExports.jsx(
18448
+ ActivityHeader,
18449
+ {
18450
+ requestHistory,
18451
+ onClearHistory,
18452
+ onToggleCollapse
18453
+ }
18454
+ ),
18455
+ requestHistory.length === 0 ? /* @__PURE__ */ jsxRuntimeExports.jsx(EmptyState$1, {}) : /* @__PURE__ */ jsxRuntimeExports.jsxs(jsxRuntimeExports.Fragment, { children: [
18456
+ !showHeader && requestHistory.length > 0 && /* @__PURE__ */ jsxRuntimeExports.jsx(
18457
+ CompactHeader,
18458
+ {
18459
+ requestHistory,
18460
+ onClearHistory
18461
+ }
18462
+ ),
18463
+ /* @__PURE__ */ jsxRuntimeExports.jsx(RequestHistoryList, { requestHistory })
18464
+ ] })
18465
+ ]
18466
+ }
18467
+ );
18468
+ };
18469
+ const ToolResult = ({ toolResult }) => {
18470
+ if (!toolResult) return null;
18471
+ if ("content" in toolResult) {
18472
+ const parsedResult = CallToolResultSchema.safeParse(toolResult);
18473
+ if (!parsedResult.success) {
18474
+ return /* @__PURE__ */ jsxRuntimeExports.jsxs(jsxRuntimeExports.Fragment, { children: [
18475
+ /* @__PURE__ */ jsxRuntimeExports.jsx("h4", { className: "font-semibold mb-2", children: "Invalid Tool Result:" }),
18476
+ /* @__PURE__ */ jsxRuntimeExports.jsx(JsonView, { data: toolResult }),
18477
+ /* @__PURE__ */ jsxRuntimeExports.jsx("h4", { className: "font-semibold mb-2", children: "Errors:" }),
18478
+ parsedResult.error.errors.map((error, idx) => /* @__PURE__ */ jsxRuntimeExports.jsx(JsonView, { data: error }, idx))
18479
+ ] });
18480
+ }
18481
+ const structuredResult = parsedResult.data;
18482
+ const isError = structuredResult.isError ?? false;
18483
+ return /* @__PURE__ */ jsxRuntimeExports.jsxs(jsxRuntimeExports.Fragment, { children: [
18484
+ /* @__PURE__ */ jsxRuntimeExports.jsxs("h4", { className: "font-semibold mb-2", children: [
18485
+ "Tool Result:",
18486
+ " ",
18487
+ isError ? /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "text-red-600 font-semibold", children: "Error" }) : /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "text-green-600 font-semibold", children: "Success" })
18488
+ ] }),
18489
+ structuredResult.content.map((item, index2) => {
18490
+ var _a2, _b;
18491
+ return /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "mb-2", children: [
18492
+ item.type === "text" && /* @__PURE__ */ jsxRuntimeExports.jsx(JsonView, { data: item.text, isError }),
18493
+ item.type === "image" && /* @__PURE__ */ jsxRuntimeExports.jsx(
18494
+ "img",
18495
+ {
18496
+ src: `data:${item.mimeType};base64,${item.data}`,
18497
+ alt: "Tool result image",
18498
+ className: "max-w-full h-auto"
18499
+ }
18500
+ ),
18501
+ item.type === "resource" && (((_b = (_a2 = item.resource) == null ? void 0 : _a2.mimeType) == null ? void 0 : _b.startsWith("audio/")) ? /* @__PURE__ */ jsxRuntimeExports.jsx(
18502
+ "audio",
18503
+ {
18504
+ controls: true,
18505
+ src: `data:${item.resource.mimeType};base64,${item.resource.blob}`,
18506
+ className: "w-full",
18507
+ children: /* @__PURE__ */ jsxRuntimeExports.jsx("p", { children: "Your browser does not support audio playback" })
18508
+ }
18509
+ ) : /* @__PURE__ */ jsxRuntimeExports.jsx(JsonView, { data: item.resource }))
18510
+ ] }, index2);
18511
+ })
18512
+ ] });
18513
+ } else if ("toolResult" in toolResult) {
18514
+ return /* @__PURE__ */ jsxRuntimeExports.jsxs(jsxRuntimeExports.Fragment, { children: [
18515
+ /* @__PURE__ */ jsxRuntimeExports.jsx("h4", { className: "font-semibold mb-2", children: "Tool Result (Legacy):" }),
18516
+ /* @__PURE__ */ jsxRuntimeExports.jsx(JsonView, { data: toolResult.toolResult })
18517
+ ] });
18518
+ }
18519
+ return null;
18520
+ };
18521
+ const ResultsTab = ({ toolResult, onToggleCollapse, showHeader = true }) => {
18522
+ return /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: `flex-1 overflow-y-auto ${showHeader ? "p-6" : ""}`, children: [
18523
+ showHeader && /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex items-center justify-between mb-6", children: [
18524
+ /* @__PURE__ */ jsxRuntimeExports.jsxs("h2", { className: "text-lg font-bold text-foreground flex items-center space-x-2", children: [
18525
+ /* @__PURE__ */ jsxRuntimeExports.jsx(ScrollText, { className: "w-5 h-5 text-primary" }),
18526
+ /* @__PURE__ */ jsxRuntimeExports.jsx("span", { children: "Results" })
18527
+ ] }),
18528
+ onToggleCollapse && /* @__PURE__ */ jsxRuntimeExports.jsx(
18529
+ "button",
18530
+ {
18531
+ onClick: onToggleCollapse,
18532
+ className: "p-2 rounded-lg hover:bg-accent/50 transition-all duration-200",
18533
+ children: /* @__PURE__ */ jsxRuntimeExports.jsx(ChevronDown, { className: "w-5 h-5 text-muted-foreground hover:text-foreground" })
18534
+ }
18535
+ )
18536
+ ] }),
18537
+ !toolResult ? /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex flex-col items-center justify-center py-12 text-center", children: [
18538
+ /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "w-12 h-12 rounded-full bg-muted/20 flex items-center justify-center mb-4", children: /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "text-2xl", children: "🎯" }) }),
18539
+ /* @__PURE__ */ jsxRuntimeExports.jsx("p", { className: "text-muted-foreground text-lg font-medium mb-2", children: "No results yet" }),
18540
+ /* @__PURE__ */ jsxRuntimeExports.jsx("p", { className: "text-muted-foreground/60 text-sm", children: "Tool execution results will appear here" })
18541
+ ] }) : /* @__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 }) })
18542
+ ] });
18543
+ };
18544
+ const ClientLogsTab = ({
18545
+ clientLogs,
18546
+ onClearLogs,
18547
+ showHeader = true
18548
+ }) => {
18549
+ const reversedClientLogs = [...clientLogs].reverse();
18550
+ const formatTimestamp = (timestamp) => {
18551
+ const date = new Date(timestamp);
18552
+ return date.toLocaleTimeString("en-US", {
18553
+ hour12: true,
18554
+ hour: "2-digit",
18555
+ minute: "2-digit",
18556
+ second: "2-digit"
18557
+ });
18558
+ };
18559
+ const getLogLevelConfig = (level) => {
18560
+ switch (level) {
18561
+ case "error":
18562
+ return {
18563
+ icon: CircleAlert,
18564
+ bgColor: "bg-red-50 dark:bg-red-950/20",
18565
+ borderColor: "border-red-200 dark:border-red-800/50",
18566
+ textColor: "text-red-800 dark:text-red-300",
18567
+ iconColor: "text-red-500",
18568
+ label: "ERROR"
18569
+ };
18570
+ case "warn":
18571
+ return {
18572
+ icon: TriangleAlert,
18573
+ bgColor: "bg-yellow-50 dark:bg-yellow-950/20",
18574
+ borderColor: "border-yellow-200 dark:border-yellow-800/50",
18575
+ textColor: "text-yellow-800 dark:text-yellow-300",
18576
+ iconColor: "text-yellow-500",
18577
+ label: "WARN"
18578
+ };
18579
+ case "debug":
18580
+ return {
18581
+ icon: Bug,
18582
+ bgColor: "bg-gray-50 dark:bg-gray-950/20",
18583
+ borderColor: "border-gray-200 dark:border-gray-800/50",
18584
+ textColor: "text-gray-800 dark:text-gray-300",
18585
+ iconColor: "text-gray-500",
18586
+ label: "DEBUG"
18587
+ };
18588
+ case "info":
18589
+ default:
18590
+ return {
18591
+ icon: Info,
18592
+ bgColor: "bg-blue-50 dark:bg-blue-950/20",
18593
+ borderColor: "border-blue-200 dark:border-blue-800/50",
18594
+ textColor: "text-blue-800 dark:text-blue-300",
18595
+ iconColor: "text-blue-500",
18596
+ label: "INFO"
18597
+ };
18598
+ }
18599
+ };
18600
+ const LogEntry = ({ log }) => {
18601
+ const config = getLogLevelConfig(log.level);
18602
+ const IconComponent = config.icon;
18603
+ return /* @__PURE__ */ jsxRuntimeExports.jsxs(
18604
+ "div",
18605
+ {
18606
+ className: `flex items-start space-x-3 p-3 rounded-lg border ${config.bgColor} ${config.borderColor} hover:shadow-sm transition-all duration-200`,
18607
+ children: [
18608
+ /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: `flex-shrink-0 mt-0.5 ${config.iconColor}`, children: /* @__PURE__ */ jsxRuntimeExports.jsx(IconComponent, { className: "w-4 h-4" }) }),
18609
+ /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex-1 min-w-0", children: [
18610
+ /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex items-center space-x-2 mb-1", children: [
18611
+ /* @__PURE__ */ jsxRuntimeExports.jsx(
18612
+ "span",
18613
+ {
18614
+ className: `text-xs font-mono font-semibold px-2 py-0.5 rounded ${config.textColor} ${config.bgColor}`,
18615
+ children: config.label
18616
+ }
18617
+ ),
18618
+ /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "text-xs text-muted-foreground font-mono", children: formatTimestamp(log.timestamp) })
18619
+ ] }),
18620
+ /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: `text-sm ${config.textColor} font-mono break-words`, children: log.message })
18621
+ ] })
18622
+ ]
18623
+ }
18624
+ );
18625
+ };
18626
+ return /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "h-full flex flex-col", children: [
18627
+ !showHeader && clientLogs.length > 0 && /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex items-center justify-between mb-6", children: [
18628
+ /* @__PURE__ */ jsxRuntimeExports.jsxs("span", { className: "text-sm text-muted-foreground bg-muted/50 px-3 py-1 rounded-full", children: [
18629
+ clientLogs.length,
18630
+ " log",
18631
+ clientLogs.length !== 1 ? "s" : ""
18632
+ ] }),
18633
+ /* @__PURE__ */ jsxRuntimeExports.jsx(
18634
+ "button",
18635
+ {
18636
+ onClick: onClearLogs,
18637
+ className: "p-2 rounded-lg hover:bg-destructive/10 hover:text-destructive transition-all duration-200 group",
18638
+ title: "Clear all activity",
18639
+ children: /* @__PURE__ */ jsxRuntimeExports.jsx(Trash2, { className: "w-4 h-4 text-muted-foreground group-hover:text-destructive" })
18640
+ }
18641
+ )
18642
+ ] }),
18643
+ /* @__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: [
18644
+ /* @__PURE__ */ jsxRuntimeExports.jsx(Bug, { className: "w-12 h-12 text-muted-foreground/50 mb-4" }),
18645
+ /* @__PURE__ */ jsxRuntimeExports.jsx("h3", { className: "text-lg font-medium text-muted-foreground mb-2", children: "No logs yet" }),
18646
+ /* @__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." })
18647
+ ] }) : /* @__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}`)) }) })
18648
+ ] });
18649
+ };
18650
+ const TabbedHistoryPanel = ({
18651
+ requestHistory,
18652
+ toolResult,
18653
+ clientLogs,
18654
+ onClearHistory,
18655
+ onClearLogs,
18656
+ onToggleCollapse
18657
+ }) => {
18658
+ const [activeTab, setActiveTab] = reactExports.useState("activity");
18659
+ const [isToolResultError, setIsToolResultError] = reactExports.useState(false);
18660
+ reactExports.useEffect(() => {
18661
+ if (toolResult) {
18662
+ setIsToolResultError(toolResult.isError === true);
18663
+ setActiveTab("results");
18664
+ }
18665
+ }, [toolResult]);
18666
+ reactExports.useEffect(() => {
18667
+ if (clientLogs.length > 0) {
18668
+ const isLastLogError = clientLogs[clientLogs.length - 1].level === "error";
18669
+ const isLastLogToolCall = clientLogs[clientLogs.length - 1].message.includes(
18670
+ "Error calling tool"
18671
+ );
18672
+ if (isLastLogError && !isLastLogToolCall) {
18673
+ setActiveTab("logs");
18674
+ }
18675
+ }
18676
+ }, [clientLogs]);
18677
+ const renderActivityTabButton = () => {
18678
+ return /* @__PURE__ */ jsxRuntimeExports.jsxs(
18679
+ "button",
18680
+ {
18681
+ onClick: () => setActiveTab("activity"),
18682
+ className: `flex items-center space-x-2 px-4 py-2 rounded-lg transition-all duration-200 ${activeTab === "activity" ? "bg-primary/10 text-primary border border-primary/20" : "text-muted-foreground hover:text-foreground hover:bg-accent/50"}`,
18683
+ children: [
18684
+ /* @__PURE__ */ jsxRuntimeExports.jsx(Activity, { className: "w-4 h-4" }),
18685
+ /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "text-sm font-medium", children: "Activity" }),
18686
+ requestHistory.length > 0 && /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "px-2 py-1 text-xs bg-primary/10 text-primary rounded-full", children: requestHistory.length })
18687
+ ]
18688
+ },
18689
+ "activity"
18690
+ );
18691
+ };
18692
+ const renderResultsTabButton = () => {
18693
+ const renderCircleIndicator = () => {
18694
+ if (toolResult && !isToolResultError) {
18695
+ return /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "w-2 h-2 bg-green-500 rounded-full" });
18696
+ } else if (toolResult && isToolResultError) {
18697
+ return /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "w-2 h-2 bg-red-500 rounded-full" });
18698
+ } else {
18699
+ return null;
18700
+ }
18701
+ };
18702
+ return /* @__PURE__ */ jsxRuntimeExports.jsxs(
18703
+ "button",
18704
+ {
18705
+ onClick: () => setActiveTab("results"),
18706
+ className: `flex items-center space-x-2 px-4 py-2 rounded-lg transition-all duration-200 ${activeTab === "results" ? "bg-primary/10 text-primary border border-primary/20" : "text-muted-foreground hover:text-foreground hover:bg-accent/50"}`,
18707
+ children: [
18708
+ /* @__PURE__ */ jsxRuntimeExports.jsx(ScrollText, { className: "w-4 h-4" }),
18709
+ /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "text-sm font-medium", children: "Results" }),
18710
+ renderCircleIndicator()
18711
+ ]
18712
+ },
18713
+ "results"
18714
+ );
18715
+ };
18716
+ const renderLogsTabButton = () => {
18717
+ return /* @__PURE__ */ jsxRuntimeExports.jsxs(
18718
+ "button",
18719
+ {
18720
+ onClick: () => setActiveTab("logs"),
18721
+ className: `flex items-center space-x-2 px-4 py-2 rounded-lg transition-all duration-200 ${activeTab === "logs" ? "bg-primary/10 text-primary border border-primary/20" : "text-muted-foreground hover:text-foreground hover:bg-accent/50"}`,
18722
+ children: [
18723
+ /* @__PURE__ */ jsxRuntimeExports.jsx(Bug, { className: "w-4 h-4" }),
18724
+ /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "text-sm font-medium", children: "Logs" }),
18725
+ clientLogs.length > 0 && /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "px-2 py-1 text-xs bg-primary/10 text-primary rounded-full", children: clientLogs.length })
18726
+ ]
18727
+ },
18728
+ "logs"
18729
+ );
18730
+ };
18731
+ const renderTabContent = () => {
18732
+ switch (activeTab) {
18733
+ case "activity":
18734
+ return /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "h-full overflow-y-auto p-6", children: /* @__PURE__ */ jsxRuntimeExports.jsx(
18735
+ ActivityTab,
18736
+ {
18737
+ requestHistory,
18738
+ onClearHistory,
18739
+ showHeader: false
18740
+ }
18741
+ ) });
18742
+ case "results":
18743
+ return /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "h-full overflow-y-auto p-6", children: /* @__PURE__ */ jsxRuntimeExports.jsx(ResultsTab, { toolResult, showHeader: false }) });
18744
+ case "logs":
18745
+ return /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "h-full overflow-y-auto p-6", children: /* @__PURE__ */ jsxRuntimeExports.jsx(
18746
+ ClientLogsTab,
18747
+ {
18748
+ clientLogs,
18749
+ onClearLogs,
18750
+ showHeader: false
18751
+ }
18752
+ ) });
18753
+ default:
18754
+ return null;
18755
+ }
18756
+ };
18757
+ return /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "bg-transparent flex flex-col h-full", children: [
18758
+ /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex items-center justify-between border-b border-border/20 px-6 py-3", children: [
18759
+ /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex space-x-1", children: [
18760
+ renderActivityTabButton(),
18761
+ renderResultsTabButton(),
18762
+ renderLogsTabButton()
18763
+ ] }),
18764
+ /* @__PURE__ */ jsxRuntimeExports.jsx(
18765
+ "button",
18766
+ {
18767
+ onClick: onToggleCollapse,
18768
+ className: "p-2 rounded-lg hover:bg-accent/50 transition-all duration-200",
18769
+ children: /* @__PURE__ */ jsxRuntimeExports.jsx(ChevronDown, { className: "w-5 h-5 text-muted-foreground hover:text-foreground" })
18770
+ }
18771
+ )
18772
+ ] }),
18773
+ /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "flex-1 overflow-hidden", children: renderTabContent() })
18774
+ ] });
18775
+ };
18164
18776
  const HistoryAndNotifications = ({
18165
18777
  requestHistory,
18166
18778
  toolResult,
18167
- onClearHistory
18779
+ clientLogs,
18780
+ onClearHistory,
18781
+ onClearLogs
18168
18782
  }) => {
18169
- const [expandedRequests, setExpandedRequests] = reactExports.useState({});
18170
18783
  const [isHistoryCollapsed, setIsHistoryCollapsed] = reactExports.useState(true);
18171
18784
  const {
18172
18785
  height: historyPaneHeight,
18173
18786
  handleDragStart,
18174
18787
  resetHeight
18175
- } = useDraggablePane(isHistoryCollapsed ? 60 : 500);
18176
- const toggleRequestExpansion = (index2) => {
18177
- setExpandedRequests((prev) => ({ ...prev, [index2]: !prev[index2] }));
18178
- };
18788
+ } = useDraggablePane(500);
18789
+ const toggleCollapse = reactExports.useCallback(() => {
18790
+ setIsHistoryCollapsed(!isHistoryCollapsed);
18791
+ }, [isHistoryCollapsed]);
18179
18792
  reactExports.useEffect(() => {
18180
18793
  if (toolResult) {
18181
18794
  resetHeight();
18182
18795
  setIsHistoryCollapsed(false);
18183
18796
  }
18184
- }, [toolResult]);
18185
- const renderToolResult = () => {
18186
- if (!toolResult) return null;
18187
- if ("content" in toolResult) {
18188
- const parsedResult = CallToolResultSchema.safeParse(toolResult);
18189
- if (!parsedResult.success) {
18190
- return /* @__PURE__ */ jsxRuntimeExports.jsxs(jsxRuntimeExports.Fragment, { children: [
18191
- /* @__PURE__ */ jsxRuntimeExports.jsx("h4", { className: "font-semibold mb-2", children: "Invalid Tool Result:" }),
18192
- /* @__PURE__ */ jsxRuntimeExports.jsx(JsonView, { data: toolResult }),
18193
- /* @__PURE__ */ jsxRuntimeExports.jsx("h4", { className: "font-semibold mb-2", children: "Errors:" }),
18194
- parsedResult.error.errors.map((error, idx) => /* @__PURE__ */ jsxRuntimeExports.jsx(JsonView, { data: error }, idx))
18195
- ] });
18797
+ }, [toolResult, resetHeight]);
18798
+ reactExports.useEffect(() => {
18799
+ if (clientLogs.length > 0) {
18800
+ const isLastError = clientLogs[clientLogs.length - 1].level === "error";
18801
+ if (isLastError) {
18802
+ resetHeight();
18803
+ setIsHistoryCollapsed(false);
18196
18804
  }
18197
- const structuredResult = parsedResult.data;
18198
- const isError = structuredResult.isError ?? false;
18199
- return /* @__PURE__ */ jsxRuntimeExports.jsxs(jsxRuntimeExports.Fragment, { children: [
18200
- /* @__PURE__ */ jsxRuntimeExports.jsxs("h4", { className: "font-semibold mb-2", children: [
18201
- "Tool Result:",
18202
- " ",
18203
- isError ? /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "text-red-600 font-semibold", children: "Error" }) : /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "text-green-600 font-semibold", children: "Success" })
18204
- ] }),
18205
- structuredResult.content.map((item, index2) => {
18206
- var _a2, _b;
18207
- return /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "mb-2", children: [
18208
- item.type === "text" && /* @__PURE__ */ jsxRuntimeExports.jsx(JsonView, { data: item.text, isError }),
18209
- item.type === "image" && /* @__PURE__ */ jsxRuntimeExports.jsx(
18210
- "img",
18211
- {
18212
- src: `data:${item.mimeType};base64,${item.data}`,
18213
- alt: "Tool result image",
18214
- className: "max-w-full h-auto"
18215
- }
18216
- ),
18217
- item.type === "resource" && (((_b = (_a2 = item.resource) == null ? void 0 : _a2.mimeType) == null ? void 0 : _b.startsWith("audio/")) ? /* @__PURE__ */ jsxRuntimeExports.jsx(
18218
- "audio",
18219
- {
18220
- controls: true,
18221
- src: `data:${item.resource.mimeType};base64,${item.resource.blob}`,
18222
- className: "w-full",
18223
- children: /* @__PURE__ */ jsxRuntimeExports.jsx("p", { children: "Your browser does not support audio playback" })
18224
- }
18225
- ) : /* @__PURE__ */ jsxRuntimeExports.jsx(JsonView, { data: item.resource }))
18226
- ] }, index2);
18227
- })
18228
- ] });
18229
- } else if ("toolResult" in toolResult) {
18230
- return /* @__PURE__ */ jsxRuntimeExports.jsxs(jsxRuntimeExports.Fragment, { children: [
18231
- /* @__PURE__ */ jsxRuntimeExports.jsx("h4", { className: "font-semibold mb-2", children: "Tool Result (Legacy):" }),
18232
- /* @__PURE__ */ jsxRuntimeExports.jsx(JsonView, { data: toolResult.toolResult })
18233
- ] });
18234
18805
  }
18235
- };
18806
+ }, [clientLogs, resetHeight]);
18236
18807
  return /* @__PURE__ */ jsxRuntimeExports.jsxs(
18237
18808
  "div",
18238
18809
  {
@@ -18248,122 +18819,26 @@ const HistoryAndNotifications = ({
18248
18819
  onMouseDown: handleDragStart
18249
18820
  }
18250
18821
  ),
18251
- /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "h-full overflow-hidden", children: !isHistoryCollapsed ? /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "bg-transparent flex h-full", children: [
18252
- /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex-1 overflow-y-auto p-6 border-r border-border/20", children: [
18253
- /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex items-center justify-between mb-6", children: [
18254
- /* @__PURE__ */ jsxRuntimeExports.jsxs("h2", { className: "text-lg font-bold text-foreground flex items-center space-x-2", children: [
18255
- /* @__PURE__ */ jsxRuntimeExports.jsx(Activity, { className: "w-5 h-5 text-primary" }),
18256
- /* @__PURE__ */ jsxRuntimeExports.jsx("span", { children: "All Activity" })
18257
- ] }),
18258
- /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex items-center space-x-3", children: [
18259
- requestHistory.length > 0 && /* @__PURE__ */ jsxRuntimeExports.jsxs(jsxRuntimeExports.Fragment, { children: [
18260
- /* @__PURE__ */ jsxRuntimeExports.jsxs("span", { className: "text-sm text-muted-foreground bg-muted/50 px-3 py-1 rounded-full", children: [
18261
- requestHistory.length,
18262
- " request",
18263
- requestHistory.length !== 1 ? "s" : ""
18264
- ] }),
18265
- /* @__PURE__ */ jsxRuntimeExports.jsx(
18266
- "button",
18267
- {
18268
- onClick: onClearHistory,
18269
- className: "p-2 rounded-lg hover:bg-destructive/10 hover:text-destructive transition-all duration-200 group",
18270
- title: "Clear all activity",
18271
- children: /* @__PURE__ */ jsxRuntimeExports.jsx(Trash2, { className: "w-4 h-4 text-muted-foreground group-hover:text-destructive" })
18272
- }
18273
- )
18274
- ] }),
18275
- /* @__PURE__ */ jsxRuntimeExports.jsx(
18276
- "button",
18277
- {
18278
- onClick: () => setIsHistoryCollapsed(!isHistoryCollapsed),
18279
- className: "p-2 rounded-lg hover:bg-accent/50 transition-all duration-200",
18280
- children: /* @__PURE__ */ jsxRuntimeExports.jsx(ChevronDown, { className: "w-5 h-5 text-muted-foreground hover:text-foreground" })
18281
- }
18282
- )
18283
- ] })
18284
- ] }),
18285
- requestHistory.length === 0 ? /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex flex-col items-center justify-center py-12 text-center", children: [
18286
- /* @__PURE__ */ jsxRuntimeExports.jsx(Activity, { className: "w-12 h-12 text-muted-foreground/40 mb-4" }),
18287
- /* @__PURE__ */ jsxRuntimeExports.jsx("p", { className: "text-muted-foreground text-lg font-medium mb-2", children: "No activity yet" }),
18288
- /* @__PURE__ */ jsxRuntimeExports.jsx("p", { className: "text-muted-foreground/60 text-sm", children: "MCP requests and responses will appear here" })
18289
- ] }) : /* @__PURE__ */ jsxRuntimeExports.jsx("ul", { className: "space-y-4", children: requestHistory.slice().reverse().map((request, index2) => /* @__PURE__ */ jsxRuntimeExports.jsxs(
18290
- "li",
18291
- {
18292
- className: "text-sm bg-gradient-to-r from-secondary/50 via-secondary/70 to-secondary/50 backdrop-blur-sm p-4 rounded-xl border border-border/30 hover:border-border/60 transition-all duration-200 hover:shadow-lg",
18293
- children: [
18294
- /* @__PURE__ */ jsxRuntimeExports.jsxs(
18295
- "div",
18296
- {
18297
- className: "flex justify-between items-center cursor-pointer group",
18298
- onClick: () => toggleRequestExpansion(
18299
- requestHistory.length - 1 - index2
18300
- ),
18301
- children: [
18302
- /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex items-center space-x-3", children: [
18303
- /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "flex items-center justify-center w-6 h-6 bg-primary/10 text-primary text-xs font-bold rounded-full", children: requestHistory.length - index2 }),
18304
- /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "font-mono font-semibold text-foreground", children: JSON.parse(request.request).method })
18305
- ] }),
18306
- /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "text-muted-foreground group-hover:text-foreground transition-colors duration-200", children: expandedRequests[requestHistory.length - 1 - index2] ? "▼" : "▶" })
18307
- ]
18308
- }
18309
- ),
18310
- expandedRequests[requestHistory.length - 1 - index2] && /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "mt-4 space-y-4", children: [
18311
- /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { children: [
18312
- /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "flex items-center mb-2", children: /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "font-semibold text-foreground text-sm", children: "Request" }) }),
18313
- /* @__PURE__ */ jsxRuntimeExports.jsx(
18314
- JsonView,
18315
- {
18316
- data: request.request,
18317
- className: "bg-background/80 backdrop-blur-sm border border-border/20 rounded-lg"
18318
- }
18319
- )
18320
- ] }),
18321
- request.response && /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { children: [
18322
- /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "flex items-center mb-2", children: /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "font-semibold text-foreground text-sm", children: "Response" }) }),
18323
- /* @__PURE__ */ jsxRuntimeExports.jsx(
18324
- JsonView,
18325
- {
18326
- data: request.response,
18327
- className: "bg-background/80 backdrop-blur-sm border border-border/20 rounded-lg"
18328
- }
18329
- )
18330
- ] })
18331
- ] })
18332
- ]
18333
- },
18334
- index2
18335
- )) })
18336
- ] }),
18337
- /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex-1 overflow-y-auto p-6", children: [
18338
- /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex items-center justify-between mb-6", children: [
18339
- /* @__PURE__ */ jsxRuntimeExports.jsxs("h2", { className: "text-lg font-bold text-foreground flex items-center space-x-2", children: [
18340
- /* @__PURE__ */ jsxRuntimeExports.jsx(ScrollText, { className: "w-5 h-5 text-primary" }),
18341
- /* @__PURE__ */ jsxRuntimeExports.jsx("span", { children: "Results" })
18342
- ] }),
18343
- /* @__PURE__ */ jsxRuntimeExports.jsx(
18344
- "button",
18345
- {
18346
- onClick: () => setIsHistoryCollapsed(!isHistoryCollapsed),
18347
- className: "p-2 rounded-lg hover:bg-accent/50 transition-all duration-200",
18348
- children: /* @__PURE__ */ jsxRuntimeExports.jsx(ChevronDown, { className: "w-5 h-5 text-muted-foreground hover:text-foreground" })
18349
- }
18350
- )
18351
- ] }),
18352
- !toolResult ? /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex flex-col items-center justify-center py-12 text-center", children: [
18353
- /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "w-12 h-12 rounded-full bg-muted/20 flex items-center justify-center mb-4", children: /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "text-2xl", children: "🎯" }) }),
18354
- /* @__PURE__ */ jsxRuntimeExports.jsx("p", { className: "text-muted-foreground text-lg font-medium mb-2", children: "No results yet" }),
18355
- /* @__PURE__ */ jsxRuntimeExports.jsx("p", { className: "text-muted-foreground/60 text-sm", children: "Tool execution results will appear here" })
18356
- ] }) : /* @__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: renderToolResult() })
18357
- ] })
18358
- ] }) : /* @__PURE__ */ jsxRuntimeExports.jsx(
18822
+ /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "h-full overflow-hidden", children: !isHistoryCollapsed ? /* @__PURE__ */ jsxRuntimeExports.jsx(
18823
+ TabbedHistoryPanel,
18824
+ {
18825
+ requestHistory,
18826
+ toolResult,
18827
+ clientLogs,
18828
+ onClearHistory,
18829
+ onClearLogs,
18830
+ onToggleCollapse: toggleCollapse
18831
+ }
18832
+ ) : /* @__PURE__ */ jsxRuntimeExports.jsx(
18359
18833
  "div",
18360
18834
  {
18361
18835
  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",
18362
- onClick: () => setIsHistoryCollapsed(!isHistoryCollapsed),
18836
+ onClick: toggleCollapse,
18363
18837
  children: /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex items-center space-x-4 text-muted-foreground", children: [
18364
18838
  /* @__PURE__ */ jsxRuntimeExports.jsx(History, { className: "w-5 h-5" }),
18365
18839
  /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "text-sm font-medium", children: "History & Results" }),
18366
18840
  requestHistory.length > 0 && /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "px-2 py-1 text-xs bg-primary/10 text-primary rounded-full", children: requestHistory.length }),
18841
+ 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 }),
18367
18842
  /* @__PURE__ */ jsxRuntimeExports.jsx(ChevronDown, { className: "w-4 h-4 rotate-180" })
18368
18843
  ] })
18369
18844
  }
@@ -19449,7 +19924,7 @@ var hideOthers = function(originalTarget, parentNode, markerName) {
19449
19924
  var DIALOG_NAME = "Dialog";
19450
19925
  var [createDialogContext, createDialogScope] = createContextScope(DIALOG_NAME);
19451
19926
  var [DialogProvider, useDialogContext] = createDialogContext(DIALOG_NAME);
19452
- var Dialog = (props) => {
19927
+ var Dialog$1 = (props) => {
19453
19928
  const {
19454
19929
  __scopeDialog,
19455
19930
  children,
@@ -19483,7 +19958,7 @@ var Dialog = (props) => {
19483
19958
  }
19484
19959
  );
19485
19960
  };
19486
- Dialog.displayName = DIALOG_NAME;
19961
+ Dialog$1.displayName = DIALOG_NAME;
19487
19962
  var TRIGGER_NAME$4 = "DialogTrigger";
19488
19963
  var DialogTrigger = reactExports.forwardRef(
19489
19964
  (props, forwardedRef) => {
@@ -19744,7 +20219,7 @@ var DescriptionWarning = ({ contentRef, descriptionId }) => {
19744
20219
  }, [MESSAGE, contentRef, descriptionId]);
19745
20220
  return null;
19746
20221
  };
19747
- var Root$2 = Dialog;
20222
+ var Root$2 = Dialog$1;
19748
20223
  var Portal$2 = DialogPortal$1;
19749
20224
  var Overlay = DialogOverlay$1;
19750
20225
  var Content$1 = DialogContent$1;
@@ -20043,6 +20518,7 @@ function B({ asChild: r2, children: o }, n) {
20043
20518
  return r2 && reactExports.isValidElement(o) ? reactExports.cloneElement(Me(o), { ref: o.ref }, n(o.props.children)) : n(o);
20044
20519
  }
20045
20520
  var Te = { position: "absolute", width: "1px", height: "1px", padding: "0", margin: "-1px", overflow: "hidden", clip: "rect(0, 0, 0, 0)", whiteSpace: "nowrap", borderWidth: "0" };
20521
+ const Dialog = Root$2;
20046
20522
  const DialogPortal = Portal$2;
20047
20523
  const DialogOverlay = reactExports.forwardRef(({ className, ...props }, ref2) => /* @__PURE__ */ jsxRuntimeExports.jsx(
20048
20524
  Overlay,
@@ -20078,6 +20554,20 @@ const DialogContent = reactExports.forwardRef(({ className, children, ...props }
20078
20554
  )
20079
20555
  ] }));
20080
20556
  DialogContent.displayName = Content$1.displayName;
20557
+ const DialogHeader = ({
20558
+ className,
20559
+ ...props
20560
+ }) => /* @__PURE__ */ jsxRuntimeExports.jsx(
20561
+ "div",
20562
+ {
20563
+ className: cn(
20564
+ "flex flex-col space-y-1.5 text-center sm:text-left",
20565
+ className
20566
+ ),
20567
+ ...props
20568
+ }
20569
+ );
20570
+ DialogHeader.displayName = "DialogHeader";
20081
20571
  const DialogTitle = reactExports.forwardRef(({ className, ...props }, ref2) => /* @__PURE__ */ jsxRuntimeExports.jsx(
20082
20572
  Title,
20083
20573
  {
@@ -26462,10 +26952,14 @@ const ToolRunCard = ({
26462
26952
  setParams(loadedRequest.parameters);
26463
26953
  setParamsInitialized(true);
26464
26954
  setCurrentRequestId(loadedRequest.id);
26465
- } else if (selectedTool && !paramsInitialized) {
26466
- setParams(initializeParams(selectedTool));
26467
- setParamsInitialized(true);
26468
- setCurrentRequestId(null);
26955
+ } else if (selectedTool) {
26956
+ if (!paramsInitialized) {
26957
+ setParams(initializeParams(selectedTool));
26958
+ setParamsInitialized(true);
26959
+ setCurrentRequestId(null);
26960
+ } else if (!loadedRequest) {
26961
+ setCurrentRequestId(null);
26962
+ }
26469
26963
  }
26470
26964
  }, [selectedTool, loadedRequest, paramsInitialized]);
26471
26965
  const handleParamChange = (key, value) => {
@@ -26540,7 +27034,7 @@ const ToolRunCard = ({
26540
27034
  const isUpdatingExistingRequest = currentRequestId !== null;
26541
27035
  return /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "bg-gradient-to-br from-card/95 via-card to-card/95 backdrop-blur-sm rounded-xl shadow-lg border border-border/40 overflow-hidden transition-all duration-300 hover:shadow-xl hover:border-border/60", children: [
26542
27036
  /* @__PURE__ */ jsxRuntimeExports.jsx(ToolHeader, { tool: selectedTool }),
26543
- /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "p-3", children: selectedTool ? /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "space-y-3", children: [
27037
+ /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "overflow-y-auto max-h-96", children: /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "p-3", children: selectedTool ? /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "space-y-3", children: [
26544
27038
  /* @__PURE__ */ jsxRuntimeExports.jsx(
26545
27039
  ParametersSection,
26546
27040
  {
@@ -26549,15 +27043,6 @@ const ToolRunCard = ({
26549
27043
  onParamChange: handleParamChange
26550
27044
  }
26551
27045
  ),
26552
- /* @__PURE__ */ jsxRuntimeExports.jsx(
26553
- ActionButtons,
26554
- {
26555
- onSave: handleOpenSaveDialog,
26556
- onRun: handleRunTool,
26557
- isRunning: isToolRunning,
26558
- isUpdating: isUpdatingExistingRequest
26559
- }
26560
- ),
26561
27046
  /* @__PURE__ */ jsxRuntimeExports.jsx(
26562
27047
  SaveDialog,
26563
27048
  {
@@ -26572,7 +27057,16 @@ const ToolRunCard = ({
26572
27057
  onDescriptionChange: setSaveRequestDescription
26573
27058
  }
26574
27059
  )
26575
- ] }) : /* @__PURE__ */ jsxRuntimeExports.jsx(EmptyState, {}) })
27060
+ ] }) : /* @__PURE__ */ jsxRuntimeExports.jsx(EmptyState, {}) }) }),
27061
+ selectedTool && /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "p-3 border-t border-border/20 bg-gradient-to-r from-card/80 to-card/60", children: /* @__PURE__ */ jsxRuntimeExports.jsx(
27062
+ ActionButtons,
27063
+ {
27064
+ onSave: handleOpenSaveDialog,
27065
+ onRun: handleRunTool,
27066
+ isRunning: isToolRunning,
27067
+ isUpdating: isUpdatingExistingRequest
27068
+ }
27069
+ ) })
26576
27070
  ] });
26577
27071
  };
26578
27072
  const ToolsTab = ({
@@ -26743,7 +27237,7 @@ const ToolsTab = ({
26743
27237
  variant: "ghost",
26744
27238
  className: "h-6 w-6 p-0 hover:bg-blue-500/20 hover:text-blue-500 opacity-0 group-hover:opacity-100 transition-opacity",
26745
27239
  title: "Duplicate request",
26746
- children: /* @__PURE__ */ jsxRuntimeExports.jsx(Copy, { className: "w-3 h-3" })
27240
+ children: /* @__PURE__ */ jsxRuntimeExports.jsx(CopyPlus, { className: "w-3 h-3" })
26747
27241
  }
26748
27242
  ),
26749
27243
  /* @__PURE__ */ jsxRuntimeExports.jsx(
@@ -28479,7 +28973,7 @@ var ItemText = SelectItemText;
28479
28973
  var ItemIndicator = SelectItemIndicator;
28480
28974
  var ScrollUpButton = SelectScrollUpButton$1;
28481
28975
  var ScrollDownButton = SelectScrollDownButton$1;
28482
- var Separator = SelectSeparator$1;
28976
+ var Separator$1 = SelectSeparator$1;
28483
28977
  const Select = Root2;
28484
28978
  const SelectValue = Value;
28485
28979
  const SelectTrigger = reactExports.forwardRef(({ className, children, ...props }, ref2) => /* @__PURE__ */ jsxRuntimeExports.jsxs(
@@ -28578,14 +29072,14 @@ const SelectItem = reactExports.forwardRef(({ className, children, ...props }, r
28578
29072
  ));
28579
29073
  SelectItem.displayName = Item.displayName;
28580
29074
  const SelectSeparator = reactExports.forwardRef(({ className, ...props }, ref2) => /* @__PURE__ */ jsxRuntimeExports.jsx(
28581
- Separator,
29075
+ Separator$1,
28582
29076
  {
28583
29077
  ref: ref2,
28584
29078
  className: cn("-mx-1 my-1 h-px bg-muted", className),
28585
29079
  ...props
28586
29080
  }
28587
29081
  ));
28588
- SelectSeparator.displayName = Separator.displayName;
29082
+ SelectSeparator.displayName = Separator$1.displayName;
28589
29083
  const useTheme = () => {
28590
29084
  const [theme, setTheme] = reactExports.useState(() => {
28591
29085
  const savedTheme = localStorage.getItem("theme");
@@ -28625,7 +29119,7 @@ const useTheme = () => {
28625
29119
  [theme, setThemeWithSideEffect]
28626
29120
  );
28627
29121
  };
28628
- const version$1 = "0.2.3";
29122
+ const version$1 = "0.3.0";
28629
29123
  var [createTooltipContext, createTooltipScope] = createContextScope("Tooltip", [
28630
29124
  createPopperScope
28631
29125
  ]);
@@ -29161,22 +29655,10 @@ const Sidebar = ({
29161
29655
  return "text-gray-500 dark:text-gray-400";
29162
29656
  }
29163
29657
  };
29164
- const shouldDisableConnection = (connection) => {
29165
- if (!mcpAgent || connection.connectionStatus === "connected") {
29166
- return false;
29167
- }
29168
- if (connection.config.transportType !== "stdio") {
29169
- const hasConnectedRemote = mcpAgent.hasConnectedRemoteServer();
29170
- const connectedRemoteName = mcpAgent.getConnectedRemoteServerName();
29171
- return hasConnectedRemote && connectedRemoteName !== connection.name;
29172
- }
29658
+ const shouldDisableConnection = () => {
29173
29659
  return false;
29174
29660
  };
29175
- const getConnectTooltipMessage = (connection) => {
29176
- if (shouldDisableConnection(connection)) {
29177
- const connectedRemoteName = mcpAgent == null ? void 0 : mcpAgent.getConnectedRemoteServerName();
29178
- return `Cannot connect: "${connectedRemoteName}" is already connected (only one remote server allowed at a time)`;
29179
- }
29661
+ const getConnectTooltipMessage = () => {
29180
29662
  return "Connect to this server";
29181
29663
  };
29182
29664
  const getConnectionDisplayText = (connection) => {
@@ -29292,11 +29774,11 @@ const Sidebar = ({
29292
29774
  },
29293
29775
  size: "sm",
29294
29776
  className: "h-6 text-xs px-2",
29295
- disabled: shouldDisableConnection(connection),
29777
+ disabled: shouldDisableConnection(),
29296
29778
  children: "Connect"
29297
29779
  }
29298
29780
  ) }) }),
29299
- /* @__PURE__ */ jsxRuntimeExports.jsx(TooltipContent, { children: getConnectTooltipMessage(connection) })
29781
+ /* @__PURE__ */ jsxRuntimeExports.jsx(TooltipContent, { children: getConnectTooltipMessage() })
29300
29782
  ] });
29301
29783
  };
29302
29784
  const renderConnectionItem = (connection) => /* @__PURE__ */ jsxRuntimeExports.jsx(
@@ -29656,6 +30138,475 @@ const SettingsTab = ({
29656
30138
  ] })
29657
30139
  ] }) });
29658
30140
  };
30141
+ function isValidJSON(jsonString) {
30142
+ try {
30143
+ JSON.parse(jsonString);
30144
+ return true;
30145
+ } catch {
30146
+ return false;
30147
+ }
30148
+ }
30149
+ function isValidMCPConfig(config) {
30150
+ return typeof config === "object" && config !== null && "mcpServers" in config && typeof config.mcpServers === "object" && config.mcpServers !== null;
30151
+ }
30152
+ function isValidServerConfig(config) {
30153
+ if (typeof config !== "object" || config === null) {
30154
+ return false;
30155
+ }
30156
+ const configObj = config;
30157
+ const hasCommand = "command" in configObj && typeof configObj.command === "string";
30158
+ const hasUrl = "url" in configObj && typeof configObj.url === "string";
30159
+ return hasCommand || hasUrl;
30160
+ }
30161
+ function isSingleNamedServerConfig(config) {
30162
+ if (typeof config !== "object" || config === null) {
30163
+ return false;
30164
+ }
30165
+ const configObj = config;
30166
+ const keys = Object.keys(configObj);
30167
+ if (keys.length !== 1) {
30168
+ return false;
30169
+ }
30170
+ const serverConfig = configObj[keys[0]];
30171
+ return isValidServerConfig(serverConfig);
30172
+ }
30173
+ function validateMCPConfigStructure(config) {
30174
+ const errors = [];
30175
+ if (typeof config !== "object" || config === null) {
30176
+ errors.push("Configuration must be a JSON object");
30177
+ return { isGlobal: false, isSingleNamed: false, errors };
30178
+ }
30179
+ if (isValidMCPConfig(config)) {
30180
+ const mcpServers = config.mcpServers;
30181
+ const serverNames = Object.keys(mcpServers);
30182
+ if (serverNames.length === 0) {
30183
+ errors.push('"mcpServers" object is empty. Please add at least one server configuration');
30184
+ }
30185
+ return { isGlobal: true, isSingleNamed: false, errors };
30186
+ }
30187
+ if (isSingleNamedServerConfig(config)) {
30188
+ return { isGlobal: false, isSingleNamed: true, errors };
30189
+ }
30190
+ errors.push(
30191
+ 'Invalid configuration format. Please provide either:\n• A global config: {"mcpServers": {"server-name": {...}}}\n• A named server config: {"server-name": {"command": "npx", "args": [...]}}'
30192
+ );
30193
+ return { isGlobal: false, isSingleNamed: false, errors };
30194
+ }
30195
+ function convertToMCPJamServerConfig(entry) {
30196
+ if (entry.command) {
30197
+ return {
30198
+ transportType: "stdio",
30199
+ command: entry.command,
30200
+ args: entry.args,
30201
+ env: entry.env,
30202
+ timeout: entry.timeout,
30203
+ capabilities: entry.capabilities,
30204
+ enableServerLogs: entry.enableServerLogs
30205
+ };
30206
+ } else if (entry.url) {
30207
+ let transportType;
30208
+ if (entry.type) {
30209
+ transportType = entry.type === "sse" ? "sse" : "streamable-http";
30210
+ } else {
30211
+ transportType = entry.url.toLowerCase().includes("sse") ? "sse" : "streamable-http";
30212
+ }
30213
+ return {
30214
+ transportType,
30215
+ url: new URL(entry.url),
30216
+ requestInit: entry.requestInit,
30217
+ eventSourceInit: entry.eventSourceInit,
30218
+ reconnectionOptions: entry.reconnectionOptions,
30219
+ sessionId: entry.sessionId,
30220
+ timeout: entry.timeout,
30221
+ capabilities: entry.capabilities,
30222
+ enableServerLogs: entry.enableServerLogs
30223
+ };
30224
+ } else {
30225
+ throw new Error("Invalid server configuration: missing command or url");
30226
+ }
30227
+ }
30228
+ function validateServerConfig(name, entry) {
30229
+ const errors = [];
30230
+ if (!entry.command && !entry.url) {
30231
+ errors.push(
30232
+ `Server "${name}": Must have either 'command' (for STDIO) or 'url' (for HTTP/SSE). Example: {"command": "npx", "args": ["server-package"]} or {"url": "https://...", "type": "sse"}`
30233
+ );
30234
+ }
30235
+ if (entry.command && entry.url) {
30236
+ errors.push(
30237
+ `Server "${name}": Cannot have both 'command' and 'url'. Use 'command' for STDIO servers or 'url' for HTTP/SSE servers, but not both`
30238
+ );
30239
+ }
30240
+ if (entry.command) {
30241
+ if (typeof entry.command !== "string" || entry.command.trim() === "") {
30242
+ errors.push(
30243
+ `Server "${name}": 'command' must be a non-empty string. Example: "npx", "node", "python", etc.`
30244
+ );
30245
+ }
30246
+ if (entry.args && !Array.isArray(entry.args)) {
30247
+ errors.push(
30248
+ `Server "${name}": 'args' must be an array of strings. Example: ["@modelcontextprotocol/server-everything"] or ["build/index.js", "--port", "3000"]`
30249
+ );
30250
+ }
30251
+ if (entry.env && typeof entry.env !== "object") {
30252
+ errors.push(
30253
+ `Server "${name}": 'env' must be an object with string keys and values. Example: {"API_KEY": "your-key", "DEBUG": "true"}`
30254
+ );
30255
+ }
30256
+ }
30257
+ if (entry.url) {
30258
+ try {
30259
+ new URL(entry.url);
30260
+ } catch {
30261
+ errors.push(
30262
+ `Server "${name}": 'url' must be a valid URL. Example: "https://api.example.com/mcp" or "https://localhost:3000/sse"`
30263
+ );
30264
+ }
30265
+ if (entry.type && !["sse", "streamable-http"].includes(entry.type)) {
30266
+ errors.push(
30267
+ `Server "${name}": 'type' must be either 'sse' or 'streamable-http'. If not specified, defaults to 'streamable-http'`
30268
+ );
30269
+ }
30270
+ }
30271
+ return errors;
30272
+ }
30273
+ function parseConfigFile(jsonString) {
30274
+ const result = {
30275
+ success: false,
30276
+ servers: [],
30277
+ errors: []
30278
+ };
30279
+ if (!isValidJSON(jsonString)) {
30280
+ result.errors.push("Invalid JSON format. Please check for missing quotes, commas, or brackets");
30281
+ return result;
30282
+ }
30283
+ let parsedConfig;
30284
+ try {
30285
+ parsedConfig = JSON.parse(jsonString);
30286
+ } catch (error) {
30287
+ result.errors.push(`JSON parsing error: ${error instanceof Error ? error.message : String(error)}`);
30288
+ return result;
30289
+ }
30290
+ const { isGlobal, isSingleNamed, errors: structureErrors } = validateMCPConfigStructure(parsedConfig);
30291
+ if (structureErrors.length > 0) {
30292
+ result.errors.push(...structureErrors);
30293
+ return result;
30294
+ }
30295
+ const servers = [];
30296
+ const allErrors = [];
30297
+ if (isGlobal) {
30298
+ const validConfig = parsedConfig;
30299
+ for (const [serverName, serverConfig] of Object.entries(validConfig.mcpServers)) {
30300
+ if (typeof serverName !== "string" || serverName.trim() === "") {
30301
+ allErrors.push("Server names must be non-empty strings");
30302
+ continue;
30303
+ }
30304
+ const validationErrors = validateServerConfig(serverName, serverConfig);
30305
+ if (validationErrors.length > 0) {
30306
+ allErrors.push(...validationErrors);
30307
+ continue;
30308
+ }
30309
+ try {
30310
+ const mcpConfig = convertToMCPJamServerConfig(serverConfig);
30311
+ servers.push({
30312
+ name: serverName,
30313
+ config: mcpConfig
30314
+ });
30315
+ } catch (error) {
30316
+ allErrors.push(
30317
+ `Server "${serverName}": ${error instanceof Error ? error.message : String(error)}`
30318
+ );
30319
+ }
30320
+ }
30321
+ } else if (isSingleNamed) {
30322
+ const serverConfig = parsedConfig;
30323
+ const serverName = Object.keys(serverConfig)[0];
30324
+ const validationErrors = validateServerConfig(serverName, serverConfig[serverName]);
30325
+ if (validationErrors.length > 0) {
30326
+ allErrors.push(...validationErrors);
30327
+ } else {
30328
+ try {
30329
+ const mcpConfig = convertToMCPJamServerConfig(serverConfig[serverName]);
30330
+ servers.push({
30331
+ name: serverName,
30332
+ config: mcpConfig
30333
+ });
30334
+ } catch (error) {
30335
+ allErrors.push(
30336
+ `Server configuration: ${error instanceof Error ? error.message : String(error)}`
30337
+ );
30338
+ }
30339
+ }
30340
+ }
30341
+ result.servers = servers;
30342
+ result.errors = allErrors;
30343
+ result.success = allErrors.length === 0 && servers.length > 0;
30344
+ return result;
30345
+ }
30346
+ function generateExampleConfig() {
30347
+ const exampleConfig = {
30348
+ mcpServers: {
30349
+ "example-stdio-server": {
30350
+ command: "npx",
30351
+ args: ["@modelcontextprotocol/server-everything"],
30352
+ env: {
30353
+ API_KEY: "your-api-key",
30354
+ DEBUG: "true"
30355
+ }
30356
+ },
30357
+ "example-sse-server": {
30358
+ url: "https://api.example.com/mcp/sse",
30359
+ type: "sse"
30360
+ },
30361
+ "example-http-server": {
30362
+ url: "https://api.example.com/mcp/http",
30363
+ type: "streamable-http"
30364
+ }
30365
+ }
30366
+ };
30367
+ return JSON.stringify(exampleConfig, null, 2);
30368
+ }
30369
+ const ConfigImportDialog = ({
30370
+ open,
30371
+ onOpenChange,
30372
+ onImportServers
30373
+ }) => {
30374
+ const [configText, setConfigText] = reactExports.useState("");
30375
+ const [parseResult, setParseResult] = reactExports.useState(null);
30376
+ const [isValidating, setIsValidating] = reactExports.useState(false);
30377
+ const { toast: toast2 } = useToast();
30378
+ const handleConfigChange = reactExports.useCallback((value) => {
30379
+ setConfigText(value);
30380
+ setParseResult(null);
30381
+ }, []);
30382
+ const validateConfig = reactExports.useCallback(() => {
30383
+ if (!configText.trim()) {
30384
+ setParseResult({
30385
+ success: false,
30386
+ servers: [],
30387
+ errors: ["Please enter a configuration"]
30388
+ });
30389
+ return;
30390
+ }
30391
+ setIsValidating(true);
30392
+ try {
30393
+ const result = parseConfigFile(configText);
30394
+ setParseResult(result);
30395
+ } catch (error) {
30396
+ setParseResult({
30397
+ success: false,
30398
+ servers: [],
30399
+ errors: [`Unexpected error: ${error instanceof Error ? error.message : String(error)}`]
30400
+ });
30401
+ } finally {
30402
+ setIsValidating(false);
30403
+ }
30404
+ }, [configText]);
30405
+ const handleImport = reactExports.useCallback(() => {
30406
+ if ((parseResult == null ? void 0 : parseResult.success) && parseResult.servers.length > 0) {
30407
+ onImportServers(parseResult.servers);
30408
+ toast2({
30409
+ title: "Configuration imported",
30410
+ description: `Successfully imported ${parseResult.servers.length} server(s)`
30411
+ });
30412
+ onOpenChange(false);
30413
+ setConfigText("");
30414
+ setParseResult(null);
30415
+ }
30416
+ }, [parseResult, onImportServers, onOpenChange, toast2]);
30417
+ const handlePasteExample = reactExports.useCallback(() => {
30418
+ const example = generateExampleConfig();
30419
+ setConfigText(example);
30420
+ setParseResult(null);
30421
+ }, []);
30422
+ const handleCopyExample = reactExports.useCallback(async () => {
30423
+ try {
30424
+ const example = generateExampleConfig();
30425
+ await navigator.clipboard.writeText(example);
30426
+ toast2({
30427
+ title: "Example copied",
30428
+ description: "Example configuration has been copied to clipboard"
30429
+ });
30430
+ } catch {
30431
+ toast2({
30432
+ title: "Copy failed",
30433
+ description: "Failed to copy example configuration",
30434
+ variant: "destructive"
30435
+ });
30436
+ }
30437
+ }, [toast2]);
30438
+ const handleClose = reactExports.useCallback(() => {
30439
+ onOpenChange(false);
30440
+ setConfigText("");
30441
+ setParseResult(null);
30442
+ }, [onOpenChange]);
30443
+ return /* @__PURE__ */ jsxRuntimeExports.jsx(Dialog, { open, onOpenChange, children: /* @__PURE__ */ jsxRuntimeExports.jsxs(DialogContent, { className: "max-w-4xl max-h-[90vh] flex flex-col", children: [
30444
+ /* @__PURE__ */ jsxRuntimeExports.jsxs(DialogHeader, { children: [
30445
+ /* @__PURE__ */ jsxRuntimeExports.jsxs(DialogTitle, { className: "flex items-center gap-2", children: [
30446
+ /* @__PURE__ */ jsxRuntimeExports.jsx(Upload, { className: "h-5 w-5" }),
30447
+ "Import MCP Configuration"
30448
+ ] }),
30449
+ /* @__PURE__ */ jsxRuntimeExports.jsxs(DialogDescription, { children: [
30450
+ "Paste your MCP configuration JSON to import servers. Supports:",
30451
+ /* @__PURE__ */ jsxRuntimeExports.jsx("br", {}),
30452
+ "• ",
30453
+ /* @__PURE__ */ jsxRuntimeExports.jsx("strong", { children: "Global config" }),
30454
+ ': Complete mcp.json with "mcpServers" wrapper',
30455
+ /* @__PURE__ */ jsxRuntimeExports.jsx("br", {}),
30456
+ "• ",
30457
+ /* @__PURE__ */ jsxRuntimeExports.jsx("strong", { children: "Named server" }),
30458
+ ": Single server with name key"
30459
+ ] })
30460
+ ] }),
30461
+ /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex-1 flex flex-col gap-4 min-h-0", children: [
30462
+ /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "space-y-2", children: [
30463
+ /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex items-center justify-between", children: [
30464
+ /* @__PURE__ */ jsxRuntimeExports.jsx("label", { className: "text-sm font-medium", children: "Configuration JSON" }),
30465
+ /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex gap-2", children: [
30466
+ /* @__PURE__ */ jsxRuntimeExports.jsxs(
30467
+ Button,
30468
+ {
30469
+ variant: "outline",
30470
+ size: "sm",
30471
+ onClick: handlePasteExample,
30472
+ className: "h-7 px-2 text-xs",
30473
+ children: [
30474
+ /* @__PURE__ */ jsxRuntimeExports.jsx(FileText, { className: "h-3 w-3 mr-1" }),
30475
+ "Paste Example"
30476
+ ]
30477
+ }
30478
+ ),
30479
+ /* @__PURE__ */ jsxRuntimeExports.jsxs(
30480
+ Button,
30481
+ {
30482
+ variant: "outline",
30483
+ size: "sm",
30484
+ onClick: handleCopyExample,
30485
+ className: "h-7 px-2 text-xs",
30486
+ children: [
30487
+ /* @__PURE__ */ jsxRuntimeExports.jsx(Copy, { className: "h-3 w-3 mr-1" }),
30488
+ "Copy Example"
30489
+ ]
30490
+ }
30491
+ )
30492
+ ] })
30493
+ ] }),
30494
+ /* @__PURE__ */ jsxRuntimeExports.jsx(
30495
+ Textarea,
30496
+ {
30497
+ value: configText,
30498
+ onChange: (e) => handleConfigChange(e.target.value),
30499
+ placeholder: `Paste your configuration here. Supports two formats:
30500
+
30501
+ 1. Global config (complete mcp.json):
30502
+ {
30503
+ "mcpServers": {
30504
+ "my-server": {
30505
+ "command": "npx",
30506
+ "args": ["@modelcontextprotocol/server-everything"]
30507
+ }
30508
+ }
30509
+ }
30510
+
30511
+ 2. Named server config:
30512
+ {
30513
+ "everything": {
30514
+ "command": "npx",
30515
+ "args": ["@modelcontextprotocol/server-everything"]
30516
+ }
30517
+ }
30518
+
30519
+ or
30520
+
30521
+ {
30522
+ "my-sse-server": {
30523
+ "url": "https://api.example.com/mcp",
30524
+ "type": "sse"
30525
+ }
30526
+ }`,
30527
+ className: "font-mono text-xs min-h-[200px] resize-none"
30528
+ }
30529
+ )
30530
+ ] }),
30531
+ /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "flex gap-2", children: /* @__PURE__ */ jsxRuntimeExports.jsx(
30532
+ Button,
30533
+ {
30534
+ onClick: validateConfig,
30535
+ disabled: !configText.trim() || isValidating,
30536
+ variant: "outline",
30537
+ className: "flex-1",
30538
+ children: isValidating ? /* @__PURE__ */ jsxRuntimeExports.jsxs(jsxRuntimeExports.Fragment, { children: [
30539
+ /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "animate-spin rounded-full h-4 w-4 border-b-2 border-current mr-2" }),
30540
+ "Validating..."
30541
+ ] }) : /* @__PURE__ */ jsxRuntimeExports.jsxs(jsxRuntimeExports.Fragment, { children: [
30542
+ /* @__PURE__ */ jsxRuntimeExports.jsx(CircleAlert, { className: "h-4 w-4 mr-2" }),
30543
+ "Validate Configuration"
30544
+ ] })
30545
+ }
30546
+ ) }),
30547
+ parseResult && /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "space-y-3 flex-1 min-h-0 overflow-y-auto", children: parseResult.success ? /* @__PURE__ */ jsxRuntimeExports.jsxs(Alert, { children: [
30548
+ /* @__PURE__ */ jsxRuntimeExports.jsx(CircleCheckBig, { className: "h-4 w-4" }),
30549
+ /* @__PURE__ */ jsxRuntimeExports.jsx(AlertTitle, { children: "Configuration Valid" }),
30550
+ /* @__PURE__ */ jsxRuntimeExports.jsxs(AlertDescription, { children: [
30551
+ "Found ",
30552
+ parseResult.servers.length,
30553
+ " server(s) ready to import:",
30554
+ /* @__PURE__ */ jsxRuntimeExports.jsx("ul", { className: "mt-2 space-y-1", children: parseResult.servers.map((server) => {
30555
+ var _a2;
30556
+ return /* @__PURE__ */ jsxRuntimeExports.jsxs("li", { className: "text-xs font-mono", children: [
30557
+ "• ",
30558
+ /* @__PURE__ */ jsxRuntimeExports.jsx("strong", { children: server.name }),
30559
+ " (",
30560
+ server.config.transportType,
30561
+ ")",
30562
+ server.config.transportType === "stdio" && "command" in server.config && /* @__PURE__ */ jsxRuntimeExports.jsxs("span", { className: "text-muted-foreground ml-2", children: [
30563
+ server.config.command,
30564
+ " ",
30565
+ (_a2 = server.config.args) == null ? void 0 : _a2.join(" ")
30566
+ ] }),
30567
+ server.config.transportType !== "stdio" && "url" in server.config && server.config.url && /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "text-muted-foreground ml-2", children: server.config.url.toString() })
30568
+ ] }, server.name);
30569
+ }) })
30570
+ ] })
30571
+ ] }) : /* @__PURE__ */ jsxRuntimeExports.jsxs(Alert, { variant: "destructive", children: [
30572
+ /* @__PURE__ */ jsxRuntimeExports.jsx(CircleAlert, { className: "h-4 w-4" }),
30573
+ /* @__PURE__ */ jsxRuntimeExports.jsx(AlertTitle, { children: "Configuration Invalid" }),
30574
+ /* @__PURE__ */ jsxRuntimeExports.jsx(AlertDescription, { children: /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "space-y-1", children: parseResult.errors.map((error, index2) => /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "text-xs font-mono", children: [
30575
+ "• ",
30576
+ error
30577
+ ] }, index2)) }) })
30578
+ ] }) })
30579
+ ] }),
30580
+ /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex gap-2 pt-4 border-t", children: [
30581
+ /* @__PURE__ */ jsxRuntimeExports.jsxs(
30582
+ Button,
30583
+ {
30584
+ variant: "outline",
30585
+ onClick: handleClose,
30586
+ className: "flex-1",
30587
+ children: [
30588
+ /* @__PURE__ */ jsxRuntimeExports.jsx(X$1, { className: "h-4 w-4 mr-2" }),
30589
+ "Cancel"
30590
+ ]
30591
+ }
30592
+ ),
30593
+ /* @__PURE__ */ jsxRuntimeExports.jsxs(
30594
+ Button,
30595
+ {
30596
+ onClick: handleImport,
30597
+ disabled: !(parseResult == null ? void 0 : parseResult.success) || parseResult.servers.length === 0,
30598
+ className: "flex-1",
30599
+ children: [
30600
+ /* @__PURE__ */ jsxRuntimeExports.jsx(Upload, { className: "h-4 w-4 mr-2" }),
30601
+ "Import ",
30602
+ (parseResult == null ? void 0 : parseResult.servers.length) || 0,
30603
+ " Server(s)"
30604
+ ]
30605
+ }
30606
+ )
30607
+ ] })
30608
+ ] }) });
30609
+ };
29659
30610
  const ConnectionSection = ({
29660
30611
  connectionStatus,
29661
30612
  transportType,
@@ -29681,12 +30632,14 @@ const ConnectionSection = ({
29681
30632
  loggingSupported,
29682
30633
  config,
29683
30634
  setConfig,
29684
- hideActionButtons
30635
+ hideActionButtons,
30636
+ onImportServers
29685
30637
  }) => {
29686
30638
  const [activeTab, setActiveTab] = reactExports.useState("connection");
29687
30639
  const [shownEnvVars, setShownEnvVars] = reactExports.useState(/* @__PURE__ */ new Set());
29688
30640
  const [copiedServerEntry, setCopiedServerEntry] = reactExports.useState(false);
29689
30641
  const [copiedServerFile, setCopiedServerFile] = reactExports.useState(false);
30642
+ const [showImportDialog, setShowImportDialog] = reactExports.useState(false);
29690
30643
  const { toast: toast2 } = useToast();
29691
30644
  const reportError2 = reactExports.useCallback(
29692
30645
  (error) => {
@@ -29782,7 +30735,8 @@ const ConnectionSection = ({
29782
30735
  { key: "auth", label: "Auth" },
29783
30736
  ...transportType === "stdio" ? [{ key: "env", label: "Environment" }] : [],
29784
30737
  { key: "config", label: "Configuration" },
29785
- ...loggingSupported ? [{ key: "logging", label: "Logging" }] : []
30738
+ ...loggingSupported ? [{ key: "logging", label: "Logging" }] : [],
30739
+ ...onImportServers ? [{ key: "import", label: "Import" }] : []
29786
30740
  ].map((tab) => /* @__PURE__ */ jsxRuntimeExports.jsx(
29787
30741
  "button",
29788
30742
  {
@@ -30020,6 +30974,21 @@ const ConnectionSection = ({
30020
30974
  }
30021
30975
  )
30022
30976
  ] })
30977
+ ] }),
30978
+ activeTab === "import" && onImportServers && /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "space-y-3", children: [
30979
+ /* @__PURE__ */ jsxRuntimeExports.jsx("h3", { className: "text-sm font-semibold text-slate-800 dark:text-slate-200", children: "Import Configuration" }),
30980
+ /* @__PURE__ */ jsxRuntimeExports.jsx("p", { className: "text-xs text-slate-600 dark:text-slate-400", children: "Import multiple servers from a configuration file. Supports the same format used by Claude Desktop and Cursor." }),
30981
+ /* @__PURE__ */ jsxRuntimeExports.jsxs(
30982
+ Button,
30983
+ {
30984
+ onClick: () => setShowImportDialog(true),
30985
+ className: "w-full h-8 text-xs",
30986
+ children: [
30987
+ /* @__PURE__ */ jsxRuntimeExports.jsx(Upload, { className: "w-3 h-3 mr-2" }),
30988
+ "Import from Configuration File"
30989
+ ]
30990
+ }
30991
+ )
30023
30992
  ] })
30024
30993
  ] });
30025
30994
  };
@@ -30217,9 +31186,106 @@ const ConnectionSection = ({
30217
31186
  },
30218
31187
  index2
30219
31188
  )) })
30220
- ] }) })
31189
+ ] }) }),
31190
+ onImportServers && /* @__PURE__ */ jsxRuntimeExports.jsx(
31191
+ ConfigImportDialog,
31192
+ {
31193
+ open: showImportDialog,
31194
+ onOpenChange: setShowImportDialog,
31195
+ onImportServers
31196
+ }
31197
+ )
30221
31198
  ] });
30222
31199
  };
31200
+ const Card = reactExports.forwardRef(({ className, ...props }, ref2) => /* @__PURE__ */ jsxRuntimeExports.jsx(
31201
+ "div",
31202
+ {
31203
+ ref: ref2,
31204
+ className: cn(
31205
+ "rounded-lg border bg-card text-card-foreground shadow-sm",
31206
+ className
31207
+ ),
31208
+ ...props
31209
+ }
31210
+ ));
31211
+ Card.displayName = "Card";
31212
+ const CardHeader = reactExports.forwardRef(({ className, ...props }, ref2) => /* @__PURE__ */ jsxRuntimeExports.jsx(
31213
+ "div",
31214
+ {
31215
+ ref: ref2,
31216
+ className: cn("flex flex-col space-y-1.5 p-6", className),
31217
+ ...props
31218
+ }
31219
+ ));
31220
+ CardHeader.displayName = "CardHeader";
31221
+ const CardTitle = reactExports.forwardRef(({ className, ...props }, ref2) => /* @__PURE__ */ jsxRuntimeExports.jsx(
31222
+ "h3",
31223
+ {
31224
+ ref: ref2,
31225
+ className: cn(
31226
+ "text-2xl font-semibold leading-none tracking-tight",
31227
+ className
31228
+ ),
31229
+ ...props
31230
+ }
31231
+ ));
31232
+ CardTitle.displayName = "CardTitle";
31233
+ const CardDescription = reactExports.forwardRef(({ className, ...props }, ref2) => /* @__PURE__ */ jsxRuntimeExports.jsx(
31234
+ "p",
31235
+ {
31236
+ ref: ref2,
31237
+ className: cn("text-sm text-muted-foreground", className),
31238
+ ...props
31239
+ }
31240
+ ));
31241
+ CardDescription.displayName = "CardDescription";
31242
+ const CardContent = reactExports.forwardRef(({ className, ...props }, ref2) => /* @__PURE__ */ jsxRuntimeExports.jsx("div", { ref: ref2, className: cn("p-6 pt-0", className), ...props }));
31243
+ CardContent.displayName = "CardContent";
31244
+ const CardFooter = reactExports.forwardRef(({ className, ...props }, ref2) => /* @__PURE__ */ jsxRuntimeExports.jsx(
31245
+ "div",
31246
+ {
31247
+ ref: ref2,
31248
+ className: cn("flex items-center p-6 pt-0", className),
31249
+ ...props
31250
+ }
31251
+ ));
31252
+ CardFooter.displayName = "CardFooter";
31253
+ const Separator = reactExports.forwardRef(
31254
+ ({ className, orientation = "horizontal", decorative = true, ...props }, ref2) => /* @__PURE__ */ jsxRuntimeExports.jsx(
31255
+ "div",
31256
+ {
31257
+ ref: ref2,
31258
+ role: decorative ? "none" : "separator",
31259
+ "aria-orientation": orientation,
31260
+ className: cn(
31261
+ "shrink-0 bg-border",
31262
+ orientation === "horizontal" ? "h-[1px] w-full" : "h-full w-[1px]",
31263
+ className
31264
+ ),
31265
+ ...props
31266
+ }
31267
+ )
31268
+ );
31269
+ Separator.displayName = "Separator";
31270
+ const badgeVariants = cva(
31271
+ "inline-flex items-center rounded-full border px-2.5 py-0.5 text-xs font-semibold transition-colors focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2",
31272
+ {
31273
+ variants: {
31274
+ variant: {
31275
+ default: "border-transparent bg-primary text-primary-foreground hover:bg-primary/80",
31276
+ secondary: "border-transparent bg-secondary text-secondary-foreground hover:bg-secondary/80",
31277
+ destructive: "border-transparent bg-destructive text-destructive-foreground hover:bg-destructive/80",
31278
+ outline: "text-foreground"
31279
+ }
31280
+ },
31281
+ defaultVariants: {
31282
+ variant: "default"
31283
+ }
31284
+ }
31285
+ );
31286
+ function Badge({ className, variant, ...props }) {
31287
+ return /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: cn(badgeVariants({ variant }), className), ...props });
31288
+ }
30223
31289
  const ClientFormSection = ({
30224
31290
  isCreating,
30225
31291
  editingClientName,
@@ -30234,15 +31300,35 @@ const ClientFormSection = ({
30234
31300
  headerName,
30235
31301
  setHeaderName,
30236
31302
  onSave,
30237
- onCancel
31303
+ onCancel,
31304
+ onImportMultipleServers,
31305
+ onSaveMultiple
30238
31306
  }) => {
30239
31307
  const [argsString, setArgsString] = reactExports.useState("");
31308
+ const [sseUrlString, setSseUrlString] = reactExports.useState("");
31309
+ const [multipleClients, setMultipleClients] = reactExports.useState([]);
31310
+ const [isMultipleMode, setIsMultipleMode] = reactExports.useState(false);
31311
+ const [isManualConfigExpanded, setIsManualConfigExpanded] = reactExports.useState(false);
31312
+ const { toast: toast2 } = useToast();
31313
+ const [showImportDialog, setShowImportDialog] = reactExports.useState(false);
31314
+ const [nameError, setNameError] = reactExports.useState("");
30240
31315
  reactExports.useEffect(() => {
30241
- var _a2;
31316
+ var _a2, _b;
30242
31317
  if (clientFormConfig.transportType === "stdio" && "args" in clientFormConfig) {
30243
31318
  setArgsString(((_a2 = clientFormConfig.args) == null ? void 0 : _a2.join(" ")) || "");
31319
+ setSseUrlString("");
31320
+ } else if (clientFormConfig.transportType !== "stdio" && "url" in clientFormConfig) {
31321
+ setArgsString("");
31322
+ setSseUrlString(((_b = clientFormConfig.url) == null ? void 0 : _b.toString()) || "");
30244
31323
  }
30245
31324
  }, [clientFormConfig]);
31325
+ reactExports.useEffect(() => {
31326
+ if (clientFormName.trim()) {
31327
+ setNameError("");
31328
+ } else {
31329
+ setNameError("Client name is required");
31330
+ }
31331
+ }, [clientFormName]);
30246
31332
  const handleArgsChange = (newArgsString) => {
30247
31333
  setArgsString(newArgsString);
30248
31334
  if (clientFormConfig.transportType === "stdio") {
@@ -30252,117 +31338,539 @@ const ClientFormSection = ({
30252
31338
  });
30253
31339
  }
30254
31340
  };
30255
- return /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "flex-1 flex flex-col overflow-auto p-6", children: /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "max-w-4xl mx-auto w-full", children: [
30256
- /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "mb-6", children: [
30257
- /* @__PURE__ */ jsxRuntimeExports.jsx("h2", { className: "text-2xl font-bold mb-2", children: isCreating ? "Create New Client" : `Edit Client: ${editingClientName}` }),
30258
- /* @__PURE__ */ jsxRuntimeExports.jsx("p", { className: "text-muted-foreground", children: "Configure your MCP client connection settings below." })
30259
- ] }),
30260
- /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "space-y-4", children: [
30261
- /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { children: [
30262
- /* @__PURE__ */ jsxRuntimeExports.jsx("label", { className: "text-sm font-medium mb-2 block", children: "Client Name" }),
31341
+ const handleSseUrlChange = (newSseUrlString) => {
31342
+ setSseUrlString(newSseUrlString);
31343
+ };
31344
+ const handleImportServers = (servers) => {
31345
+ var _a2, _b;
31346
+ if (servers.length > 1) {
31347
+ const clients = servers.map((server, index2) => {
31348
+ var _a3, _b2;
31349
+ return {
31350
+ id: `client-${Date.now()}-${index2}`,
31351
+ name: server.name,
31352
+ config: server.config,
31353
+ argsString: server.config.transportType === "stdio" && "args" in server.config ? ((_a3 = server.config.args) == null ? void 0 : _a3.join(" ")) || "" : "",
31354
+ sseUrlString: server.config.transportType !== "stdio" && "url" in server.config ? ((_b2 = server.config.url) == null ? void 0 : _b2.toString()) || "" : ""
31355
+ };
31356
+ });
31357
+ setMultipleClients(clients);
31358
+ setIsMultipleMode(true);
31359
+ toast2({
31360
+ title: "Multiple servers imported",
31361
+ description: `Imported ${servers.length} server configurations. Configure each client below.`
31362
+ });
31363
+ } else if (servers.length === 1) {
31364
+ const firstServer = servers[0];
31365
+ setClientFormConfig(firstServer.config);
31366
+ if (!clientFormName.trim()) {
31367
+ setClientFormName(firstServer.name);
31368
+ }
31369
+ if (firstServer.config.transportType === "stdio" && "args" in firstServer.config) {
31370
+ setArgsString(((_a2 = firstServer.config.args) == null ? void 0 : _a2.join(" ")) || "");
31371
+ setSseUrlString("");
31372
+ } else if (firstServer.config.transportType !== "stdio" && "url" in firstServer.config) {
31373
+ setArgsString("");
31374
+ setSseUrlString(((_b = firstServer.config.url) == null ? void 0 : _b.toString()) || "");
31375
+ }
31376
+ toast2({
31377
+ title: "Configuration imported",
31378
+ description: `Imported configuration for "${firstServer.name}".`
31379
+ });
31380
+ }
31381
+ if (onImportMultipleServers) {
31382
+ onImportMultipleServers(servers);
31383
+ }
31384
+ };
31385
+ const handleUpdateClient = (clientId, updates) => {
31386
+ setMultipleClients(
31387
+ (prev) => prev.map(
31388
+ (client2) => client2.id === clientId ? { ...client2, ...updates } : client2
31389
+ )
31390
+ );
31391
+ };
31392
+ const handleRemoveClient = (clientId) => {
31393
+ setMultipleClients(
31394
+ (prev) => prev.filter((client2) => client2.id !== clientId)
31395
+ );
31396
+ };
31397
+ const handleAddClient = () => {
31398
+ const newClient = {
31399
+ id: `client-${Date.now()}`,
31400
+ name: "",
31401
+ config: {
31402
+ transportType: "stdio",
31403
+ command: "npx",
31404
+ args: ["@modelcontextprotocol/server-everything"],
31405
+ env: {}
31406
+ },
31407
+ argsString: "@modelcontextprotocol/server-everything",
31408
+ sseUrlString: ""
31409
+ };
31410
+ setMultipleClients((prev) => [...prev, newClient]);
31411
+ };
31412
+ const handleSingleSave = () => {
31413
+ let configToSave = { ...clientFormConfig };
31414
+ if (configToSave.transportType !== "stdio") {
31415
+ try {
31416
+ const url = new URL(sseUrlString);
31417
+ configToSave = {
31418
+ ...configToSave,
31419
+ url
31420
+ };
31421
+ } catch {
31422
+ toast2({
31423
+ title: "Invalid URL",
31424
+ description: "Please enter a valid URL for the client.",
31425
+ variant: "destructive"
31426
+ });
31427
+ return;
31428
+ }
31429
+ }
31430
+ onSave(configToSave);
31431
+ };
31432
+ const handleSaveAll = async () => {
31433
+ if (!onSaveMultiple) return;
31434
+ const validClients = multipleClients.filter((c) => c.name.trim());
31435
+ if (validClients.length === 0) {
31436
+ toast2({
31437
+ title: "No valid clients",
31438
+ description: "Please provide names for at least one client.",
31439
+ variant: "destructive"
31440
+ });
31441
+ return;
31442
+ }
31443
+ const clientsToSave = validClients.map((client2) => {
31444
+ let configToSave = { ...client2.config };
31445
+ if (configToSave.transportType !== "stdio") {
31446
+ try {
31447
+ const url = new URL(client2.sseUrlString);
31448
+ configToSave = {
31449
+ ...configToSave,
31450
+ url
31451
+ };
31452
+ } catch {
31453
+ throw new Error(`Invalid URL for client "${client2.name}"`);
31454
+ }
31455
+ }
31456
+ return {
31457
+ name: client2.name,
31458
+ config: configToSave
31459
+ };
31460
+ });
31461
+ try {
31462
+ const result = await onSaveMultiple(clientsToSave);
31463
+ if (result.success.length > 0) {
31464
+ toast2({
31465
+ title: "Clients created successfully",
31466
+ description: `Successfully created ${result.success.length} client(s).`
31467
+ });
31468
+ }
31469
+ if (result.failed.length > 0) {
31470
+ toast2({
31471
+ title: "Some clients failed to create",
31472
+ description: `${result.failed.length} client(s) failed to create. Check the console for details.`,
31473
+ variant: "destructive"
31474
+ });
31475
+ }
31476
+ } catch (error) {
31477
+ toast2({
31478
+ title: "Error creating clients",
31479
+ description: error instanceof Error ? error.message : "An unexpected error occurred.",
31480
+ variant: "destructive"
31481
+ });
31482
+ }
31483
+ };
31484
+ const handleBackToSingle = () => {
31485
+ setIsMultipleMode(false);
31486
+ setMultipleClients([]);
31487
+ };
31488
+ if (isMultipleMode) {
31489
+ 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: [
31490
+ /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex items-center gap-3", children: [
30263
31491
  /* @__PURE__ */ jsxRuntimeExports.jsx(
30264
- "input",
31492
+ Button,
30265
31493
  {
30266
- type: "text",
30267
- value: clientFormName,
30268
- onChange: (e) => setClientFormName(e.target.value),
30269
- placeholder: "Enter client name",
30270
- className: "w-full px-3 py-2 border border-border rounded-md bg-background"
31494
+ variant: "ghost",
31495
+ size: "sm",
31496
+ onClick: handleBackToSingle,
31497
+ className: "h-8 w-8 p-0",
31498
+ children: /* @__PURE__ */ jsxRuntimeExports.jsx(ArrowLeft, { className: "h-4 w-4" })
30271
31499
  }
30272
- )
31500
+ ),
31501
+ /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { children: [
31502
+ /* @__PURE__ */ jsxRuntimeExports.jsx("h1", { className: "text-3xl font-bold tracking-tight", children: "Create Multiple Clients" }),
31503
+ /* @__PURE__ */ jsxRuntimeExports.jsx("p", { className: "text-muted-foreground mt-1", children: "Configure each imported server as a separate client" })
31504
+ ] }),
31505
+ /* @__PURE__ */ jsxRuntimeExports.jsxs(Badge, { variant: "secondary", className: "ml-auto", children: [
31506
+ /* @__PURE__ */ jsxRuntimeExports.jsx(Users, { className: "h-3 w-3 mr-1" }),
31507
+ multipleClients.length,
31508
+ " clients"
31509
+ ] })
30273
31510
  ] }),
30274
- /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "border border-border rounded-lg", children: /* @__PURE__ */ jsxRuntimeExports.jsx(
30275
- ConnectionSection,
30276
- {
30277
- connectionStatus: "disconnected",
30278
- transportType: clientFormConfig.transportType,
30279
- setTransportType: (type2) => {
30280
- if (type2 === "stdio") {
30281
- const newConfig = {
30282
- transportType: type2,
30283
- command: "npx",
30284
- args: ["@modelcontextprotocol/server-everything"],
30285
- env: {}
30286
- };
30287
- setClientFormConfig(newConfig);
30288
- setArgsString("@modelcontextprotocol/server-everything");
30289
- } else {
30290
- setClientFormConfig({
30291
- transportType: type2,
30292
- url: new URL("https://example.com")
30293
- });
30294
- setArgsString("");
30295
- }
30296
- },
30297
- command: clientFormConfig.transportType === "stdio" && "command" in clientFormConfig ? clientFormConfig.command || "" : "",
30298
- setCommand: (command) => {
30299
- if (clientFormConfig.transportType === "stdio") {
30300
- setClientFormConfig({
30301
- ...clientFormConfig,
30302
- command
30303
- });
30304
- }
30305
- },
30306
- args: argsString,
30307
- setArgs: handleArgsChange,
30308
- sseUrl: "url" in clientFormConfig && clientFormConfig.url ? clientFormConfig.url.toString() : "",
30309
- setSseUrl: (url) => {
30310
- if (clientFormConfig.transportType !== "stdio") {
30311
- setClientFormConfig({
30312
- ...clientFormConfig,
30313
- url: new URL(url)
30314
- });
30315
- }
30316
- },
30317
- env: clientFormConfig.transportType === "stdio" && "env" in clientFormConfig ? clientFormConfig.env || {} : {},
30318
- setEnv: (env) => {
30319
- if (clientFormConfig.transportType === "stdio") {
30320
- setClientFormConfig({
30321
- ...clientFormConfig,
30322
- env
30323
- });
30324
- }
30325
- },
30326
- config,
30327
- setConfig,
30328
- bearerToken,
30329
- setBearerToken,
30330
- headerName,
30331
- setHeaderName,
30332
- onConnect: () => {
30333
- },
30334
- onDisconnect: () => {
30335
- },
30336
- stdErrNotifications: [],
30337
- clearStdErrNotifications: () => {
30338
- },
30339
- logLevel: "debug",
30340
- sendLogLevelRequest: async () => {
31511
+ /* @__PURE__ */ jsxRuntimeExports.jsx(Separator, {}),
31512
+ /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "grid gap-6", children: [
31513
+ multipleClients.map((client2, index2) => /* @__PURE__ */ jsxRuntimeExports.jsxs(
31514
+ Card,
31515
+ {
31516
+ className: "border-2 border-border/50 hover:border-border transition-colors",
31517
+ children: [
31518
+ /* @__PURE__ */ jsxRuntimeExports.jsx(CardHeader, { className: "pb-4", children: /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex items-center justify-between", children: [
31519
+ /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex items-center gap-3", children: [
31520
+ /* @__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 }),
31521
+ /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { children: [
31522
+ /* @__PURE__ */ jsxRuntimeExports.jsxs(CardTitle, { className: "text-lg", children: [
31523
+ "Client ",
31524
+ index2 + 1
31525
+ ] }),
31526
+ /* @__PURE__ */ jsxRuntimeExports.jsx(CardDescription, { children: client2.name || "Unnamed client" })
31527
+ ] })
31528
+ ] }),
31529
+ /* @__PURE__ */ jsxRuntimeExports.jsx(
31530
+ Button,
31531
+ {
31532
+ variant: "ghost",
31533
+ size: "sm",
31534
+ onClick: () => handleRemoveClient(client2.id),
31535
+ className: "h-8 w-8 p-0 text-muted-foreground hover:text-destructive",
31536
+ children: /* @__PURE__ */ jsxRuntimeExports.jsx(X$1, { className: "h-4 w-4" })
31537
+ }
31538
+ )
31539
+ ] }) }),
31540
+ /* @__PURE__ */ jsxRuntimeExports.jsxs(CardContent, { className: "space-y-6", children: [
31541
+ /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "space-y-2", children: [
31542
+ /* @__PURE__ */ jsxRuntimeExports.jsx(
31543
+ Label$1,
31544
+ {
31545
+ htmlFor: `client-name-${client2.id}`,
31546
+ className: "text-sm font-medium",
31547
+ children: "Client Name"
31548
+ }
31549
+ ),
31550
+ /* @__PURE__ */ jsxRuntimeExports.jsx(
31551
+ Input,
31552
+ {
31553
+ id: `client-name-${client2.id}`,
31554
+ value: client2.name,
31555
+ onChange: (e) => handleUpdateClient(client2.id, { name: e.target.value }),
31556
+ placeholder: "Enter a descriptive name for this client",
31557
+ className: "max-w-md"
31558
+ }
31559
+ )
31560
+ ] }),
31561
+ /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "space-y-3", children: [
31562
+ /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex items-center gap-2", children: [
31563
+ /* @__PURE__ */ jsxRuntimeExports.jsx(Settings, { className: "h-4 w-4 text-muted-foreground" }),
31564
+ /* @__PURE__ */ jsxRuntimeExports.jsx(Label$1, { className: "text-sm font-medium", children: "Connection Settings" })
31565
+ ] }),
31566
+ /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "border border-border/50 rounded-lg p-4 bg-muted/30", children: /* @__PURE__ */ jsxRuntimeExports.jsx(
31567
+ ConnectionSection,
31568
+ {
31569
+ connectionStatus: "disconnected",
31570
+ transportType: client2.config.transportType,
31571
+ setTransportType: (type2) => {
31572
+ let newConfig;
31573
+ let newArgsString = "";
31574
+ if (type2 === "stdio") {
31575
+ newConfig = {
31576
+ transportType: type2,
31577
+ command: "npx",
31578
+ args: ["@modelcontextprotocol/server-everything"],
31579
+ env: {}
31580
+ };
31581
+ newArgsString = "@modelcontextprotocol/server-everything";
31582
+ } else {
31583
+ newConfig = {
31584
+ transportType: type2,
31585
+ url: new URL("https://example.com")
31586
+ };
31587
+ }
31588
+ handleUpdateClient(client2.id, {
31589
+ config: newConfig,
31590
+ argsString: newArgsString,
31591
+ sseUrlString: newConfig.transportType !== "stdio" && "url" in newConfig && newConfig.url ? newConfig.url.toString() : ""
31592
+ });
31593
+ },
31594
+ command: client2.config.transportType === "stdio" && "command" in client2.config ? client2.config.command || "" : "",
31595
+ setCommand: (command) => {
31596
+ if (client2.config.transportType === "stdio") {
31597
+ handleUpdateClient(client2.id, {
31598
+ config: {
31599
+ ...client2.config,
31600
+ command
31601
+ }
31602
+ });
31603
+ }
31604
+ },
31605
+ args: client2.argsString,
31606
+ setArgs: (newArgsString) => {
31607
+ if (client2.config.transportType === "stdio") {
31608
+ handleUpdateClient(client2.id, {
31609
+ argsString: newArgsString,
31610
+ config: {
31611
+ ...client2.config,
31612
+ args: newArgsString.trim() ? newArgsString.split(/\s+/) : []
31613
+ }
31614
+ });
31615
+ }
31616
+ },
31617
+ sseUrl: client2.sseUrlString,
31618
+ setSseUrl: (url) => {
31619
+ handleUpdateClient(client2.id, { sseUrlString: url });
31620
+ },
31621
+ env: client2.config.transportType === "stdio" && "env" in client2.config ? client2.config.env || {} : {},
31622
+ setEnv: (env) => {
31623
+ if (client2.config.transportType === "stdio") {
31624
+ handleUpdateClient(client2.id, {
31625
+ config: {
31626
+ ...client2.config,
31627
+ env
31628
+ }
31629
+ });
31630
+ }
31631
+ },
31632
+ config,
31633
+ setConfig,
31634
+ bearerToken,
31635
+ setBearerToken,
31636
+ headerName,
31637
+ setHeaderName,
31638
+ onConnect: () => {
31639
+ },
31640
+ onDisconnect: () => {
31641
+ },
31642
+ stdErrNotifications: [],
31643
+ clearStdErrNotifications: () => {
31644
+ },
31645
+ logLevel: "debug",
31646
+ sendLogLevelRequest: async () => {
31647
+ },
31648
+ loggingSupported: false,
31649
+ hideActionButtons: true
31650
+ }
31651
+ ) })
31652
+ ] })
31653
+ ] })
31654
+ ]
30341
31655
  },
30342
- loggingSupported: false,
30343
- hideActionButtons: true
30344
- }
30345
- ) }),
30346
- /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex space-x-3 pt-4", children: [
30347
- /* @__PURE__ */ jsxRuntimeExports.jsx(
30348
- "button",
31656
+ client2.id
31657
+ )),
31658
+ /* @__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(
31659
+ Button,
30349
31660
  {
30350
- onClick: onSave,
30351
- disabled: !clientFormName.trim(),
30352
- className: "px-4 py-2 bg-primary text-primary-foreground rounded-md hover:bg-primary/90 disabled:opacity-50 disabled:cursor-not-allowed",
30353
- children: isCreating ? "Create Client" : "Update Client"
31661
+ variant: "ghost",
31662
+ onClick: handleAddClient,
31663
+ className: "w-full h-16 text-muted-foreground hover:text-foreground",
31664
+ children: [
31665
+ /* @__PURE__ */ jsxRuntimeExports.jsx(Plus, { className: "h-5 w-5 mr-2" }),
31666
+ "Add Another Client"
31667
+ ]
30354
31668
  }
30355
- ),
30356
- /* @__PURE__ */ jsxRuntimeExports.jsx(
30357
- "button",
31669
+ ) }) })
31670
+ ] }),
31671
+ /* @__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: [
31672
+ /* @__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: [
31673
+ /* @__PURE__ */ jsxRuntimeExports.jsx(CircleAlert, { className: "h-4 w-4" }),
31674
+ /* @__PURE__ */ jsxRuntimeExports.jsx("span", { children: "Some clients need names" })
31675
+ ] }) }),
31676
+ /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex items-center gap-3", children: [
31677
+ /* @__PURE__ */ jsxRuntimeExports.jsx(Button, { variant: "outline", onClick: onCancel, children: "Cancel" }),
31678
+ /* @__PURE__ */ jsxRuntimeExports.jsxs(
31679
+ Button,
31680
+ {
31681
+ onClick: handleSaveAll,
31682
+ disabled: multipleClients.filter((c) => c.name.trim()).length === 0,
31683
+ className: "min-w-[200px]",
31684
+ children: [
31685
+ /* @__PURE__ */ jsxRuntimeExports.jsx(Save, { className: "h-4 w-4 mr-2" }),
31686
+ "Create ",
31687
+ multipleClients.filter((c) => c.name.trim()).length,
31688
+ " ",
31689
+ "Client(s)"
31690
+ ]
31691
+ }
31692
+ )
31693
+ ] })
31694
+ ] }) })
31695
+ ] }) });
31696
+ }
31697
+ 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: [
31698
+ isCreating && /* @__PURE__ */ jsxRuntimeExports.jsxs(Card, { className: "border-2 border-primary/20 bg-gradient-to-r from-primary/5 to-primary/10", children: [
31699
+ /* @__PURE__ */ jsxRuntimeExports.jsx(CardHeader, { children: /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex items-center gap-3", children: [
31700
+ /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "p-2 bg-primary/10 rounded-lg", children: /* @__PURE__ */ jsxRuntimeExports.jsx(Upload, { className: "h-5 w-5 text-primary" }) }),
31701
+ /* @__PURE__ */ jsxRuntimeExports.jsx("div", { children: /* @__PURE__ */ jsxRuntimeExports.jsx(CardTitle, { className: "text-lg", children: "Quick Import" }) }),
31702
+ /* @__PURE__ */ jsxRuntimeExports.jsxs(Badge, { variant: "secondary", className: "ml-auto", children: [
31703
+ /* @__PURE__ */ jsxRuntimeExports.jsx(Sparkles, { className: "h-3 w-3 mr-1" }),
31704
+ "Recommended"
31705
+ ] })
31706
+ ] }) }),
31707
+ /* @__PURE__ */ jsxRuntimeExports.jsxs(CardContent, { children: [
31708
+ /* @__PURE__ */ jsxRuntimeExports.jsx("p", { className: "text-sm text-muted-foreground mb-4", children: "Supports the same format used by Claude Desktop and Cursor." }),
31709
+ /* @__PURE__ */ jsxRuntimeExports.jsxs(
31710
+ Button,
30358
31711
  {
30359
- onClick: onCancel,
30360
- className: "px-4 py-2 border border-border rounded-md hover:bg-muted",
30361
- children: "Cancel"
31712
+ onClick: () => setShowImportDialog(true),
31713
+ className: "w-full sm:w-auto",
31714
+ children: [
31715
+ /* @__PURE__ */ jsxRuntimeExports.jsx(Upload, { className: "w-4 h-4 mr-2" }),
31716
+ "Import from Configuration File"
31717
+ ]
30362
31718
  }
30363
31719
  )
30364
31720
  ] })
30365
- ] })
31721
+ ] }),
31722
+ isCreating && /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "flex items-center justify-center", children: /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex items-center gap-4", children: [
31723
+ /* @__PURE__ */ jsxRuntimeExports.jsx(Separator, { className: "w-16" }),
31724
+ /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "text-sm font-medium text-muted-foreground", children: "or" }),
31725
+ /* @__PURE__ */ jsxRuntimeExports.jsx(Separator, { className: "w-16" })
31726
+ ] }) }),
31727
+ /* @__PURE__ */ jsxRuntimeExports.jsxs(Card, { className: "border-2 border-border/50", children: [
31728
+ /* @__PURE__ */ jsxRuntimeExports.jsx(
31729
+ CardHeader,
31730
+ {
31731
+ className: "cursor-pointer",
31732
+ onClick: () => setIsManualConfigExpanded(!isManualConfigExpanded),
31733
+ children: /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex items-center justify-between", children: [
31734
+ /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex items-center gap-3", children: [
31735
+ /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "p-2 bg-muted rounded-lg", children: /* @__PURE__ */ jsxRuntimeExports.jsx(Settings, { className: "h-5 w-5 text-muted-foreground" }) }),
31736
+ /* @__PURE__ */ jsxRuntimeExports.jsx("div", { children: /* @__PURE__ */ jsxRuntimeExports.jsx(CardTitle, { className: "text-lg", children: isCreating ? "Manual Setup" : `Edit: ${editingClientName}` }) })
31737
+ ] }),
31738
+ /* @__PURE__ */ jsxRuntimeExports.jsx(
31739
+ Button,
31740
+ {
31741
+ variant: "ghost",
31742
+ size: "sm",
31743
+ className: "h-8 w-8 p-0",
31744
+ onClick: (e) => {
31745
+ e.stopPropagation();
31746
+ setIsManualConfigExpanded(!isManualConfigExpanded);
31747
+ },
31748
+ children: isManualConfigExpanded ? /* @__PURE__ */ jsxRuntimeExports.jsx(ChevronDown, { className: "h-4 w-4" }) : /* @__PURE__ */ jsxRuntimeExports.jsx(ChevronRight, { className: "h-4 w-4" })
31749
+ }
31750
+ )
31751
+ ] })
31752
+ }
31753
+ ),
31754
+ isManualConfigExpanded && /* @__PURE__ */ jsxRuntimeExports.jsxs(CardContent, { className: "space-y-6", children: [
31755
+ /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "space-y-2", children: [
31756
+ /* @__PURE__ */ jsxRuntimeExports.jsx(Label$1, { htmlFor: "client-name", className: "text-sm font-medium", children: "Name" }),
31757
+ /* @__PURE__ */ jsxRuntimeExports.jsx(
31758
+ Input,
31759
+ {
31760
+ id: "client-name",
31761
+ value: clientFormName,
31762
+ onChange: (e) => setClientFormName(e.target.value),
31763
+ placeholder: "Enter client name",
31764
+ className: `max-w-md ${nameError ? "border-red-500 focus:border-red-500 focus:ring-red-500" : ""}`
31765
+ }
31766
+ ),
31767
+ nameError && /* @__PURE__ */ jsxRuntimeExports.jsxs("p", { className: "text-sm text-red-500 flex items-center gap-1", children: [
31768
+ /* @__PURE__ */ jsxRuntimeExports.jsx(CircleAlert, { className: "h-3 w-3" }),
31769
+ nameError
31770
+ ] })
31771
+ ] }),
31772
+ /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "space-y-3", children: [
31773
+ /* @__PURE__ */ jsxRuntimeExports.jsx(Label$1, { className: "text-sm font-medium", children: "Connection" }),
31774
+ /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "border border-border/50 rounded-lg p-4 bg-muted/30", children: /* @__PURE__ */ jsxRuntimeExports.jsx(
31775
+ ConnectionSection,
31776
+ {
31777
+ connectionStatus: "disconnected",
31778
+ transportType: clientFormConfig.transportType,
31779
+ setTransportType: (type2) => {
31780
+ if (type2 === "stdio") {
31781
+ const newConfig = {
31782
+ transportType: type2,
31783
+ command: "npx",
31784
+ args: ["@modelcontextprotocol/server-everything"],
31785
+ env: {}
31786
+ };
31787
+ setClientFormConfig(newConfig);
31788
+ setArgsString(
31789
+ "@modelcontextprotocol/server-everything"
31790
+ );
31791
+ } else {
31792
+ setClientFormConfig({
31793
+ transportType: type2,
31794
+ url: new URL("https://example.com")
31795
+ });
31796
+ setArgsString("");
31797
+ }
31798
+ },
31799
+ command: clientFormConfig.transportType === "stdio" && "command" in clientFormConfig ? clientFormConfig.command || "" : "",
31800
+ setCommand: (command) => {
31801
+ if (clientFormConfig.transportType === "stdio") {
31802
+ setClientFormConfig({
31803
+ ...clientFormConfig,
31804
+ command
31805
+ });
31806
+ }
31807
+ },
31808
+ args: argsString,
31809
+ setArgs: handleArgsChange,
31810
+ sseUrl: sseUrlString,
31811
+ setSseUrl: handleSseUrlChange,
31812
+ env: clientFormConfig.transportType === "stdio" && "env" in clientFormConfig ? clientFormConfig.env || {} : {},
31813
+ setEnv: (env) => {
31814
+ if (clientFormConfig.transportType === "stdio") {
31815
+ setClientFormConfig({
31816
+ ...clientFormConfig,
31817
+ env
31818
+ });
31819
+ }
31820
+ },
31821
+ config,
31822
+ setConfig,
31823
+ bearerToken,
31824
+ setBearerToken,
31825
+ headerName,
31826
+ setHeaderName,
31827
+ onConnect: () => {
31828
+ },
31829
+ onDisconnect: () => {
31830
+ },
31831
+ stdErrNotifications: [],
31832
+ clearStdErrNotifications: () => {
31833
+ },
31834
+ logLevel: "debug",
31835
+ sendLogLevelRequest: async () => {
31836
+ },
31837
+ loggingSupported: false,
31838
+ hideActionButtons: true
31839
+ }
31840
+ ) })
31841
+ ] })
31842
+ ] })
31843
+ ] }),
31844
+ /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex flex-col items-center gap-3 pt-4", children: [
31845
+ /* @__PURE__ */ jsxRuntimeExports.jsxs(
31846
+ Button,
31847
+ {
31848
+ onClick: handleSingleSave,
31849
+ disabled: !clientFormName.trim(),
31850
+ 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",
31851
+ children: [
31852
+ /* @__PURE__ */ jsxRuntimeExports.jsx(CircleCheck, { className: "h-5 w-5 mr-2" }),
31853
+ isCreating ? "Create Client" : "Update Client"
31854
+ ]
31855
+ }
31856
+ ),
31857
+ /* @__PURE__ */ jsxRuntimeExports.jsx(
31858
+ "button",
31859
+ {
31860
+ onClick: onCancel,
31861
+ className: "text-sm text-muted-foreground hover:text-foreground transition-colors underline-offset-4 hover:underline",
31862
+ children: "Cancel"
31863
+ }
31864
+ )
31865
+ ] }),
31866
+ /* @__PURE__ */ jsxRuntimeExports.jsx(
31867
+ ConfigImportDialog,
31868
+ {
31869
+ open: showImportDialog,
31870
+ onOpenChange: setShowImportDialog,
31871
+ onImportServers: handleImportServers
31872
+ }
31873
+ )
30366
31874
  ] }) });
30367
31875
  };
30368
31876
  const StarGitHubModal = ({
@@ -30423,33 +31931,39 @@ const StarGitHubModal = ({
30423
31931
  const SERVER_CONFIGS_STORAGE_KEY = "mcpServerConfigs_v1";
30424
31932
  const SELECTED_SERVER_STORAGE_KEY = "selectedServerName_v1";
30425
31933
  const serializeServerConfigs = (configs) => {
30426
- const serializable = Object.entries(configs).reduce((acc, [name, config]) => {
30427
- if ("url" in config && config.url) {
30428
- acc[name] = {
30429
- ...config,
30430
- url: config.url.toString()
30431
- };
30432
- } else {
30433
- acc[name] = config;
30434
- }
30435
- return acc;
30436
- }, {});
30437
- return JSON.stringify(serializable);
30438
- };
30439
- const deserializeServerConfigs = (serialized) => {
30440
- try {
30441
- const parsed = JSON.parse(serialized);
30442
- return Object.entries(parsed).reduce((acc, [name, config]) => {
30443
- if ("url" in config && config.url && typeof config.url === "string") {
31934
+ const serializable = Object.entries(configs).reduce(
31935
+ (acc, [name, config]) => {
31936
+ if ("url" in config && config.url) {
30444
31937
  acc[name] = {
30445
31938
  ...config,
30446
- url: new URL(config.url)
31939
+ url: config.url.toString()
30447
31940
  };
30448
31941
  } else {
30449
31942
  acc[name] = config;
30450
31943
  }
30451
31944
  return acc;
30452
- }, {});
31945
+ },
31946
+ {}
31947
+ );
31948
+ return JSON.stringify(serializable);
31949
+ };
31950
+ const deserializeServerConfigs = (serialized) => {
31951
+ try {
31952
+ const parsed = JSON.parse(serialized);
31953
+ return Object.entries(parsed).reduce(
31954
+ (acc, [name, config]) => {
31955
+ if ("url" in config && config.url && typeof config.url === "string") {
31956
+ acc[name] = {
31957
+ ...config,
31958
+ url: new URL(config.url)
31959
+ };
31960
+ } else {
31961
+ acc[name] = config;
31962
+ }
31963
+ return acc;
31964
+ },
31965
+ {}
31966
+ );
30453
31967
  } catch (error) {
30454
31968
  console.warn("Failed to deserialize server configs:", error);
30455
31969
  return {};
@@ -40880,7 +42394,7 @@ Anthropic.Models = Models2;
40880
42394
  Anthropic.Beta = Beta;
40881
42395
  const { HUMAN_PROMPT, AI_PROMPT } = Anthropic;
40882
42396
  const readline = {};
40883
- const version = "0.2.3";
42397
+ const version = "0.3.0";
40884
42398
  const packageJson = {
40885
42399
  version
40886
42400
  };
@@ -40906,17 +42420,20 @@ const getConfigOverridesFromQueryParams = (defaultConfig) => {
40906
42420
  for (const key of Object.keys(defaultConfig)) {
40907
42421
  const param = url.searchParams.get(key);
40908
42422
  if (param !== null) {
40909
- const defaultValue = defaultConfig[key].value;
40910
- let value = param;
40911
- if (typeof defaultValue === "number") {
40912
- value = Number(param);
40913
- } else if (typeof defaultValue === "boolean") {
40914
- value = param === "true";
40915
- }
40916
- overrides[key] = {
40917
- ...defaultConfig[key],
40918
- value
40919
- };
42423
+ const defaultConfigItem = defaultConfig[key];
42424
+ if (defaultConfigItem) {
42425
+ const defaultValue = defaultConfigItem.value;
42426
+ let value = param;
42427
+ if (typeof defaultValue === "number") {
42428
+ value = Number(param);
42429
+ } else if (typeof defaultValue === "boolean") {
42430
+ value = param === "true";
42431
+ }
42432
+ overrides[key] = {
42433
+ ...defaultConfigItem,
42434
+ value
42435
+ };
42436
+ }
40920
42437
  }
40921
42438
  }
40922
42439
  return overrides;
@@ -40930,10 +42447,13 @@ const initializeInspectorConfig = (localStorageKey) => {
40930
42447
  ...JSON.parse(savedConfig)
40931
42448
  };
40932
42449
  for (const [key, value] of Object.entries(mergedConfig)) {
40933
- mergedConfig[key] = {
40934
- ...value,
40935
- label: DEFAULT_INSPECTOR_CONFIG[key].label
40936
- };
42450
+ const defaultConfigItem = DEFAULT_INSPECTOR_CONFIG[key];
42451
+ if (defaultConfigItem) {
42452
+ mergedConfig[key] = {
42453
+ ...value,
42454
+ label: defaultConfigItem.label
42455
+ };
42456
+ }
40937
42457
  }
40938
42458
  baseConfig = mergedConfig;
40939
42459
  } else {
@@ -41873,7 +43393,7 @@ const mappedTools = (tools) => {
41873
43393
  });
41874
43394
  };
41875
43395
  class MCPJamClient extends Client {
41876
- constructor(serverConfig, config, addRequestHistory, bearerToken, headerName, onStdErrNotification, claudeApiKey, onPendingRequest, getRoots) {
43396
+ constructor(serverConfig, config, addRequestHistory, addClientLog, bearerToken, headerName, onStdErrNotification, claudeApiKey, onPendingRequest, getRoots) {
41877
43397
  super(
41878
43398
  { name: "mcpjam-inspector", version: packageJson.version },
41879
43399
  {
@@ -41901,11 +43421,16 @@ class MCPJamClient extends Client {
41901
43421
  __publicField(this, "onPendingRequest");
41902
43422
  __publicField(this, "getRoots");
41903
43423
  __publicField(this, "addRequestHistory");
43424
+ __publicField(this, "addClientLog");
41904
43425
  __publicField(this, "is401Error", (error) => {
41905
43426
  return error instanceof SseError && error.code === 401 || error instanceof Error && error.message.includes("401") || error instanceof Error && error.message.includes("Unauthorized");
41906
43427
  });
41907
43428
  __publicField(this, "handleAuthError", async (error) => {
41908
43429
  if (this.is401Error(error)) {
43430
+ this.addClientLog(
43431
+ "Authentication error detected, attempting OAuth flow",
43432
+ "warn"
43433
+ );
41909
43434
  if (this.serverConfig.transportType !== "stdio" && "url" in this.serverConfig && this.serverConfig.url) {
41910
43435
  const serverAuthProvider = new InspectorOAuthClientProvider(
41911
43436
  this.serverConfig.url.toString()
@@ -41913,6 +43438,11 @@ class MCPJamClient extends Client {
41913
43438
  const result = await auth(serverAuthProvider, {
41914
43439
  serverUrl: this.serverConfig.url.toString()
41915
43440
  });
43441
+ if (result === "AUTHORIZED") {
43442
+ this.addClientLog("OAuth authentication successful", "info");
43443
+ } else {
43444
+ this.addClientLog("OAuth authentication failed", "error");
43445
+ }
41916
43446
  return result === "AUTHORIZED";
41917
43447
  }
41918
43448
  }
@@ -41924,10 +43454,13 @@ class MCPJamClient extends Client {
41924
43454
  apiKey: newApiKey,
41925
43455
  dangerouslyAllowBrowser: true
41926
43456
  });
43457
+ this.addClientLog("Anthropic API key updated", "info");
41927
43458
  }
41928
43459
  });
41929
43460
  __publicField(this, "handleCompletion", async (ref2, argName, value, signal) => {
43461
+ var _a2;
41930
43462
  if (!this.completionsSupported) {
43463
+ this.addClientLog("Completions not supported by server", "debug");
41931
43464
  return [];
41932
43465
  }
41933
43466
  const request = {
@@ -41941,19 +43474,31 @@ class MCPJamClient extends Client {
41941
43474
  }
41942
43475
  };
41943
43476
  try {
43477
+ this.addClientLog(`Requesting completion for ${argName}`, "debug");
41944
43478
  const response = await this.makeRequest(request, CompleteResultSchema, {
41945
43479
  signal,
41946
43480
  suppressToast: true
41947
43481
  });
43482
+ const completionCount = ((_a2 = response == null ? void 0 : response.completion.values) == null ? void 0 : _a2.length) || 0;
43483
+ this.addClientLog(
43484
+ `Received ${completionCount} completion suggestions`,
43485
+ "debug"
43486
+ );
41948
43487
  return (response == null ? void 0 : response.completion.values) || [];
41949
43488
  } catch (e) {
41950
43489
  if (e instanceof McpError && e.code === ErrorCode.MethodNotFound) {
41951
43490
  this.completionsSupported = false;
43491
+ this.addClientLog(
43492
+ "Completions disabled - server does not support them",
43493
+ "warn"
43494
+ );
41952
43495
  return [];
41953
43496
  }
43497
+ const errorMessage = e instanceof Error ? e.message : String(e);
43498
+ this.addClientLog(`Completion request failed: ${errorMessage}`, "error");
41954
43499
  toast({
41955
43500
  title: "Error",
41956
- description: e instanceof Error ? e.message : String(e),
43501
+ description: errorMessage,
41957
43502
  variant: "destructive"
41958
43503
  });
41959
43504
  throw e;
@@ -41979,6 +43524,7 @@ class MCPJamClient extends Client {
41979
43524
  this.onPendingRequest = onPendingRequest;
41980
43525
  this.getRoots = getRoots;
41981
43526
  this.addRequestHistory = addRequestHistory;
43527
+ this.addClientLog = addClientLog;
41982
43528
  }
41983
43529
  async connectStdio() {
41984
43530
  var _a2;
@@ -42005,13 +43551,27 @@ class MCPJamClient extends Client {
42005
43551
  };
42006
43552
  this.mcpProxyServerUrl = serverUrl;
42007
43553
  try {
43554
+ const command = "command" in this.serverConfig ? this.serverConfig.command : "unknown";
43555
+ this.addClientLog(
43556
+ `Connecting to MCP server via stdio: ${command}`,
43557
+ "info"
43558
+ );
42008
43559
  this.clientTransport = new SSEClientTransport(
42009
43560
  serverUrl,
42010
43561
  transportOptions
42011
43562
  );
42012
43563
  await this.connect(this.clientTransport);
42013
43564
  this.connectionStatus = "connected";
43565
+ this.addClientLog(
43566
+ "Successfully connected to MCP server via stdio",
43567
+ "info"
43568
+ );
42014
43569
  } catch (error) {
43570
+ const errorMessage = error instanceof Error ? error.message : String(error);
43571
+ this.addClientLog(
43572
+ `Failed to connect to MCP server via stdio: ${errorMessage}`,
43573
+ "error"
43574
+ );
42015
43575
  console.error("Error connecting to MCP server:", error);
42016
43576
  this.connectionStatus = "error";
42017
43577
  throw error;
@@ -42038,9 +43598,19 @@ class MCPJamClient extends Client {
42038
43598
  transportOptions
42039
43599
  );
42040
43600
  this.mcpProxyServerUrl = serverUrl;
43601
+ this.addClientLog(
43602
+ `Connecting to MCP server via SSE: ${this.serverConfig.url}`,
43603
+ "info"
43604
+ );
42041
43605
  await this.connect(this.clientTransport);
42042
43606
  this.connectionStatus = "connected";
43607
+ this.addClientLog("Successfully connected to MCP server via SSE", "info");
42043
43608
  } catch (error) {
43609
+ const errorMessage = error instanceof Error ? error.message : String(error);
43610
+ this.addClientLog(
43611
+ `Failed to connect to MCP server via SSE: ${errorMessage}`,
43612
+ "error"
43613
+ );
42044
43614
  console.error("Error connecting to MCP server:", error);
42045
43615
  this.connectionStatus = "error";
42046
43616
  throw error;
@@ -42070,9 +43640,22 @@ class MCPJamClient extends Client {
42070
43640
  transportOptions
42071
43641
  );
42072
43642
  this.mcpProxyServerUrl = serverUrl;
43643
+ this.addClientLog(
43644
+ `Connecting to MCP server via Streamable HTTP: ${this.serverConfig.url}`,
43645
+ "info"
43646
+ );
42073
43647
  await this.connect(this.clientTransport);
42074
43648
  this.connectionStatus = "connected";
43649
+ this.addClientLog(
43650
+ "Successfully connected to MCP server via Streamable HTTP",
43651
+ "info"
43652
+ );
42075
43653
  } catch (error) {
43654
+ const errorMessage = error instanceof Error ? error.message : String(error);
43655
+ this.addClientLog(
43656
+ `Failed to connect to MCP server via Streamable HTTP: ${errorMessage}`,
43657
+ "error"
43658
+ );
42076
43659
  console.error("Error connecting to MCP server:", error);
42077
43660
  this.connectionStatus = "error";
42078
43661
  throw error;
@@ -42083,12 +43666,20 @@ class MCPJamClient extends Client {
42083
43666
  const proxyHealthUrl = new URL(
42084
43667
  `${getMCPProxyAddress(this.inspectorConfig)}/health`
42085
43668
  );
43669
+ this.addClientLog("Checking MCP proxy server health", "debug");
42086
43670
  const proxyHealthResponse = await fetch(proxyHealthUrl);
42087
43671
  const proxyHealth = await proxyHealthResponse.json();
42088
43672
  if ((proxyHealth == null ? void 0 : proxyHealth.status) !== "ok") {
43673
+ this.addClientLog("MCP Proxy Server is not healthy", "error");
42089
43674
  throw new Error("MCP Proxy Server is not healthy");
42090
43675
  }
43676
+ this.addClientLog("MCP proxy server health check passed", "debug");
42091
43677
  } catch (e) {
43678
+ const errorMessage = e instanceof Error ? e.message : String(e);
43679
+ this.addClientLog(
43680
+ `Failed to connect to MCP Proxy Server: ${errorMessage}`,
43681
+ "error"
43682
+ );
42092
43683
  console.error("Couldn't connect to MCP Proxy Server", e);
42093
43684
  throw e;
42094
43685
  }
@@ -42100,11 +43691,20 @@ class MCPJamClient extends Client {
42100
43691
  await this.checkProxyHealth();
42101
43692
  } catch {
42102
43693
  this.connectionStatus = "error-connecting-to-proxy";
43694
+ this.addClientLog("Failed to connect to proxy server", "error");
42103
43695
  return;
42104
43696
  }
42105
43697
  try {
43698
+ this.addClientLog(
43699
+ `Attempting to connect to MCP server (attempt ${retryCount + 1}/${MAX_RETRIES + 1})`,
43700
+ "info"
43701
+ );
42106
43702
  const headers = {};
42107
43703
  if (this.serverConfig.transportType !== "stdio" && "url" in this.serverConfig && this.serverConfig.url) {
43704
+ this.addClientLog(
43705
+ "Setting up OAuth authentication for HTTP transport",
43706
+ "debug"
43707
+ );
42108
43708
  const serverAuthProvider = new InspectorOAuthClientProvider(
42109
43709
  this.serverConfig.url.toString()
42110
43710
  );
@@ -42112,10 +43712,23 @@ class MCPJamClient extends Client {
42112
43712
  if (token) {
42113
43713
  const authHeaderName = this.headerName || "Authorization";
42114
43714
  headers[authHeaderName] = `Bearer ${token}`;
43715
+ this.addClientLog(
43716
+ "Bearer token configured for authentication",
43717
+ "debug"
43718
+ );
43719
+ } else {
43720
+ this.addClientLog(
43721
+ "No bearer token available for authentication",
43722
+ "warn"
43723
+ );
42115
43724
  }
42116
43725
  } else if (this.bearerToken) {
42117
43726
  const authHeaderName = this.headerName || "Authorization";
42118
43727
  headers[authHeaderName] = `Bearer ${this.bearerToken}`;
43728
+ this.addClientLog(
43729
+ "Bearer token configured for stdio transport",
43730
+ "debug"
43731
+ );
42119
43732
  }
42120
43733
  this.headers = { ...this.headers, ...headers };
42121
43734
  if (this.onStdErrNotification) {
@@ -42123,6 +43736,7 @@ class MCPJamClient extends Client {
42123
43736
  StdErrNotificationSchema,
42124
43737
  this.onStdErrNotification
42125
43738
  );
43739
+ this.addClientLog("StdErr notification handler configured", "debug");
42126
43740
  }
42127
43741
  try {
42128
43742
  switch (this.serverConfig.transportType) {
@@ -42137,7 +43751,10 @@ class MCPJamClient extends Client {
42137
43751
  break;
42138
43752
  }
42139
43753
  this.serverCapabilities = this.getServerCapabilities() ?? null;
42140
- console.log("capabilities", this.serverCapabilities);
43754
+ this.addClientLog(
43755
+ `Server capabilities retrieved: ${JSON.stringify(this.serverCapabilities)}`,
43756
+ "debug"
43757
+ );
42141
43758
  const initializeRequest = {
42142
43759
  method: "initialize"
42143
43760
  };
@@ -42146,7 +43763,13 @@ class MCPJamClient extends Client {
42146
43763
  serverInfo: this.getServerVersion(),
42147
43764
  instructions: this.getInstructions()
42148
43765
  });
43766
+ this.addClientLog("MCP client initialization completed", "info");
42149
43767
  } catch (error) {
43768
+ const errorMessage = error instanceof Error ? error.message : String(error);
43769
+ this.addClientLog(
43770
+ `Failed to connect to MCP Server via the MCP Inspector Proxy: ${errorMessage}`,
43771
+ "error"
43772
+ );
42150
43773
  console.error(
42151
43774
  `Failed to connect to MCP Server via the MCP Inspector Proxy: ${this.getMCPProxyServerUrl()}:`,
42152
43775
  error
@@ -42154,14 +43777,19 @@ class MCPJamClient extends Client {
42154
43777
  if (retryCount < MAX_RETRIES) {
42155
43778
  const shouldRetry = await this.handleAuthError(error);
42156
43779
  if (shouldRetry) {
42157
- console.log(
42158
- `Retrying connection (attempt ${retryCount + 1}/${MAX_RETRIES})`
43780
+ this.addClientLog(
43781
+ `Retrying connection (attempt ${retryCount + 1}/${MAX_RETRIES})`,
43782
+ "info"
42159
43783
  );
42160
43784
  return this.connectToServer(void 0, retryCount + 1);
42161
43785
  }
42162
43786
  }
42163
43787
  if (this.is401Error(error)) {
42164
43788
  this.connectionStatus = "error";
43789
+ this.addClientLog(
43790
+ "Authentication failed, connection terminated",
43791
+ "error"
43792
+ );
42165
43793
  return;
42166
43794
  }
42167
43795
  throw error;
@@ -42180,9 +43808,16 @@ class MCPJamClient extends Client {
42180
43808
  var _a3;
42181
43809
  return { roots: ((_a3 = this.getRoots) == null ? void 0 : _a3.call(this)) ?? [] };
42182
43810
  });
43811
+ this.addClientLog("Roots request handler configured", "debug");
42183
43812
  }
42184
43813
  this.connectionStatus = "connected";
43814
+ this.addClientLog(
43815
+ "MCP client connection established successfully",
43816
+ "info"
43817
+ );
42185
43818
  } catch (e) {
43819
+ const errorMessage = e instanceof Error ? e.message : String(e);
43820
+ this.addClientLog(`Connection failed: ${errorMessage}`, "error");
42186
43821
  console.error(e);
42187
43822
  this.connectionStatus = "error";
42188
43823
  }
@@ -42195,6 +43830,7 @@ class MCPJamClient extends Client {
42195
43830
  }
42196
43831
  async makeRequest(request, schema, options) {
42197
43832
  console.log("makeRequestTriggered");
43833
+ this.addClientLog(`Making MCP request: ${request.method}`, "debug");
42198
43834
  try {
42199
43835
  const abortController = new AbortController();
42200
43836
  const mcpRequestOptions = {
@@ -42205,14 +43841,20 @@ class MCPJamClient extends Client {
42205
43841
  };
42206
43842
  if (mcpRequestOptions.resetTimeoutOnProgress) {
42207
43843
  mcpRequestOptions.onprogress = (_params) => {
43844
+ this.addClientLog("Progress notification received", "debug");
42208
43845
  };
42209
43846
  }
42210
43847
  let response;
42211
43848
  try {
42212
43849
  response = await this.request(request, schema, mcpRequestOptions);
43850
+ this.addClientLog(`MCP request successful: ${request.method}`, "info");
42213
43851
  this.addRequestHistory(request, response);
42214
43852
  } catch (error) {
42215
43853
  const errorMessage = error instanceof Error ? error.message : String(error);
43854
+ this.addClientLog(
43855
+ `MCP request failed: ${request.method} - ${errorMessage}`,
43856
+ "error"
43857
+ );
42216
43858
  this.addRequestHistory(request, { error: errorMessage });
42217
43859
  throw error;
42218
43860
  }
@@ -42220,6 +43862,10 @@ class MCPJamClient extends Client {
42220
43862
  } catch (e) {
42221
43863
  if (!(options == null ? void 0 : options.suppressToast)) {
42222
43864
  const errorString = e.message ?? String(e);
43865
+ this.addClientLog(
43866
+ `Request error (toast shown): ${errorString}`,
43867
+ "error"
43868
+ );
42223
43869
  toast({
42224
43870
  title: "Error",
42225
43871
  description: errorString,
@@ -42230,10 +43876,13 @@ class MCPJamClient extends Client {
42230
43876
  }
42231
43877
  }
42232
43878
  async tools() {
43879
+ this.addClientLog("Listing available tools", "debug");
42233
43880
  const tools = await this.listTools();
43881
+ this.addClientLog(`Found ${tools.tools.length} tools`, "info");
42234
43882
  return tools;
42235
43883
  }
42236
43884
  async disconnect() {
43885
+ this.addClientLog("Disconnecting from MCP server", "info");
42237
43886
  await this.close();
42238
43887
  this.connectionStatus = "disconnected";
42239
43888
  if (this.serverConfig.transportType !== "stdio") {
@@ -42241,21 +43890,34 @@ class MCPJamClient extends Client {
42241
43890
  this.serverConfig.url.toString()
42242
43891
  );
42243
43892
  authProvider.clear();
43893
+ this.addClientLog("OAuth tokens cleared", "debug");
42244
43894
  }
42245
43895
  this.serverCapabilities = null;
43896
+ this.addClientLog("MCP client disconnected successfully", "info");
42246
43897
  }
42247
43898
  async setServerCapabilities(capabilities) {
42248
43899
  this.serverCapabilities = capabilities;
43900
+ this.addClientLog("Server capabilities updated", "debug");
42249
43901
  }
42250
43902
  async processQuery(query, tools, onUpdate, model = "claude-3-5-sonnet-latest") {
42251
43903
  if (!this.anthropic) {
42252
- throw new Error("Anthropic client not initialized");
43904
+ const errorMessage = "Anthropic client not initialized";
43905
+ this.addClientLog(errorMessage, "error");
43906
+ throw new Error(errorMessage);
42253
43907
  }
43908
+ this.addClientLog(
43909
+ `Processing query with ${tools.length} tools using model ${model}`,
43910
+ "info"
43911
+ );
42254
43912
  const context = this.initializeQueryContext(query, tools, model);
42255
43913
  const response = await this.makeInitialApiCall(context);
42256
43914
  return this.processIterations(response, context, onUpdate);
42257
43915
  }
42258
43916
  initializeQueryContext(query, tools, model) {
43917
+ this.addClientLog(
43918
+ `Initializing query context with ${tools.length} tools`,
43919
+ "debug"
43920
+ );
42259
43921
  return {
42260
43922
  messages: [{ role: "user", content: query }],
42261
43923
  finalText: [],
@@ -42265,6 +43927,7 @@ class MCPJamClient extends Client {
42265
43927
  };
42266
43928
  }
42267
43929
  async makeInitialApiCall(context) {
43930
+ this.addClientLog("Making initial API call to Anthropic", "debug");
42268
43931
  return this.anthropic.messages.create({
42269
43932
  model: context.model,
42270
43933
  max_tokens: 1e3,
@@ -42277,21 +43940,34 @@ class MCPJamClient extends Client {
42277
43940
  let iteration = 0;
42278
43941
  while (iteration < context.MAX_ITERATIONS) {
42279
43942
  iteration++;
43943
+ this.addClientLog(
43944
+ `Processing iteration ${iteration}/${context.MAX_ITERATIONS}`,
43945
+ "debug"
43946
+ );
42280
43947
  const iterationResult = await this.processIteration(response, context);
42281
43948
  this.sendIterationUpdate(iterationResult.content, onUpdate);
42282
43949
  if (!iterationResult.hasToolUse) {
43950
+ this.addClientLog("No tool use detected, ending iterations", "debug");
42283
43951
  break;
42284
43952
  }
42285
43953
  try {
42286
43954
  response = await this.makeFollowUpApiCall(context);
42287
43955
  } catch (error) {
42288
43956
  const errorMessage = `[API Error: ${error}]`;
43957
+ this.addClientLog(
43958
+ `API error in iteration ${iteration}: ${error}`,
43959
+ "error"
43960
+ );
42289
43961
  context.finalText.push(errorMessage);
42290
43962
  this.sendIterationUpdate(errorMessage, onUpdate);
42291
43963
  break;
42292
43964
  }
42293
43965
  }
42294
43966
  this.handleMaxIterationsWarning(iteration, context, onUpdate);
43967
+ this.addClientLog(
43968
+ `Query processing completed in ${iteration} iterations`,
43969
+ "info"
43970
+ );
42295
43971
  return context.finalText.join("\n");
42296
43972
  }
42297
43973
  async processIteration(response, context) {
@@ -42308,6 +43984,7 @@ class MCPJamClient extends Client {
42308
43984
  );
42309
43985
  } else if (content.type === "tool_use") {
42310
43986
  hasToolUse = true;
43987
+ this.addClientLog(`Tool use detected: ${content.name}`, "debug");
42311
43988
  await this.handleToolUse(
42312
43989
  content,
42313
43990
  iterationContent,
@@ -42332,12 +44009,18 @@ class MCPJamClient extends Client {
42332
44009
  iterationContent.push(toolMessage);
42333
44010
  context.finalText.push(toolMessage);
42334
44011
  try {
44012
+ this.addClientLog(`Executing tool: ${content.name}`, "debug");
42335
44013
  await this.executeToolAndUpdateMessages(
42336
44014
  content,
42337
44015
  context,
42338
44016
  assistantContent
42339
44017
  );
44018
+ this.addClientLog(`Tool execution successful: ${content.name}`, "debug");
42340
44019
  } catch (error) {
44020
+ this.addClientLog(
44021
+ `Tool execution failed: ${content.name} - ${error}`,
44022
+ "error"
44023
+ );
42341
44024
  this.handleToolError(
42342
44025
  error,
42343
44026
  content,
@@ -42395,6 +44078,7 @@ class MCPJamClient extends Client {
42395
44078
  });
42396
44079
  }
42397
44080
  async makeFollowUpApiCall(context) {
44081
+ this.addClientLog("Making follow-up API call to Anthropic", "debug");
42398
44082
  return this.anthropic.messages.create({
42399
44083
  model: context.model,
42400
44084
  max_tokens: 1e3,
@@ -42412,11 +44096,16 @@ class MCPJamClient extends Client {
42412
44096
  handleMaxIterationsWarning(iteration, context, onUpdate) {
42413
44097
  if (iteration >= context.MAX_ITERATIONS) {
42414
44098
  const warningMessage = `[Warning: Reached maximum iterations (${context.MAX_ITERATIONS}). Stopping to prevent excessive API usage.]`;
44099
+ this.addClientLog(
44100
+ `Maximum iterations reached (${context.MAX_ITERATIONS})`,
44101
+ "warn"
44102
+ );
42415
44103
  context.finalText.push(warningMessage);
42416
44104
  this.sendIterationUpdate(warningMessage, onUpdate);
42417
44105
  }
42418
44106
  }
42419
44107
  async chatLoop(tools) {
44108
+ this.addClientLog("Starting interactive chat loop", "info");
42420
44109
  const rl = readline.createInterface({
42421
44110
  input: process.stdin,
42422
44111
  output: process.stdout
@@ -42427,16 +44116,23 @@ class MCPJamClient extends Client {
42427
44116
  while (true) {
42428
44117
  const message = await rl.question("\nQuery: ");
42429
44118
  if (message.toLowerCase() === "quit") {
44119
+ this.addClientLog("Chat loop terminated by user", "info");
42430
44120
  break;
42431
44121
  }
44122
+ this.addClientLog(
44123
+ `Processing user query: ${message.substring(0, 50)}${message.length > 50 ? "..." : ""}`,
44124
+ "debug"
44125
+ );
42432
44126
  const response = await this.processQuery(message, tools);
42433
44127
  console.log("\n" + response);
42434
44128
  }
42435
44129
  } finally {
42436
44130
  rl.close();
44131
+ this.addClientLog("Chat loop interface closed", "debug");
42437
44132
  }
42438
44133
  }
42439
44134
  async cleanup() {
44135
+ this.addClientLog("Cleaning up MCP client", "info");
42440
44136
  await this.close();
42441
44137
  }
42442
44138
  }
@@ -42452,6 +44148,7 @@ class MCPJamAgent {
42452
44148
  __publicField(this, "onPendingRequest");
42453
44149
  __publicField(this, "getRoots");
42454
44150
  __publicField(this, "addRequestHistory");
44151
+ __publicField(this, "addClientLog");
42455
44152
  this.serverConfigs = options.servers;
42456
44153
  this.config = options.config || createDefaultConfig();
42457
44154
  this.bearerToken = options.bearerToken;
@@ -42461,6 +44158,7 @@ class MCPJamAgent {
42461
44158
  this.onPendingRequest = options.onPendingRequest;
42462
44159
  this.getRoots = options.getRoots;
42463
44160
  this.addRequestHistory = options.addRequestHistory;
44161
+ this.addClientLog = options.addClientLog;
42464
44162
  }
42465
44163
  // Add or update a server configuration
42466
44164
  addServer(name, config) {
@@ -42545,26 +44243,6 @@ class MCPJamAgent {
42545
44243
  if (existingClient && existingClient.connectionStatus === "connected") {
42546
44244
  return existingClient;
42547
44245
  }
42548
- if (this.isRemoteServer(config)) {
42549
- const connectedRemoteServerName = this.getConnectedRemoteServerName();
42550
- if (connectedRemoteServerName && connectedRemoteServerName !== name) {
42551
- console.log(
42552
- `Automatically disconnecting existing remote server: ${connectedRemoteServerName}`
42553
- );
42554
- await this.disconnectFromServer(connectedRemoteServerName);
42555
- const connectedConfig = this.serverConfigs[connectedRemoteServerName];
42556
- if (connectedConfig && "url" in connectedConfig && connectedConfig.url) {
42557
- const { InspectorOAuthClientProvider: InspectorOAuthClientProvider2 } = await __vitePreload(async () => {
42558
- const { InspectorOAuthClientProvider: InspectorOAuthClientProvider3 } = await Promise.resolve().then(() => auth$1);
42559
- return { InspectorOAuthClientProvider: InspectorOAuthClientProvider3 };
42560
- }, true ? void 0 : void 0);
42561
- const oldAuthProvider = new InspectorOAuthClientProvider2(
42562
- connectedConfig.url.toString()
42563
- );
42564
- oldAuthProvider.clear();
42565
- }
42566
- }
42567
- }
42568
44246
  if (existingClient && existingClient.connectionStatus === "disconnected") {
42569
44247
  try {
42570
44248
  await existingClient.connectToServer();
@@ -42580,6 +44258,8 @@ class MCPJamAgent {
42580
44258
  // config (second parameter)
42581
44259
  this.addRequestHistory,
42582
44260
  // addRequestHistory
44261
+ this.addClientLog,
44262
+ // addClientLog
42583
44263
  this.bearerToken,
42584
44264
  // bearerToken
42585
44265
  this.headerName,
@@ -42717,7 +44397,6 @@ class MCPJamAgent {
42717
44397
  ).length;
42718
44398
  if (errorCount > 0) return "error";
42719
44399
  if (connectedCount === connections.length) return "connected";
42720
- if (connectedCount > 0) return "partial";
42721
44400
  return "disconnected";
42722
44401
  }
42723
44402
  // Check if there are any connected remote servers (HTTP/SSE)
@@ -42740,12 +44419,8 @@ class MCPJamAgent {
42740
44419
  }
42741
44420
  return null;
42742
44421
  }
42743
- // Check if a server config is for a remote connection
42744
- isRemoteServer(config) {
42745
- return config.transportType !== "stdio";
42746
- }
42747
44422
  }
42748
- const useConnectionState = (addRequestHistory) => {
44423
+ const useConnectionState = (addRequestHistory, addClientLog) => {
42749
44424
  const [mcpAgent, setMcpAgent] = reactExports.useState(null);
42750
44425
  const [sidebarUpdateTrigger, setSidebarUpdateTrigger] = reactExports.useState(0);
42751
44426
  const forceUpdateSidebar = reactExports.useCallback(() => {
@@ -42766,7 +44441,8 @@ const useConnectionState = (addRequestHistory) => {
42766
44441
  onStdErrNotification,
42767
44442
  onPendingRequest,
42768
44443
  getRoots,
42769
- addRequestHistory
44444
+ addRequestHistory,
44445
+ addClientLog
42770
44446
  };
42771
44447
  const agent = new MCPJamAgent(options);
42772
44448
  try {
@@ -42779,7 +44455,7 @@ const useConnectionState = (addRequestHistory) => {
42779
44455
  throw error;
42780
44456
  }
42781
44457
  },
42782
- [addRequestHistory]
44458
+ [addRequestHistory, addClientLog]
42783
44459
  );
42784
44460
  const createAgentWithoutConnecting = reactExports.useCallback(
42785
44461
  async (serverConfigs, config, bearerToken, headerName, claudeApiKey, onStdErrNotification, onPendingRequest, getRoots) => {
@@ -42792,13 +44468,14 @@ const useConnectionState = (addRequestHistory) => {
42792
44468
  onStdErrNotification,
42793
44469
  onPendingRequest,
42794
44470
  getRoots,
42795
- addRequestHistory
44471
+ addRequestHistory,
44472
+ addClientLog
42796
44473
  };
42797
44474
  const agent = new MCPJamAgent(options);
42798
44475
  setMcpAgent(agent);
42799
44476
  return agent;
42800
44477
  },
42801
- [addRequestHistory]
44478
+ [addRequestHistory, addClientLog]
42802
44479
  );
42803
44480
  const addServer = reactExports.useCallback(
42804
44481
  async (name, serverConfig, config, bearerToken, headerName, claudeApiKey, onStdErrNotification, onPendingRequest, getRoots) => {
@@ -42814,7 +44491,8 @@ const useConnectionState = (addRequestHistory) => {
42814
44491
  onStdErrNotification,
42815
44492
  onPendingRequest,
42816
44493
  getRoots,
42817
- addRequestHistory
44494
+ addRequestHistory,
44495
+ addClientLog
42818
44496
  };
42819
44497
  const agent = new MCPJamAgent(options);
42820
44498
  try {
@@ -42848,7 +44526,7 @@ const useConnectionState = (addRequestHistory) => {
42848
44526
  }
42849
44527
  }
42850
44528
  },
42851
- [mcpAgent, forceUpdateSidebar, addRequestHistory]
44529
+ [mcpAgent, forceUpdateSidebar, addRequestHistory, addClientLog]
42852
44530
  );
42853
44531
  const removeServer = reactExports.useCallback(
42854
44532
  async (serverName) => {
@@ -42970,41 +44648,85 @@ const useMCPOperations = () => {
42970
44648
  const [stdErrNotifications, setStdErrNotifications] = reactExports.useState([]);
42971
44649
  const [roots, setRoots] = reactExports.useState([]);
42972
44650
  const [pendingSampleRequests, setPendingSampleRequests] = reactExports.useState([]);
42973
- const [requestHistory, setRequestHistory] = reactExports.useState([]);
44651
+ const [requestHistory, setRequestHistory] = reactExports.useState(
44652
+ []
44653
+ );
44654
+ const [clientLogs, setClientLogs] = reactExports.useState([]);
42974
44655
  const progressTokenRef = reactExports.useRef(0);
42975
44656
  const clearError = reactExports.useCallback((tabKey) => {
42976
44657
  setErrors((prev) => ({ ...prev, [tabKey]: null }));
42977
44658
  }, []);
42978
44659
  const addRequestHistory = reactExports.useCallback(
42979
- (request, response) => {
44660
+ (request, response, timestamp, latency) => {
42980
44661
  const requestEntry = {
42981
44662
  request: JSON.stringify(request, null, 2),
42982
- response: response ? JSON.stringify(response, null, 2) : void 0
44663
+ response: response ? JSON.stringify(response, null, 2) : void 0,
44664
+ timestamp: timestamp || (/* @__PURE__ */ new Date()).toISOString(),
44665
+ latency
42983
44666
  };
42984
44667
  setRequestHistory((prev) => [...prev, requestEntry]);
42985
44668
  },
42986
44669
  []
42987
44670
  );
44671
+ const getRequestHistory = reactExports.useCallback(() => {
44672
+ return requestHistory;
44673
+ }, [requestHistory]);
44674
+ const clearRequestHistory = reactExports.useCallback(() => {
44675
+ setRequestHistory([]);
44676
+ }, []);
44677
+ const addClientLog = reactExports.useCallback(
44678
+ (message, level) => {
44679
+ setClientLogs((prev) => [
44680
+ ...prev,
44681
+ { message, level, timestamp: (/* @__PURE__ */ new Date()).toISOString() }
44682
+ ]);
44683
+ },
44684
+ []
44685
+ );
44686
+ const clearClientLogs = reactExports.useCallback(() => {
44687
+ setClientLogs([]);
44688
+ }, []);
44689
+ const getClientLogs = reactExports.useCallback(() => {
44690
+ return clientLogs;
44691
+ }, [clientLogs]);
42988
44692
  const listResources = reactExports.useCallback(
42989
44693
  async (mcpAgent, selectedServerName) => {
42990
44694
  if (!mcpAgent) return;
44695
+ const startTime = performance.now();
44696
+ const operationTimestamp = (/* @__PURE__ */ new Date()).toISOString();
42991
44697
  if (selectedServerName === "all") {
42992
44698
  const allServerResources = await mcpAgent.getAllResources();
42993
44699
  const flatResources = allServerResources.flatMap(
42994
44700
  ({ resources: resources2 }) => resources2
42995
44701
  );
44702
+ const endTime = performance.now();
44703
+ const latency = Math.round(endTime - startTime);
44704
+ addClientLog(
44705
+ `Listed ${flatResources.length} resources from all servers`,
44706
+ "info"
44707
+ );
42996
44708
  addRequestHistory(
42997
44709
  { method: "resources/list/all" },
42998
- { resources: flatResources }
44710
+ { resources: flatResources },
44711
+ operationTimestamp,
44712
+ latency
42999
44713
  );
43000
44714
  setResources(flatResources);
43001
44715
  } else {
43002
44716
  const client2 = mcpAgent.getClient(selectedServerName);
43003
44717
  if (client2) {
43004
44718
  const resourcesResponse = await client2.listResources();
44719
+ const endTime = performance.now();
44720
+ const latency = Math.round(endTime - startTime);
44721
+ addClientLog(
44722
+ `Listed ${resourcesResponse.resources.length} resources from ${selectedServerName}`,
44723
+ "info"
44724
+ );
43005
44725
  addRequestHistory(
43006
44726
  { method: "resources/list", server: selectedServerName },
43007
- { resources: resourcesResponse.resources }
44727
+ { resources: resourcesResponse.resources },
44728
+ operationTimestamp,
44729
+ latency
43008
44730
  );
43009
44731
  setResources(resourcesResponse.resources);
43010
44732
  }
@@ -43015,15 +44737,25 @@ const useMCPOperations = () => {
43015
44737
  const listResourceTemplates = reactExports.useCallback(
43016
44738
  async (mcpAgent, selectedServerName) => {
43017
44739
  if (!mcpAgent) return;
44740
+ const startTime = performance.now();
44741
+ const operationTimestamp = (/* @__PURE__ */ new Date()).toISOString();
43018
44742
  if (selectedServerName === "all") {
43019
44743
  const allServerResources = await mcpAgent.getAllResources();
43020
44744
  if (allServerResources.length > 0) {
43021
44745
  const client2 = mcpAgent.getClient(allServerResources[0].serverName);
43022
44746
  if (client2) {
43023
44747
  const templatesResponse = await client2.listResourceTemplates();
44748
+ const endTime = performance.now();
44749
+ const latency = Math.round(endTime - startTime);
44750
+ addClientLog(
44751
+ `Listed ${templatesResponse.resourceTemplates.length} resource templates from all servers`,
44752
+ "info"
44753
+ );
43024
44754
  addRequestHistory(
43025
44755
  { method: "resourceTemplates/list/all" },
43026
- { resourceTemplates: templatesResponse.resourceTemplates }
44756
+ { resourceTemplates: templatesResponse.resourceTemplates },
44757
+ operationTimestamp,
44758
+ latency
43027
44759
  );
43028
44760
  setResourceTemplates(templatesResponse.resourceTemplates);
43029
44761
  }
@@ -43032,9 +44764,17 @@ const useMCPOperations = () => {
43032
44764
  const client2 = mcpAgent.getClient(selectedServerName);
43033
44765
  if (client2) {
43034
44766
  const templatesResponse = await client2.listResourceTemplates();
44767
+ const endTime = performance.now();
44768
+ const latency = Math.round(endTime - startTime);
44769
+ addClientLog(
44770
+ `Listed ${templatesResponse.resourceTemplates.length} resource templates from ${selectedServerName}`,
44771
+ "info"
44772
+ );
43035
44773
  addRequestHistory(
43036
44774
  { method: "resourceTemplates/list", server: selectedServerName },
43037
- { resourceTemplates: templatesResponse.resourceTemplates }
44775
+ { resourceTemplates: templatesResponse.resourceTemplates },
44776
+ operationTimestamp,
44777
+ latency
43038
44778
  );
43039
44779
  setResourceTemplates(templatesResponse.resourceTemplates);
43040
44780
  }
@@ -43045,14 +44785,21 @@ const useMCPOperations = () => {
43045
44785
  const readResource = reactExports.useCallback(
43046
44786
  async (mcpAgent, selectedServerName, uri) => {
43047
44787
  if (!mcpAgent) return;
44788
+ const startTime = performance.now();
44789
+ const operationTimestamp = (/* @__PURE__ */ new Date()).toISOString();
43048
44790
  if (selectedServerName !== "all") {
43049
44791
  const result = await mcpAgent.readResourceFromServer(
43050
44792
  selectedServerName,
43051
44793
  uri
43052
44794
  );
44795
+ const endTime = performance.now();
44796
+ const latency = Math.round(endTime - startTime);
44797
+ addClientLog(`Read resource ${uri} from ${selectedServerName}`, "info");
43053
44798
  addRequestHistory(
43054
44799
  { method: "resources/read", server: selectedServerName, uri },
43055
- result
44800
+ result,
44801
+ operationTimestamp,
44802
+ latency
43056
44803
  );
43057
44804
  return result;
43058
44805
  } else {
@@ -43063,9 +44810,14 @@ const useMCPOperations = () => {
43063
44810
  serverName,
43064
44811
  uri
43065
44812
  );
44813
+ const endTime = performance.now();
44814
+ const latency = Math.round(endTime - startTime);
44815
+ addClientLog(`Read resource ${uri} from ${serverName}`, "info");
43066
44816
  addRequestHistory(
43067
44817
  { method: "resources/read", server: serverName, uri },
43068
- result
44818
+ result,
44819
+ operationTimestamp,
44820
+ latency
43069
44821
  );
43070
44822
  return result;
43071
44823
  }
@@ -43078,12 +44830,22 @@ const useMCPOperations = () => {
43078
44830
  const subscribeToResource = reactExports.useCallback(
43079
44831
  async (mcpAgent, selectedServerName, uri) => {
43080
44832
  if (!mcpAgent || selectedServerName === "all") return;
44833
+ const startTime = performance.now();
44834
+ const operationTimestamp = (/* @__PURE__ */ new Date()).toISOString();
43081
44835
  const client2 = mcpAgent.getClient(selectedServerName);
43082
44836
  if (client2) {
43083
44837
  const result = await client2.subscribeResource({ uri });
44838
+ const endTime = performance.now();
44839
+ const latency = Math.round(endTime - startTime);
44840
+ addClientLog(
44841
+ `Subscribed to resource ${uri} from ${selectedServerName}`,
44842
+ "info"
44843
+ );
43084
44844
  addRequestHistory(
43085
44845
  { method: "resources/subscribe", server: selectedServerName, uri },
43086
- result
44846
+ result,
44847
+ operationTimestamp,
44848
+ latency
43087
44849
  );
43088
44850
  return result;
43089
44851
  }
@@ -43093,12 +44855,22 @@ const useMCPOperations = () => {
43093
44855
  const unsubscribeFromResource = reactExports.useCallback(
43094
44856
  async (mcpAgent, selectedServerName, uri) => {
43095
44857
  if (!mcpAgent || selectedServerName === "all") return;
44858
+ const startTime = performance.now();
44859
+ const operationTimestamp = (/* @__PURE__ */ new Date()).toISOString();
43096
44860
  const client2 = mcpAgent.getClient(selectedServerName);
43097
44861
  if (client2) {
43098
44862
  const result = await client2.unsubscribeResource({ uri });
44863
+ const endTime = performance.now();
44864
+ const latency = Math.round(endTime - startTime);
44865
+ addClientLog(
44866
+ `Unsubscribed from resource ${uri} from ${selectedServerName}`,
44867
+ "info"
44868
+ );
43099
44869
  addRequestHistory(
43100
44870
  { method: "resources/unsubscribe", server: selectedServerName, uri },
43101
- result
44871
+ result,
44872
+ operationTimestamp,
44873
+ latency
43102
44874
  );
43103
44875
  return result;
43104
44876
  }
@@ -43108,21 +44880,39 @@ const useMCPOperations = () => {
43108
44880
  const listPrompts = reactExports.useCallback(
43109
44881
  async (mcpAgent, selectedServerName) => {
43110
44882
  if (!mcpAgent) return;
44883
+ const startTime = performance.now();
44884
+ const operationTimestamp = (/* @__PURE__ */ new Date()).toISOString();
43111
44885
  if (selectedServerName === "all") {
43112
44886
  const allServerPrompts = await mcpAgent.getAllPrompts();
43113
44887
  const flatPrompts = allServerPrompts.flatMap(({ prompts: prompts2 }) => prompts2);
44888
+ const endTime = performance.now();
44889
+ const latency = Math.round(endTime - startTime);
44890
+ addClientLog(
44891
+ `Listed ${flatPrompts.length} prompts from all servers`,
44892
+ "info"
44893
+ );
43114
44894
  addRequestHistory(
43115
44895
  { method: "prompts/list/all" },
43116
- { prompts: flatPrompts }
44896
+ { prompts: flatPrompts },
44897
+ operationTimestamp,
44898
+ latency
43117
44899
  );
43118
44900
  setPrompts(flatPrompts);
43119
44901
  } else {
43120
44902
  const client2 = mcpAgent.getClient(selectedServerName);
43121
44903
  if (client2) {
43122
44904
  const promptsResponse = await client2.listPrompts();
44905
+ const endTime = performance.now();
44906
+ const latency = Math.round(endTime - startTime);
44907
+ addClientLog(
44908
+ `Listed ${promptsResponse.prompts.length} prompts from ${selectedServerName}`,
44909
+ "info"
44910
+ );
43123
44911
  addRequestHistory(
43124
44912
  { method: "prompts/list", server: selectedServerName },
43125
- { prompts: promptsResponse.prompts }
44913
+ { prompts: promptsResponse.prompts },
44914
+ operationTimestamp,
44915
+ latency
43126
44916
  );
43127
44917
  setPrompts(promptsResponse.prompts);
43128
44918
  }
@@ -43133,15 +44923,22 @@ const useMCPOperations = () => {
43133
44923
  const getPrompt = reactExports.useCallback(
43134
44924
  async (mcpAgent, selectedServerName, name, args = {}) => {
43135
44925
  if (!mcpAgent) return;
44926
+ const startTime = performance.now();
44927
+ const operationTimestamp = (/* @__PURE__ */ new Date()).toISOString();
43136
44928
  if (selectedServerName !== "all") {
43137
44929
  const result = await mcpAgent.getPromptFromServer(
43138
44930
  selectedServerName,
43139
44931
  name,
43140
44932
  args
43141
44933
  );
44934
+ const endTime = performance.now();
44935
+ const latency = Math.round(endTime - startTime);
44936
+ addClientLog(`Got prompt ${name} from ${selectedServerName}`, "info");
43142
44937
  addRequestHistory(
43143
44938
  { method: "prompts/get", server: selectedServerName, name, args },
43144
- result
44939
+ result,
44940
+ operationTimestamp,
44941
+ latency
43145
44942
  );
43146
44943
  return result;
43147
44944
  } else {
@@ -43153,9 +44950,14 @@ const useMCPOperations = () => {
43153
44950
  name,
43154
44951
  args
43155
44952
  );
44953
+ const endTime = performance.now();
44954
+ const latency = Math.round(endTime - startTime);
44955
+ addClientLog(`Got prompt ${name} from ${serverName}`, "info");
43156
44956
  addRequestHistory(
43157
44957
  { method: "prompts/get", server: serverName, name, args },
43158
- result
44958
+ result,
44959
+ operationTimestamp,
44960
+ latency
43159
44961
  );
43160
44962
  return result;
43161
44963
  }
@@ -43168,18 +44970,39 @@ const useMCPOperations = () => {
43168
44970
  const listTools = reactExports.useCallback(
43169
44971
  async (mcpAgent, selectedServerName) => {
43170
44972
  if (!mcpAgent) return;
44973
+ const startTime = performance.now();
44974
+ const operationTimestamp = (/* @__PURE__ */ new Date()).toISOString();
43171
44975
  if (selectedServerName === "all") {
43172
44976
  const allServerTools = await mcpAgent.getAllTools();
43173
44977
  const flatTools = allServerTools.flatMap(({ tools: tools2 }) => tools2);
43174
- addRequestHistory({ method: "tools/list/all" }, { tools: flatTools });
44978
+ const endTime = performance.now();
44979
+ const latency = Math.round(endTime - startTime);
44980
+ addClientLog(
44981
+ `Listed ${flatTools.length} tools from all servers`,
44982
+ "info"
44983
+ );
44984
+ addRequestHistory(
44985
+ { method: "tools/list/all" },
44986
+ { tools: flatTools },
44987
+ operationTimestamp,
44988
+ latency
44989
+ );
43175
44990
  setTools(flatTools);
43176
44991
  } else {
43177
44992
  const client2 = mcpAgent.getClient(selectedServerName);
43178
44993
  if (client2) {
43179
44994
  const toolsResponse = await client2.tools();
44995
+ const endTime = performance.now();
44996
+ const latency = Math.round(endTime - startTime);
44997
+ addClientLog(
44998
+ `Listed ${toolsResponse.tools.length} tools from ${selectedServerName}`,
44999
+ "info"
45000
+ );
43180
45001
  addRequestHistory(
43181
- { method: "tools/list" },
43182
- { tools: toolsResponse.tools }
45002
+ { method: "tools/list", server: selectedServerName },
45003
+ { tools: toolsResponse.tools },
45004
+ operationTimestamp,
45005
+ latency
43183
45006
  );
43184
45007
  setTools(toolsResponse.tools);
43185
45008
  }
@@ -43190,6 +45013,8 @@ const useMCPOperations = () => {
43190
45013
  const callTool = reactExports.useCallback(
43191
45014
  async (mcpAgent, selectedServerName, name, params) => {
43192
45015
  if (!mcpAgent) return;
45016
+ const startTime = performance.now();
45017
+ const operationTimestamp = (/* @__PURE__ */ new Date()).toISOString();
43193
45018
  try {
43194
45019
  if (selectedServerName !== "all") {
43195
45020
  const result = await mcpAgent.callToolOnServer(
@@ -43197,9 +45022,14 @@ const useMCPOperations = () => {
43197
45022
  name,
43198
45023
  params
43199
45024
  );
45025
+ const endTime = performance.now();
45026
+ const latency = Math.round(endTime - startTime);
45027
+ addClientLog(`Called tool ${name} on ${selectedServerName}`, "info");
43200
45028
  addRequestHistory(
43201
45029
  { method: "tools/call", server: selectedServerName, name, params },
43202
- result
45030
+ result,
45031
+ operationTimestamp,
45032
+ latency
43203
45033
  );
43204
45034
  setToolResult(result);
43205
45035
  } else {
@@ -43211,9 +45041,14 @@ const useMCPOperations = () => {
43211
45041
  name,
43212
45042
  params
43213
45043
  );
45044
+ const endTime = performance.now();
45045
+ const latency = Math.round(endTime - startTime);
45046
+ addClientLog(`Called tool ${name} on ${serverName}`, "info");
43214
45047
  addRequestHistory(
43215
45048
  { method: "tools/call", server: serverName, name, params },
43216
- result
45049
+ result,
45050
+ operationTimestamp,
45051
+ latency
43217
45052
  );
43218
45053
  setToolResult(result);
43219
45054
  return;
@@ -43222,6 +45057,12 @@ const useMCPOperations = () => {
43222
45057
  throw new Error(`Tool ${name} not found on any server`);
43223
45058
  }
43224
45059
  } catch (e) {
45060
+ const endTime = performance.now();
45061
+ const latency = Math.round(endTime - startTime);
45062
+ addClientLog(
45063
+ `Error calling tool ${name} on ${selectedServerName}`,
45064
+ "error"
45065
+ );
43225
45066
  const toolResult2 = {
43226
45067
  content: [
43227
45068
  {
@@ -43233,7 +45074,9 @@ const useMCPOperations = () => {
43233
45074
  };
43234
45075
  addRequestHistory(
43235
45076
  { method: "tools/call", server: selectedServerName, name, params },
43236
- { error: e.message ?? String(e) }
45077
+ { error: e.message ?? String(e) },
45078
+ operationTimestamp,
45079
+ latency
43237
45080
  );
43238
45081
  setToolResult(toolResult2);
43239
45082
  }
@@ -43264,11 +45107,19 @@ const useMCPOperations = () => {
43264
45107
  if (!mcpAgent || selectedServerName === "all") {
43265
45108
  return [];
43266
45109
  }
45110
+ const startTime = performance.now();
45111
+ const operationTimestamp = (/* @__PURE__ */ new Date()).toISOString();
43267
45112
  const client2 = mcpAgent.getClient(selectedServerName);
43268
45113
  if (!client2) {
43269
45114
  return [];
43270
45115
  }
43271
45116
  const result = await client2.handleCompletion(ref2, argName, value, signal);
45117
+ const endTime = performance.now();
45118
+ const latency = Math.round(endTime - startTime);
45119
+ addClientLog(
45120
+ `Completed completion for ${ref2.type} ${ref2.name} on ${selectedServerName}`,
45121
+ "info"
45122
+ );
43272
45123
  addRequestHistory(
43273
45124
  {
43274
45125
  method: "completion",
@@ -43277,11 +45128,13 @@ const useMCPOperations = () => {
43277
45128
  argName,
43278
45129
  value
43279
45130
  },
43280
- { completions: result }
45131
+ { completions: result },
45132
+ operationTimestamp,
45133
+ latency
43281
45134
  );
43282
45135
  return result;
43283
45136
  },
43284
- [addRequestHistory]
45137
+ [addRequestHistory, addClientLog]
43285
45138
  );
43286
45139
  const handleApproveSampling = reactExports.useCallback(
43287
45140
  (id, result) => {
@@ -43310,12 +45163,6 @@ const useMCPOperations = () => {
43310
45163
  return updatedRequests;
43311
45164
  });
43312
45165
  }, []);
43313
- const getRequestHistory = reactExports.useCallback(() => {
43314
- return requestHistory;
43315
- }, [requestHistory]);
43316
- const clearRequestHistory = reactExports.useCallback(() => {
43317
- setRequestHistory([]);
43318
- }, []);
43319
45166
  return {
43320
45167
  // State
43321
45168
  resources,
@@ -43376,7 +45223,10 @@ const useMCPOperations = () => {
43376
45223
  handleRejectSampling,
43377
45224
  addRequestHistory,
43378
45225
  getRequestHistory,
43379
- clearRequestHistory
45226
+ clearRequestHistory,
45227
+ addClientLog,
45228
+ clearClientLogs,
45229
+ getClientLogs
43380
45230
  };
43381
45231
  };
43382
45232
  const CONFIG_LOCAL_STORAGE_KEY = "inspectorConfig_v1";
@@ -43506,7 +45356,10 @@ const App = () => {
43506
45356
  var _a2, _b;
43507
45357
  const serverState = useServerState();
43508
45358
  const mcpOperations = useMCPOperations();
43509
- const connectionState = useConnectionState(mcpOperations.addRequestHistory);
45359
+ const connectionState = useConnectionState(
45360
+ mcpOperations.addRequestHistory,
45361
+ mcpOperations.addClientLog
45362
+ );
43510
45363
  const configState = useConfigState();
43511
45364
  const rootsRef = reactExports.useRef(mcpOperations.roots);
43512
45365
  const nextRequestId = reactExports.useRef(0);
@@ -43516,6 +45369,7 @@ const App = () => {
43516
45369
  });
43517
45370
  const [isSidebarExpanded, setIsSidebarExpanded] = reactExports.useState(true);
43518
45371
  const [showStarModal, setShowStarModal] = reactExports.useState(false);
45372
+ const { addClientLog } = mcpOperations;
43519
45373
  reactExports.useEffect(() => {
43520
45374
  const handleHashChange = () => {
43521
45375
  const hash = window.location.hash.slice(1);
@@ -43544,7 +45398,7 @@ const App = () => {
43544
45398
  (notification) => {
43545
45399
  mcpOperations.setStdErrNotifications((prev) => [...prev, notification]);
43546
45400
  },
43547
- [mcpOperations.setStdErrNotifications]
45401
+ [mcpOperations]
43548
45402
  );
43549
45403
  const onPendingRequest = reactExports.useCallback(
43550
45404
  (request, resolve, reject) => {
@@ -43553,7 +45407,7 @@ const App = () => {
43553
45407
  { id: nextRequestId.current++, request, resolve, reject }
43554
45408
  ]);
43555
45409
  },
43556
- [mcpOperations.setPendingSampleRequests]
45410
+ [mcpOperations]
43557
45411
  );
43558
45412
  const getRootsCallback = reactExports.useCallback(() => rootsRef.current, []);
43559
45413
  const connectionStatus = connectionState.getConnectionStatus();
@@ -43565,10 +45419,11 @@ const App = () => {
43565
45419
  serverState.selectedServerName
43566
45420
  );
43567
45421
  const handleAddServer = reactExports.useCallback(
43568
- async (name, serverConfig) => {
43569
- console.log("🔧 Adding server without auto-connect:", {
45422
+ async (name, serverConfig, options = {}) => {
45423
+ console.log("🔧 Adding server with options:", {
43570
45424
  name,
43571
- serverConfig
45425
+ serverConfig,
45426
+ options
43572
45427
  });
43573
45428
  const shouldSelectNewServer = Object.keys(serverState.serverConfigs).length === 0;
43574
45429
  serverState.updateServerConfig(name, serverConfig);
@@ -43576,15 +45431,17 @@ const App = () => {
43576
45431
  serverState.setSelectedServerName(name);
43577
45432
  }
43578
45433
  if (!connectionState.mcpAgent) {
43579
- console.log(
43580
- "🆕 Creating agent with server config (no auto-connect)..."
45434
+ console.log("🆕 Creating agent with server config...");
45435
+ addClientLog(
45436
+ `🆕 Creating agent with server config (no auto-connect) ${name} ${JSON.stringify(serverConfig)}`,
45437
+ "info"
43581
45438
  );
43582
45439
  try {
43583
45440
  const allServerConfigs = {
43584
45441
  ...serverState.serverConfigs,
43585
45442
  [name]: serverConfig
43586
45443
  };
43587
- await connectionState.createAgentWithoutConnecting(
45444
+ const agent = await connectionState.createAgentWithoutConnecting(
43588
45445
  allServerConfigs,
43589
45446
  configState.config,
43590
45447
  configState.bearerToken,
@@ -43594,26 +45451,41 @@ const App = () => {
43594
45451
  onPendingRequest,
43595
45452
  getRootsCallback
43596
45453
  );
45454
+ if (options.autoConnect) {
45455
+ console.log("🔌 Auto-connecting to all servers...");
45456
+ await agent.connectToAllServers();
45457
+ console.log("✅ Successfully connected to all servers");
45458
+ serverState.setSelectedServerName(name);
45459
+ connectionState.forceUpdateSidebar();
45460
+ }
43597
45461
  } catch (error) {
43598
- console.error("❌ Failed to create agent:", error);
45462
+ console.error("❌ Failed to create agent and connect:", error);
43599
45463
  throw error;
43600
45464
  }
43601
45465
  } else {
43602
45466
  connectionState.mcpAgent.addServer(name, serverConfig);
43603
45467
  connectionState.forceUpdateSidebar();
45468
+ if (options.autoConnect) {
45469
+ console.log(`🔌 Auto-connecting to server: "${name}"`);
45470
+ try {
45471
+ serverState.setSelectedServerName(name);
45472
+ await connectionState.connectServer(name);
45473
+ console.log(`✅ Successfully auto-connected to "${name}"`);
45474
+ } catch (error) {
45475
+ console.error(`❌ Failed to auto-connect to "${name}":`, error);
45476
+ }
45477
+ }
43604
45478
  }
43605
45479
  return name;
43606
45480
  },
43607
45481
  [
43608
45482
  serverState,
43609
45483
  connectionState,
43610
- configState.config,
43611
- configState.bearerToken,
43612
- configState.headerName,
43613
- configState.claudeApiKey,
45484
+ configState,
43614
45485
  onStdErrNotification,
43615
45486
  onPendingRequest,
43616
- getRootsCallback
45487
+ getRootsCallback,
45488
+ addClientLog
43617
45489
  ]
43618
45490
  );
43619
45491
  const handleRemoveServer = reactExports.useCallback(
@@ -43633,43 +45505,99 @@ const App = () => {
43633
45505
  );
43634
45506
  const handleUpdateServer = reactExports.useCallback(
43635
45507
  async (serverName, config) => {
43636
- await connectionState.updateServerWithoutConnecting(serverName, config);
45508
+ await connectionState.updateServer(serverName, config);
43637
45509
  serverState.updateServerConfig(serverName, config);
45510
+ addClientLog(
45511
+ `🔧 Updated server: ${serverName} ${JSON.stringify(config)}`,
45512
+ "info"
45513
+ );
43638
45514
  },
43639
- [connectionState, serverState]
45515
+ [connectionState, serverState, addClientLog]
43640
45516
  );
43641
- const handleSaveClient = reactExports.useCallback(async () => {
43642
- if (!serverState.clientFormName.trim()) return;
43643
- try {
43644
- if (serverState.isCreatingClient) {
43645
- await handleAddServer(
43646
- serverState.clientFormName,
43647
- serverState.clientFormConfig
43648
- );
43649
- } else if (serverState.editingClientName) {
43650
- const oldServerName = serverState.editingClientName;
43651
- const newServerName = serverState.clientFormName.trim();
43652
- if (oldServerName !== newServerName) {
43653
- console.log(
43654
- `🔄 Server name changed from "${oldServerName}" to "${newServerName}"`
43655
- );
43656
- await handleRemoveServer(oldServerName);
43657
- await handleAddServer(newServerName, serverState.clientFormConfig);
43658
- if (serverState.selectedServerName === oldServerName) {
43659
- serverState.setSelectedServerName(newServerName);
45517
+ const handleSaveClient = reactExports.useCallback(
45518
+ async (config) => {
45519
+ if (!serverState.clientFormName.trim()) return;
45520
+ try {
45521
+ if (serverState.isCreatingClient) {
45522
+ await handleAddServer(serverState.clientFormName, config, {
45523
+ autoConnect: true
45524
+ });
45525
+ } else if (serverState.editingClientName) {
45526
+ const oldServerName = serverState.editingClientName;
45527
+ const newServerName = serverState.clientFormName.trim();
45528
+ if (oldServerName !== newServerName) {
45529
+ addClientLog(
45530
+ `🔄 Server name changed from "${oldServerName}" to "${newServerName}"`,
45531
+ "info"
45532
+ );
45533
+ await handleRemoveServer(oldServerName);
45534
+ await handleAddServer(newServerName, config, {
45535
+ autoConnect: true
45536
+ });
45537
+ if (serverState.selectedServerName === oldServerName) {
45538
+ serverState.setSelectedServerName(newServerName);
45539
+ }
45540
+ } else {
45541
+ await handleUpdateServer(serverState.editingClientName, config);
43660
45542
  }
43661
- } else {
43662
- await handleUpdateServer(
43663
- serverState.editingClientName,
43664
- serverState.clientFormConfig
45543
+ }
45544
+ serverState.handleCancelClientForm();
45545
+ } catch (error) {
45546
+ console.error("Failed to save client:", error);
45547
+ }
45548
+ },
45549
+ [
45550
+ serverState,
45551
+ handleAddServer,
45552
+ handleUpdateServer,
45553
+ handleRemoveServer,
45554
+ addClientLog
45555
+ ]
45556
+ );
45557
+ const handleSaveMultiple = reactExports.useCallback(
45558
+ async (clients) => {
45559
+ const results = {
45560
+ success: [],
45561
+ failed: []
45562
+ };
45563
+ console.log(`🔄 Creating ${clients.length} client(s)...`);
45564
+ for (const client2 of clients) {
45565
+ try {
45566
+ console.log(`🔧 Creating client: "${client2.name}"`);
45567
+ await handleAddServer(client2.name, client2.config, {
45568
+ autoConnect: false
45569
+ });
45570
+ results.success.push(client2.name);
45571
+ addClientLog(
45572
+ `✅ Successfully created client: "${client2.name}"`,
45573
+ "info"
43665
45574
  );
45575
+ } catch (error) {
45576
+ const errorMessage = error instanceof Error ? error.message : String(error);
45577
+ addClientLog(
45578
+ `❌ Failed to create client "${client2.name}": ${errorMessage}`,
45579
+ "error"
45580
+ );
45581
+ results.failed.push({ name: client2.name, error: errorMessage });
43666
45582
  }
43667
45583
  }
43668
45584
  serverState.handleCancelClientForm();
43669
- } catch (error) {
43670
- console.error("Failed to save client:", error);
43671
- }
43672
- }, [serverState, handleAddServer, handleUpdateServer, handleRemoveServer]);
45585
+ if (results.success.length > 0) {
45586
+ addClientLog(
45587
+ `✅ Successfully created ${results.success.length} client(s): ${results.success.join(", ")}`,
45588
+ "info"
45589
+ );
45590
+ }
45591
+ if (results.failed.length > 0) {
45592
+ addClientLog(
45593
+ `❌ Failed to create ${results.failed.length} client(s): ${results.failed.map(({ name, error }) => `${name}: ${error}`).join(", ")}`,
45594
+ "error"
45595
+ );
45596
+ }
45597
+ return results;
45598
+ },
45599
+ [handleAddServer, serverState, addClientLog]
45600
+ );
43673
45601
  const handleEditClient = reactExports.useCallback(
43674
45602
  (serverName) => {
43675
45603
  const serverConnections = connectionState.mcpAgent ? connectionState.mcpAgent.getAllConnectionInfo() : [];
@@ -43697,6 +45625,13 @@ const App = () => {
43697
45625
  configState.updateClaudeApiKey(newApiKey);
43698
45626
  updateApiKey(newApiKey);
43699
45627
  };
45628
+ const handleConnectServer = reactExports.useCallback(
45629
+ async (serverName) => {
45630
+ await connectionState.connectServer(serverName);
45631
+ mcpOperations.listTools(connectionState.mcpAgent, serverName);
45632
+ },
45633
+ [connectionState, mcpOperations]
45634
+ );
43700
45635
  const makeRequest = reactExports.useCallback(
43701
45636
  async (request) => {
43702
45637
  return await mcpOperations.makeRequest(
@@ -43746,10 +45681,10 @@ const App = () => {
43746
45681
  }, [mcpOperations.roots]);
43747
45682
  reactExports.useEffect(() => {
43748
45683
  const restoreAgentWithoutConnecting = async () => {
45684
+ if (window.location.pathname.startsWith("/oauth/callback")) {
45685
+ return;
45686
+ }
43749
45687
  if (Object.keys(serverState.serverConfigs).length > 0 && !connectionState.mcpAgent) {
43750
- console.log(
43751
- "🔄 Restoring agent with saved server configs (no auto-connect)..."
43752
- );
43753
45688
  try {
43754
45689
  await connectionState.createAgentWithoutConnecting(
43755
45690
  serverState.serverConfigs,
@@ -43761,24 +45696,26 @@ const App = () => {
43761
45696
  onPendingRequest,
43762
45697
  getRootsCallback
43763
45698
  );
43764
- console.log("✅ Successfully restored agent with server configs");
43765
45699
  } catch (error) {
43766
- console.error("❌ Failed to restore agent:", error);
45700
+ addClientLog(
45701
+ `❌ Failed to restore agent: ${error instanceof Error ? error.message : String(error)}`,
45702
+ "error"
45703
+ );
43767
45704
  }
43768
45705
  }
43769
45706
  };
43770
45707
  restoreAgentWithoutConnecting();
43771
45708
  }, [
43772
45709
  serverState.serverConfigs,
43773
- connectionState.mcpAgent,
43774
- connectionState.createAgentWithoutConnecting,
45710
+ connectionState,
43775
45711
  configState.config,
43776
45712
  configState.bearerToken,
43777
45713
  configState.headerName,
43778
45714
  configState.claudeApiKey,
43779
45715
  onStdErrNotification,
43780
45716
  onPendingRequest,
43781
- getRootsCallback
45717
+ getRootsCallback,
45718
+ addClientLog
43782
45719
  ]);
43783
45720
  reactExports.useEffect(() => {
43784
45721
  const currentConfig = serverState.serverConfigs[serverState.selectedServerName];
@@ -43829,24 +45766,19 @@ const App = () => {
43829
45766
  }
43830
45767
  }
43831
45768
  const finalServerName = existingServerName || serverName;
43832
- console.log(
43833
- `🔐 OAuth connecting to: ${serverUrl} as server "${finalServerName}"`
43834
- );
43835
45769
  const serverConfig = {
43836
45770
  transportType: "sse",
43837
45771
  url: new URL(serverUrl)
43838
45772
  };
43839
45773
  try {
43840
- await handleAddServer(finalServerName, serverConfig);
43841
- serverState.setSelectedServerName(finalServerName);
43842
- console.log("🔌 Auto-connecting after OAuth success...");
43843
- await connectionState.connectServer(finalServerName);
43844
- console.log("✅ Auto-connected successfully after OAuth");
45774
+ await handleAddServer(finalServerName, serverConfig, {
45775
+ autoConnect: true
45776
+ });
43845
45777
  } catch (error) {
43846
45778
  console.error("Failed to connect OAuth server:", error);
43847
45779
  }
43848
45780
  },
43849
- [serverState, handleAddServer, connectionState.connectServer]
45781
+ [serverState, handleAddServer]
43850
45782
  );
43851
45783
  const onOAuthDebugConnect = reactExports.useCallback(
43852
45784
  ({
@@ -43894,7 +45826,7 @@ const App = () => {
43894
45826
  }, []);
43895
45827
  if (window.location.pathname === "/oauth/callback") {
43896
45828
  const OAuthCallback = React.lazy(
43897
- () => __vitePreload(() => import("./OAuthCallback-CfsBsNUt.js"), true ? __vite__mapDeps([0,1]) : void 0)
45829
+ () => __vitePreload(() => import("./OAuthCallback-CdxuZKBm.js"), true ? __vite__mapDeps([0,1]) : void 0)
43898
45830
  );
43899
45831
  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(
43900
45832
  reactExports.Suspense,
@@ -43909,7 +45841,7 @@ const App = () => {
43909
45841
  }
43910
45842
  if (window.location.pathname === "/oauth/callback/debug") {
43911
45843
  const OAuthDebugCallback = React.lazy(
43912
- () => __vitePreload(() => import("./OAuthDebugCallback-DuorYCq_.js"), true ? __vite__mapDeps([2,1]) : void 0)
45844
+ () => __vitePreload(() => import("./OAuthDebugCallback-BJaIMNT8.js"), true ? __vite__mapDeps([2,1]) : void 0)
43913
45845
  );
43914
45846
  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(
43915
45847
  reactExports.Suspense,
@@ -43940,6 +45872,7 @@ const App = () => {
43940
45872
  headerName: configState.headerName,
43941
45873
  setHeaderName: configState.setHeaderName,
43942
45874
  onSave: handleSaveClient,
45875
+ onSaveMultiple: handleSaveMultiple,
43943
45876
  onCancel: serverState.handleCancelClientForm
43944
45877
  }
43945
45878
  );
@@ -44191,7 +46124,7 @@ const App = () => {
44191
46124
  selectedServerName: serverState.selectedServerName,
44192
46125
  onServerSelect: serverState.setSelectedServerName,
44193
46126
  onRemoveServer: handleRemoveServer,
44194
- onConnectServer: connectionState.connectServer,
46127
+ onConnectServer: handleConnectServer,
44195
46128
  onDisconnectServer: connectionState.disconnectServer,
44196
46129
  onCreateClient: serverState.handleCreateClient,
44197
46130
  onEditClient: handleEditClient,
@@ -44217,7 +46150,9 @@ const App = () => {
44217
46150
  {
44218
46151
  requestHistory,
44219
46152
  toolResult: mcpOperations.toolResult,
44220
- onClearHistory: mcpOperations.clearRequestHistory
46153
+ clientLogs: mcpOperations.getClientLogs(),
46154
+ onClearHistory: mcpOperations.clearRequestHistory,
46155
+ onClearLogs: mcpOperations.clearClientLogs
44221
46156
  }
44222
46157
  )
44223
46158
  ] })