@mcpjam/inspector 0.2.3 → 0.2.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/client/bin/start.js +28 -4
- package/client/dist/assets/{OAuthCallback-CfsBsNUt.js → OAuthCallback-DkLMDxkx.js} +1 -1
- package/client/dist/assets/{OAuthDebugCallback-DuorYCq_.js → OAuthDebugCallback-DaNmVTKt.js} +1 -1
- package/client/dist/assets/{index-CHsLKjnG.js → index-CLxTHffA.js} +1469 -279
- package/client/dist/assets/{index-C5Ywrn22.css → index-ebsMqCvj.css} +31 -0
- package/client/dist/index.html +2 -2
- package/package.json +1 -1
- package/server/build/index.js +25 -35
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
const __vite__mapDeps=(i,m=__vite__mapDeps,d=(m.f||(m.f=["assets/OAuthCallback-
|
|
1
|
+
const __vite__mapDeps=(i,m=__vite__mapDeps,d=(m.f||(m.f=["assets/OAuthCallback-DkLMDxkx.js","assets/oauthUtils-DTcoXpSP.js","assets/OAuthDebugCallback-DaNmVTKt.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);
|
|
@@ -16608,6 +16608,17 @@ const TriangleAlert = createLucideIcon("TriangleAlert", [
|
|
|
16608
16608
|
["path", { d: "M12 9v4", key: "juzpu7" }],
|
|
16609
16609
|
["path", { d: "M12 17h.01", key: "p32p05" }]
|
|
16610
16610
|
]);
|
|
16611
|
+
/**
|
|
16612
|
+
* @license lucide-react v0.447.0 - ISC
|
|
16613
|
+
*
|
|
16614
|
+
* This source code is licensed under the ISC license.
|
|
16615
|
+
* See the LICENSE file in the root directory of this source tree.
|
|
16616
|
+
*/
|
|
16617
|
+
const Upload = createLucideIcon("Upload", [
|
|
16618
|
+
["path", { d: "M21 15v4a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2v-4", key: "ih7n3h" }],
|
|
16619
|
+
["polyline", { points: "17 8 12 3 7 8", key: "t8dd8p" }],
|
|
16620
|
+
["line", { x1: "12", x2: "12", y1: "3", y2: "15", key: "widbto" }]
|
|
16621
|
+
]);
|
|
16611
16622
|
/**
|
|
16612
16623
|
* @license lucide-react v0.447.0 - ISC
|
|
16613
16624
|
*
|
|
@@ -17648,6 +17659,7 @@ const AuthDebugger = ({
|
|
|
17648
17659
|
authState,
|
|
17649
17660
|
updateAuthState
|
|
17650
17661
|
}) => {
|
|
17662
|
+
const [showFullToken, setShowFullToken] = reactExports.useState(false);
|
|
17651
17663
|
const startOAuthFlow = reactExports.useCallback(() => {
|
|
17652
17664
|
if (!serverUrl) {
|
|
17653
17665
|
updateAuthState({
|
|
@@ -17772,9 +17784,19 @@ const AuthDebugger = ({
|
|
|
17772
17784
|
authState.loading ? /* @__PURE__ */ jsxRuntimeExports.jsx("p", { children: "Loading authentication status..." }) : /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "space-y-4", children: [
|
|
17773
17785
|
authState.oauthTokens && /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "space-y-2", children: [
|
|
17774
17786
|
/* @__PURE__ */ jsxRuntimeExports.jsx("p", { className: "text-sm font-medium", children: "Access Token:" }),
|
|
17775
|
-
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "
|
|
17776
|
-
authState.oauthTokens.access_token
|
|
17777
|
-
|
|
17787
|
+
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "relative", children: [
|
|
17788
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "bg-muted p-2 rounded-md text-xs overflow-x-auto pr-10", children: showFullToken ? authState.oauthTokens.access_token : "********************************" }),
|
|
17789
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
17790
|
+
Button,
|
|
17791
|
+
{
|
|
17792
|
+
variant: "ghost",
|
|
17793
|
+
size: "sm",
|
|
17794
|
+
className: "absolute right-1 top-1 h-6 w-6 p-0 hover:bg-muted-foreground/10",
|
|
17795
|
+
onClick: () => setShowFullToken(!showFullToken),
|
|
17796
|
+
title: showFullToken ? "Hide token" : "Show full token",
|
|
17797
|
+
children: showFullToken ? /* @__PURE__ */ jsxRuntimeExports.jsx(EyeOff, { className: "h-3 w-3" }) : /* @__PURE__ */ jsxRuntimeExports.jsx(Eye, { className: "h-3 w-3" })
|
|
17798
|
+
}
|
|
17799
|
+
)
|
|
17778
17800
|
] })
|
|
17779
17801
|
] }),
|
|
17780
17802
|
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex gap-4", children: [
|
|
@@ -17813,6 +17835,61 @@ const AuthDebugger = ({
|
|
|
17813
17835
|
] });
|
|
17814
17836
|
};
|
|
17815
17837
|
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" }) });
|
|
17838
|
+
function useDraggablePane(initialHeight) {
|
|
17839
|
+
const [height, setHeight] = reactExports.useState(initialHeight);
|
|
17840
|
+
const [isDragging, setIsDragging] = reactExports.useState(false);
|
|
17841
|
+
const dragStartY = reactExports.useRef(0);
|
|
17842
|
+
const dragStartHeight = reactExports.useRef(0);
|
|
17843
|
+
const handleDragStart = reactExports.useCallback(
|
|
17844
|
+
(e) => {
|
|
17845
|
+
setIsDragging(true);
|
|
17846
|
+
dragStartY.current = e.clientY;
|
|
17847
|
+
dragStartHeight.current = height;
|
|
17848
|
+
document.body.style.userSelect = "none";
|
|
17849
|
+
},
|
|
17850
|
+
[height]
|
|
17851
|
+
);
|
|
17852
|
+
const handleDragMove = reactExports.useCallback(
|
|
17853
|
+
(e) => {
|
|
17854
|
+
if (!isDragging) return;
|
|
17855
|
+
const deltaY = dragStartY.current - e.clientY;
|
|
17856
|
+
const newHeight = Math.max(
|
|
17857
|
+
100,
|
|
17858
|
+
Math.min(800, dragStartHeight.current + deltaY)
|
|
17859
|
+
);
|
|
17860
|
+
setHeight(newHeight);
|
|
17861
|
+
},
|
|
17862
|
+
[isDragging]
|
|
17863
|
+
);
|
|
17864
|
+
const handleDragEnd = reactExports.useCallback(() => {
|
|
17865
|
+
setIsDragging(false);
|
|
17866
|
+
document.body.style.userSelect = "";
|
|
17867
|
+
}, []);
|
|
17868
|
+
const resetHeight = reactExports.useCallback(() => {
|
|
17869
|
+
setHeight(initialHeight);
|
|
17870
|
+
}, [initialHeight]);
|
|
17871
|
+
reactExports.useEffect(() => {
|
|
17872
|
+
if (!isDragging) {
|
|
17873
|
+
setHeight(initialHeight);
|
|
17874
|
+
}
|
|
17875
|
+
}, [initialHeight, isDragging]);
|
|
17876
|
+
reactExports.useEffect(() => {
|
|
17877
|
+
if (isDragging) {
|
|
17878
|
+
window.addEventListener("mousemove", handleDragMove);
|
|
17879
|
+
window.addEventListener("mouseup", handleDragEnd);
|
|
17880
|
+
return () => {
|
|
17881
|
+
window.removeEventListener("mousemove", handleDragMove);
|
|
17882
|
+
window.removeEventListener("mouseup", handleDragEnd);
|
|
17883
|
+
};
|
|
17884
|
+
}
|
|
17885
|
+
}, [isDragging, handleDragMove, handleDragEnd]);
|
|
17886
|
+
return {
|
|
17887
|
+
height,
|
|
17888
|
+
isDragging,
|
|
17889
|
+
handleDragStart,
|
|
17890
|
+
resetHeight
|
|
17891
|
+
};
|
|
17892
|
+
}
|
|
17816
17893
|
function getDataType(value) {
|
|
17817
17894
|
if (Array.isArray(value)) return "array";
|
|
17818
17895
|
if (value === null) return "null";
|
|
@@ -18106,133 +18183,368 @@ const JsonNode = reactExports.memo(
|
|
|
18106
18183
|
}
|
|
18107
18184
|
);
|
|
18108
18185
|
JsonNode.displayName = "JsonNode";
|
|
18109
|
-
|
|
18110
|
-
const [
|
|
18111
|
-
const
|
|
18112
|
-
|
|
18113
|
-
|
|
18114
|
-
const
|
|
18115
|
-
|
|
18116
|
-
|
|
18117
|
-
|
|
18118
|
-
|
|
18119
|
-
|
|
18120
|
-
|
|
18121
|
-
|
|
18122
|
-
|
|
18123
|
-
|
|
18124
|
-
|
|
18125
|
-
|
|
18126
|
-
|
|
18127
|
-
|
|
18128
|
-
|
|
18129
|
-
|
|
18130
|
-
|
|
18131
|
-
|
|
18186
|
+
const RequestHistoryItem = ({ request, index: index2, totalRequests }) => {
|
|
18187
|
+
const [isExpanded, setIsExpanded] = reactExports.useState(false);
|
|
18188
|
+
const toggleExpansion = () => {
|
|
18189
|
+
setIsExpanded(!isExpanded);
|
|
18190
|
+
};
|
|
18191
|
+
const requestData = JSON.parse(request.request);
|
|
18192
|
+
const requestNumber = totalRequests - index2;
|
|
18193
|
+
const formatTimestamp = (timestamp) => {
|
|
18194
|
+
const date = new Date(timestamp);
|
|
18195
|
+
return date.toLocaleTimeString("en-US", {
|
|
18196
|
+
hour12: true,
|
|
18197
|
+
hour: "2-digit",
|
|
18198
|
+
minute: "2-digit",
|
|
18199
|
+
second: "2-digit"
|
|
18200
|
+
});
|
|
18201
|
+
};
|
|
18202
|
+
const formatLatency = (latency) => {
|
|
18203
|
+
if (latency === void 0) return void 0;
|
|
18204
|
+
return `${latency}ms`;
|
|
18205
|
+
};
|
|
18206
|
+
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: [
|
|
18207
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
18208
|
+
RequestHeader,
|
|
18209
|
+
{
|
|
18210
|
+
requestNumber,
|
|
18211
|
+
method: requestData.method,
|
|
18212
|
+
server: requestData.server,
|
|
18213
|
+
timestamp: formatTimestamp(request.timestamp),
|
|
18214
|
+
latency: formatLatency(request.latency),
|
|
18215
|
+
isExpanded,
|
|
18216
|
+
onToggle: toggleExpansion
|
|
18217
|
+
}
|
|
18218
|
+
),
|
|
18219
|
+
isExpanded && /* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
18220
|
+
RequestDetails,
|
|
18221
|
+
{
|
|
18222
|
+
requestData: request.request,
|
|
18223
|
+
responseData: request.response
|
|
18224
|
+
}
|
|
18225
|
+
)
|
|
18226
|
+
] });
|
|
18227
|
+
};
|
|
18228
|
+
const RequestHeader = ({ requestNumber, method, server, timestamp, latency, isExpanded, onToggle }) => /* @__PURE__ */ jsxRuntimeExports.jsxs(
|
|
18229
|
+
"header",
|
|
18230
|
+
{
|
|
18231
|
+
className: "flex justify-between items-center cursor-pointer group",
|
|
18232
|
+
onClick: onToggle,
|
|
18233
|
+
role: "button",
|
|
18234
|
+
tabIndex: 0,
|
|
18235
|
+
onKeyDown: (e) => {
|
|
18236
|
+
if (e.key === "Enter" || e.key === " ") {
|
|
18237
|
+
e.preventDefault();
|
|
18238
|
+
onToggle();
|
|
18239
|
+
}
|
|
18132
18240
|
},
|
|
18133
|
-
|
|
18134
|
-
|
|
18135
|
-
|
|
18136
|
-
|
|
18137
|
-
|
|
18138
|
-
|
|
18139
|
-
|
|
18140
|
-
|
|
18141
|
-
|
|
18142
|
-
|
|
18143
|
-
|
|
18144
|
-
|
|
18241
|
+
"aria-expanded": isExpanded,
|
|
18242
|
+
"aria-label": `Request ${requestNumber}: ${method}`,
|
|
18243
|
+
children: [
|
|
18244
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx(RequestInfo, { requestNumber, method, server, timestamp, latency }),
|
|
18245
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx(ExpandIcon, { isExpanded })
|
|
18246
|
+
]
|
|
18247
|
+
}
|
|
18248
|
+
);
|
|
18249
|
+
const RequestInfo = ({ requestNumber, method, server, timestamp, latency }) => /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex items-center space-x-3", children: [
|
|
18250
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx(RequestBadge, { number: requestNumber }),
|
|
18251
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx(TimeStamp, { timestamp }),
|
|
18252
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx(MethodLabel, { method, server }),
|
|
18253
|
+
latency && /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "text-xs text-muted-foreground font-mono", children: latency })
|
|
18254
|
+
] });
|
|
18255
|
+
const RequestBadge = ({ number }) => /* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
18256
|
+
"span",
|
|
18257
|
+
{
|
|
18258
|
+
className: "flex items-center justify-center w-6 h-6 bg-primary/10 text-primary text-xs font-bold rounded-full",
|
|
18259
|
+
"aria-label": `Request number ${number}`,
|
|
18260
|
+
children: number
|
|
18261
|
+
}
|
|
18262
|
+
);
|
|
18263
|
+
const TimeStamp = ({ timestamp }) => /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "text-xs text-muted-foreground font-mono", children: timestamp });
|
|
18264
|
+
const MethodLabel = ({ method, server }) => /* @__PURE__ */ jsxRuntimeExports.jsxs("span", { className: "font-mono font-semibold text-foreground", children: [
|
|
18265
|
+
method,
|
|
18266
|
+
server && ` (${server})`
|
|
18267
|
+
] });
|
|
18268
|
+
const ExpandIcon = ({ isExpanded }) => /* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
18269
|
+
"span",
|
|
18270
|
+
{
|
|
18271
|
+
className: "text-muted-foreground group-hover:text-foreground transition-colors duration-200",
|
|
18272
|
+
"aria-hidden": "true",
|
|
18273
|
+
children: isExpanded ? "▼" : "▶"
|
|
18274
|
+
}
|
|
18275
|
+
);
|
|
18276
|
+
const RequestDetails = ({ requestData, responseData }) => /* @__PURE__ */ jsxRuntimeExports.jsxs("section", { className: "mt-4 space-y-4", "aria-label": "Request and response details", children: [
|
|
18277
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx(RequestSection, { title: "Request", data: requestData }),
|
|
18278
|
+
responseData && /* @__PURE__ */ jsxRuntimeExports.jsx(RequestSection, { title: "Response", data: responseData })
|
|
18279
|
+
] });
|
|
18280
|
+
const RequestSection = ({ title: title2, data: data2 }) => /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { children: [
|
|
18281
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx(SectionHeader, { title: title2 }),
|
|
18282
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
18283
|
+
JsonView,
|
|
18284
|
+
{
|
|
18285
|
+
data: data2,
|
|
18286
|
+
className: "bg-background/80 backdrop-blur-sm border border-border/20 rounded-lg"
|
|
18145
18287
|
}
|
|
18146
|
-
|
|
18288
|
+
)
|
|
18289
|
+
] });
|
|
18290
|
+
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 }) });
|
|
18291
|
+
const ActivityTab = ({
|
|
18292
|
+
requestHistory,
|
|
18293
|
+
onClearHistory,
|
|
18294
|
+
onToggleCollapse,
|
|
18295
|
+
showHeader = true
|
|
18296
|
+
}) => {
|
|
18297
|
+
return /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: `flex-1 overflow-y-auto ${showHeader ? "p-6 border-r border-border/20" : ""}`, children: [
|
|
18298
|
+
showHeader && /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex items-center justify-between mb-6", children: [
|
|
18299
|
+
/* @__PURE__ */ jsxRuntimeExports.jsxs("h2", { className: "text-lg font-bold text-foreground flex items-center space-x-2", children: [
|
|
18300
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx(Activity, { className: "w-5 h-5 text-primary" }),
|
|
18301
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("span", { children: "All Activity" })
|
|
18302
|
+
] }),
|
|
18303
|
+
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex items-center space-x-3", children: [
|
|
18304
|
+
requestHistory.length > 0 && /* @__PURE__ */ jsxRuntimeExports.jsxs(jsxRuntimeExports.Fragment, { children: [
|
|
18305
|
+
/* @__PURE__ */ jsxRuntimeExports.jsxs("span", { className: "text-sm text-muted-foreground bg-muted/50 px-3 py-1 rounded-full", children: [
|
|
18306
|
+
requestHistory.length,
|
|
18307
|
+
" request",
|
|
18308
|
+
requestHistory.length !== 1 ? "s" : ""
|
|
18309
|
+
] }),
|
|
18310
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
18311
|
+
"button",
|
|
18312
|
+
{
|
|
18313
|
+
onClick: onClearHistory,
|
|
18314
|
+
className: "p-2 rounded-lg hover:bg-destructive/10 hover:text-destructive transition-all duration-200 group",
|
|
18315
|
+
title: "Clear all activity",
|
|
18316
|
+
children: /* @__PURE__ */ jsxRuntimeExports.jsx(Trash2, { className: "w-4 h-4 text-muted-foreground group-hover:text-destructive" })
|
|
18317
|
+
}
|
|
18318
|
+
)
|
|
18319
|
+
] }),
|
|
18320
|
+
onToggleCollapse && /* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
18321
|
+
"button",
|
|
18322
|
+
{
|
|
18323
|
+
onClick: onToggleCollapse,
|
|
18324
|
+
className: "p-2 rounded-lg hover:bg-accent/50 transition-all duration-200",
|
|
18325
|
+
children: /* @__PURE__ */ jsxRuntimeExports.jsx(ChevronDown, { className: "w-5 h-5 text-muted-foreground hover:text-foreground" })
|
|
18326
|
+
}
|
|
18327
|
+
)
|
|
18328
|
+
] })
|
|
18329
|
+
] }),
|
|
18330
|
+
requestHistory.length === 0 ? /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex flex-col items-center justify-center py-12 text-center", children: [
|
|
18331
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx(Activity, { className: "w-12 h-12 text-muted-foreground/40 mb-4" }),
|
|
18332
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("p", { className: "text-muted-foreground text-lg font-medium mb-2", children: "No activity yet" }),
|
|
18333
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("p", { className: "text-muted-foreground/60 text-sm", children: "MCP requests and responses will appear here" })
|
|
18334
|
+
] }) : /* @__PURE__ */ jsxRuntimeExports.jsxs(jsxRuntimeExports.Fragment, { children: [
|
|
18335
|
+
!showHeader && requestHistory.length > 0 && /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex items-center justify-between mb-6", children: [
|
|
18336
|
+
/* @__PURE__ */ jsxRuntimeExports.jsxs("span", { className: "text-sm text-muted-foreground bg-muted/50 px-3 py-1 rounded-full", children: [
|
|
18337
|
+
requestHistory.length,
|
|
18338
|
+
" request",
|
|
18339
|
+
requestHistory.length !== 1 ? "s" : ""
|
|
18340
|
+
] }),
|
|
18341
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
18342
|
+
"button",
|
|
18343
|
+
{
|
|
18344
|
+
onClick: onClearHistory,
|
|
18345
|
+
className: "p-2 rounded-lg hover:bg-destructive/10 hover:text-destructive transition-all duration-200 group",
|
|
18346
|
+
title: "Clear all activity",
|
|
18347
|
+
children: /* @__PURE__ */ jsxRuntimeExports.jsx(Trash2, { className: "w-4 h-4 text-muted-foreground group-hover:text-destructive" })
|
|
18348
|
+
}
|
|
18349
|
+
)
|
|
18350
|
+
] }),
|
|
18351
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("ul", { className: "space-y-4", children: requestHistory.slice().reverse().map((request, index2) => /* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
18352
|
+
RequestHistoryItem,
|
|
18353
|
+
{
|
|
18354
|
+
request,
|
|
18355
|
+
index: index2,
|
|
18356
|
+
totalRequests: requestHistory.length
|
|
18357
|
+
},
|
|
18358
|
+
index2
|
|
18359
|
+
)) })
|
|
18360
|
+
] })
|
|
18361
|
+
] });
|
|
18362
|
+
};
|
|
18363
|
+
const ToolResult = ({ toolResult }) => {
|
|
18364
|
+
if (!toolResult) return null;
|
|
18365
|
+
if ("content" in toolResult) {
|
|
18366
|
+
const parsedResult = CallToolResultSchema.safeParse(toolResult);
|
|
18367
|
+
if (!parsedResult.success) {
|
|
18368
|
+
return /* @__PURE__ */ jsxRuntimeExports.jsxs(jsxRuntimeExports.Fragment, { children: [
|
|
18369
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("h4", { className: "font-semibold mb-2", children: "Invalid Tool Result:" }),
|
|
18370
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx(JsonView, { data: toolResult }),
|
|
18371
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("h4", { className: "font-semibold mb-2", children: "Errors:" }),
|
|
18372
|
+
parsedResult.error.errors.map((error, idx) => /* @__PURE__ */ jsxRuntimeExports.jsx(JsonView, { data: error }, idx))
|
|
18373
|
+
] });
|
|
18374
|
+
}
|
|
18375
|
+
const structuredResult = parsedResult.data;
|
|
18376
|
+
const isError = structuredResult.isError ?? false;
|
|
18377
|
+
return /* @__PURE__ */ jsxRuntimeExports.jsxs(jsxRuntimeExports.Fragment, { children: [
|
|
18378
|
+
/* @__PURE__ */ jsxRuntimeExports.jsxs("h4", { className: "font-semibold mb-2", children: [
|
|
18379
|
+
"Tool Result:",
|
|
18380
|
+
" ",
|
|
18381
|
+
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" })
|
|
18382
|
+
] }),
|
|
18383
|
+
structuredResult.content.map((item, index2) => {
|
|
18384
|
+
var _a2, _b;
|
|
18385
|
+
return /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "mb-2", children: [
|
|
18386
|
+
item.type === "text" && /* @__PURE__ */ jsxRuntimeExports.jsx(JsonView, { data: item.text, isError }),
|
|
18387
|
+
item.type === "image" && /* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
18388
|
+
"img",
|
|
18389
|
+
{
|
|
18390
|
+
src: `data:${item.mimeType};base64,${item.data}`,
|
|
18391
|
+
alt: "Tool result image",
|
|
18392
|
+
className: "max-w-full h-auto"
|
|
18393
|
+
}
|
|
18394
|
+
),
|
|
18395
|
+
item.type === "resource" && (((_b = (_a2 = item.resource) == null ? void 0 : _a2.mimeType) == null ? void 0 : _b.startsWith("audio/")) ? /* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
18396
|
+
"audio",
|
|
18397
|
+
{
|
|
18398
|
+
controls: true,
|
|
18399
|
+
src: `data:${item.resource.mimeType};base64,${item.resource.blob}`,
|
|
18400
|
+
className: "w-full",
|
|
18401
|
+
children: /* @__PURE__ */ jsxRuntimeExports.jsx("p", { children: "Your browser does not support audio playback" })
|
|
18402
|
+
}
|
|
18403
|
+
) : /* @__PURE__ */ jsxRuntimeExports.jsx(JsonView, { data: item.resource }))
|
|
18404
|
+
] }, index2);
|
|
18405
|
+
})
|
|
18406
|
+
] });
|
|
18407
|
+
} else if ("toolResult" in toolResult) {
|
|
18408
|
+
return /* @__PURE__ */ jsxRuntimeExports.jsxs(jsxRuntimeExports.Fragment, { children: [
|
|
18409
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("h4", { className: "font-semibold mb-2", children: "Tool Result (Legacy):" }),
|
|
18410
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx(JsonView, { data: toolResult.toolResult })
|
|
18411
|
+
] });
|
|
18412
|
+
}
|
|
18413
|
+
return null;
|
|
18414
|
+
};
|
|
18415
|
+
const ResultsTab = ({ toolResult, onToggleCollapse, showHeader = true }) => {
|
|
18416
|
+
return /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: `flex-1 overflow-y-auto ${showHeader ? "p-6" : ""}`, children: [
|
|
18417
|
+
showHeader && /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex items-center justify-between mb-6", children: [
|
|
18418
|
+
/* @__PURE__ */ jsxRuntimeExports.jsxs("h2", { className: "text-lg font-bold text-foreground flex items-center space-x-2", children: [
|
|
18419
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx(ScrollText, { className: "w-5 h-5 text-primary" }),
|
|
18420
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("span", { children: "Results" })
|
|
18421
|
+
] }),
|
|
18422
|
+
onToggleCollapse && /* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
18423
|
+
"button",
|
|
18424
|
+
{
|
|
18425
|
+
onClick: onToggleCollapse,
|
|
18426
|
+
className: "p-2 rounded-lg hover:bg-accent/50 transition-all duration-200",
|
|
18427
|
+
children: /* @__PURE__ */ jsxRuntimeExports.jsx(ChevronDown, { className: "w-5 h-5 text-muted-foreground hover:text-foreground" })
|
|
18428
|
+
}
|
|
18429
|
+
)
|
|
18430
|
+
] }),
|
|
18431
|
+
!toolResult ? /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex flex-col items-center justify-center py-12 text-center", children: [
|
|
18432
|
+
/* @__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: "🎯" }) }),
|
|
18433
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("p", { className: "text-muted-foreground text-lg font-medium mb-2", children: "No results yet" }),
|
|
18434
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("p", { className: "text-muted-foreground/60 text-sm", children: "Tool execution results will appear here" })
|
|
18435
|
+
] }) : /* @__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 }) })
|
|
18436
|
+
] });
|
|
18437
|
+
};
|
|
18438
|
+
const TabbedHistoryPanel = ({
|
|
18439
|
+
requestHistory,
|
|
18440
|
+
toolResult,
|
|
18441
|
+
onClearHistory,
|
|
18442
|
+
onToggleCollapse
|
|
18443
|
+
}) => {
|
|
18444
|
+
const [activeTab, setActiveTab] = reactExports.useState("activity");
|
|
18445
|
+
const [isToolResultError, setIsToolResultError] = reactExports.useState(false);
|
|
18147
18446
|
reactExports.useEffect(() => {
|
|
18148
|
-
if (
|
|
18149
|
-
|
|
18150
|
-
|
|
18151
|
-
|
|
18152
|
-
window.removeEventListener("mousemove", handleDragMove);
|
|
18153
|
-
window.removeEventListener("mouseup", handleDragEnd);
|
|
18154
|
-
};
|
|
18447
|
+
if (toolResult) {
|
|
18448
|
+
console.log("toolResult", toolResult);
|
|
18449
|
+
setIsToolResultError(toolResult.isError === true);
|
|
18450
|
+
setActiveTab("results");
|
|
18155
18451
|
}
|
|
18156
|
-
}, [
|
|
18157
|
-
|
|
18158
|
-
|
|
18159
|
-
|
|
18160
|
-
|
|
18161
|
-
|
|
18452
|
+
}, [toolResult]);
|
|
18453
|
+
const renderActivityTabButton = () => {
|
|
18454
|
+
return /* @__PURE__ */ jsxRuntimeExports.jsxs(
|
|
18455
|
+
"button",
|
|
18456
|
+
{
|
|
18457
|
+
onClick: () => setActiveTab("activity"),
|
|
18458
|
+
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"}`,
|
|
18459
|
+
children: [
|
|
18460
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx(Activity, { className: "w-4 h-4" }),
|
|
18461
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "text-sm font-medium", children: "Activity" }),
|
|
18462
|
+
requestHistory.length > 0 && /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "px-2 py-1 text-xs bg-primary/10 text-primary rounded-full", children: requestHistory.length })
|
|
18463
|
+
]
|
|
18464
|
+
},
|
|
18465
|
+
"activity"
|
|
18466
|
+
);
|
|
18162
18467
|
};
|
|
18163
|
-
|
|
18468
|
+
const renderResultsTabButton = () => {
|
|
18469
|
+
console.log("isToolResultError", isToolResultError);
|
|
18470
|
+
const renderCircleIndicator = () => {
|
|
18471
|
+
if (toolResult && !isToolResultError) {
|
|
18472
|
+
return /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "w-2 h-2 bg-green-500 rounded-full" });
|
|
18473
|
+
} else if (toolResult && isToolResultError) {
|
|
18474
|
+
return /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "w-2 h-2 bg-red-500 rounded-full" });
|
|
18475
|
+
} else {
|
|
18476
|
+
return null;
|
|
18477
|
+
}
|
|
18478
|
+
};
|
|
18479
|
+
return /* @__PURE__ */ jsxRuntimeExports.jsxs(
|
|
18480
|
+
"button",
|
|
18481
|
+
{
|
|
18482
|
+
onClick: () => setActiveTab("results"),
|
|
18483
|
+
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"}`,
|
|
18484
|
+
children: [
|
|
18485
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx(ScrollText, { className: "w-4 h-4" }),
|
|
18486
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "text-sm font-medium", children: "Results" }),
|
|
18487
|
+
renderCircleIndicator()
|
|
18488
|
+
]
|
|
18489
|
+
},
|
|
18490
|
+
"results"
|
|
18491
|
+
);
|
|
18492
|
+
};
|
|
18493
|
+
const renderTabContent = () => {
|
|
18494
|
+
switch (activeTab) {
|
|
18495
|
+
case "activity":
|
|
18496
|
+
return /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "h-full overflow-y-auto p-6", children: /* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
18497
|
+
ActivityTab,
|
|
18498
|
+
{
|
|
18499
|
+
requestHistory,
|
|
18500
|
+
onClearHistory,
|
|
18501
|
+
showHeader: false
|
|
18502
|
+
}
|
|
18503
|
+
) });
|
|
18504
|
+
case "results":
|
|
18505
|
+
return /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "h-full overflow-y-auto p-6", children: /* @__PURE__ */ jsxRuntimeExports.jsx(ResultsTab, { toolResult, showHeader: false }) });
|
|
18506
|
+
default:
|
|
18507
|
+
return null;
|
|
18508
|
+
}
|
|
18509
|
+
};
|
|
18510
|
+
return /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "bg-transparent flex flex-col h-full", children: [
|
|
18511
|
+
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex items-center justify-between border-b border-border/20 px-6 py-3", children: [
|
|
18512
|
+
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex space-x-1", children: [
|
|
18513
|
+
renderActivityTabButton(),
|
|
18514
|
+
renderResultsTabButton()
|
|
18515
|
+
] }),
|
|
18516
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
18517
|
+
"button",
|
|
18518
|
+
{
|
|
18519
|
+
onClick: onToggleCollapse,
|
|
18520
|
+
className: "p-2 rounded-lg hover:bg-accent/50 transition-all duration-200",
|
|
18521
|
+
children: /* @__PURE__ */ jsxRuntimeExports.jsx(ChevronDown, { className: "w-5 h-5 text-muted-foreground hover:text-foreground" })
|
|
18522
|
+
}
|
|
18523
|
+
)
|
|
18524
|
+
] }),
|
|
18525
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "flex-1 overflow-hidden", children: renderTabContent() })
|
|
18526
|
+
] });
|
|
18527
|
+
};
|
|
18164
18528
|
const HistoryAndNotifications = ({
|
|
18165
18529
|
requestHistory,
|
|
18166
18530
|
toolResult,
|
|
18167
18531
|
onClearHistory
|
|
18168
18532
|
}) => {
|
|
18169
|
-
const [expandedRequests, setExpandedRequests] = reactExports.useState({});
|
|
18170
18533
|
const [isHistoryCollapsed, setIsHistoryCollapsed] = reactExports.useState(true);
|
|
18171
18534
|
const {
|
|
18172
18535
|
height: historyPaneHeight,
|
|
18173
18536
|
handleDragStart,
|
|
18174
18537
|
resetHeight
|
|
18175
|
-
} = useDraggablePane(
|
|
18176
|
-
const
|
|
18177
|
-
|
|
18178
|
-
};
|
|
18538
|
+
} = useDraggablePane(500);
|
|
18539
|
+
const toggleCollapse = reactExports.useCallback(() => {
|
|
18540
|
+
setIsHistoryCollapsed(!isHistoryCollapsed);
|
|
18541
|
+
}, [isHistoryCollapsed]);
|
|
18179
18542
|
reactExports.useEffect(() => {
|
|
18180
18543
|
if (toolResult) {
|
|
18181
18544
|
resetHeight();
|
|
18182
18545
|
setIsHistoryCollapsed(false);
|
|
18183
18546
|
}
|
|
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
|
-
] });
|
|
18196
|
-
}
|
|
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
|
-
}
|
|
18235
|
-
};
|
|
18547
|
+
}, [toolResult, resetHeight]);
|
|
18236
18548
|
return /* @__PURE__ */ jsxRuntimeExports.jsxs(
|
|
18237
18549
|
"div",
|
|
18238
18550
|
{
|
|
@@ -18248,118 +18560,19 @@ const HistoryAndNotifications = ({
|
|
|
18248
18560
|
onMouseDown: handleDragStart
|
|
18249
18561
|
}
|
|
18250
18562
|
),
|
|
18251
|
-
/* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "h-full overflow-hidden", children: !isHistoryCollapsed ? /* @__PURE__ */ jsxRuntimeExports.
|
|
18252
|
-
|
|
18253
|
-
|
|
18254
|
-
|
|
18255
|
-
|
|
18256
|
-
|
|
18257
|
-
|
|
18258
|
-
|
|
18259
|
-
|
|
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(
|
|
18563
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "h-full overflow-hidden", children: !isHistoryCollapsed ? /* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
18564
|
+
TabbedHistoryPanel,
|
|
18565
|
+
{
|
|
18566
|
+
requestHistory,
|
|
18567
|
+
toolResult,
|
|
18568
|
+
onClearHistory,
|
|
18569
|
+
onToggleCollapse: toggleCollapse
|
|
18570
|
+
}
|
|
18571
|
+
) : /* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
18359
18572
|
"div",
|
|
18360
18573
|
{
|
|
18361
18574
|
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:
|
|
18575
|
+
onClick: toggleCollapse,
|
|
18363
18576
|
children: /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex items-center space-x-4 text-muted-foreground", children: [
|
|
18364
18577
|
/* @__PURE__ */ jsxRuntimeExports.jsx(History, { className: "w-5 h-5" }),
|
|
18365
18578
|
/* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "text-sm font-medium", children: "History & Results" }),
|
|
@@ -19449,7 +19662,7 @@ var hideOthers = function(originalTarget, parentNode, markerName) {
|
|
|
19449
19662
|
var DIALOG_NAME = "Dialog";
|
|
19450
19663
|
var [createDialogContext, createDialogScope] = createContextScope(DIALOG_NAME);
|
|
19451
19664
|
var [DialogProvider, useDialogContext] = createDialogContext(DIALOG_NAME);
|
|
19452
|
-
var Dialog = (props) => {
|
|
19665
|
+
var Dialog$1 = (props) => {
|
|
19453
19666
|
const {
|
|
19454
19667
|
__scopeDialog,
|
|
19455
19668
|
children,
|
|
@@ -19483,7 +19696,7 @@ var Dialog = (props) => {
|
|
|
19483
19696
|
}
|
|
19484
19697
|
);
|
|
19485
19698
|
};
|
|
19486
|
-
Dialog.displayName = DIALOG_NAME;
|
|
19699
|
+
Dialog$1.displayName = DIALOG_NAME;
|
|
19487
19700
|
var TRIGGER_NAME$4 = "DialogTrigger";
|
|
19488
19701
|
var DialogTrigger = reactExports.forwardRef(
|
|
19489
19702
|
(props, forwardedRef) => {
|
|
@@ -19744,7 +19957,7 @@ var DescriptionWarning = ({ contentRef, descriptionId }) => {
|
|
|
19744
19957
|
}, [MESSAGE, contentRef, descriptionId]);
|
|
19745
19958
|
return null;
|
|
19746
19959
|
};
|
|
19747
|
-
var Root$2 = Dialog;
|
|
19960
|
+
var Root$2 = Dialog$1;
|
|
19748
19961
|
var Portal$2 = DialogPortal$1;
|
|
19749
19962
|
var Overlay = DialogOverlay$1;
|
|
19750
19963
|
var Content$1 = DialogContent$1;
|
|
@@ -20043,6 +20256,7 @@ function B({ asChild: r2, children: o }, n) {
|
|
|
20043
20256
|
return r2 && reactExports.isValidElement(o) ? reactExports.cloneElement(Me(o), { ref: o.ref }, n(o.props.children)) : n(o);
|
|
20044
20257
|
}
|
|
20045
20258
|
var Te = { position: "absolute", width: "1px", height: "1px", padding: "0", margin: "-1px", overflow: "hidden", clip: "rect(0, 0, 0, 0)", whiteSpace: "nowrap", borderWidth: "0" };
|
|
20259
|
+
const Dialog = Root$2;
|
|
20046
20260
|
const DialogPortal = Portal$2;
|
|
20047
20261
|
const DialogOverlay = reactExports.forwardRef(({ className, ...props }, ref2) => /* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
20048
20262
|
Overlay,
|
|
@@ -20078,6 +20292,20 @@ const DialogContent = reactExports.forwardRef(({ className, children, ...props }
|
|
|
20078
20292
|
)
|
|
20079
20293
|
] }));
|
|
20080
20294
|
DialogContent.displayName = Content$1.displayName;
|
|
20295
|
+
const DialogHeader = ({
|
|
20296
|
+
className,
|
|
20297
|
+
...props
|
|
20298
|
+
}) => /* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
20299
|
+
"div",
|
|
20300
|
+
{
|
|
20301
|
+
className: cn(
|
|
20302
|
+
"flex flex-col space-y-1.5 text-center sm:text-left",
|
|
20303
|
+
className
|
|
20304
|
+
),
|
|
20305
|
+
...props
|
|
20306
|
+
}
|
|
20307
|
+
);
|
|
20308
|
+
DialogHeader.displayName = "DialogHeader";
|
|
20081
20309
|
const DialogTitle = reactExports.forwardRef(({ className, ...props }, ref2) => /* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
20082
20310
|
Title,
|
|
20083
20311
|
{
|
|
@@ -26540,7 +26768,7 @@ const ToolRunCard = ({
|
|
|
26540
26768
|
const isUpdatingExistingRequest = currentRequestId !== null;
|
|
26541
26769
|
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
26770
|
/* @__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: [
|
|
26771
|
+
/* @__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
26772
|
/* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
26545
26773
|
ParametersSection,
|
|
26546
26774
|
{
|
|
@@ -26549,15 +26777,6 @@ const ToolRunCard = ({
|
|
|
26549
26777
|
onParamChange: handleParamChange
|
|
26550
26778
|
}
|
|
26551
26779
|
),
|
|
26552
|
-
/* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
26553
|
-
ActionButtons,
|
|
26554
|
-
{
|
|
26555
|
-
onSave: handleOpenSaveDialog,
|
|
26556
|
-
onRun: handleRunTool,
|
|
26557
|
-
isRunning: isToolRunning,
|
|
26558
|
-
isUpdating: isUpdatingExistingRequest
|
|
26559
|
-
}
|
|
26560
|
-
),
|
|
26561
26780
|
/* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
26562
26781
|
SaveDialog,
|
|
26563
26782
|
{
|
|
@@ -26572,7 +26791,16 @@ const ToolRunCard = ({
|
|
|
26572
26791
|
onDescriptionChange: setSaveRequestDescription
|
|
26573
26792
|
}
|
|
26574
26793
|
)
|
|
26575
|
-
] }) : /* @__PURE__ */ jsxRuntimeExports.jsx(EmptyState, {}) })
|
|
26794
|
+
] }) : /* @__PURE__ */ jsxRuntimeExports.jsx(EmptyState, {}) }) }),
|
|
26795
|
+
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(
|
|
26796
|
+
ActionButtons,
|
|
26797
|
+
{
|
|
26798
|
+
onSave: handleOpenSaveDialog,
|
|
26799
|
+
onRun: handleRunTool,
|
|
26800
|
+
isRunning: isToolRunning,
|
|
26801
|
+
isUpdating: isUpdatingExistingRequest
|
|
26802
|
+
}
|
|
26803
|
+
) })
|
|
26576
26804
|
] });
|
|
26577
26805
|
};
|
|
26578
26806
|
const ToolsTab = ({
|
|
@@ -28625,7 +28853,7 @@ const useTheme = () => {
|
|
|
28625
28853
|
[theme, setThemeWithSideEffect]
|
|
28626
28854
|
);
|
|
28627
28855
|
};
|
|
28628
|
-
const version$1 = "0.2.
|
|
28856
|
+
const version$1 = "0.2.4";
|
|
28629
28857
|
var [createTooltipContext, createTooltipScope] = createContextScope("Tooltip", [
|
|
28630
28858
|
createPopperScope
|
|
28631
28859
|
]);
|
|
@@ -29656,6 +29884,475 @@ const SettingsTab = ({
|
|
|
29656
29884
|
] })
|
|
29657
29885
|
] }) });
|
|
29658
29886
|
};
|
|
29887
|
+
function isValidJSON(jsonString) {
|
|
29888
|
+
try {
|
|
29889
|
+
JSON.parse(jsonString);
|
|
29890
|
+
return true;
|
|
29891
|
+
} catch {
|
|
29892
|
+
return false;
|
|
29893
|
+
}
|
|
29894
|
+
}
|
|
29895
|
+
function isValidMCPConfig(config) {
|
|
29896
|
+
return typeof config === "object" && config !== null && "mcpServers" in config && typeof config.mcpServers === "object" && config.mcpServers !== null;
|
|
29897
|
+
}
|
|
29898
|
+
function isValidServerConfig(config) {
|
|
29899
|
+
if (typeof config !== "object" || config === null) {
|
|
29900
|
+
return false;
|
|
29901
|
+
}
|
|
29902
|
+
const configObj = config;
|
|
29903
|
+
const hasCommand = "command" in configObj && typeof configObj.command === "string";
|
|
29904
|
+
const hasUrl = "url" in configObj && typeof configObj.url === "string";
|
|
29905
|
+
return hasCommand || hasUrl;
|
|
29906
|
+
}
|
|
29907
|
+
function isSingleNamedServerConfig(config) {
|
|
29908
|
+
if (typeof config !== "object" || config === null) {
|
|
29909
|
+
return false;
|
|
29910
|
+
}
|
|
29911
|
+
const configObj = config;
|
|
29912
|
+
const keys = Object.keys(configObj);
|
|
29913
|
+
if (keys.length !== 1) {
|
|
29914
|
+
return false;
|
|
29915
|
+
}
|
|
29916
|
+
const serverConfig = configObj[keys[0]];
|
|
29917
|
+
return isValidServerConfig(serverConfig);
|
|
29918
|
+
}
|
|
29919
|
+
function validateMCPConfigStructure(config) {
|
|
29920
|
+
const errors = [];
|
|
29921
|
+
if (typeof config !== "object" || config === null) {
|
|
29922
|
+
errors.push("Configuration must be a JSON object");
|
|
29923
|
+
return { isGlobal: false, isSingleNamed: false, errors };
|
|
29924
|
+
}
|
|
29925
|
+
if (isValidMCPConfig(config)) {
|
|
29926
|
+
const mcpServers = config.mcpServers;
|
|
29927
|
+
const serverNames = Object.keys(mcpServers);
|
|
29928
|
+
if (serverNames.length === 0) {
|
|
29929
|
+
errors.push('"mcpServers" object is empty. Please add at least one server configuration');
|
|
29930
|
+
}
|
|
29931
|
+
return { isGlobal: true, isSingleNamed: false, errors };
|
|
29932
|
+
}
|
|
29933
|
+
if (isSingleNamedServerConfig(config)) {
|
|
29934
|
+
return { isGlobal: false, isSingleNamed: true, errors };
|
|
29935
|
+
}
|
|
29936
|
+
errors.push(
|
|
29937
|
+
'Invalid configuration format. Please provide either:\n• A global config: {"mcpServers": {"server-name": {...}}}\n• A named server config: {"server-name": {"command": "npx", "args": [...]}}'
|
|
29938
|
+
);
|
|
29939
|
+
return { isGlobal: false, isSingleNamed: false, errors };
|
|
29940
|
+
}
|
|
29941
|
+
function convertToMCPJamServerConfig(entry) {
|
|
29942
|
+
if (entry.command) {
|
|
29943
|
+
return {
|
|
29944
|
+
transportType: "stdio",
|
|
29945
|
+
command: entry.command,
|
|
29946
|
+
args: entry.args,
|
|
29947
|
+
env: entry.env,
|
|
29948
|
+
timeout: entry.timeout,
|
|
29949
|
+
capabilities: entry.capabilities,
|
|
29950
|
+
enableServerLogs: entry.enableServerLogs
|
|
29951
|
+
};
|
|
29952
|
+
} else if (entry.url) {
|
|
29953
|
+
let transportType;
|
|
29954
|
+
if (entry.type) {
|
|
29955
|
+
transportType = entry.type === "sse" ? "sse" : "streamable-http";
|
|
29956
|
+
} else {
|
|
29957
|
+
transportType = entry.url.toLowerCase().includes("sse") ? "sse" : "streamable-http";
|
|
29958
|
+
}
|
|
29959
|
+
return {
|
|
29960
|
+
transportType,
|
|
29961
|
+
url: new URL(entry.url),
|
|
29962
|
+
requestInit: entry.requestInit,
|
|
29963
|
+
eventSourceInit: entry.eventSourceInit,
|
|
29964
|
+
reconnectionOptions: entry.reconnectionOptions,
|
|
29965
|
+
sessionId: entry.sessionId,
|
|
29966
|
+
timeout: entry.timeout,
|
|
29967
|
+
capabilities: entry.capabilities,
|
|
29968
|
+
enableServerLogs: entry.enableServerLogs
|
|
29969
|
+
};
|
|
29970
|
+
} else {
|
|
29971
|
+
throw new Error("Invalid server configuration: missing command or url");
|
|
29972
|
+
}
|
|
29973
|
+
}
|
|
29974
|
+
function validateServerConfig(name, entry) {
|
|
29975
|
+
const errors = [];
|
|
29976
|
+
if (!entry.command && !entry.url) {
|
|
29977
|
+
errors.push(
|
|
29978
|
+
`Server "${name}": Must have either 'command' (for STDIO) or 'url' (for HTTP/SSE). Example: {"command": "npx", "args": ["server-package"]} or {"url": "https://...", "type": "sse"}`
|
|
29979
|
+
);
|
|
29980
|
+
}
|
|
29981
|
+
if (entry.command && entry.url) {
|
|
29982
|
+
errors.push(
|
|
29983
|
+
`Server "${name}": Cannot have both 'command' and 'url'. Use 'command' for STDIO servers or 'url' for HTTP/SSE servers, but not both`
|
|
29984
|
+
);
|
|
29985
|
+
}
|
|
29986
|
+
if (entry.command) {
|
|
29987
|
+
if (typeof entry.command !== "string" || entry.command.trim() === "") {
|
|
29988
|
+
errors.push(
|
|
29989
|
+
`Server "${name}": 'command' must be a non-empty string. Example: "npx", "node", "python", etc.`
|
|
29990
|
+
);
|
|
29991
|
+
}
|
|
29992
|
+
if (entry.args && !Array.isArray(entry.args)) {
|
|
29993
|
+
errors.push(
|
|
29994
|
+
`Server "${name}": 'args' must be an array of strings. Example: ["@modelcontextprotocol/server-everything"] or ["build/index.js", "--port", "3000"]`
|
|
29995
|
+
);
|
|
29996
|
+
}
|
|
29997
|
+
if (entry.env && typeof entry.env !== "object") {
|
|
29998
|
+
errors.push(
|
|
29999
|
+
`Server "${name}": 'env' must be an object with string keys and values. Example: {"API_KEY": "your-key", "DEBUG": "true"}`
|
|
30000
|
+
);
|
|
30001
|
+
}
|
|
30002
|
+
}
|
|
30003
|
+
if (entry.url) {
|
|
30004
|
+
try {
|
|
30005
|
+
new URL(entry.url);
|
|
30006
|
+
} catch {
|
|
30007
|
+
errors.push(
|
|
30008
|
+
`Server "${name}": 'url' must be a valid URL. Example: "https://api.example.com/mcp" or "https://localhost:3000/sse"`
|
|
30009
|
+
);
|
|
30010
|
+
}
|
|
30011
|
+
if (entry.type && !["sse", "streamable-http"].includes(entry.type)) {
|
|
30012
|
+
errors.push(
|
|
30013
|
+
`Server "${name}": 'type' must be either 'sse' or 'streamable-http'. If not specified, defaults to 'streamable-http'`
|
|
30014
|
+
);
|
|
30015
|
+
}
|
|
30016
|
+
}
|
|
30017
|
+
return errors;
|
|
30018
|
+
}
|
|
30019
|
+
function parseConfigFile(jsonString) {
|
|
30020
|
+
const result = {
|
|
30021
|
+
success: false,
|
|
30022
|
+
servers: [],
|
|
30023
|
+
errors: []
|
|
30024
|
+
};
|
|
30025
|
+
if (!isValidJSON(jsonString)) {
|
|
30026
|
+
result.errors.push("Invalid JSON format. Please check for missing quotes, commas, or brackets");
|
|
30027
|
+
return result;
|
|
30028
|
+
}
|
|
30029
|
+
let parsedConfig;
|
|
30030
|
+
try {
|
|
30031
|
+
parsedConfig = JSON.parse(jsonString);
|
|
30032
|
+
} catch (error) {
|
|
30033
|
+
result.errors.push(`JSON parsing error: ${error instanceof Error ? error.message : String(error)}`);
|
|
30034
|
+
return result;
|
|
30035
|
+
}
|
|
30036
|
+
const { isGlobal, isSingleNamed, errors: structureErrors } = validateMCPConfigStructure(parsedConfig);
|
|
30037
|
+
if (structureErrors.length > 0) {
|
|
30038
|
+
result.errors.push(...structureErrors);
|
|
30039
|
+
return result;
|
|
30040
|
+
}
|
|
30041
|
+
const servers = [];
|
|
30042
|
+
const allErrors = [];
|
|
30043
|
+
if (isGlobal) {
|
|
30044
|
+
const validConfig = parsedConfig;
|
|
30045
|
+
for (const [serverName, serverConfig] of Object.entries(validConfig.mcpServers)) {
|
|
30046
|
+
if (typeof serverName !== "string" || serverName.trim() === "") {
|
|
30047
|
+
allErrors.push("Server names must be non-empty strings");
|
|
30048
|
+
continue;
|
|
30049
|
+
}
|
|
30050
|
+
const validationErrors = validateServerConfig(serverName, serverConfig);
|
|
30051
|
+
if (validationErrors.length > 0) {
|
|
30052
|
+
allErrors.push(...validationErrors);
|
|
30053
|
+
continue;
|
|
30054
|
+
}
|
|
30055
|
+
try {
|
|
30056
|
+
const mcpConfig = convertToMCPJamServerConfig(serverConfig);
|
|
30057
|
+
servers.push({
|
|
30058
|
+
name: serverName,
|
|
30059
|
+
config: mcpConfig
|
|
30060
|
+
});
|
|
30061
|
+
} catch (error) {
|
|
30062
|
+
allErrors.push(
|
|
30063
|
+
`Server "${serverName}": ${error instanceof Error ? error.message : String(error)}`
|
|
30064
|
+
);
|
|
30065
|
+
}
|
|
30066
|
+
}
|
|
30067
|
+
} else if (isSingleNamed) {
|
|
30068
|
+
const serverConfig = parsedConfig;
|
|
30069
|
+
const serverName = Object.keys(serverConfig)[0];
|
|
30070
|
+
const validationErrors = validateServerConfig(serverName, serverConfig[serverName]);
|
|
30071
|
+
if (validationErrors.length > 0) {
|
|
30072
|
+
allErrors.push(...validationErrors);
|
|
30073
|
+
} else {
|
|
30074
|
+
try {
|
|
30075
|
+
const mcpConfig = convertToMCPJamServerConfig(serverConfig[serverName]);
|
|
30076
|
+
servers.push({
|
|
30077
|
+
name: serverName,
|
|
30078
|
+
config: mcpConfig
|
|
30079
|
+
});
|
|
30080
|
+
} catch (error) {
|
|
30081
|
+
allErrors.push(
|
|
30082
|
+
`Server configuration: ${error instanceof Error ? error.message : String(error)}`
|
|
30083
|
+
);
|
|
30084
|
+
}
|
|
30085
|
+
}
|
|
30086
|
+
}
|
|
30087
|
+
result.servers = servers;
|
|
30088
|
+
result.errors = allErrors;
|
|
30089
|
+
result.success = allErrors.length === 0 && servers.length > 0;
|
|
30090
|
+
return result;
|
|
30091
|
+
}
|
|
30092
|
+
function generateExampleConfig() {
|
|
30093
|
+
const exampleConfig = {
|
|
30094
|
+
mcpServers: {
|
|
30095
|
+
"example-stdio-server": {
|
|
30096
|
+
command: "npx",
|
|
30097
|
+
args: ["@modelcontextprotocol/server-everything"],
|
|
30098
|
+
env: {
|
|
30099
|
+
API_KEY: "your-api-key",
|
|
30100
|
+
DEBUG: "true"
|
|
30101
|
+
}
|
|
30102
|
+
},
|
|
30103
|
+
"example-sse-server": {
|
|
30104
|
+
url: "https://api.example.com/mcp/sse",
|
|
30105
|
+
type: "sse"
|
|
30106
|
+
},
|
|
30107
|
+
"example-http-server": {
|
|
30108
|
+
url: "https://api.example.com/mcp/http",
|
|
30109
|
+
type: "streamable-http"
|
|
30110
|
+
}
|
|
30111
|
+
}
|
|
30112
|
+
};
|
|
30113
|
+
return JSON.stringify(exampleConfig, null, 2);
|
|
30114
|
+
}
|
|
30115
|
+
const ConfigImportDialog = ({
|
|
30116
|
+
open,
|
|
30117
|
+
onOpenChange,
|
|
30118
|
+
onImportServers
|
|
30119
|
+
}) => {
|
|
30120
|
+
const [configText, setConfigText] = reactExports.useState("");
|
|
30121
|
+
const [parseResult, setParseResult] = reactExports.useState(null);
|
|
30122
|
+
const [isValidating, setIsValidating] = reactExports.useState(false);
|
|
30123
|
+
const { toast: toast2 } = useToast();
|
|
30124
|
+
const handleConfigChange = reactExports.useCallback((value) => {
|
|
30125
|
+
setConfigText(value);
|
|
30126
|
+
setParseResult(null);
|
|
30127
|
+
}, []);
|
|
30128
|
+
const validateConfig = reactExports.useCallback(() => {
|
|
30129
|
+
if (!configText.trim()) {
|
|
30130
|
+
setParseResult({
|
|
30131
|
+
success: false,
|
|
30132
|
+
servers: [],
|
|
30133
|
+
errors: ["Please enter a configuration"]
|
|
30134
|
+
});
|
|
30135
|
+
return;
|
|
30136
|
+
}
|
|
30137
|
+
setIsValidating(true);
|
|
30138
|
+
try {
|
|
30139
|
+
const result = parseConfigFile(configText);
|
|
30140
|
+
setParseResult(result);
|
|
30141
|
+
} catch (error) {
|
|
30142
|
+
setParseResult({
|
|
30143
|
+
success: false,
|
|
30144
|
+
servers: [],
|
|
30145
|
+
errors: [`Unexpected error: ${error instanceof Error ? error.message : String(error)}`]
|
|
30146
|
+
});
|
|
30147
|
+
} finally {
|
|
30148
|
+
setIsValidating(false);
|
|
30149
|
+
}
|
|
30150
|
+
}, [configText]);
|
|
30151
|
+
const handleImport = reactExports.useCallback(() => {
|
|
30152
|
+
if ((parseResult == null ? void 0 : parseResult.success) && parseResult.servers.length > 0) {
|
|
30153
|
+
onImportServers(parseResult.servers);
|
|
30154
|
+
toast2({
|
|
30155
|
+
title: "Configuration imported",
|
|
30156
|
+
description: `Successfully imported ${parseResult.servers.length} server(s)`
|
|
30157
|
+
});
|
|
30158
|
+
onOpenChange(false);
|
|
30159
|
+
setConfigText("");
|
|
30160
|
+
setParseResult(null);
|
|
30161
|
+
}
|
|
30162
|
+
}, [parseResult, onImportServers, onOpenChange, toast2]);
|
|
30163
|
+
const handlePasteExample = reactExports.useCallback(() => {
|
|
30164
|
+
const example = generateExampleConfig();
|
|
30165
|
+
setConfigText(example);
|
|
30166
|
+
setParseResult(null);
|
|
30167
|
+
}, []);
|
|
30168
|
+
const handleCopyExample = reactExports.useCallback(async () => {
|
|
30169
|
+
try {
|
|
30170
|
+
const example = generateExampleConfig();
|
|
30171
|
+
await navigator.clipboard.writeText(example);
|
|
30172
|
+
toast2({
|
|
30173
|
+
title: "Example copied",
|
|
30174
|
+
description: "Example configuration has been copied to clipboard"
|
|
30175
|
+
});
|
|
30176
|
+
} catch {
|
|
30177
|
+
toast2({
|
|
30178
|
+
title: "Copy failed",
|
|
30179
|
+
description: "Failed to copy example configuration",
|
|
30180
|
+
variant: "destructive"
|
|
30181
|
+
});
|
|
30182
|
+
}
|
|
30183
|
+
}, [toast2]);
|
|
30184
|
+
const handleClose = reactExports.useCallback(() => {
|
|
30185
|
+
onOpenChange(false);
|
|
30186
|
+
setConfigText("");
|
|
30187
|
+
setParseResult(null);
|
|
30188
|
+
}, [onOpenChange]);
|
|
30189
|
+
return /* @__PURE__ */ jsxRuntimeExports.jsx(Dialog, { open, onOpenChange, children: /* @__PURE__ */ jsxRuntimeExports.jsxs(DialogContent, { className: "max-w-4xl max-h-[90vh] flex flex-col", children: [
|
|
30190
|
+
/* @__PURE__ */ jsxRuntimeExports.jsxs(DialogHeader, { children: [
|
|
30191
|
+
/* @__PURE__ */ jsxRuntimeExports.jsxs(DialogTitle, { className: "flex items-center gap-2", children: [
|
|
30192
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx(Upload, { className: "h-5 w-5" }),
|
|
30193
|
+
"Import MCP Configuration"
|
|
30194
|
+
] }),
|
|
30195
|
+
/* @__PURE__ */ jsxRuntimeExports.jsxs(DialogDescription, { children: [
|
|
30196
|
+
"Paste your MCP configuration JSON to import servers. Supports:",
|
|
30197
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("br", {}),
|
|
30198
|
+
"• ",
|
|
30199
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("strong", { children: "Global config" }),
|
|
30200
|
+
': Complete mcp.json with "mcpServers" wrapper',
|
|
30201
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("br", {}),
|
|
30202
|
+
"• ",
|
|
30203
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("strong", { children: "Named server" }),
|
|
30204
|
+
": Single server with name key"
|
|
30205
|
+
] })
|
|
30206
|
+
] }),
|
|
30207
|
+
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex-1 flex flex-col gap-4 min-h-0", children: [
|
|
30208
|
+
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "space-y-2", children: [
|
|
30209
|
+
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex items-center justify-between", children: [
|
|
30210
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("label", { className: "text-sm font-medium", children: "Configuration JSON" }),
|
|
30211
|
+
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex gap-2", children: [
|
|
30212
|
+
/* @__PURE__ */ jsxRuntimeExports.jsxs(
|
|
30213
|
+
Button,
|
|
30214
|
+
{
|
|
30215
|
+
variant: "outline",
|
|
30216
|
+
size: "sm",
|
|
30217
|
+
onClick: handlePasteExample,
|
|
30218
|
+
className: "h-7 px-2 text-xs",
|
|
30219
|
+
children: [
|
|
30220
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx(FileText, { className: "h-3 w-3 mr-1" }),
|
|
30221
|
+
"Paste Example"
|
|
30222
|
+
]
|
|
30223
|
+
}
|
|
30224
|
+
),
|
|
30225
|
+
/* @__PURE__ */ jsxRuntimeExports.jsxs(
|
|
30226
|
+
Button,
|
|
30227
|
+
{
|
|
30228
|
+
variant: "outline",
|
|
30229
|
+
size: "sm",
|
|
30230
|
+
onClick: handleCopyExample,
|
|
30231
|
+
className: "h-7 px-2 text-xs",
|
|
30232
|
+
children: [
|
|
30233
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx(Copy, { className: "h-3 w-3 mr-1" }),
|
|
30234
|
+
"Copy Example"
|
|
30235
|
+
]
|
|
30236
|
+
}
|
|
30237
|
+
)
|
|
30238
|
+
] })
|
|
30239
|
+
] }),
|
|
30240
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
30241
|
+
Textarea,
|
|
30242
|
+
{
|
|
30243
|
+
value: configText,
|
|
30244
|
+
onChange: (e) => handleConfigChange(e.target.value),
|
|
30245
|
+
placeholder: `Paste your configuration here. Supports two formats:
|
|
30246
|
+
|
|
30247
|
+
1. Global config (complete mcp.json):
|
|
30248
|
+
{
|
|
30249
|
+
"mcpServers": {
|
|
30250
|
+
"my-server": {
|
|
30251
|
+
"command": "npx",
|
|
30252
|
+
"args": ["@modelcontextprotocol/server-everything"]
|
|
30253
|
+
}
|
|
30254
|
+
}
|
|
30255
|
+
}
|
|
30256
|
+
|
|
30257
|
+
2. Named server config:
|
|
30258
|
+
{
|
|
30259
|
+
"everything": {
|
|
30260
|
+
"command": "npx",
|
|
30261
|
+
"args": ["@modelcontextprotocol/server-everything"]
|
|
30262
|
+
}
|
|
30263
|
+
}
|
|
30264
|
+
|
|
30265
|
+
or
|
|
30266
|
+
|
|
30267
|
+
{
|
|
30268
|
+
"my-sse-server": {
|
|
30269
|
+
"url": "https://api.example.com/mcp",
|
|
30270
|
+
"type": "sse"
|
|
30271
|
+
}
|
|
30272
|
+
}`,
|
|
30273
|
+
className: "font-mono text-xs min-h-[200px] resize-none"
|
|
30274
|
+
}
|
|
30275
|
+
)
|
|
30276
|
+
] }),
|
|
30277
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "flex gap-2", children: /* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
30278
|
+
Button,
|
|
30279
|
+
{
|
|
30280
|
+
onClick: validateConfig,
|
|
30281
|
+
disabled: !configText.trim() || isValidating,
|
|
30282
|
+
variant: "outline",
|
|
30283
|
+
className: "flex-1",
|
|
30284
|
+
children: isValidating ? /* @__PURE__ */ jsxRuntimeExports.jsxs(jsxRuntimeExports.Fragment, { children: [
|
|
30285
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "animate-spin rounded-full h-4 w-4 border-b-2 border-current mr-2" }),
|
|
30286
|
+
"Validating..."
|
|
30287
|
+
] }) : /* @__PURE__ */ jsxRuntimeExports.jsxs(jsxRuntimeExports.Fragment, { children: [
|
|
30288
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx(CircleAlert, { className: "h-4 w-4 mr-2" }),
|
|
30289
|
+
"Validate Configuration"
|
|
30290
|
+
] })
|
|
30291
|
+
}
|
|
30292
|
+
) }),
|
|
30293
|
+
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: [
|
|
30294
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx(CircleCheckBig, { className: "h-4 w-4" }),
|
|
30295
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx(AlertTitle, { children: "Configuration Valid" }),
|
|
30296
|
+
/* @__PURE__ */ jsxRuntimeExports.jsxs(AlertDescription, { children: [
|
|
30297
|
+
"Found ",
|
|
30298
|
+
parseResult.servers.length,
|
|
30299
|
+
" server(s) ready to import:",
|
|
30300
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("ul", { className: "mt-2 space-y-1", children: parseResult.servers.map((server) => {
|
|
30301
|
+
var _a2;
|
|
30302
|
+
return /* @__PURE__ */ jsxRuntimeExports.jsxs("li", { className: "text-xs font-mono", children: [
|
|
30303
|
+
"• ",
|
|
30304
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("strong", { children: server.name }),
|
|
30305
|
+
" (",
|
|
30306
|
+
server.config.transportType,
|
|
30307
|
+
")",
|
|
30308
|
+
server.config.transportType === "stdio" && "command" in server.config && /* @__PURE__ */ jsxRuntimeExports.jsxs("span", { className: "text-muted-foreground ml-2", children: [
|
|
30309
|
+
server.config.command,
|
|
30310
|
+
" ",
|
|
30311
|
+
(_a2 = server.config.args) == null ? void 0 : _a2.join(" ")
|
|
30312
|
+
] }),
|
|
30313
|
+
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() })
|
|
30314
|
+
] }, server.name);
|
|
30315
|
+
}) })
|
|
30316
|
+
] })
|
|
30317
|
+
] }) : /* @__PURE__ */ jsxRuntimeExports.jsxs(Alert, { variant: "destructive", children: [
|
|
30318
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx(CircleAlert, { className: "h-4 w-4" }),
|
|
30319
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx(AlertTitle, { children: "Configuration Invalid" }),
|
|
30320
|
+
/* @__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: [
|
|
30321
|
+
"• ",
|
|
30322
|
+
error
|
|
30323
|
+
] }, index2)) }) })
|
|
30324
|
+
] }) })
|
|
30325
|
+
] }),
|
|
30326
|
+
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex gap-2 pt-4 border-t", children: [
|
|
30327
|
+
/* @__PURE__ */ jsxRuntimeExports.jsxs(
|
|
30328
|
+
Button,
|
|
30329
|
+
{
|
|
30330
|
+
variant: "outline",
|
|
30331
|
+
onClick: handleClose,
|
|
30332
|
+
className: "flex-1",
|
|
30333
|
+
children: [
|
|
30334
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx(X$1, { className: "h-4 w-4 mr-2" }),
|
|
30335
|
+
"Cancel"
|
|
30336
|
+
]
|
|
30337
|
+
}
|
|
30338
|
+
),
|
|
30339
|
+
/* @__PURE__ */ jsxRuntimeExports.jsxs(
|
|
30340
|
+
Button,
|
|
30341
|
+
{
|
|
30342
|
+
onClick: handleImport,
|
|
30343
|
+
disabled: !(parseResult == null ? void 0 : parseResult.success) || parseResult.servers.length === 0,
|
|
30344
|
+
className: "flex-1",
|
|
30345
|
+
children: [
|
|
30346
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx(Upload, { className: "h-4 w-4 mr-2" }),
|
|
30347
|
+
"Import ",
|
|
30348
|
+
(parseResult == null ? void 0 : parseResult.servers.length) || 0,
|
|
30349
|
+
" Server(s)"
|
|
30350
|
+
]
|
|
30351
|
+
}
|
|
30352
|
+
)
|
|
30353
|
+
] })
|
|
30354
|
+
] }) });
|
|
30355
|
+
};
|
|
29659
30356
|
const ConnectionSection = ({
|
|
29660
30357
|
connectionStatus,
|
|
29661
30358
|
transportType,
|
|
@@ -29681,12 +30378,14 @@ const ConnectionSection = ({
|
|
|
29681
30378
|
loggingSupported,
|
|
29682
30379
|
config,
|
|
29683
30380
|
setConfig,
|
|
29684
|
-
hideActionButtons
|
|
30381
|
+
hideActionButtons,
|
|
30382
|
+
onImportServers
|
|
29685
30383
|
}) => {
|
|
29686
30384
|
const [activeTab, setActiveTab] = reactExports.useState("connection");
|
|
29687
30385
|
const [shownEnvVars, setShownEnvVars] = reactExports.useState(/* @__PURE__ */ new Set());
|
|
29688
30386
|
const [copiedServerEntry, setCopiedServerEntry] = reactExports.useState(false);
|
|
29689
30387
|
const [copiedServerFile, setCopiedServerFile] = reactExports.useState(false);
|
|
30388
|
+
const [showImportDialog, setShowImportDialog] = reactExports.useState(false);
|
|
29690
30389
|
const { toast: toast2 } = useToast();
|
|
29691
30390
|
const reportError2 = reactExports.useCallback(
|
|
29692
30391
|
(error) => {
|
|
@@ -29782,7 +30481,8 @@ const ConnectionSection = ({
|
|
|
29782
30481
|
{ key: "auth", label: "Auth" },
|
|
29783
30482
|
...transportType === "stdio" ? [{ key: "env", label: "Environment" }] : [],
|
|
29784
30483
|
{ key: "config", label: "Configuration" },
|
|
29785
|
-
...loggingSupported ? [{ key: "logging", label: "Logging" }] : []
|
|
30484
|
+
...loggingSupported ? [{ key: "logging", label: "Logging" }] : [],
|
|
30485
|
+
...onImportServers ? [{ key: "import", label: "Import" }] : []
|
|
29786
30486
|
].map((tab) => /* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
29787
30487
|
"button",
|
|
29788
30488
|
{
|
|
@@ -30020,6 +30720,21 @@ const ConnectionSection = ({
|
|
|
30020
30720
|
}
|
|
30021
30721
|
)
|
|
30022
30722
|
] })
|
|
30723
|
+
] }),
|
|
30724
|
+
activeTab === "import" && onImportServers && /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "space-y-3", children: [
|
|
30725
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("h3", { className: "text-sm font-semibold text-slate-800 dark:text-slate-200", children: "Import Configuration" }),
|
|
30726
|
+
/* @__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." }),
|
|
30727
|
+
/* @__PURE__ */ jsxRuntimeExports.jsxs(
|
|
30728
|
+
Button,
|
|
30729
|
+
{
|
|
30730
|
+
onClick: () => setShowImportDialog(true),
|
|
30731
|
+
className: "w-full h-8 text-xs",
|
|
30732
|
+
children: [
|
|
30733
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx(Upload, { className: "w-3 h-3 mr-2" }),
|
|
30734
|
+
"Import from Configuration File"
|
|
30735
|
+
]
|
|
30736
|
+
}
|
|
30737
|
+
)
|
|
30023
30738
|
] })
|
|
30024
30739
|
] });
|
|
30025
30740
|
};
|
|
@@ -30217,7 +30932,15 @@ const ConnectionSection = ({
|
|
|
30217
30932
|
},
|
|
30218
30933
|
index2
|
|
30219
30934
|
)) })
|
|
30220
|
-
] }) })
|
|
30935
|
+
] }) }),
|
|
30936
|
+
onImportServers && /* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
30937
|
+
ConfigImportDialog,
|
|
30938
|
+
{
|
|
30939
|
+
open: showImportDialog,
|
|
30940
|
+
onOpenChange: setShowImportDialog,
|
|
30941
|
+
onImportServers
|
|
30942
|
+
}
|
|
30943
|
+
)
|
|
30221
30944
|
] });
|
|
30222
30945
|
};
|
|
30223
30946
|
const ClientFormSection = ({
|
|
@@ -30234,9 +30957,15 @@ const ClientFormSection = ({
|
|
|
30234
30957
|
headerName,
|
|
30235
30958
|
setHeaderName,
|
|
30236
30959
|
onSave,
|
|
30237
|
-
onCancel
|
|
30960
|
+
onCancel,
|
|
30961
|
+
onImportMultipleServers,
|
|
30962
|
+
onSaveMultiple
|
|
30238
30963
|
}) => {
|
|
30239
30964
|
const [argsString, setArgsString] = reactExports.useState("");
|
|
30965
|
+
const [multipleClients, setMultipleClients] = reactExports.useState([]);
|
|
30966
|
+
const [isMultipleMode, setIsMultipleMode] = reactExports.useState(false);
|
|
30967
|
+
const { toast: toast2 } = useToast();
|
|
30968
|
+
const [showImportDialog, setShowImportDialog] = reactExports.useState(false);
|
|
30240
30969
|
reactExports.useEffect(() => {
|
|
30241
30970
|
var _a2;
|
|
30242
30971
|
if (clientFormConfig.transportType === "stdio" && "args" in clientFormConfig) {
|
|
@@ -30252,12 +30981,328 @@ const ClientFormSection = ({
|
|
|
30252
30981
|
});
|
|
30253
30982
|
}
|
|
30254
30983
|
};
|
|
30984
|
+
const handleImportServers = (servers) => {
|
|
30985
|
+
var _a2;
|
|
30986
|
+
if (servers.length > 1) {
|
|
30987
|
+
const clients = servers.map((server, index2) => {
|
|
30988
|
+
var _a3;
|
|
30989
|
+
return {
|
|
30990
|
+
id: `client-${Date.now()}-${index2}`,
|
|
30991
|
+
name: server.name,
|
|
30992
|
+
config: server.config,
|
|
30993
|
+
argsString: server.config.transportType === "stdio" && "args" in server.config ? ((_a3 = server.config.args) == null ? void 0 : _a3.join(" ")) || "" : ""
|
|
30994
|
+
};
|
|
30995
|
+
});
|
|
30996
|
+
setMultipleClients(clients);
|
|
30997
|
+
setIsMultipleMode(true);
|
|
30998
|
+
toast2({
|
|
30999
|
+
title: "Multiple servers imported",
|
|
31000
|
+
description: `Imported ${servers.length} server configurations. Configure each client below.`
|
|
31001
|
+
});
|
|
31002
|
+
} else if (servers.length === 1) {
|
|
31003
|
+
const firstServer = servers[0];
|
|
31004
|
+
setClientFormConfig(firstServer.config);
|
|
31005
|
+
if (!clientFormName.trim()) {
|
|
31006
|
+
setClientFormName(firstServer.name);
|
|
31007
|
+
}
|
|
31008
|
+
if (firstServer.config.transportType === "stdio" && "args" in firstServer.config) {
|
|
31009
|
+
setArgsString(((_a2 = firstServer.config.args) == null ? void 0 : _a2.join(" ")) || "");
|
|
31010
|
+
}
|
|
31011
|
+
toast2({
|
|
31012
|
+
title: "Configuration imported",
|
|
31013
|
+
description: `Imported configuration for "${firstServer.name}".`
|
|
31014
|
+
});
|
|
31015
|
+
}
|
|
31016
|
+
if (onImportMultipleServers) {
|
|
31017
|
+
onImportMultipleServers(servers);
|
|
31018
|
+
}
|
|
31019
|
+
};
|
|
31020
|
+
const handleUpdateClient = (clientId, updates) => {
|
|
31021
|
+
setMultipleClients(
|
|
31022
|
+
(prev) => prev.map(
|
|
31023
|
+
(client2) => client2.id === clientId ? { ...client2, ...updates } : client2
|
|
31024
|
+
)
|
|
31025
|
+
);
|
|
31026
|
+
};
|
|
31027
|
+
const handleRemoveClient = (clientId) => {
|
|
31028
|
+
setMultipleClients((prev) => prev.filter((client2) => client2.id !== clientId));
|
|
31029
|
+
};
|
|
31030
|
+
const handleAddClient = () => {
|
|
31031
|
+
const newClient = {
|
|
31032
|
+
id: `client-${Date.now()}`,
|
|
31033
|
+
name: "",
|
|
31034
|
+
config: {
|
|
31035
|
+
transportType: "stdio",
|
|
31036
|
+
command: "npx",
|
|
31037
|
+
args: ["@modelcontextprotocol/server-everything"],
|
|
31038
|
+
env: {}
|
|
31039
|
+
},
|
|
31040
|
+
argsString: "@modelcontextprotocol/server-everything"
|
|
31041
|
+
};
|
|
31042
|
+
setMultipleClients((prev) => [...prev, newClient]);
|
|
31043
|
+
};
|
|
31044
|
+
const handleSaveAll = async () => {
|
|
31045
|
+
const validClients = multipleClients.filter((client2) => client2.name.trim());
|
|
31046
|
+
if (validClients.length === 0) {
|
|
31047
|
+
toast2({
|
|
31048
|
+
title: "No valid clients",
|
|
31049
|
+
description: "Please provide names for at least one client.",
|
|
31050
|
+
variant: "destructive"
|
|
31051
|
+
});
|
|
31052
|
+
return;
|
|
31053
|
+
}
|
|
31054
|
+
const names = validClients.map((c) => c.name.trim());
|
|
31055
|
+
const duplicates = names.filter((name, index2) => names.indexOf(name) !== index2);
|
|
31056
|
+
if (duplicates.length > 0) {
|
|
31057
|
+
toast2({
|
|
31058
|
+
title: "Duplicate client names",
|
|
31059
|
+
description: `Please ensure all client names are unique. Duplicates: ${[...new Set(duplicates)].join(", ")}`,
|
|
31060
|
+
variant: "destructive"
|
|
31061
|
+
});
|
|
31062
|
+
return;
|
|
31063
|
+
}
|
|
31064
|
+
if (onSaveMultiple) {
|
|
31065
|
+
try {
|
|
31066
|
+
const results = await onSaveMultiple(validClients.map((client2) => ({
|
|
31067
|
+
name: client2.name.trim(),
|
|
31068
|
+
config: client2.config
|
|
31069
|
+
})));
|
|
31070
|
+
if (results.success.length > 0) {
|
|
31071
|
+
toast2({
|
|
31072
|
+
title: "Clients created",
|
|
31073
|
+
description: `Successfully created ${results.success.length} client(s): ${results.success.join(", ")}`
|
|
31074
|
+
});
|
|
31075
|
+
}
|
|
31076
|
+
if (results.failed.length > 0) {
|
|
31077
|
+
toast2({
|
|
31078
|
+
title: "Some clients failed",
|
|
31079
|
+
description: `${results.failed.length} client(s) failed to create. Check console for details.`,
|
|
31080
|
+
variant: "destructive"
|
|
31081
|
+
});
|
|
31082
|
+
}
|
|
31083
|
+
} catch (error) {
|
|
31084
|
+
console.error("Failed to create clients:", error);
|
|
31085
|
+
toast2({
|
|
31086
|
+
title: "Creation failed",
|
|
31087
|
+
description: `Failed to create clients: ${error instanceof Error ? error.message : String(error)}`,
|
|
31088
|
+
variant: "destructive"
|
|
31089
|
+
});
|
|
31090
|
+
}
|
|
31091
|
+
}
|
|
31092
|
+
};
|
|
31093
|
+
const handleBackToSingle = () => {
|
|
31094
|
+
setIsMultipleMode(false);
|
|
31095
|
+
setMultipleClients([]);
|
|
31096
|
+
};
|
|
31097
|
+
if (isMultipleMode) {
|
|
31098
|
+
return /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "flex-1 flex flex-col overflow-auto p-6", children: /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "max-w-6xl mx-auto w-full", children: [
|
|
31099
|
+
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "mb-6", children: [
|
|
31100
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("h2", { className: "text-2xl font-bold mb-2", children: "Create Multiple Clients" }),
|
|
31101
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("p", { className: "text-muted-foreground", children: "Configure each imported server as a separate client. You can modify settings individually." })
|
|
31102
|
+
] }),
|
|
31103
|
+
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "space-y-6", children: [
|
|
31104
|
+
multipleClients.map((client2, index2) => /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "border border-border rounded-lg p-4 space-y-4", children: [
|
|
31105
|
+
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex items-center justify-between", children: [
|
|
31106
|
+
/* @__PURE__ */ jsxRuntimeExports.jsxs("h3", { className: "text-lg font-semibold", children: [
|
|
31107
|
+
"Client ",
|
|
31108
|
+
index2 + 1
|
|
31109
|
+
] }),
|
|
31110
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
31111
|
+
Button,
|
|
31112
|
+
{
|
|
31113
|
+
variant: "outline",
|
|
31114
|
+
size: "sm",
|
|
31115
|
+
onClick: () => handleRemoveClient(client2.id),
|
|
31116
|
+
className: "h-8 w-8 p-0",
|
|
31117
|
+
children: /* @__PURE__ */ jsxRuntimeExports.jsx(X$1, { className: "h-4 w-4" })
|
|
31118
|
+
}
|
|
31119
|
+
)
|
|
31120
|
+
] }),
|
|
31121
|
+
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { children: [
|
|
31122
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("label", { className: "text-sm font-medium mb-2 block", children: "Client Name" }),
|
|
31123
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
31124
|
+
Input,
|
|
31125
|
+
{
|
|
31126
|
+
value: client2.name,
|
|
31127
|
+
onChange: (e) => handleUpdateClient(client2.id, { name: e.target.value }),
|
|
31128
|
+
placeholder: "Enter client name",
|
|
31129
|
+
className: "w-full"
|
|
31130
|
+
}
|
|
31131
|
+
)
|
|
31132
|
+
] }),
|
|
31133
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "border border-border rounded-lg", children: /* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
31134
|
+
ConnectionSection,
|
|
31135
|
+
{
|
|
31136
|
+
connectionStatus: "disconnected",
|
|
31137
|
+
transportType: client2.config.transportType,
|
|
31138
|
+
setTransportType: (type2) => {
|
|
31139
|
+
let newConfig;
|
|
31140
|
+
let newArgsString = "";
|
|
31141
|
+
if (type2 === "stdio") {
|
|
31142
|
+
newConfig = {
|
|
31143
|
+
transportType: type2,
|
|
31144
|
+
command: "npx",
|
|
31145
|
+
args: ["@modelcontextprotocol/server-everything"],
|
|
31146
|
+
env: {}
|
|
31147
|
+
};
|
|
31148
|
+
newArgsString = "@modelcontextprotocol/server-everything";
|
|
31149
|
+
} else {
|
|
31150
|
+
newConfig = {
|
|
31151
|
+
transportType: type2,
|
|
31152
|
+
url: new URL("https://example.com")
|
|
31153
|
+
};
|
|
31154
|
+
}
|
|
31155
|
+
handleUpdateClient(client2.id, {
|
|
31156
|
+
config: newConfig,
|
|
31157
|
+
argsString: newArgsString
|
|
31158
|
+
});
|
|
31159
|
+
},
|
|
31160
|
+
command: client2.config.transportType === "stdio" && "command" in client2.config ? client2.config.command || "" : "",
|
|
31161
|
+
setCommand: (command) => {
|
|
31162
|
+
if (client2.config.transportType === "stdio") {
|
|
31163
|
+
handleUpdateClient(client2.id, {
|
|
31164
|
+
config: {
|
|
31165
|
+
...client2.config,
|
|
31166
|
+
command
|
|
31167
|
+
}
|
|
31168
|
+
});
|
|
31169
|
+
}
|
|
31170
|
+
},
|
|
31171
|
+
args: client2.argsString,
|
|
31172
|
+
setArgs: (newArgsString) => {
|
|
31173
|
+
if (client2.config.transportType === "stdio") {
|
|
31174
|
+
handleUpdateClient(client2.id, {
|
|
31175
|
+
argsString: newArgsString,
|
|
31176
|
+
config: {
|
|
31177
|
+
...client2.config,
|
|
31178
|
+
args: newArgsString.trim() ? newArgsString.split(/\s+/) : []
|
|
31179
|
+
}
|
|
31180
|
+
});
|
|
31181
|
+
}
|
|
31182
|
+
},
|
|
31183
|
+
sseUrl: "url" in client2.config && client2.config.url ? client2.config.url.toString() : "",
|
|
31184
|
+
setSseUrl: (url) => {
|
|
31185
|
+
if (client2.config.transportType !== "stdio") {
|
|
31186
|
+
handleUpdateClient(client2.id, {
|
|
31187
|
+
config: {
|
|
31188
|
+
...client2.config,
|
|
31189
|
+
url: new URL(url)
|
|
31190
|
+
}
|
|
31191
|
+
});
|
|
31192
|
+
}
|
|
31193
|
+
},
|
|
31194
|
+
env: client2.config.transportType === "stdio" && "env" in client2.config ? client2.config.env || {} : {},
|
|
31195
|
+
setEnv: (env) => {
|
|
31196
|
+
if (client2.config.transportType === "stdio") {
|
|
31197
|
+
handleUpdateClient(client2.id, {
|
|
31198
|
+
config: {
|
|
31199
|
+
...client2.config,
|
|
31200
|
+
env
|
|
31201
|
+
}
|
|
31202
|
+
});
|
|
31203
|
+
}
|
|
31204
|
+
},
|
|
31205
|
+
config,
|
|
31206
|
+
setConfig,
|
|
31207
|
+
bearerToken,
|
|
31208
|
+
setBearerToken,
|
|
31209
|
+
headerName,
|
|
31210
|
+
setHeaderName,
|
|
31211
|
+
onConnect: () => {
|
|
31212
|
+
},
|
|
31213
|
+
onDisconnect: () => {
|
|
31214
|
+
},
|
|
31215
|
+
stdErrNotifications: [],
|
|
31216
|
+
clearStdErrNotifications: () => {
|
|
31217
|
+
},
|
|
31218
|
+
logLevel: "debug",
|
|
31219
|
+
sendLogLevelRequest: async () => {
|
|
31220
|
+
},
|
|
31221
|
+
loggingSupported: false,
|
|
31222
|
+
hideActionButtons: true
|
|
31223
|
+
}
|
|
31224
|
+
) })
|
|
31225
|
+
] }, client2.id)),
|
|
31226
|
+
/* @__PURE__ */ jsxRuntimeExports.jsxs(
|
|
31227
|
+
Button,
|
|
31228
|
+
{
|
|
31229
|
+
variant: "outline",
|
|
31230
|
+
onClick: handleAddClient,
|
|
31231
|
+
className: "w-full",
|
|
31232
|
+
children: [
|
|
31233
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx(Plus, { className: "h-4 w-4 mr-2" }),
|
|
31234
|
+
"Add Another Client"
|
|
31235
|
+
]
|
|
31236
|
+
}
|
|
31237
|
+
),
|
|
31238
|
+
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex space-x-3 pt-4 border-t", children: [
|
|
31239
|
+
/* @__PURE__ */ jsxRuntimeExports.jsxs(
|
|
31240
|
+
Button,
|
|
31241
|
+
{
|
|
31242
|
+
onClick: handleSaveAll,
|
|
31243
|
+
disabled: multipleClients.filter((c) => c.name.trim()).length === 0,
|
|
31244
|
+
className: "flex-1",
|
|
31245
|
+
children: [
|
|
31246
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx(Save, { className: "h-4 w-4 mr-2" }),
|
|
31247
|
+
"Create ",
|
|
31248
|
+
multipleClients.filter((c) => c.name.trim()).length,
|
|
31249
|
+
" Client(s)"
|
|
31250
|
+
]
|
|
31251
|
+
}
|
|
31252
|
+
),
|
|
31253
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
31254
|
+
Button,
|
|
31255
|
+
{
|
|
31256
|
+
variant: "outline",
|
|
31257
|
+
onClick: handleBackToSingle,
|
|
31258
|
+
className: "flex-1",
|
|
31259
|
+
children: "Back to Single Mode"
|
|
31260
|
+
}
|
|
31261
|
+
),
|
|
31262
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
31263
|
+
Button,
|
|
31264
|
+
{
|
|
31265
|
+
variant: "outline",
|
|
31266
|
+
onClick: onCancel,
|
|
31267
|
+
children: "Cancel"
|
|
31268
|
+
}
|
|
31269
|
+
)
|
|
31270
|
+
] }),
|
|
31271
|
+
multipleClients.some((c) => !c.name.trim()) && /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex items-center gap-2 text-amber-600 text-sm", children: [
|
|
31272
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx(CircleAlert, { className: "h-4 w-4" }),
|
|
31273
|
+
"Some clients don't have names and won't be created."
|
|
31274
|
+
] })
|
|
31275
|
+
] })
|
|
31276
|
+
] }) });
|
|
31277
|
+
}
|
|
30255
31278
|
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
31279
|
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "mb-6", children: [
|
|
30257
31280
|
/* @__PURE__ */ jsxRuntimeExports.jsx("h2", { className: "text-2xl font-bold mb-2", children: isCreating ? "Create New Client" : `Edit Client: ${editingClientName}` }),
|
|
30258
31281
|
/* @__PURE__ */ jsxRuntimeExports.jsx("p", { className: "text-muted-foreground", children: "Configure your MCP client connection settings below." })
|
|
30259
31282
|
] }),
|
|
31283
|
+
isCreating && /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "mb-6 p-4 rounded-lg bg-card border border-border/50 shadow-sm", children: /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex items-start gap-3", children: [
|
|
31284
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "p-2 bg-muted rounded-lg", children: /* @__PURE__ */ jsxRuntimeExports.jsx(Upload, { className: "h-5 w-5 text-muted-foreground" }) }),
|
|
31285
|
+
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex-1", children: [
|
|
31286
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("h3", { className: "text-lg font-semibold mb-1", children: "Import Configuration" }),
|
|
31287
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("p", { className: "text-sm text-muted-foreground mb-3", children: "Import multiple servers from a configuration file. Supports the same format used by Claude Desktop and Cursor." }),
|
|
31288
|
+
/* @__PURE__ */ jsxRuntimeExports.jsxs(
|
|
31289
|
+
Button,
|
|
31290
|
+
{
|
|
31291
|
+
onClick: () => setShowImportDialog(true),
|
|
31292
|
+
size: "sm",
|
|
31293
|
+
children: [
|
|
31294
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx(Upload, { className: "w-4 h-4 mr-2" }),
|
|
31295
|
+
"Import from Configuration File"
|
|
31296
|
+
]
|
|
31297
|
+
}
|
|
31298
|
+
)
|
|
31299
|
+
] })
|
|
31300
|
+
] }) }),
|
|
30260
31301
|
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "space-y-4", children: [
|
|
31302
|
+
isCreating && /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "border-t pt-4", children: [
|
|
31303
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("h3", { className: "text-lg font-medium mb-1", children: "Manual Configuration" }),
|
|
31304
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("p", { className: "text-sm text-muted-foreground mb-4", children: "Or configure a single client manually with the options below." })
|
|
31305
|
+
] }),
|
|
30261
31306
|
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { children: [
|
|
30262
31307
|
/* @__PURE__ */ jsxRuntimeExports.jsx("label", { className: "text-sm font-medium mb-2 block", children: "Client Name" }),
|
|
30263
31308
|
/* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
@@ -30362,7 +31407,15 @@ const ClientFormSection = ({
|
|
|
30362
31407
|
}
|
|
30363
31408
|
)
|
|
30364
31409
|
] })
|
|
30365
|
-
] })
|
|
31410
|
+
] }),
|
|
31411
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
31412
|
+
ConfigImportDialog,
|
|
31413
|
+
{
|
|
31414
|
+
open: showImportDialog,
|
|
31415
|
+
onOpenChange: setShowImportDialog,
|
|
31416
|
+
onImportServers: handleImportServers
|
|
31417
|
+
}
|
|
31418
|
+
)
|
|
30366
31419
|
] }) });
|
|
30367
31420
|
};
|
|
30368
31421
|
const StarGitHubModal = ({
|
|
@@ -40880,7 +41933,7 @@ Anthropic.Models = Models2;
|
|
|
40880
41933
|
Anthropic.Beta = Beta;
|
|
40881
41934
|
const { HUMAN_PROMPT, AI_PROMPT } = Anthropic;
|
|
40882
41935
|
const readline = {};
|
|
40883
|
-
const version = "0.2.
|
|
41936
|
+
const version = "0.2.4";
|
|
40884
41937
|
const packageJson = {
|
|
40885
41938
|
version
|
|
40886
41939
|
};
|
|
@@ -40906,17 +41959,20 @@ const getConfigOverridesFromQueryParams = (defaultConfig) => {
|
|
|
40906
41959
|
for (const key of Object.keys(defaultConfig)) {
|
|
40907
41960
|
const param = url.searchParams.get(key);
|
|
40908
41961
|
if (param !== null) {
|
|
40909
|
-
const
|
|
40910
|
-
|
|
40911
|
-
|
|
40912
|
-
value =
|
|
40913
|
-
|
|
40914
|
-
|
|
40915
|
-
|
|
40916
|
-
|
|
40917
|
-
|
|
40918
|
-
|
|
40919
|
-
|
|
41962
|
+
const defaultConfigItem = defaultConfig[key];
|
|
41963
|
+
if (defaultConfigItem) {
|
|
41964
|
+
const defaultValue = defaultConfigItem.value;
|
|
41965
|
+
let value = param;
|
|
41966
|
+
if (typeof defaultValue === "number") {
|
|
41967
|
+
value = Number(param);
|
|
41968
|
+
} else if (typeof defaultValue === "boolean") {
|
|
41969
|
+
value = param === "true";
|
|
41970
|
+
}
|
|
41971
|
+
overrides[key] = {
|
|
41972
|
+
...defaultConfigItem,
|
|
41973
|
+
value
|
|
41974
|
+
};
|
|
41975
|
+
}
|
|
40920
41976
|
}
|
|
40921
41977
|
}
|
|
40922
41978
|
return overrides;
|
|
@@ -40930,10 +41986,13 @@ const initializeInspectorConfig = (localStorageKey) => {
|
|
|
40930
41986
|
...JSON.parse(savedConfig)
|
|
40931
41987
|
};
|
|
40932
41988
|
for (const [key, value] of Object.entries(mergedConfig)) {
|
|
40933
|
-
|
|
40934
|
-
|
|
40935
|
-
|
|
40936
|
-
|
|
41989
|
+
const defaultConfigItem = DEFAULT_INSPECTOR_CONFIG[key];
|
|
41990
|
+
if (defaultConfigItem) {
|
|
41991
|
+
mergedConfig[key] = {
|
|
41992
|
+
...value,
|
|
41993
|
+
label: defaultConfigItem.label
|
|
41994
|
+
};
|
|
41995
|
+
}
|
|
40937
41996
|
}
|
|
40938
41997
|
baseConfig = mergedConfig;
|
|
40939
41998
|
} else {
|
|
@@ -42976,10 +44035,12 @@ const useMCPOperations = () => {
|
|
|
42976
44035
|
setErrors((prev) => ({ ...prev, [tabKey]: null }));
|
|
42977
44036
|
}, []);
|
|
42978
44037
|
const addRequestHistory = reactExports.useCallback(
|
|
42979
|
-
(request, response) => {
|
|
44038
|
+
(request, response, timestamp, latency) => {
|
|
42980
44039
|
const requestEntry = {
|
|
42981
44040
|
request: JSON.stringify(request, null, 2),
|
|
42982
|
-
response: response ? JSON.stringify(response, null, 2) : void 0
|
|
44041
|
+
response: response ? JSON.stringify(response, null, 2) : void 0,
|
|
44042
|
+
timestamp: timestamp || (/* @__PURE__ */ new Date()).toISOString(),
|
|
44043
|
+
latency
|
|
42983
44044
|
};
|
|
42984
44045
|
setRequestHistory((prev) => [...prev, requestEntry]);
|
|
42985
44046
|
},
|
|
@@ -42988,23 +44049,33 @@ const useMCPOperations = () => {
|
|
|
42988
44049
|
const listResources = reactExports.useCallback(
|
|
42989
44050
|
async (mcpAgent, selectedServerName) => {
|
|
42990
44051
|
if (!mcpAgent) return;
|
|
44052
|
+
const startTime = performance.now();
|
|
44053
|
+
const operationTimestamp = (/* @__PURE__ */ new Date()).toISOString();
|
|
42991
44054
|
if (selectedServerName === "all") {
|
|
42992
44055
|
const allServerResources = await mcpAgent.getAllResources();
|
|
42993
44056
|
const flatResources = allServerResources.flatMap(
|
|
42994
44057
|
({ resources: resources2 }) => resources2
|
|
42995
44058
|
);
|
|
44059
|
+
const endTime = performance.now();
|
|
44060
|
+
const latency = Math.round(endTime - startTime);
|
|
42996
44061
|
addRequestHistory(
|
|
42997
44062
|
{ method: "resources/list/all" },
|
|
42998
|
-
{ resources: flatResources }
|
|
44063
|
+
{ resources: flatResources },
|
|
44064
|
+
operationTimestamp,
|
|
44065
|
+
latency
|
|
42999
44066
|
);
|
|
43000
44067
|
setResources(flatResources);
|
|
43001
44068
|
} else {
|
|
43002
44069
|
const client2 = mcpAgent.getClient(selectedServerName);
|
|
43003
44070
|
if (client2) {
|
|
43004
44071
|
const resourcesResponse = await client2.listResources();
|
|
44072
|
+
const endTime = performance.now();
|
|
44073
|
+
const latency = Math.round(endTime - startTime);
|
|
43005
44074
|
addRequestHistory(
|
|
43006
44075
|
{ method: "resources/list", server: selectedServerName },
|
|
43007
|
-
{ resources: resourcesResponse.resources }
|
|
44076
|
+
{ resources: resourcesResponse.resources },
|
|
44077
|
+
operationTimestamp,
|
|
44078
|
+
latency
|
|
43008
44079
|
);
|
|
43009
44080
|
setResources(resourcesResponse.resources);
|
|
43010
44081
|
}
|
|
@@ -43015,15 +44086,21 @@ const useMCPOperations = () => {
|
|
|
43015
44086
|
const listResourceTemplates = reactExports.useCallback(
|
|
43016
44087
|
async (mcpAgent, selectedServerName) => {
|
|
43017
44088
|
if (!mcpAgent) return;
|
|
44089
|
+
const startTime = performance.now();
|
|
44090
|
+
const operationTimestamp = (/* @__PURE__ */ new Date()).toISOString();
|
|
43018
44091
|
if (selectedServerName === "all") {
|
|
43019
44092
|
const allServerResources = await mcpAgent.getAllResources();
|
|
43020
44093
|
if (allServerResources.length > 0) {
|
|
43021
44094
|
const client2 = mcpAgent.getClient(allServerResources[0].serverName);
|
|
43022
44095
|
if (client2) {
|
|
43023
44096
|
const templatesResponse = await client2.listResourceTemplates();
|
|
44097
|
+
const endTime = performance.now();
|
|
44098
|
+
const latency = Math.round(endTime - startTime);
|
|
43024
44099
|
addRequestHistory(
|
|
43025
44100
|
{ method: "resourceTemplates/list/all" },
|
|
43026
|
-
{ resourceTemplates: templatesResponse.resourceTemplates }
|
|
44101
|
+
{ resourceTemplates: templatesResponse.resourceTemplates },
|
|
44102
|
+
operationTimestamp,
|
|
44103
|
+
latency
|
|
43027
44104
|
);
|
|
43028
44105
|
setResourceTemplates(templatesResponse.resourceTemplates);
|
|
43029
44106
|
}
|
|
@@ -43032,9 +44109,13 @@ const useMCPOperations = () => {
|
|
|
43032
44109
|
const client2 = mcpAgent.getClient(selectedServerName);
|
|
43033
44110
|
if (client2) {
|
|
43034
44111
|
const templatesResponse = await client2.listResourceTemplates();
|
|
44112
|
+
const endTime = performance.now();
|
|
44113
|
+
const latency = Math.round(endTime - startTime);
|
|
43035
44114
|
addRequestHistory(
|
|
43036
44115
|
{ method: "resourceTemplates/list", server: selectedServerName },
|
|
43037
|
-
{ resourceTemplates: templatesResponse.resourceTemplates }
|
|
44116
|
+
{ resourceTemplates: templatesResponse.resourceTemplates },
|
|
44117
|
+
operationTimestamp,
|
|
44118
|
+
latency
|
|
43038
44119
|
);
|
|
43039
44120
|
setResourceTemplates(templatesResponse.resourceTemplates);
|
|
43040
44121
|
}
|
|
@@ -43045,14 +44126,20 @@ const useMCPOperations = () => {
|
|
|
43045
44126
|
const readResource = reactExports.useCallback(
|
|
43046
44127
|
async (mcpAgent, selectedServerName, uri) => {
|
|
43047
44128
|
if (!mcpAgent) return;
|
|
44129
|
+
const startTime = performance.now();
|
|
44130
|
+
const operationTimestamp = (/* @__PURE__ */ new Date()).toISOString();
|
|
43048
44131
|
if (selectedServerName !== "all") {
|
|
43049
44132
|
const result = await mcpAgent.readResourceFromServer(
|
|
43050
44133
|
selectedServerName,
|
|
43051
44134
|
uri
|
|
43052
44135
|
);
|
|
44136
|
+
const endTime = performance.now();
|
|
44137
|
+
const latency = Math.round(endTime - startTime);
|
|
43053
44138
|
addRequestHistory(
|
|
43054
44139
|
{ method: "resources/read", server: selectedServerName, uri },
|
|
43055
|
-
result
|
|
44140
|
+
result,
|
|
44141
|
+
operationTimestamp,
|
|
44142
|
+
latency
|
|
43056
44143
|
);
|
|
43057
44144
|
return result;
|
|
43058
44145
|
} else {
|
|
@@ -43063,9 +44150,13 @@ const useMCPOperations = () => {
|
|
|
43063
44150
|
serverName,
|
|
43064
44151
|
uri
|
|
43065
44152
|
);
|
|
44153
|
+
const endTime = performance.now();
|
|
44154
|
+
const latency = Math.round(endTime - startTime);
|
|
43066
44155
|
addRequestHistory(
|
|
43067
44156
|
{ method: "resources/read", server: serverName, uri },
|
|
43068
|
-
result
|
|
44157
|
+
result,
|
|
44158
|
+
operationTimestamp,
|
|
44159
|
+
latency
|
|
43069
44160
|
);
|
|
43070
44161
|
return result;
|
|
43071
44162
|
}
|
|
@@ -43078,12 +44169,18 @@ const useMCPOperations = () => {
|
|
|
43078
44169
|
const subscribeToResource = reactExports.useCallback(
|
|
43079
44170
|
async (mcpAgent, selectedServerName, uri) => {
|
|
43080
44171
|
if (!mcpAgent || selectedServerName === "all") return;
|
|
44172
|
+
const startTime = performance.now();
|
|
44173
|
+
const operationTimestamp = (/* @__PURE__ */ new Date()).toISOString();
|
|
43081
44174
|
const client2 = mcpAgent.getClient(selectedServerName);
|
|
43082
44175
|
if (client2) {
|
|
43083
44176
|
const result = await client2.subscribeResource({ uri });
|
|
44177
|
+
const endTime = performance.now();
|
|
44178
|
+
const latency = Math.round(endTime - startTime);
|
|
43084
44179
|
addRequestHistory(
|
|
43085
44180
|
{ method: "resources/subscribe", server: selectedServerName, uri },
|
|
43086
|
-
result
|
|
44181
|
+
result,
|
|
44182
|
+
operationTimestamp,
|
|
44183
|
+
latency
|
|
43087
44184
|
);
|
|
43088
44185
|
return result;
|
|
43089
44186
|
}
|
|
@@ -43093,12 +44190,18 @@ const useMCPOperations = () => {
|
|
|
43093
44190
|
const unsubscribeFromResource = reactExports.useCallback(
|
|
43094
44191
|
async (mcpAgent, selectedServerName, uri) => {
|
|
43095
44192
|
if (!mcpAgent || selectedServerName === "all") return;
|
|
44193
|
+
const startTime = performance.now();
|
|
44194
|
+
const operationTimestamp = (/* @__PURE__ */ new Date()).toISOString();
|
|
43096
44195
|
const client2 = mcpAgent.getClient(selectedServerName);
|
|
43097
44196
|
if (client2) {
|
|
43098
44197
|
const result = await client2.unsubscribeResource({ uri });
|
|
44198
|
+
const endTime = performance.now();
|
|
44199
|
+
const latency = Math.round(endTime - startTime);
|
|
43099
44200
|
addRequestHistory(
|
|
43100
44201
|
{ method: "resources/unsubscribe", server: selectedServerName, uri },
|
|
43101
|
-
result
|
|
44202
|
+
result,
|
|
44203
|
+
operationTimestamp,
|
|
44204
|
+
latency
|
|
43102
44205
|
);
|
|
43103
44206
|
return result;
|
|
43104
44207
|
}
|
|
@@ -43108,21 +44211,31 @@ const useMCPOperations = () => {
|
|
|
43108
44211
|
const listPrompts = reactExports.useCallback(
|
|
43109
44212
|
async (mcpAgent, selectedServerName) => {
|
|
43110
44213
|
if (!mcpAgent) return;
|
|
44214
|
+
const startTime = performance.now();
|
|
44215
|
+
const operationTimestamp = (/* @__PURE__ */ new Date()).toISOString();
|
|
43111
44216
|
if (selectedServerName === "all") {
|
|
43112
44217
|
const allServerPrompts = await mcpAgent.getAllPrompts();
|
|
43113
44218
|
const flatPrompts = allServerPrompts.flatMap(({ prompts: prompts2 }) => prompts2);
|
|
44219
|
+
const endTime = performance.now();
|
|
44220
|
+
const latency = Math.round(endTime - startTime);
|
|
43114
44221
|
addRequestHistory(
|
|
43115
44222
|
{ method: "prompts/list/all" },
|
|
43116
|
-
{ prompts: flatPrompts }
|
|
44223
|
+
{ prompts: flatPrompts },
|
|
44224
|
+
operationTimestamp,
|
|
44225
|
+
latency
|
|
43117
44226
|
);
|
|
43118
44227
|
setPrompts(flatPrompts);
|
|
43119
44228
|
} else {
|
|
43120
44229
|
const client2 = mcpAgent.getClient(selectedServerName);
|
|
43121
44230
|
if (client2) {
|
|
43122
44231
|
const promptsResponse = await client2.listPrompts();
|
|
44232
|
+
const endTime = performance.now();
|
|
44233
|
+
const latency = Math.round(endTime - startTime);
|
|
43123
44234
|
addRequestHistory(
|
|
43124
44235
|
{ method: "prompts/list", server: selectedServerName },
|
|
43125
|
-
{ prompts: promptsResponse.prompts }
|
|
44236
|
+
{ prompts: promptsResponse.prompts },
|
|
44237
|
+
operationTimestamp,
|
|
44238
|
+
latency
|
|
43126
44239
|
);
|
|
43127
44240
|
setPrompts(promptsResponse.prompts);
|
|
43128
44241
|
}
|
|
@@ -43133,15 +44246,21 @@ const useMCPOperations = () => {
|
|
|
43133
44246
|
const getPrompt = reactExports.useCallback(
|
|
43134
44247
|
async (mcpAgent, selectedServerName, name, args = {}) => {
|
|
43135
44248
|
if (!mcpAgent) return;
|
|
44249
|
+
const startTime = performance.now();
|
|
44250
|
+
const operationTimestamp = (/* @__PURE__ */ new Date()).toISOString();
|
|
43136
44251
|
if (selectedServerName !== "all") {
|
|
43137
44252
|
const result = await mcpAgent.getPromptFromServer(
|
|
43138
44253
|
selectedServerName,
|
|
43139
44254
|
name,
|
|
43140
44255
|
args
|
|
43141
44256
|
);
|
|
44257
|
+
const endTime = performance.now();
|
|
44258
|
+
const latency = Math.round(endTime - startTime);
|
|
43142
44259
|
addRequestHistory(
|
|
43143
44260
|
{ method: "prompts/get", server: selectedServerName, name, args },
|
|
43144
|
-
result
|
|
44261
|
+
result,
|
|
44262
|
+
operationTimestamp,
|
|
44263
|
+
latency
|
|
43145
44264
|
);
|
|
43146
44265
|
return result;
|
|
43147
44266
|
} else {
|
|
@@ -43153,9 +44272,13 @@ const useMCPOperations = () => {
|
|
|
43153
44272
|
name,
|
|
43154
44273
|
args
|
|
43155
44274
|
);
|
|
44275
|
+
const endTime = performance.now();
|
|
44276
|
+
const latency = Math.round(endTime - startTime);
|
|
43156
44277
|
addRequestHistory(
|
|
43157
44278
|
{ method: "prompts/get", server: serverName, name, args },
|
|
43158
|
-
result
|
|
44279
|
+
result,
|
|
44280
|
+
operationTimestamp,
|
|
44281
|
+
latency
|
|
43159
44282
|
);
|
|
43160
44283
|
return result;
|
|
43161
44284
|
}
|
|
@@ -43168,18 +44291,31 @@ const useMCPOperations = () => {
|
|
|
43168
44291
|
const listTools = reactExports.useCallback(
|
|
43169
44292
|
async (mcpAgent, selectedServerName) => {
|
|
43170
44293
|
if (!mcpAgent) return;
|
|
44294
|
+
const startTime = performance.now();
|
|
44295
|
+
const operationTimestamp = (/* @__PURE__ */ new Date()).toISOString();
|
|
43171
44296
|
if (selectedServerName === "all") {
|
|
43172
44297
|
const allServerTools = await mcpAgent.getAllTools();
|
|
43173
44298
|
const flatTools = allServerTools.flatMap(({ tools: tools2 }) => tools2);
|
|
43174
|
-
|
|
44299
|
+
const endTime = performance.now();
|
|
44300
|
+
const latency = Math.round(endTime - startTime);
|
|
44301
|
+
addRequestHistory(
|
|
44302
|
+
{ method: "tools/list/all" },
|
|
44303
|
+
{ tools: flatTools },
|
|
44304
|
+
operationTimestamp,
|
|
44305
|
+
latency
|
|
44306
|
+
);
|
|
43175
44307
|
setTools(flatTools);
|
|
43176
44308
|
} else {
|
|
43177
44309
|
const client2 = mcpAgent.getClient(selectedServerName);
|
|
43178
44310
|
if (client2) {
|
|
43179
44311
|
const toolsResponse = await client2.tools();
|
|
44312
|
+
const endTime = performance.now();
|
|
44313
|
+
const latency = Math.round(endTime - startTime);
|
|
43180
44314
|
addRequestHistory(
|
|
43181
|
-
{ method: "tools/list" },
|
|
43182
|
-
{ tools: toolsResponse.tools }
|
|
44315
|
+
{ method: "tools/list", server: selectedServerName },
|
|
44316
|
+
{ tools: toolsResponse.tools },
|
|
44317
|
+
operationTimestamp,
|
|
44318
|
+
latency
|
|
43183
44319
|
);
|
|
43184
44320
|
setTools(toolsResponse.tools);
|
|
43185
44321
|
}
|
|
@@ -43190,6 +44326,8 @@ const useMCPOperations = () => {
|
|
|
43190
44326
|
const callTool = reactExports.useCallback(
|
|
43191
44327
|
async (mcpAgent, selectedServerName, name, params) => {
|
|
43192
44328
|
if (!mcpAgent) return;
|
|
44329
|
+
const startTime = performance.now();
|
|
44330
|
+
const operationTimestamp = (/* @__PURE__ */ new Date()).toISOString();
|
|
43193
44331
|
try {
|
|
43194
44332
|
if (selectedServerName !== "all") {
|
|
43195
44333
|
const result = await mcpAgent.callToolOnServer(
|
|
@@ -43197,9 +44335,13 @@ const useMCPOperations = () => {
|
|
|
43197
44335
|
name,
|
|
43198
44336
|
params
|
|
43199
44337
|
);
|
|
44338
|
+
const endTime = performance.now();
|
|
44339
|
+
const latency = Math.round(endTime - startTime);
|
|
43200
44340
|
addRequestHistory(
|
|
43201
44341
|
{ method: "tools/call", server: selectedServerName, name, params },
|
|
43202
|
-
result
|
|
44342
|
+
result,
|
|
44343
|
+
operationTimestamp,
|
|
44344
|
+
latency
|
|
43203
44345
|
);
|
|
43204
44346
|
setToolResult(result);
|
|
43205
44347
|
} else {
|
|
@@ -43211,9 +44353,13 @@ const useMCPOperations = () => {
|
|
|
43211
44353
|
name,
|
|
43212
44354
|
params
|
|
43213
44355
|
);
|
|
44356
|
+
const endTime = performance.now();
|
|
44357
|
+
const latency = Math.round(endTime - startTime);
|
|
43214
44358
|
addRequestHistory(
|
|
43215
44359
|
{ method: "tools/call", server: serverName, name, params },
|
|
43216
|
-
result
|
|
44360
|
+
result,
|
|
44361
|
+
operationTimestamp,
|
|
44362
|
+
latency
|
|
43217
44363
|
);
|
|
43218
44364
|
setToolResult(result);
|
|
43219
44365
|
return;
|
|
@@ -43222,6 +44368,8 @@ const useMCPOperations = () => {
|
|
|
43222
44368
|
throw new Error(`Tool ${name} not found on any server`);
|
|
43223
44369
|
}
|
|
43224
44370
|
} catch (e) {
|
|
44371
|
+
const endTime = performance.now();
|
|
44372
|
+
const latency = Math.round(endTime - startTime);
|
|
43225
44373
|
const toolResult2 = {
|
|
43226
44374
|
content: [
|
|
43227
44375
|
{
|
|
@@ -43233,7 +44381,9 @@ const useMCPOperations = () => {
|
|
|
43233
44381
|
};
|
|
43234
44382
|
addRequestHistory(
|
|
43235
44383
|
{ method: "tools/call", server: selectedServerName, name, params },
|
|
43236
|
-
{ error: e.message ?? String(e) }
|
|
44384
|
+
{ error: e.message ?? String(e) },
|
|
44385
|
+
operationTimestamp,
|
|
44386
|
+
latency
|
|
43237
44387
|
);
|
|
43238
44388
|
setToolResult(toolResult2);
|
|
43239
44389
|
}
|
|
@@ -43264,11 +44414,15 @@ const useMCPOperations = () => {
|
|
|
43264
44414
|
if (!mcpAgent || selectedServerName === "all") {
|
|
43265
44415
|
return [];
|
|
43266
44416
|
}
|
|
44417
|
+
const startTime = performance.now();
|
|
44418
|
+
const operationTimestamp = (/* @__PURE__ */ new Date()).toISOString();
|
|
43267
44419
|
const client2 = mcpAgent.getClient(selectedServerName);
|
|
43268
44420
|
if (!client2) {
|
|
43269
44421
|
return [];
|
|
43270
44422
|
}
|
|
43271
44423
|
const result = await client2.handleCompletion(ref2, argName, value, signal);
|
|
44424
|
+
const endTime = performance.now();
|
|
44425
|
+
const latency = Math.round(endTime - startTime);
|
|
43272
44426
|
addRequestHistory(
|
|
43273
44427
|
{
|
|
43274
44428
|
method: "completion",
|
|
@@ -43277,7 +44431,9 @@ const useMCPOperations = () => {
|
|
|
43277
44431
|
argName,
|
|
43278
44432
|
value
|
|
43279
44433
|
},
|
|
43280
|
-
{ completions: result }
|
|
44434
|
+
{ completions: result },
|
|
44435
|
+
operationTimestamp,
|
|
44436
|
+
latency
|
|
43281
44437
|
);
|
|
43282
44438
|
return result;
|
|
43283
44439
|
},
|
|
@@ -43670,6 +44826,39 @@ const App = () => {
|
|
|
43670
44826
|
console.error("Failed to save client:", error);
|
|
43671
44827
|
}
|
|
43672
44828
|
}, [serverState, handleAddServer, handleUpdateServer, handleRemoveServer]);
|
|
44829
|
+
const handleSaveMultiple = reactExports.useCallback(
|
|
44830
|
+
async (clients) => {
|
|
44831
|
+
const results = {
|
|
44832
|
+
success: [],
|
|
44833
|
+
failed: []
|
|
44834
|
+
};
|
|
44835
|
+
console.log(`🔄 Creating ${clients.length} client(s)...`);
|
|
44836
|
+
for (const client2 of clients) {
|
|
44837
|
+
try {
|
|
44838
|
+
console.log(`🔧 Creating client: "${client2.name}"`);
|
|
44839
|
+
await handleAddServer(client2.name, client2.config);
|
|
44840
|
+
results.success.push(client2.name);
|
|
44841
|
+
console.log(`✅ Successfully created client: "${client2.name}"`);
|
|
44842
|
+
} catch (error) {
|
|
44843
|
+
const errorMessage = error instanceof Error ? error.message : String(error);
|
|
44844
|
+
console.error(`❌ Failed to create client "${client2.name}":`, errorMessage);
|
|
44845
|
+
results.failed.push({ name: client2.name, error: errorMessage });
|
|
44846
|
+
}
|
|
44847
|
+
}
|
|
44848
|
+
serverState.handleCancelClientForm();
|
|
44849
|
+
if (results.success.length > 0) {
|
|
44850
|
+
console.log(`✅ Successfully created ${results.success.length} client(s): ${results.success.join(", ")}`);
|
|
44851
|
+
}
|
|
44852
|
+
if (results.failed.length > 0) {
|
|
44853
|
+
console.error(`❌ Failed to create ${results.failed.length} client(s):`, results.failed);
|
|
44854
|
+
results.failed.forEach(({ name, error }) => {
|
|
44855
|
+
console.error(` - ${name}: ${error}`);
|
|
44856
|
+
});
|
|
44857
|
+
}
|
|
44858
|
+
return results;
|
|
44859
|
+
},
|
|
44860
|
+
[handleAddServer, serverState]
|
|
44861
|
+
);
|
|
43673
44862
|
const handleEditClient = reactExports.useCallback(
|
|
43674
44863
|
(serverName) => {
|
|
43675
44864
|
const serverConnections = connectionState.mcpAgent ? connectionState.mcpAgent.getAllConnectionInfo() : [];
|
|
@@ -43894,7 +45083,7 @@ const App = () => {
|
|
|
43894
45083
|
}, []);
|
|
43895
45084
|
if (window.location.pathname === "/oauth/callback") {
|
|
43896
45085
|
const OAuthCallback = React.lazy(
|
|
43897
|
-
() => __vitePreload(() => import("./OAuthCallback-
|
|
45086
|
+
() => __vitePreload(() => import("./OAuthCallback-DkLMDxkx.js"), true ? __vite__mapDeps([0,1]) : void 0)
|
|
43898
45087
|
);
|
|
43899
45088
|
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
45089
|
reactExports.Suspense,
|
|
@@ -43909,7 +45098,7 @@ const App = () => {
|
|
|
43909
45098
|
}
|
|
43910
45099
|
if (window.location.pathname === "/oauth/callback/debug") {
|
|
43911
45100
|
const OAuthDebugCallback = React.lazy(
|
|
43912
|
-
() => __vitePreload(() => import("./OAuthDebugCallback-
|
|
45101
|
+
() => __vitePreload(() => import("./OAuthDebugCallback-DaNmVTKt.js"), true ? __vite__mapDeps([2,1]) : void 0)
|
|
43913
45102
|
);
|
|
43914
45103
|
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
45104
|
reactExports.Suspense,
|
|
@@ -43940,6 +45129,7 @@ const App = () => {
|
|
|
43940
45129
|
headerName: configState.headerName,
|
|
43941
45130
|
setHeaderName: configState.setHeaderName,
|
|
43942
45131
|
onSave: handleSaveClient,
|
|
45132
|
+
onSaveMultiple: handleSaveMultiple,
|
|
43943
45133
|
onCancel: serverState.handleCancelClientForm
|
|
43944
45134
|
}
|
|
43945
45135
|
);
|