@mcp-use/inspector 0.14.0-canary.9 → 0.14.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (31) hide show
  1. package/dist/client/assets/{browser-CAet5h5U.js → browser-EyInsrZa.js} +48 -48
  2. package/dist/client/assets/client-JeU2zpxn.js +92 -0
  3. package/dist/client/assets/{display-A5IEINAP-CQoSnHLt.js → display-A5IEINAP-Btv2gL3n.js} +2 -2
  4. package/dist/client/assets/{embeddings-DtafgfMS.js → embeddings-Dya_KnH0.js} +1 -1
  5. package/dist/client/assets/{index-Meiz2XrK.js → index--IpKhg5F.js} +1 -1
  6. package/dist/client/assets/{index-BwjhL_Ts.js → index-01y2e9ko.js} +1 -1
  7. package/dist/client/assets/{index-BghX1ooe.js → index-3gQQW6s7.js} +1 -1
  8. package/dist/client/assets/{index-hiNxmj9U.js → index-BZCfajuh.js} +1 -1
  9. package/dist/client/assets/{index-DrmcYZGT.js → index-BiUxRAkS.js} +1 -1
  10. package/dist/client/assets/{index-DXT6rsWo.js → index-CwGEcSpK.js} +1 -1
  11. package/dist/client/assets/{index-c1SU-y-r.js → index-D7646HFQ.js} +1 -1
  12. package/dist/client/assets/index-DoHGzyNN.js +1753 -0
  13. package/dist/client/assets/index-G80eS8Oh.css +1 -0
  14. package/dist/client/assets/{index-B8ArYgSz.js → index-dRu1bjMq.js} +1 -1
  15. package/dist/client/assets/{llms-Bpg_7xxf.js → llms-CQ_t8ic9.js} +1 -1
  16. package/dist/client/index.html +3 -3
  17. package/dist/client/index.js +1096 -0
  18. package/dist/server/server.d.ts +11 -0
  19. package/dist/server/server.d.ts.map +1 -1
  20. package/dist/server/shared-static.d.ts +5 -1
  21. package/dist/server/shared-static.d.ts.map +1 -1
  22. package/dist/server/shared-utils-browser.d.ts +9 -1
  23. package/dist/server/shared-utils-browser.d.ts.map +1 -1
  24. package/dist/server/transport-wrapper.d.ts +1 -1
  25. package/dist/server/transport-wrapper.d.ts.map +1 -1
  26. package/dist/server/utils.d.ts +13 -0
  27. package/dist/server/utils.d.ts.map +1 -1
  28. package/package.json +9 -4
  29. package/dist/client/assets/client-CAJCPqsR.js +0 -92
  30. package/dist/client/assets/index-D_5vBeGJ.css +0 -1
  31. package/dist/client/assets/index-DfGhdcvP.js +0 -1753
@@ -0,0 +1,1096 @@
1
+ // ../../node_modules/.pnpm/@radix-ui+react-slot@1.2.4_@types+react@19.2.7_react@19.2.3/node_modules/@radix-ui/react-slot/dist/index.mjs
2
+ import * as React2 from "react";
3
+
4
+ // ../../node_modules/.pnpm/@radix-ui+react-compose-refs@1.1.2_@types+react@19.2.7_react@19.2.3/node_modules/@radix-ui/react-compose-refs/dist/index.mjs
5
+ import * as React from "react";
6
+ function setRef(ref, value) {
7
+ if (typeof ref === "function") {
8
+ return ref(value);
9
+ } else if (ref !== null && ref !== void 0) {
10
+ ref.current = value;
11
+ }
12
+ }
13
+ function composeRefs(...refs) {
14
+ return (node) => {
15
+ let hasCleanup = false;
16
+ const cleanups = refs.map((ref) => {
17
+ const cleanup = setRef(ref, node);
18
+ if (!hasCleanup && typeof cleanup == "function") {
19
+ hasCleanup = true;
20
+ }
21
+ return cleanup;
22
+ });
23
+ if (hasCleanup) {
24
+ return () => {
25
+ for (let i = 0; i < cleanups.length; i++) {
26
+ const cleanup = cleanups[i];
27
+ if (typeof cleanup == "function") {
28
+ cleanup();
29
+ } else {
30
+ setRef(refs[i], null);
31
+ }
32
+ }
33
+ };
34
+ }
35
+ };
36
+ }
37
+
38
+ // ../../node_modules/.pnpm/@radix-ui+react-slot@1.2.4_@types+react@19.2.7_react@19.2.3/node_modules/@radix-ui/react-slot/dist/index.mjs
39
+ import { Fragment as Fragment2, jsx } from "react/jsx-runtime";
40
+ var REACT_LAZY_TYPE = /* @__PURE__ */ Symbol.for("react.lazy");
41
+ var use = React2[" use ".trim().toString()];
42
+ function isPromiseLike(value) {
43
+ return typeof value === "object" && value !== null && "then" in value;
44
+ }
45
+ function isLazyComponent(element) {
46
+ return element != null && typeof element === "object" && "$$typeof" in element && element.$$typeof === REACT_LAZY_TYPE && "_payload" in element && isPromiseLike(element._payload);
47
+ }
48
+ // @__NO_SIDE_EFFECTS__
49
+ function createSlot(ownerName) {
50
+ const SlotClone = /* @__PURE__ */ createSlotClone(ownerName);
51
+ const Slot2 = React2.forwardRef((props, forwardedRef) => {
52
+ let { children, ...slotProps } = props;
53
+ if (isLazyComponent(children) && typeof use === "function") {
54
+ children = use(children._payload);
55
+ }
56
+ const childrenArray = React2.Children.toArray(children);
57
+ const slottable = childrenArray.find(isSlottable);
58
+ if (slottable) {
59
+ const newElement = slottable.props.children;
60
+ const newChildren = childrenArray.map((child) => {
61
+ if (child === slottable) {
62
+ if (React2.Children.count(newElement) > 1) return React2.Children.only(null);
63
+ return React2.isValidElement(newElement) ? newElement.props.children : null;
64
+ } else {
65
+ return child;
66
+ }
67
+ });
68
+ return /* @__PURE__ */ jsx(SlotClone, { ...slotProps, ref: forwardedRef, children: React2.isValidElement(newElement) ? React2.cloneElement(newElement, void 0, newChildren) : null });
69
+ }
70
+ return /* @__PURE__ */ jsx(SlotClone, { ...slotProps, ref: forwardedRef, children });
71
+ });
72
+ Slot2.displayName = `${ownerName}.Slot`;
73
+ return Slot2;
74
+ }
75
+ var Slot = /* @__PURE__ */ createSlot("Slot");
76
+ // @__NO_SIDE_EFFECTS__
77
+ function createSlotClone(ownerName) {
78
+ const SlotClone = React2.forwardRef((props, forwardedRef) => {
79
+ let { children, ...slotProps } = props;
80
+ if (isLazyComponent(children) && typeof use === "function") {
81
+ children = use(children._payload);
82
+ }
83
+ if (React2.isValidElement(children)) {
84
+ const childrenRef = getElementRef(children);
85
+ const props2 = mergeProps(slotProps, children.props);
86
+ if (children.type !== React2.Fragment) {
87
+ props2.ref = forwardedRef ? composeRefs(forwardedRef, childrenRef) : childrenRef;
88
+ }
89
+ return React2.cloneElement(children, props2);
90
+ }
91
+ return React2.Children.count(children) > 1 ? React2.Children.only(null) : null;
92
+ });
93
+ SlotClone.displayName = `${ownerName}.SlotClone`;
94
+ return SlotClone;
95
+ }
96
+ var SLOTTABLE_IDENTIFIER = /* @__PURE__ */ Symbol("radix.slottable");
97
+ function isSlottable(child) {
98
+ return React2.isValidElement(child) && typeof child.type === "function" && "__radixId" in child.type && child.type.__radixId === SLOTTABLE_IDENTIFIER;
99
+ }
100
+ function mergeProps(slotProps, childProps) {
101
+ const overrideProps = { ...childProps };
102
+ for (const propName in childProps) {
103
+ const slotPropValue = slotProps[propName];
104
+ const childPropValue = childProps[propName];
105
+ const isHandler = /^on[A-Z]/.test(propName);
106
+ if (isHandler) {
107
+ if (slotPropValue && childPropValue) {
108
+ overrideProps[propName] = (...args) => {
109
+ const result = childPropValue(...args);
110
+ slotPropValue(...args);
111
+ return result;
112
+ };
113
+ } else if (slotPropValue) {
114
+ overrideProps[propName] = slotPropValue;
115
+ }
116
+ } else if (propName === "style") {
117
+ overrideProps[propName] = { ...slotPropValue, ...childPropValue };
118
+ } else if (propName === "className") {
119
+ overrideProps[propName] = [slotPropValue, childPropValue].filter(Boolean).join(" ");
120
+ }
121
+ }
122
+ return { ...slotProps, ...overrideProps };
123
+ }
124
+ function getElementRef(element) {
125
+ let getter = Object.getOwnPropertyDescriptor(element.props, "ref")?.get;
126
+ let mayWarn = getter && "isReactWarning" in getter && getter.isReactWarning;
127
+ if (mayWarn) {
128
+ return element.ref;
129
+ }
130
+ getter = Object.getOwnPropertyDescriptor(element, "ref")?.get;
131
+ mayWarn = getter && "isReactWarning" in getter && getter.isReactWarning;
132
+ if (mayWarn) {
133
+ return element.props.ref;
134
+ }
135
+ return element.props.ref || element.ref;
136
+ }
137
+
138
+ // src/client/components/ui/button.tsx
139
+ import { cva } from "class-variance-authority";
140
+
141
+ // src/client/lib/utils.ts
142
+ import { clsx } from "clsx";
143
+ import { twMerge } from "tailwind-merge";
144
+ function cn(...inputs) {
145
+ return twMerge(clsx(inputs));
146
+ }
147
+
148
+ // src/client/components/ui/button.tsx
149
+ import { jsx as jsx2 } from "react/jsx-runtime";
150
+ var buttonVariants = cva(
151
+ "inline-flex cursor-pointer items-center justify-center gap-2 whitespace-nowrap rounded-full text-sm font-medium transition-all disabled:pointer-events-none disabled:opacity-50 [&_svg]:pointer-events-none [&_svg:not([class*='size-'])]:size-4 shrink-0 [&_svg]:shrink-0 outline-none focus-visible:border-ring focus-visible:ring-ring/50 focus-visible:ring-[3px] aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40 aria-invalid:border-destructive",
152
+ {
153
+ variants: {
154
+ variant: {
155
+ default: "bg-primary text-primary-foreground hover:bg-primary/90",
156
+ destructive: "bg-destructive text-white hover:bg-destructive/90 focus-visible:ring-destructive/20 dark:focus-visible:ring-destructive/40 dark:bg-destructive/60",
157
+ outline: "border bg-background shadow-xs hover:bg-accent hover:text-accent-foreground dark:bg-input/30 dark:border-input dark:hover:bg-input/50",
158
+ secondary: "bg-secondary text-secondary-foreground hover:bg-secondary/80",
159
+ ghost: "hover:bg-accent hover:text-accent-foreground dark:hover:bg-accent/50",
160
+ link: "text-primary underline-offset-4 hover:underline"
161
+ },
162
+ size: {
163
+ default: "h-9 px-4 py-2 has-[>svg]:px-3",
164
+ sm: "h-8 rounded-full gap-1.5 px-3 has-[>svg]:px-2.5",
165
+ lg: "h-10 rounded-full px-6 has-[>svg]:px-4",
166
+ icon: "size-9",
167
+ "icon-sm": "size-8",
168
+ "icon-lg": "size-10"
169
+ }
170
+ },
171
+ defaultVariants: {
172
+ variant: "default",
173
+ size: "default"
174
+ }
175
+ }
176
+ );
177
+ function Button({
178
+ className,
179
+ variant,
180
+ size,
181
+ asChild = false,
182
+ ...props
183
+ }) {
184
+ const Comp = asChild ? Slot : "button";
185
+ return /* @__PURE__ */ jsx2(
186
+ Comp,
187
+ {
188
+ "data-slot": "button",
189
+ className: cn(buttonVariants({ variant, size, className })),
190
+ ...props
191
+ }
192
+ );
193
+ }
194
+
195
+ // src/client/components/ui/dialog.tsx
196
+ import * as DialogPrimitive from "@radix-ui/react-dialog";
197
+ import { XIcon } from "lucide-react";
198
+ import { jsx as jsx3, jsxs } from "react/jsx-runtime";
199
+ function Dialog({
200
+ ...props
201
+ }) {
202
+ return /* @__PURE__ */ jsx3(DialogPrimitive.Root, { "data-slot": "dialog", ...props });
203
+ }
204
+ function DialogPortal({
205
+ ...props
206
+ }) {
207
+ return /* @__PURE__ */ jsx3(DialogPrimitive.Portal, { "data-slot": "dialog-portal", ...props });
208
+ }
209
+ function DialogOverlay({
210
+ className,
211
+ ...props
212
+ }) {
213
+ return /* @__PURE__ */ jsx3(
214
+ DialogPrimitive.Overlay,
215
+ {
216
+ "data-slot": "dialog-overlay",
217
+ className: cn(
218
+ "data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 fixed inset-0 z-50 bg-black/50",
219
+ className
220
+ ),
221
+ ...props
222
+ }
223
+ );
224
+ }
225
+ function DialogContent({
226
+ className,
227
+ children,
228
+ showCloseButton = true,
229
+ ...props
230
+ }) {
231
+ return /* @__PURE__ */ jsxs(DialogPortal, { "data-slot": "dialog-portal", children: [
232
+ /* @__PURE__ */ jsx3(DialogOverlay, {}),
233
+ /* @__PURE__ */ jsxs(
234
+ DialogPrimitive.Content,
235
+ {
236
+ "data-slot": "dialog-content",
237
+ className: cn(
238
+ "bg-background data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 fixed top-[50%] left-[50%] z-50 grid w-full max-w-[calc(100%-2rem)] translate-x-[-50%] translate-y-[-50%] gap-4 rounded-lg border p-6 shadow-lg duration-200 sm:max-w-lg",
239
+ className
240
+ ),
241
+ ...props,
242
+ children: [
243
+ children,
244
+ showCloseButton && /* @__PURE__ */ jsxs(
245
+ DialogPrimitive.Close,
246
+ {
247
+ "data-slot": "dialog-close",
248
+ className: "ring-offset-background focus:ring-ring data-[state=open]:bg-accent data-[state=open]:text-muted-foreground absolute top-4 right-4 rounded-xs opacity-70 transition-opacity hover:opacity-100 focus:ring-2 focus:ring-offset-2 focus:outline-hidden disabled:pointer-events-none [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4",
249
+ children: [
250
+ /* @__PURE__ */ jsx3(XIcon, {}),
251
+ /* @__PURE__ */ jsx3("span", { className: "sr-only", children: "Close" })
252
+ ]
253
+ }
254
+ )
255
+ ]
256
+ }
257
+ )
258
+ ] });
259
+ }
260
+ function DialogHeader({ className, ...props }) {
261
+ return /* @__PURE__ */ jsx3(
262
+ "div",
263
+ {
264
+ "data-slot": "dialog-header",
265
+ className: cn("flex flex-col gap-2 text-center sm:text-left", className),
266
+ ...props
267
+ }
268
+ );
269
+ }
270
+ function DialogTitle({
271
+ className,
272
+ ...props
273
+ }) {
274
+ return /* @__PURE__ */ jsx3(
275
+ DialogPrimitive.Title,
276
+ {
277
+ "data-slot": "dialog-title",
278
+ className: cn("text-lg leading-none font-semibold", className),
279
+ ...props
280
+ }
281
+ );
282
+ }
283
+ function DialogDescription({
284
+ className,
285
+ ...props
286
+ }) {
287
+ return /* @__PURE__ */ jsx3(
288
+ DialogPrimitive.Description,
289
+ {
290
+ "data-slot": "dialog-description",
291
+ className: cn("text-muted-foreground text-sm", className),
292
+ ...props
293
+ }
294
+ );
295
+ }
296
+
297
+ // src/client/components/ui/dropdown-menu.tsx
298
+ import * as DropdownMenuPrimitive from "@radix-ui/react-dropdown-menu";
299
+ import { jsx as jsx4 } from "react/jsx-runtime";
300
+ var DropdownMenu = DropdownMenuPrimitive.Root;
301
+ var DropdownMenuTrigger = DropdownMenuPrimitive.Trigger;
302
+ function DropdownMenuSubTrigger({
303
+ ref,
304
+ className,
305
+ inset,
306
+ children,
307
+ ...props
308
+ }) {
309
+ return /* @__PURE__ */ jsx4(
310
+ DropdownMenuPrimitive.SubTrigger,
311
+ {
312
+ ref,
313
+ className: cn(
314
+ "flex cursor-default select-none items-center rounded-sm px-2 py-1.5 text-sm outline-none focus:bg-accent data-[state=open]:bg-accent",
315
+ inset && "pl-8",
316
+ className
317
+ ),
318
+ ...props,
319
+ children
320
+ }
321
+ );
322
+ }
323
+ DropdownMenuSubTrigger.displayName = DropdownMenuPrimitive.SubTrigger.displayName;
324
+ function DropdownMenuSubContent({
325
+ ref,
326
+ className,
327
+ ...props
328
+ }) {
329
+ return /* @__PURE__ */ jsx4(
330
+ DropdownMenuPrimitive.SubContent,
331
+ {
332
+ ref,
333
+ className: cn(
334
+ "z-50 min-w-[8rem] overflow-hidden rounded-md border bg-popover p-1 text-popover-foreground shadow-lg data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2",
335
+ className
336
+ ),
337
+ ...props
338
+ }
339
+ );
340
+ }
341
+ DropdownMenuSubContent.displayName = DropdownMenuPrimitive.SubContent.displayName;
342
+ function DropdownMenuContent({
343
+ ref,
344
+ className,
345
+ sideOffset = 4,
346
+ ...props
347
+ }) {
348
+ return /* @__PURE__ */ jsx4(DropdownMenuPrimitive.Portal, { children: /* @__PURE__ */ jsx4(
349
+ DropdownMenuPrimitive.Content,
350
+ {
351
+ ref,
352
+ sideOffset,
353
+ className: cn(
354
+ "z-50 min-w-[8rem] overflow-hidden rounded-md border bg-popover p-1 text-popover-foreground shadow-md",
355
+ "data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2",
356
+ className
357
+ ),
358
+ ...props
359
+ }
360
+ ) });
361
+ }
362
+ DropdownMenuContent.displayName = DropdownMenuPrimitive.Content.displayName;
363
+ function DropdownMenuItem({
364
+ ref,
365
+ className,
366
+ inset,
367
+ ...props
368
+ }) {
369
+ return /* @__PURE__ */ jsx4(
370
+ DropdownMenuPrimitive.Item,
371
+ {
372
+ ref,
373
+ className: cn(
374
+ "relative flex cursor-default select-none items-center rounded-sm px-2 py-1.5 text-sm outline-none transition-colors focus:bg-accent focus:text-accent-foreground data-[disabled]:pointer-events-none data-[disabled]:opacity-50",
375
+ inset && "pl-8",
376
+ className
377
+ ),
378
+ ...props
379
+ }
380
+ );
381
+ }
382
+ DropdownMenuItem.displayName = DropdownMenuPrimitive.Item.displayName;
383
+ function DropdownMenuCheckboxItem({
384
+ ref,
385
+ className,
386
+ children,
387
+ checked,
388
+ ...props
389
+ }) {
390
+ return /* @__PURE__ */ jsx4(
391
+ DropdownMenuPrimitive.CheckboxItem,
392
+ {
393
+ ref,
394
+ className: cn(
395
+ "relative flex cursor-default select-none items-center rounded-sm py-1.5 pl-8 pr-2 text-sm outline-none transition-colors focus:bg-accent focus:text-accent-foreground data-[disabled]:pointer-events-none data-[disabled]:opacity-50",
396
+ className
397
+ ),
398
+ checked,
399
+ ...props,
400
+ children
401
+ }
402
+ );
403
+ }
404
+ DropdownMenuCheckboxItem.displayName = DropdownMenuPrimitive.CheckboxItem.displayName;
405
+ function DropdownMenuRadioItem({
406
+ ref,
407
+ className,
408
+ children,
409
+ ...props
410
+ }) {
411
+ return /* @__PURE__ */ jsx4(
412
+ DropdownMenuPrimitive.RadioItem,
413
+ {
414
+ ref,
415
+ className: cn(
416
+ "relative flex cursor-default select-none items-center rounded-sm py-1.5 pl-8 pr-2 text-sm outline-none transition-colors focus:bg-accent focus:text-accent-foreground data-[disabled]:pointer-events-none data-[disabled]:opacity-50",
417
+ className
418
+ ),
419
+ ...props,
420
+ children
421
+ }
422
+ );
423
+ }
424
+ DropdownMenuRadioItem.displayName = DropdownMenuPrimitive.RadioItem.displayName;
425
+ function DropdownMenuLabel({
426
+ ref,
427
+ className,
428
+ inset,
429
+ ...props
430
+ }) {
431
+ return /* @__PURE__ */ jsx4(
432
+ DropdownMenuPrimitive.Label,
433
+ {
434
+ ref,
435
+ className: cn(
436
+ "px-2 py-1.5 text-sm font-semibold",
437
+ inset && "pl-8",
438
+ className
439
+ ),
440
+ ...props
441
+ }
442
+ );
443
+ }
444
+ DropdownMenuLabel.displayName = DropdownMenuPrimitive.Label.displayName;
445
+ function DropdownMenuSeparator({
446
+ ref,
447
+ className,
448
+ ...props
449
+ }) {
450
+ return /* @__PURE__ */ jsx4(
451
+ DropdownMenuPrimitive.Separator,
452
+ {
453
+ ref,
454
+ className: cn("-mx-1 my-1 h-px bg-muted", className),
455
+ ...props
456
+ }
457
+ );
458
+ }
459
+ DropdownMenuSeparator.displayName = DropdownMenuPrimitive.Separator.displayName;
460
+ function DropdownMenuShortcut({
461
+ className,
462
+ ...props
463
+ }) {
464
+ return /* @__PURE__ */ jsx4(
465
+ "span",
466
+ {
467
+ className: cn("ml-auto text-xs tracking-widest opacity-60", className),
468
+ ...props
469
+ }
470
+ );
471
+ }
472
+ DropdownMenuShortcut.displayName = "DropdownMenuShortcut";
473
+
474
+ // src/client/components/AddToClientDropdown.tsx
475
+ import { Check, ChevronDown, Copy, Plus } from "lucide-react";
476
+
477
+ // src/client/utils/mcpClientUtils.ts
478
+ function sanitizeServerName(name) {
479
+ return name.replace(/[^a-zA-Z0-9-_]/g, "_").toLowerCase();
480
+ }
481
+ function escapeShellArg(arg) {
482
+ return `'${arg.replace(/'/g, "'\\''")}'`;
483
+ }
484
+ function headerToEnvVar(headerName) {
485
+ return headerName.replace(/[^a-zA-Z0-9]/g, "_").toUpperCase().replace(/^_+|_+$/g, "");
486
+ }
487
+ function generateCursorDeepLink(url, name, headers) {
488
+ const config = { url };
489
+ if (headers && Object.keys(headers).length > 0) {
490
+ const headersWithEnvVars = {};
491
+ for (const [key] of Object.entries(headers)) {
492
+ const envVar = headerToEnvVar(key);
493
+ headersWithEnvVars[key] = `{{${envVar}}}`;
494
+ }
495
+ config.headers = headersWithEnvVars;
496
+ }
497
+ const configJson = JSON.stringify(config);
498
+ const base64Config = btoa(configJson);
499
+ return `cursor://anysphere.cursor-deeplink/mcp/install?config=${base64Config}&name=${encodeURIComponent(sanitizeServerName(name))}`;
500
+ }
501
+ function generateVSCodeDeepLink(url, name, headers) {
502
+ const config = {
503
+ url,
504
+ name: sanitizeServerName(name),
505
+ type: "http"
506
+ };
507
+ if (headers && Object.keys(headers).length > 0) {
508
+ const headersWithPlaceholder = {};
509
+ for (const [key] of Object.entries(headers)) {
510
+ const envVar = headerToEnvVar(key);
511
+ headersWithPlaceholder[key] = `your-${envVar}-value`;
512
+ }
513
+ config.headers = headersWithPlaceholder;
514
+ }
515
+ const configJson = JSON.stringify(config);
516
+ const urlEncodedConfig = encodeURIComponent(configJson);
517
+ return `vscode:mcp/install?${urlEncodedConfig}`;
518
+ }
519
+ function generateMcpbConfig(url, name, headers) {
520
+ const config = {
521
+ url,
522
+ name: sanitizeServerName(name)
523
+ };
524
+ if (headers && Object.keys(headers).length > 0) {
525
+ const headersWithPlaceholder = {};
526
+ for (const [key] of Object.entries(headers)) {
527
+ const envVar = headerToEnvVar(key);
528
+ headersWithPlaceholder[key] = `your-${envVar}-value`;
529
+ }
530
+ config.headers = headersWithPlaceholder;
531
+ }
532
+ return config;
533
+ }
534
+ function downloadMcpbFile(url, name, headers) {
535
+ try {
536
+ const config = generateMcpbConfig(url, name, headers);
537
+ const configString = JSON.stringify(config, null, 2);
538
+ const BlobConstructor = globalThis.Blob;
539
+ const blob = new BlobConstructor([configString], {
540
+ type: "application/json"
541
+ });
542
+ const downloadUrl = URL.createObjectURL(blob);
543
+ const a = document.createElement("a");
544
+ a.href = downloadUrl;
545
+ a.download = `${sanitizeServerName(name)}.mcpb`;
546
+ document.body.appendChild(a);
547
+ a.click();
548
+ document.body.removeChild(a);
549
+ URL.revokeObjectURL(downloadUrl);
550
+ } catch (error) {
551
+ console.error("Failed to download .mcpb file:", error);
552
+ throw error;
553
+ }
554
+ }
555
+ function generateClaudeCodeCommand(url, name, headers) {
556
+ const sanitizedName = sanitizeServerName(name);
557
+ let command = `claude mcp add --transport http "${sanitizedName}" \\
558
+ ${escapeShellArg(url)}`;
559
+ const envVars = [];
560
+ if (headers && Object.keys(headers).length > 0) {
561
+ for (const [headerName] of Object.entries(headers)) {
562
+ const envVar = headerToEnvVar(headerName);
563
+ command += ` \\
564
+ --header ${escapeShellArg(`${headerName}:\${${envVar}}`)}`;
565
+ envVars.push({ name: envVar, header: headerName });
566
+ }
567
+ }
568
+ return { command, envVars };
569
+ }
570
+ function generateGeminiCLICommand(url, name, headers) {
571
+ const sanitizedName = sanitizeServerName(name);
572
+ let command = `gemini mcp add --transport http "${sanitizedName}" ${escapeShellArg(url)}`;
573
+ const envVars = [];
574
+ if (headers && Object.keys(headers).length > 0) {
575
+ for (const [headerName] of Object.entries(headers)) {
576
+ const envVar = headerToEnvVar(headerName);
577
+ command += ` \\
578
+ --header ${escapeShellArg(`${headerName}:\${${envVar}}`)}`;
579
+ envVars.push({ name: envVar, header: headerName });
580
+ }
581
+ }
582
+ return { command, envVars };
583
+ }
584
+ function generateCodexConfig(url, name, headers) {
585
+ const sanitizedName = sanitizeServerName(name);
586
+ let config = `[mcp_servers.${sanitizedName}]
587
+ url = "${url}"`;
588
+ const envVars = [];
589
+ if (headers && Object.keys(headers).length > 0) {
590
+ const headerEntries = [];
591
+ for (const [headerName] of Object.entries(headers)) {
592
+ const envVar = headerToEnvVar(headerName);
593
+ headerEntries.push(`"${headerName}" = "your-${envVar}-value"`);
594
+ envVars.push({ name: envVar, header: headerName });
595
+ }
596
+ config += `
597
+ http_headers = { ${headerEntries.join(", ")} }`;
598
+ if (envVars.length > 0) {
599
+ config += `
600
+
601
+ # (optional) Use environment variables instead:
602
+ # env_http_headers = { `;
603
+ const envHeaderEntries = envVars.map(
604
+ ({ name: name2, header }) => `"${header}" = "${name2}"`
605
+ );
606
+ config += envHeaderEntries.join(", ");
607
+ config += ` }`;
608
+ }
609
+ }
610
+ return { config, envVars };
611
+ }
612
+ function getEnvVarInstructions(envVars) {
613
+ if (envVars.length === 0) return "";
614
+ let instructions = "Set these environment variables in your shell:\n\n";
615
+ for (const { name } of envVars) {
616
+ instructions += `export ${name}="your-${name}-value"
617
+ `;
618
+ }
619
+ return instructions;
620
+ }
621
+ function generateTypeScriptSDKCode(url, name, serverId, headers) {
622
+ const id = serverId || sanitizeServerName(name);
623
+ const serverConfig = {
624
+ url
625
+ };
626
+ if (headers && Object.keys(headers).length > 0) {
627
+ serverConfig.headers = headers;
628
+ }
629
+ const configString = JSON.stringify(serverConfig, null, 4);
630
+ const indentedConfig = configString.split("\n").map((line, i) => i === 0 ? line : " " + line).join("\n");
631
+ return `import { MCPClient } from "mcp-use";
632
+
633
+ const client = new MCPClient({
634
+ mcpServers: {
635
+ "${id}": ${indentedConfig}
636
+ }
637
+ });
638
+
639
+ await client.createAllSessions();
640
+
641
+ const session = client.getSession("${id}");
642
+
643
+ // Get available tools
644
+ const tools = await session.listTools();
645
+ console.log('Available tools:', tools.map(tool => tool.name));
646
+
647
+ // Get available resources
648
+ const resources = await session.listResources();
649
+ console.log('Available resources:', resources.map(resource => resource.name));
650
+
651
+ // Call a tool (example)
652
+ // const result = await session.callTool("toolName", { param: "value" });
653
+
654
+ // Read a resource (example)
655
+ // const resourceContent = await session.readResource("resource-uri");`;
656
+ }
657
+ function generatePythonSDKCode(url, name, serverId, headers) {
658
+ const id = serverId || sanitizeServerName(name);
659
+ const serverConfig = {
660
+ url
661
+ };
662
+ if (headers && Object.keys(headers).length > 0) {
663
+ serverConfig.headers = headers;
664
+ }
665
+ const configString = JSON.stringify(serverConfig, null, 4);
666
+ const indentedConfig = configString.split("\n").map((line, i) => i === 0 ? line : " " + line).join("\n");
667
+ return `from mcp_use import MCPClient
668
+
669
+ client = MCPClient(config={
670
+ "mcpServers": {
671
+ "${id}": ${indentedConfig}
672
+ }
673
+ })
674
+
675
+ await client.create_all_sessions()
676
+
677
+ session = client.get_session("${id}")
678
+
679
+ # Get available tools
680
+ tools = await session.list_tools()
681
+ print(f"Available tools: {[tool.name for tool in tools]}")
682
+
683
+ # Get available resources
684
+ resources = await session.list_resources()
685
+ print(f"Available resources: {[resource.name for resource in resources]}")
686
+
687
+ # Call a tool (example)
688
+ # result = await session.call_tool("tool_name", {"param": "value"})
689
+
690
+ # Read a resource (example)
691
+ # resource_content = await session.read_resource("resource_uri")`;
692
+ }
693
+
694
+ // src/client/components/AddToClientDropdown.tsx
695
+ import { useState } from "react";
696
+
697
+ // src/client/components/ui/client-icons.tsx
698
+ import { jsx as jsx5 } from "react/jsx-runtime";
699
+ function VSCodeIcon({ className }) {
700
+ return /* @__PURE__ */ jsx5(
701
+ "svg",
702
+ {
703
+ viewBox: "0 0 24 24",
704
+ className,
705
+ fill: "currentColor",
706
+ xmlns: "http://www.w3.org/2000/svg",
707
+ children: /* @__PURE__ */ jsx5("path", { d: "M23.15 2.587L18.21.21a1.494 1.494 0 0 0-1.705.29l-9.46 8.63-4.12-3.128a.999.999 0 0 0-1.276.057L.327 7.261A1 1 0 0 0 .326 8.74L3.899 12 .326 15.26a1 1 0 0 0 .001 1.479L1.65 17.94a.999.999 0 0 0 1.276.057l4.12-3.128 9.46 8.63a1.492 1.492 0 0 0 1.704.29l4.942-2.377A1.5 1.5 0 0 0 24 20.06V3.939a1.5 1.5 0 0 0-.85-1.352zm-5.146 14.861L10.826 12l7.178-5.448v10.896z" })
708
+ }
709
+ );
710
+ }
711
+
712
+ // src/client/components/AddToClientDropdown.tsx
713
+ import { Fragment as Fragment3, jsx as jsx6, jsxs as jsxs2 } from "react/jsx-runtime";
714
+ function AddToClientDropdown({
715
+ serverConfig,
716
+ additionalItems = [],
717
+ showClients = {
718
+ cursor: true,
719
+ vsCode: true,
720
+ claudeDesktop: true,
721
+ claudeCode: true,
722
+ geminiCli: true,
723
+ codexCli: true
724
+ },
725
+ className = "",
726
+ onSuccess,
727
+ onError,
728
+ trigger
729
+ }) {
730
+ const [showModal, setShowModal] = useState(false);
731
+ const [selectedClient, setSelectedClient] = useState(null);
732
+ const [copied, setCopied] = useState(false);
733
+ const { url, name, headers } = serverConfig;
734
+ const handleCursorClick = () => {
735
+ try {
736
+ const deepLink = generateCursorDeepLink(url, name, headers);
737
+ window.location.href = deepLink;
738
+ onSuccess?.("Cursor");
739
+ } catch (error) {
740
+ console.error("Failed to generate Cursor deep link:", error);
741
+ onError?.(error);
742
+ }
743
+ };
744
+ const handleVSCodeClick = () => {
745
+ try {
746
+ const deepLink = generateVSCodeDeepLink(url, name, headers);
747
+ window.location.href = deepLink;
748
+ onSuccess?.("VS Code");
749
+ } catch (error) {
750
+ console.error("Failed to generate VS Code deep link:", error);
751
+ onError?.(error);
752
+ }
753
+ };
754
+ const handleClaudeDesktopClick = () => {
755
+ try {
756
+ downloadMcpbFile(url, name, headers);
757
+ onSuccess?.("Claude Desktop");
758
+ } catch (error) {
759
+ console.error("Failed to download .mcpb file:", error);
760
+ onError?.(error);
761
+ }
762
+ };
763
+ const handleClaudeCodeClick = () => {
764
+ setSelectedClient("claude-code");
765
+ setShowModal(true);
766
+ };
767
+ const handleGeminiCLIClick = () => {
768
+ setSelectedClient("gemini-cli");
769
+ setShowModal(true);
770
+ };
771
+ const handleCodexCLIClick = () => {
772
+ setSelectedClient("codex-cli");
773
+ setShowModal(true);
774
+ };
775
+ const handleCopy = async (text) => {
776
+ try {
777
+ await navigator.clipboard.writeText(text);
778
+ setCopied(true);
779
+ setTimeout(() => setCopied(false), 2e3);
780
+ } catch (error) {
781
+ console.error("Failed to copy:", error);
782
+ onError?.(error);
783
+ }
784
+ };
785
+ const renderModalContent = () => {
786
+ if (selectedClient === "claude-code") {
787
+ const { command, envVars } = generateClaudeCodeCommand(
788
+ url,
789
+ name,
790
+ headers
791
+ );
792
+ const envInstructions = getEnvVarInstructions(envVars);
793
+ return /* @__PURE__ */ jsxs2(Fragment3, { children: [
794
+ /* @__PURE__ */ jsxs2(DialogHeader, { children: [
795
+ /* @__PURE__ */ jsx6(DialogTitle, { children: "Add to Claude Code" }),
796
+ /* @__PURE__ */ jsx6(DialogDescription, { children: "Execute the following command in your shell to add this server to Claude Code." })
797
+ ] }),
798
+ /* @__PURE__ */ jsxs2("div", { className: "space-y-4", children: [
799
+ /* @__PURE__ */ jsxs2("div", { children: [
800
+ /* @__PURE__ */ jsx6("h5", { className: "font-semibold text-sm mb-2", children: "Instructions" }),
801
+ /* @__PURE__ */ jsxs2("ol", { className: "space-y-2 text-xs text-muted-foreground", children: [
802
+ /* @__PURE__ */ jsxs2("li", { className: "flex gap-2", children: [
803
+ /* @__PURE__ */ jsx6("span", { className: "font-semibold text-foreground", children: "1." }),
804
+ /* @__PURE__ */ jsx6("span", { children: "Ensure the Claude Code executable is available in your path" })
805
+ ] }),
806
+ /* @__PURE__ */ jsxs2("li", { className: "flex gap-2", children: [
807
+ /* @__PURE__ */ jsx6("span", { className: "font-semibold text-foreground", children: "2." }),
808
+ /* @__PURE__ */ jsx6("span", { children: "Execute the following snippet in your shell:" })
809
+ ] })
810
+ ] })
811
+ ] }),
812
+ /* @__PURE__ */ jsxs2("div", { className: "relative", children: [
813
+ /* @__PURE__ */ jsx6("div", { className: "absolute top-2 right-2 z-10", children: /* @__PURE__ */ jsx6(
814
+ Button,
815
+ {
816
+ variant: "ghost",
817
+ size: "sm",
818
+ className: "h-7 px-2 bg-background hover:bg-accent border border-border",
819
+ onClick: () => handleCopy(command),
820
+ children: copied ? /* @__PURE__ */ jsx6(Check, { className: "size-3.5 text-green-600" }) : /* @__PURE__ */ jsx6(Copy, { className: "size-3.5" })
821
+ }
822
+ ) }),
823
+ /* @__PURE__ */ jsx6("pre", { className: "bg-muted p-3 pr-14 rounded-md text-xs overflow-x-auto", children: /* @__PURE__ */ jsx6("code", { children: command }) })
824
+ ] }),
825
+ envInstructions && /* @__PURE__ */ jsxs2("div", { children: [
826
+ /* @__PURE__ */ jsx6("h5", { className: "font-semibold text-sm mb-2", children: "Environment Variables" }),
827
+ /* @__PURE__ */ jsx6("p", { className: "text-xs text-muted-foreground mb-2", children: "After installation, set these environment variables in your shell:" }),
828
+ /* @__PURE__ */ jsx6("pre", { className: "bg-muted p-3 rounded-md text-xs overflow-x-auto", children: /* @__PURE__ */ jsx6("code", { children: envInstructions }) })
829
+ ] }),
830
+ /* @__PURE__ */ jsxs2("p", { className: "text-xs text-muted-foreground", children: [
831
+ "The MCP configuration supports environment variable expansion using ",
832
+ /* @__PURE__ */ jsx6("code", { className: "text-foreground", children: "${VAR}" }),
833
+ " ",
834
+ "syntax."
835
+ ] })
836
+ ] })
837
+ ] });
838
+ }
839
+ if (selectedClient === "gemini-cli") {
840
+ const { command, envVars } = generateGeminiCLICommand(url, name, headers);
841
+ const envInstructions = getEnvVarInstructions(envVars);
842
+ return /* @__PURE__ */ jsxs2(Fragment3, { children: [
843
+ /* @__PURE__ */ jsxs2(DialogHeader, { children: [
844
+ /* @__PURE__ */ jsx6(DialogTitle, { children: "Add to Gemini CLI" }),
845
+ /* @__PURE__ */ jsx6(DialogDescription, { children: "Execute the following command in your shell to add this server to Gemini CLI." })
846
+ ] }),
847
+ /* @__PURE__ */ jsxs2("div", { className: "space-y-4", children: [
848
+ /* @__PURE__ */ jsxs2("div", { children: [
849
+ /* @__PURE__ */ jsx6("h5", { className: "font-semibold text-sm mb-2", children: "Instructions" }),
850
+ /* @__PURE__ */ jsxs2("ol", { className: "space-y-2 text-xs text-muted-foreground", children: [
851
+ /* @__PURE__ */ jsxs2("li", { className: "flex gap-2", children: [
852
+ /* @__PURE__ */ jsx6("span", { className: "font-semibold text-foreground", children: "1." }),
853
+ /* @__PURE__ */ jsx6("span", { children: "Ensure the Gemini CLI executable is available in your path" })
854
+ ] }),
855
+ envInstructions && /* @__PURE__ */ jsxs2("li", { className: "flex gap-2", children: [
856
+ /* @__PURE__ */ jsx6("span", { className: "font-semibold text-foreground", children: "2." }),
857
+ /* @__PURE__ */ jsx6("span", { children: "Set these environment variables in your shell before running the command:" })
858
+ ] }),
859
+ /* @__PURE__ */ jsxs2("li", { className: "flex gap-2", children: [
860
+ /* @__PURE__ */ jsx6("span", { className: "font-semibold text-foreground", children: envInstructions ? "3." : "2." }),
861
+ /* @__PURE__ */ jsx6("span", { children: "Execute the following snippet in your shell:" })
862
+ ] })
863
+ ] })
864
+ ] }),
865
+ envInstructions && /* @__PURE__ */ jsxs2("div", { children: [
866
+ /* @__PURE__ */ jsx6("h5", { className: "font-semibold text-sm mb-2", children: "Environment Variables" }),
867
+ /* @__PURE__ */ jsx6("pre", { className: "bg-muted p-3 rounded-md text-xs overflow-x-auto", children: /* @__PURE__ */ jsx6("code", { children: envInstructions }) })
868
+ ] }),
869
+ /* @__PURE__ */ jsxs2("div", { className: "relative", children: [
870
+ /* @__PURE__ */ jsx6("div", { className: "absolute top-2 right-2 z-10", children: /* @__PURE__ */ jsx6(
871
+ Button,
872
+ {
873
+ variant: "ghost",
874
+ size: "sm",
875
+ className: "h-7 px-2 bg-background hover:bg-accent border border-border",
876
+ onClick: () => handleCopy(command),
877
+ children: copied ? /* @__PURE__ */ jsx6(Check, { className: "size-3.5 text-green-600" }) : /* @__PURE__ */ jsx6(Copy, { className: "size-3.5" })
878
+ }
879
+ ) }),
880
+ /* @__PURE__ */ jsx6("pre", { className: "bg-muted p-3 pr-14 rounded-md text-xs overflow-x-auto", children: /* @__PURE__ */ jsx6("code", { children: command }) })
881
+ ] }),
882
+ /* @__PURE__ */ jsx6("p", { className: "text-xs text-muted-foreground", children: "Restart Gemini CLI to load the new configuration." })
883
+ ] })
884
+ ] });
885
+ }
886
+ if (selectedClient === "codex-cli") {
887
+ const { config, envVars } = generateCodexConfig(url, name, headers);
888
+ return /* @__PURE__ */ jsxs2(Fragment3, { children: [
889
+ /* @__PURE__ */ jsxs2(DialogHeader, { children: [
890
+ /* @__PURE__ */ jsx6(DialogTitle, { children: "Add to Codex CLI" }),
891
+ /* @__PURE__ */ jsxs2(DialogDescription, { children: [
892
+ "Add this configuration to your",
893
+ " ",
894
+ /* @__PURE__ */ jsx6("code", { className: "text-foreground", children: "~/.codex/config.toml" }),
895
+ " ",
896
+ "file."
897
+ ] })
898
+ ] }),
899
+ /* @__PURE__ */ jsxs2("div", { className: "space-y-4", children: [
900
+ /* @__PURE__ */ jsxs2("div", { children: [
901
+ /* @__PURE__ */ jsx6("h5", { className: "font-semibold text-sm mb-2", children: "Instructions" }),
902
+ /* @__PURE__ */ jsxs2("p", { className: "text-xs text-muted-foreground", children: [
903
+ "Add this configuration to your",
904
+ " ",
905
+ /* @__PURE__ */ jsx6("code", { className: "text-foreground", children: "~/.codex/config.toml" }),
906
+ ":"
907
+ ] })
908
+ ] }),
909
+ /* @__PURE__ */ jsxs2("div", { className: "relative", children: [
910
+ /* @__PURE__ */ jsx6("div", { className: "absolute top-2 right-2 z-10", children: /* @__PURE__ */ jsx6(
911
+ Button,
912
+ {
913
+ variant: "ghost",
914
+ size: "sm",
915
+ className: "h-7 px-2 bg-background hover:bg-accent border border-border",
916
+ onClick: () => handleCopy(config),
917
+ children: copied ? /* @__PURE__ */ jsx6(Check, { className: "size-3.5 text-green-600" }) : /* @__PURE__ */ jsx6(Copy, { className: "size-3.5" })
918
+ }
919
+ ) }),
920
+ /* @__PURE__ */ jsx6("pre", { className: "bg-muted p-3 pr-14 rounded-md text-xs overflow-x-auto", children: /* @__PURE__ */ jsx6("code", { children: config }) })
921
+ ] }),
922
+ envVars.length > 0 && /* @__PURE__ */ jsx6("div", { children: /* @__PURE__ */ jsxs2("p", { className: "text-xs text-muted-foreground", children: [
923
+ "(optional) If you would rather use variables from your system's environment, replace the",
924
+ " ",
925
+ /* @__PURE__ */ jsx6("code", { className: "text-foreground", children: "http_headers" }),
926
+ " key with the ",
927
+ /* @__PURE__ */ jsx6("code", { className: "text-foreground", children: "env_http_headers" }),
928
+ " ",
929
+ "key as shown in the commented section above."
930
+ ] }) }),
931
+ /* @__PURE__ */ jsx6("p", { className: "text-xs text-muted-foreground", children: "Restart Codex CLI to load the new configuration." })
932
+ ] })
933
+ ] });
934
+ }
935
+ return null;
936
+ };
937
+ const defaultTrigger = /* @__PURE__ */ jsxs2(
938
+ Button,
939
+ {
940
+ variant: "ghost",
941
+ className: `bg-zinc-200 dark:bg-zinc-800 hover:bg-zinc-300 dark:hover:bg-zinc-700 rounded-full transition-colors px-3 flex items-center justify-center ${className}`,
942
+ children: [
943
+ /* @__PURE__ */ jsxs2("span", { className: "xl:hidden hidden sm:flex items-center gap-1", children: [
944
+ /* @__PURE__ */ jsx6(Plus, { className: "size-3" }),
945
+ "Client"
946
+ ] }),
947
+ /* @__PURE__ */ jsxs2("span", { className: "hidden xl:flex items-center gap-1", children: [
948
+ "Add to Client",
949
+ /* @__PURE__ */ jsx6(ChevronDown, { className: "size-3" })
950
+ ] })
951
+ ]
952
+ }
953
+ );
954
+ const triggerElement = trigger ? typeof trigger === "function" ? trigger({
955
+ isOpen: false,
956
+ onClick: () => {
957
+ }
958
+ }) : trigger : defaultTrigger;
959
+ return /* @__PURE__ */ jsxs2(Fragment3, { children: [
960
+ /* @__PURE__ */ jsxs2(DropdownMenu, { children: [
961
+ /* @__PURE__ */ jsx6(DropdownMenuTrigger, { asChild: true, children: triggerElement }),
962
+ /* @__PURE__ */ jsxs2(DropdownMenuContent, { align: "end", className: "w-auto min-w-[300px]", children: [
963
+ additionalItems.map((item) => /* @__PURE__ */ jsxs2(
964
+ DropdownMenuItem,
965
+ {
966
+ onClick: async () => {
967
+ await item.onClick();
968
+ },
969
+ className: "flex items-center gap-2",
970
+ children: [
971
+ item.icon,
972
+ /* @__PURE__ */ jsx6("span", { className: "min-w-0 max-w-full whitespace-nowrap", children: item.label })
973
+ ]
974
+ },
975
+ item.id
976
+ )),
977
+ additionalItems.length > 0 && /* @__PURE__ */ jsx6(DropdownMenuSeparator, {}),
978
+ showClients.cursor && /* @__PURE__ */ jsxs2(
979
+ DropdownMenuItem,
980
+ {
981
+ onClick: handleCursorClick,
982
+ className: "flex items-center gap-2",
983
+ children: [
984
+ /* @__PURE__ */ jsx6(
985
+ "img",
986
+ {
987
+ src: "https://cdn.simpleicons.org/cursor",
988
+ alt: "Cursor",
989
+ className: "h-4 w-4"
990
+ }
991
+ ),
992
+ /* @__PURE__ */ jsx6("span", { className: "min-w-0 max-w-full whitespace-nowrap", children: "Cursor" })
993
+ ]
994
+ }
995
+ ),
996
+ showClients.claudeCode && /* @__PURE__ */ jsxs2(
997
+ DropdownMenuItem,
998
+ {
999
+ onClick: handleClaudeCodeClick,
1000
+ className: "flex items-center gap-2",
1001
+ children: [
1002
+ /* @__PURE__ */ jsx6(
1003
+ "img",
1004
+ {
1005
+ src: "https://cdn.simpleicons.org/claude",
1006
+ alt: "Claude",
1007
+ className: "h-4 w-4"
1008
+ }
1009
+ ),
1010
+ /* @__PURE__ */ jsx6("span", { className: "min-w-0 max-w-full whitespace-nowrap", children: "Claude Code" })
1011
+ ]
1012
+ }
1013
+ ),
1014
+ showClients.claudeDesktop && /* @__PURE__ */ jsxs2(
1015
+ DropdownMenuItem,
1016
+ {
1017
+ onClick: handleClaudeDesktopClick,
1018
+ className: "flex items-center gap-2",
1019
+ children: [
1020
+ /* @__PURE__ */ jsx6(
1021
+ "img",
1022
+ {
1023
+ src: "https://cdn.simpleicons.org/claude",
1024
+ alt: "Claude",
1025
+ className: "h-4 w-4"
1026
+ }
1027
+ ),
1028
+ /* @__PURE__ */ jsx6("span", { className: "min-w-0 max-w-full whitespace-nowrap", children: "Claude Desktop" })
1029
+ ]
1030
+ }
1031
+ ),
1032
+ showClients.vsCode && /* @__PURE__ */ jsxs2(
1033
+ DropdownMenuItem,
1034
+ {
1035
+ onClick: handleVSCodeClick,
1036
+ className: "flex items-center gap-2",
1037
+ children: [
1038
+ /* @__PURE__ */ jsx6(VSCodeIcon, { className: "h-4 w-4" }),
1039
+ /* @__PURE__ */ jsx6("span", { className: "min-w-0 max-w-full whitespace-nowrap", children: "VS Code" })
1040
+ ]
1041
+ }
1042
+ ),
1043
+ showClients.geminiCli && /* @__PURE__ */ jsxs2(
1044
+ DropdownMenuItem,
1045
+ {
1046
+ onClick: handleGeminiCLIClick,
1047
+ className: "flex items-center gap-2",
1048
+ children: [
1049
+ /* @__PURE__ */ jsx6(
1050
+ "img",
1051
+ {
1052
+ src: "https://cdn.simpleicons.org/googlegemini",
1053
+ alt: "Gemini",
1054
+ className: "h-4 w-4"
1055
+ }
1056
+ ),
1057
+ /* @__PURE__ */ jsx6("span", { className: "min-w-0 max-w-full whitespace-nowrap", children: "Gemini CLI" })
1058
+ ]
1059
+ }
1060
+ ),
1061
+ showClients.codexCli && /* @__PURE__ */ jsxs2(
1062
+ DropdownMenuItem,
1063
+ {
1064
+ onClick: handleCodexCLIClick,
1065
+ className: "flex items-center gap-2",
1066
+ children: [
1067
+ /* @__PURE__ */ jsx6(
1068
+ "img",
1069
+ {
1070
+ src: "https://inspector-cdn.mcp-use.com/providers/openai.png",
1071
+ alt: "Codex",
1072
+ className: "h-4 w-4"
1073
+ }
1074
+ ),
1075
+ /* @__PURE__ */ jsx6("span", { className: "min-w-0 max-w-full whitespace-nowrap", children: "Codex CLI" })
1076
+ ]
1077
+ }
1078
+ )
1079
+ ] })
1080
+ ] }),
1081
+ /* @__PURE__ */ jsx6(Dialog, { open: showModal, onOpenChange: setShowModal, children: /* @__PURE__ */ jsx6(DialogContent, { className: "max-w-3xl max-h-[80vh] overflow-y-auto", children: renderModalContent() }) })
1082
+ ] });
1083
+ }
1084
+ export {
1085
+ AddToClientDropdown,
1086
+ downloadMcpbFile,
1087
+ generateClaudeCodeCommand,
1088
+ generateCodexConfig,
1089
+ generateCursorDeepLink,
1090
+ generateGeminiCLICommand,
1091
+ generateMcpbConfig,
1092
+ generatePythonSDKCode,
1093
+ generateTypeScriptSDKCode,
1094
+ generateVSCodeDeepLink,
1095
+ getEnvVarInstructions
1096
+ };