@trops/dash-core 0.1.65 → 0.1.67

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js CHANGED
@@ -26533,94 +26533,105 @@ var ProviderDetail = function ProviderDetail(_ref) {
26533
26533
  text: isMcp ? "MCP Server" : "API Credentials"
26534
26534
  })]
26535
26535
  })]
26536
- }), isMcp && provider.mcpConfig && /*#__PURE__*/jsxRuntime.jsxs("div", {
26537
- className: "space-y-4",
26538
- children: [/*#__PURE__*/jsxRuntime.jsxs("div", {
26539
- className: "border-t border-white/10 pt-4",
26540
- children: [/*#__PURE__*/jsxRuntime.jsx("p", {
26541
- className: "text-xs font-semibold opacity-40 uppercase tracking-wider mb-3",
26542
- children: "MCP Server Configuration"
26543
- }), /*#__PURE__*/jsxRuntime.jsxs("div", {
26544
- className: "space-y-2 text-sm",
26545
- children: [/*#__PURE__*/jsxRuntime.jsxs("div", {
26546
- className: "flex gap-2",
26547
- children: [/*#__PURE__*/jsxRuntime.jsx("span", {
26548
- className: "opacity-50 w-20",
26549
- children: "Transport:"
26550
- }), /*#__PURE__*/jsxRuntime.jsx("span", {
26551
- children: provider.mcpConfig.transport === "streamable_http" ? "Streamable HTTP" : "stdio"
26552
- })]
26553
- }), provider.mcpConfig.transport === "streamable_http" ? /*#__PURE__*/jsxRuntime.jsxs("div", {
26554
- className: "flex gap-2",
26555
- children: [/*#__PURE__*/jsxRuntime.jsx("span", {
26556
- className: "opacity-50 w-20",
26557
- children: "Endpoint:"
26558
- }), /*#__PURE__*/jsxRuntime.jsx("span", {
26559
- className: "text-xs opacity-70",
26560
- children: "Remote hosted server"
26561
- })]
26562
- }) : /*#__PURE__*/jsxRuntime.jsxs(jsxRuntime.Fragment, {
26536
+ }), isMcp && provider.mcpConfig && /*#__PURE__*/jsxRuntime.jsxs(jsxRuntime.Fragment, {
26537
+ children: [/*#__PURE__*/jsxRuntime.jsx("div", {
26538
+ className: "space-y-4",
26539
+ children: /*#__PURE__*/jsxRuntime.jsxs("div", {
26540
+ className: "border-t border-white/10 pt-4",
26541
+ children: [/*#__PURE__*/jsxRuntime.jsx("p", {
26542
+ className: "text-xs font-semibold opacity-40 uppercase tracking-wider mb-3",
26543
+ children: "Server Configuration"
26544
+ }), /*#__PURE__*/jsxRuntime.jsxs("div", {
26545
+ className: "space-y-2 text-sm",
26563
26546
  children: [/*#__PURE__*/jsxRuntime.jsxs("div", {
26564
26547
  className: "flex gap-2",
26565
26548
  children: [/*#__PURE__*/jsxRuntime.jsx("span", {
26566
26549
  className: "opacity-50 w-20",
26567
- children: "Command:"
26568
- }), /*#__PURE__*/jsxRuntime.jsxs("code", {
26569
- className: "text-xs bg-white/5 px-2 py-0.5 rounded",
26570
- children: [provider.mcpConfig.command, " ", (provider.mcpConfig.args || []).join(" ")]
26550
+ children: "Transport:"
26551
+ }), /*#__PURE__*/jsxRuntime.jsx("span", {
26552
+ children: provider.mcpConfig.transport === "streamable_http" ? "Streamable HTTP" : "stdio"
26571
26553
  })]
26572
- }), provider.mcpConfig.envMapping && Object.keys(provider.mcpConfig.envMapping).length > 0 && /*#__PURE__*/jsxRuntime.jsxs("div", {
26554
+ }), provider.mcpConfig.transport === "streamable_http" ? /*#__PURE__*/jsxRuntime.jsxs("div", {
26573
26555
  className: "flex gap-2",
26574
26556
  children: [/*#__PURE__*/jsxRuntime.jsx("span", {
26575
26557
  className: "opacity-50 w-20",
26576
- children: "Env Vars:"
26558
+ children: "Endpoint:"
26577
26559
  }), /*#__PURE__*/jsxRuntime.jsx("span", {
26578
- className: "text-xs",
26579
- children: Object.keys(provider.mcpConfig.envMapping).join(", ")
26560
+ className: "text-xs opacity-70",
26561
+ children: "Remote hosted server"
26562
+ })]
26563
+ }) : /*#__PURE__*/jsxRuntime.jsxs(jsxRuntime.Fragment, {
26564
+ children: [/*#__PURE__*/jsxRuntime.jsxs("div", {
26565
+ className: "flex gap-2",
26566
+ children: [/*#__PURE__*/jsxRuntime.jsx("span", {
26567
+ className: "opacity-50 w-20",
26568
+ children: "Command:"
26569
+ }), /*#__PURE__*/jsxRuntime.jsxs("code", {
26570
+ className: "text-xs bg-white/5 px-2 py-0.5 rounded",
26571
+ children: [provider.mcpConfig.command, " ", (provider.mcpConfig.args || []).join(" ")]
26572
+ })]
26573
+ }), provider.mcpConfig.envMapping && Object.keys(provider.mcpConfig.envMapping).length > 0 && /*#__PURE__*/jsxRuntime.jsxs("div", {
26574
+ className: "flex gap-2",
26575
+ children: [/*#__PURE__*/jsxRuntime.jsx("span", {
26576
+ className: "opacity-50 w-20",
26577
+ children: "Env Vars:"
26578
+ }), /*#__PURE__*/jsxRuntime.jsx("span", {
26579
+ className: "text-xs",
26580
+ children: Object.keys(provider.mcpConfig.envMapping).join(", ")
26581
+ })]
26580
26582
  })]
26581
26583
  })]
26582
26584
  })]
26583
- })]
26584
- }), authResult && /*#__PURE__*/jsxRuntime.jsx("div", {
26585
- className: "p-3 rounded-lg text-sm ".concat(authResult.success ? "bg-green-900/30 border border-green-700 text-green-300" : "bg-red-900/30 border border-red-700 text-red-300"),
26586
- children: /*#__PURE__*/jsxRuntime.jsxs("div", {
26587
- className: "flex items-center gap-2",
26588
- children: [/*#__PURE__*/jsxRuntime.jsx(DashReact.FontAwesomeIcon, {
26589
- icon: authResult.success ? "circle-check" : "circle-exclamation"
26590
- }), /*#__PURE__*/jsxRuntime.jsx("span", {
26591
- children: authResult.message
26592
- })]
26593
- })
26594
- }), testResult && /*#__PURE__*/jsxRuntime.jsx("div", {
26595
- className: "p-3 rounded-lg text-sm ".concat(testResult.success ? "bg-green-900/30 border border-green-700 text-green-300" : "bg-red-900/30 border border-red-700 text-red-300"),
26596
- children: /*#__PURE__*/jsxRuntime.jsxs("div", {
26597
- className: "flex items-center gap-2",
26598
- children: [/*#__PURE__*/jsxRuntime.jsx(DashReact.FontAwesomeIcon, {
26599
- icon: testResult.success ? "circle-check" : "circle-exclamation"
26600
- }), /*#__PURE__*/jsxRuntime.jsx("span", {
26601
- children: testResult.message
26602
- })]
26603
26585
  })
26604
- }), (testResult === null || testResult === void 0 ? void 0 : testResult.success) && ((_testResult$tools = testResult.tools) === null || _testResult$tools === void 0 ? void 0 : _testResult$tools.length) > 0 && selectedTools && /*#__PURE__*/jsxRuntime.jsx(ToolSelector, {
26605
- tools: testResult.tools,
26606
- selectedTools: selectedTools,
26607
- onSelectionChange: setSelectedTools
26608
- }), !testResult && (provider === null || provider === void 0 ? void 0 : provider.allowedTools) && provider.allowedTools.length > 0 && /*#__PURE__*/jsxRuntime.jsxs("div", {
26609
- className: "space-y-2",
26610
- children: [/*#__PURE__*/jsxRuntime.jsx("p", {
26611
- className: "text-xs font-semibold opacity-40 uppercase tracking-wider",
26612
- children: "Allowed Tools"
26613
- }), /*#__PURE__*/jsxRuntime.jsx("div", {
26614
- className: "flex flex-wrap gap-1",
26615
- children: provider.allowedTools.map(function (tool) {
26616
- return /*#__PURE__*/jsxRuntime.jsx("span", {
26617
- className: "text-xs font-mono px-2 py-0.5 rounded bg-white/5 opacity-70",
26618
- children: tool
26619
- }, tool);
26586
+ }), /*#__PURE__*/jsxRuntime.jsxs("div", {
26587
+ className: "space-y-4",
26588
+ children: [/*#__PURE__*/jsxRuntime.jsx("div", {
26589
+ className: "border-t border-white/10 pt-4",
26590
+ children: /*#__PURE__*/jsxRuntime.jsx("p", {
26591
+ className: "text-xs font-semibold opacity-40 uppercase tracking-wider mb-3",
26592
+ children: "Connection & Tools"
26620
26593
  })
26621
- }), /*#__PURE__*/jsxRuntime.jsxs("p", {
26622
- className: "text-xs opacity-40",
26623
- children: [provider.allowedTools.length, " tool", provider.allowedTools.length !== 1 ? "s" : "", " allowed \u2014 test connection to modify"]
26594
+ }), authResult && /*#__PURE__*/jsxRuntime.jsx("div", {
26595
+ className: "p-3 rounded-lg text-sm ".concat(authResult.success ? "bg-green-900/30 border border-green-700 text-green-300" : "bg-red-900/30 border border-red-700 text-red-300"),
26596
+ children: /*#__PURE__*/jsxRuntime.jsxs("div", {
26597
+ className: "flex items-center gap-2",
26598
+ children: [/*#__PURE__*/jsxRuntime.jsx(DashReact.FontAwesomeIcon, {
26599
+ icon: authResult.success ? "circle-check" : "circle-exclamation"
26600
+ }), /*#__PURE__*/jsxRuntime.jsx("span", {
26601
+ children: authResult.message
26602
+ })]
26603
+ })
26604
+ }), testResult && /*#__PURE__*/jsxRuntime.jsx("div", {
26605
+ className: "p-3 rounded-lg text-sm ".concat(testResult.success ? "bg-green-900/30 border border-green-700 text-green-300" : "bg-red-900/30 border border-red-700 text-red-300"),
26606
+ children: /*#__PURE__*/jsxRuntime.jsxs("div", {
26607
+ className: "flex items-center gap-2",
26608
+ children: [/*#__PURE__*/jsxRuntime.jsx(DashReact.FontAwesomeIcon, {
26609
+ icon: testResult.success ? "circle-check" : "circle-exclamation"
26610
+ }), /*#__PURE__*/jsxRuntime.jsx("span", {
26611
+ children: testResult.message
26612
+ })]
26613
+ })
26614
+ }), (testResult === null || testResult === void 0 ? void 0 : testResult.success) && ((_testResult$tools = testResult.tools) === null || _testResult$tools === void 0 ? void 0 : _testResult$tools.length) > 0 && selectedTools && /*#__PURE__*/jsxRuntime.jsx(ToolSelector, {
26615
+ tools: testResult.tools,
26616
+ selectedTools: selectedTools,
26617
+ onSelectionChange: setSelectedTools
26618
+ }), !testResult && (provider === null || provider === void 0 ? void 0 : provider.allowedTools) && provider.allowedTools.length > 0 && /*#__PURE__*/jsxRuntime.jsxs("div", {
26619
+ className: "space-y-2",
26620
+ children: [/*#__PURE__*/jsxRuntime.jsx("div", {
26621
+ className: "flex flex-wrap gap-1",
26622
+ children: provider.allowedTools.map(function (tool) {
26623
+ return /*#__PURE__*/jsxRuntime.jsx("span", {
26624
+ className: "text-xs font-mono px-2 py-0.5 rounded bg-white/5 opacity-70",
26625
+ children: tool
26626
+ }, tool);
26627
+ })
26628
+ }), /*#__PURE__*/jsxRuntime.jsxs("p", {
26629
+ className: "text-xs opacity-40",
26630
+ children: [provider.allowedTools.length, " tool", provider.allowedTools.length !== 1 ? "s" : "", " allowed \u2014 test connection to modify"]
26631
+ })]
26632
+ }), !testResult && (!(provider !== null && provider !== void 0 && provider.allowedTools) || provider.allowedTools.length === 0) && /*#__PURE__*/jsxRuntime.jsx("p", {
26633
+ className: "text-sm opacity-40",
26634
+ children: "No tools configured \u2014 use Test Connection to discover available tools."
26624
26635
  })]
26625
26636
  })]
26626
26637
  })]
@@ -26817,19 +26828,25 @@ var CustomMcpServerForm = function CustomMcpServerForm(_ref2) {
26817
26828
  selectedTools = _useState22[0],
26818
26829
  setSelectedTools = _useState22[1];
26819
26830
 
26820
- // JSON editor state
26821
- var _useState23 = React.useState("form"),
26831
+ // Wizard step state
26832
+ var _useState23 = React.useState(0),
26822
26833
  _useState24 = _slicedToArray(_useState23, 2),
26823
- viewMode = _useState24[0],
26824
- setViewMode = _useState24[1]; // "form" | "json"
26825
- var _useState25 = React.useState(""),
26834
+ wizardStep = _useState24[0],
26835
+ setWizardStep = _useState24[1];
26836
+
26837
+ // JSON editor state
26838
+ var _useState25 = React.useState("form"),
26826
26839
  _useState26 = _slicedToArray(_useState25, 2),
26827
- jsonText = _useState26[0],
26828
- setJsonText = _useState26[1];
26829
- var _useState27 = React.useState(null),
26840
+ viewMode = _useState26[0],
26841
+ setViewMode = _useState26[1]; // "form" | "json"
26842
+ var _useState27 = React.useState(""),
26830
26843
  _useState28 = _slicedToArray(_useState27, 2),
26831
- jsonError = _useState28[0],
26832
- setJsonError = _useState28[1];
26844
+ jsonText = _useState28[0],
26845
+ setJsonText = _useState28[1];
26846
+ var _useState29 = React.useState(null),
26847
+ _useState30 = _slicedToArray(_useState29, 2),
26848
+ jsonError = _useState30[0],
26849
+ setJsonError = _useState30[1];
26833
26850
 
26834
26851
  // Clear credential data when transport changes (derived fields change entirely)
26835
26852
  // Only in create mode — in edit mode the initial transport is set correctly
@@ -26840,6 +26857,23 @@ var CustomMcpServerForm = function CustomMcpServerForm(_ref2) {
26840
26857
  }
26841
26858
  }, [transport, isEditMode]);
26842
26859
 
26860
+ // Wizard step navigation with validation gates
26861
+ var handleWizardStepChange = function handleWizardStepChange(newStep) {
26862
+ if (newStep < wizardStep) {
26863
+ setWizardStep(newStep);
26864
+ return;
26865
+ }
26866
+ // Step 0→1: validate form (skip validation in JSON mode, handled on save)
26867
+ if (wizardStep === 0 && newStep >= 1) {
26868
+ if (viewMode === "form" && !validateForm()) return;
26869
+ }
26870
+ // Step 1→2: require test success OR edit mode with existing tools
26871
+ if (wizardStep === 1 && newStep >= 2) {
26872
+ if (!(testResult !== null && testResult !== void 0 && testResult.success) && !(isEditMode && initialAllowedTools)) return;
26873
+ }
26874
+ setWizardStep(newStep);
26875
+ };
26876
+
26843
26877
  // Build mcpConfig from current state
26844
26878
  var mcpConfig = React.useMemo(function () {
26845
26879
  return buildMcpConfig(transport, {
@@ -26851,6 +26885,16 @@ var CustomMcpServerForm = function CustomMcpServerForm(_ref2) {
26851
26885
  });
26852
26886
  }, [transport, command, args, envMappingRows, url, headerRows]);
26853
26887
 
26888
+ // Invalidate test result when config changes after a test
26889
+ var mcpConfigRef = React.useRef(mcpConfig);
26890
+ React.useEffect(function () {
26891
+ if (mcpConfigRef.current !== mcpConfig && testResult) {
26892
+ setTestResult(null);
26893
+ setSelectedTools(initialAllowedTools);
26894
+ }
26895
+ mcpConfigRef.current = mcpConfig;
26896
+ }, [mcpConfig, testResult, initialAllowedTools]);
26897
+
26854
26898
  // Derive credential fields from the live mcpConfig
26855
26899
  var formFields = React.useMemo(function () {
26856
26900
  return deriveFormFields(mcpConfig, initialCredentialSchema);
@@ -27051,414 +27095,487 @@ var CustomMcpServerForm = function CustomMcpServerForm(_ref2) {
27051
27095
  return /*#__PURE__*/jsxRuntime.jsxs("div", {
27052
27096
  className: "flex flex-col flex-1 min-h-0",
27053
27097
  children: [/*#__PURE__*/jsxRuntime.jsxs("div", {
27054
- className: "flex-1 min-h-0 overflow-y-auto p-6 space-y-5",
27055
- children: [/*#__PURE__*/jsxRuntime.jsxs("div", {
27056
- className: "flex items-center gap-3",
27057
- children: [/*#__PURE__*/jsxRuntime.jsx("button", {
27058
- onClick: onBack,
27059
- className: "text-gray-400 hover:text-gray-200 transition-colors",
27060
- children: /*#__PURE__*/jsxRuntime.jsx(DashReact.FontAwesomeIcon, {
27061
- icon: "arrow-left",
27062
- className: "text-lg"
27063
- })
27064
- }), /*#__PURE__*/jsxRuntime.jsxs("div", {
27065
- children: [/*#__PURE__*/jsxRuntime.jsx(DashReact.SubHeading3, {
27066
- title: isEditMode ? "Edit MCP Server" : "Configure Custom MCP Server",
27067
- padding: false
27068
- }), /*#__PURE__*/jsxRuntime.jsx("p", {
27069
- className: "text-sm opacity-50 mt-1",
27070
- children: isEditMode ? "Modify this MCP server configuration" : "Define a custom MCP server connection"
27071
- })]
27072
- })]
27073
- }), /*#__PURE__*/jsxRuntime.jsxs("div", {
27074
- className: "flex flex-col gap-2",
27075
- children: [/*#__PURE__*/jsxRuntime.jsx(DashReact.FormLabel, {
27076
- label: "Provider Name",
27077
- required: true
27078
- }), /*#__PURE__*/jsxRuntime.jsx("p", {
27079
- className: "text-sm opacity-50",
27080
- children: "A name to identify this MCP server (e.g., \"My Custom Server\")"
27081
- }), /*#__PURE__*/jsxRuntime.jsx(DashReact.InputText, {
27082
- value: providerName,
27083
- onChange: function onChange(value) {
27084
- setProviderName(value);
27085
- if (formErrors.providerName && value !== null && value !== void 0 && value.trim()) {
27086
- setFormErrors(function (prev) {
27087
- var next = _objectSpread$5({}, prev);
27088
- delete next.providerName;
27089
- return next;
27090
- });
27091
- }
27092
- },
27093
- placeholder: "Enter provider name"
27094
- }), formErrors.providerName && /*#__PURE__*/jsxRuntime.jsx("p", {
27095
- className: "text-sm text-red-400",
27096
- children: formErrors.providerName
27097
- })]
27098
+ className: "flex items-center gap-3 px-6 pt-6 pb-2",
27099
+ children: [/*#__PURE__*/jsxRuntime.jsx("button", {
27100
+ onClick: onBack,
27101
+ className: "text-gray-400 hover:text-gray-200 transition-colors",
27102
+ children: /*#__PURE__*/jsxRuntime.jsx(DashReact.FontAwesomeIcon, {
27103
+ icon: "arrow-left",
27104
+ className: "text-lg"
27105
+ })
27098
27106
  }), /*#__PURE__*/jsxRuntime.jsxs("div", {
27099
- className: "flex items-center gap-1",
27100
- children: [/*#__PURE__*/jsxRuntime.jsx("button", {
27101
- onClick: function onClick() {
27102
- if (viewMode === "json") handleSwitchToForm();
27103
- },
27104
- className: "px-3 py-1 text-xs font-medium rounded-l transition-colors ".concat(viewMode === "form" ? "bg-white/10 text-white" : "text-white/50 hover:text-white/70"),
27105
- children: "Form"
27106
- }), /*#__PURE__*/jsxRuntime.jsx("button", {
27107
- onClick: function onClick() {
27108
- if (viewMode === "form") handleSwitchToJson();
27109
- },
27110
- className: "px-3 py-1 text-xs font-medium rounded-r transition-colors ".concat(viewMode === "json" ? "bg-white/10 text-white" : "text-white/50 hover:text-white/70"),
27111
- children: "JSON"
27112
- })]
27113
- }), jsonError && /*#__PURE__*/jsxRuntime.jsx("p", {
27114
- className: "text-sm text-red-400",
27115
- children: jsonError
27116
- }), viewMode === "json" && /*#__PURE__*/jsxRuntime.jsxs("div", {
27117
- className: "space-y-2",
27118
- children: [/*#__PURE__*/jsxRuntime.jsx("p", {
27119
- className: "text-xs font-semibold opacity-40 uppercase tracking-wider",
27120
- children: "MCP Server Configuration (JSON)"
27107
+ children: [/*#__PURE__*/jsxRuntime.jsx(DashReact.SubHeading3, {
27108
+ title: isEditMode ? "Edit MCP Server" : "Configure Custom MCP Server",
27109
+ padding: false
27121
27110
  }), /*#__PURE__*/jsxRuntime.jsx("p", {
27122
- className: "text-sm opacity-50",
27123
- children: "Paste a standard MCP config JSON (compatible with Claude Desktop, Cursor, etc.)"
27124
- }), /*#__PURE__*/jsxRuntime.jsx(DashReact.CodeEditorInline, {
27125
- code: jsonText,
27126
- setCode: function setCode(val) {
27127
- setJsonText(val);
27128
- setJsonError(null);
27129
- },
27130
- language: "json",
27131
- placeholder: '{\n "type": "stdio",\n "command": "npx",\n "args": ["-y", "package-name"],\n "env": {\n "API_KEY": "${API_KEY}"\n }\n}'
27111
+ className: "text-sm opacity-50 mt-1",
27112
+ children: isEditMode ? "Modify this MCP server configuration" : "Define a custom MCP server connection"
27132
27113
  })]
27133
- }), viewMode === "form" && /*#__PURE__*/jsxRuntime.jsxs(jsxRuntime.Fragment, {
27134
- children: [/*#__PURE__*/jsxRuntime.jsxs("div", {
27135
- className: "space-y-2",
27136
- children: [/*#__PURE__*/jsxRuntime.jsx("p", {
27137
- className: "text-xs font-semibold opacity-40 uppercase tracking-wider",
27138
- children: "Transport Type"
27139
- }), /*#__PURE__*/jsxRuntime.jsxs("div", {
27140
- className: "grid grid-cols-2 gap-3",
27141
- children: [/*#__PURE__*/jsxRuntime.jsxs(DashReact.Card2, {
27142
- hover: true,
27143
- selected: transport === "stdio",
27144
- onClick: function onClick() {
27145
- return setTransport("stdio");
27146
- },
27147
- className: "text-left",
27148
- children: [/*#__PURE__*/jsxRuntime.jsxs("div", {
27149
- className: "flex items-center gap-2 mb-1",
27150
- children: [/*#__PURE__*/jsxRuntime.jsx(DashReact.Icon2, {
27151
- icon: "terminal"
27152
- }), /*#__PURE__*/jsxRuntime.jsx("span", {
27153
- className: "font-semibold text-sm",
27154
- children: "Local Process (stdio)"
27155
- })]
27114
+ })]
27115
+ }), /*#__PURE__*/jsxRuntime.jsx("div", {
27116
+ className: "flex-1 min-h-0 flex flex-col",
27117
+ children: /*#__PURE__*/jsxRuntime.jsxs(DashReact.Stepper, {
27118
+ activeStep: wizardStep,
27119
+ onStepChange: handleWizardStepChange,
27120
+ showNavigation: false,
27121
+ className: "flex-1 min-h-0 flex flex-col px-6 pt-4",
27122
+ children: [/*#__PURE__*/jsxRuntime.jsx(DashReact.Stepper.Step, {
27123
+ label: "Configure",
27124
+ description: "Server & credentials",
27125
+ children: /*#__PURE__*/jsxRuntime.jsxs("div", {
27126
+ className: "flex-1 min-h-0 overflow-y-auto pb-4 space-y-5",
27127
+ children: [/*#__PURE__*/jsxRuntime.jsxs("div", {
27128
+ className: "flex flex-col gap-2",
27129
+ children: [/*#__PURE__*/jsxRuntime.jsx(DashReact.FormLabel, {
27130
+ label: "Provider Name",
27131
+ required: true
27156
27132
  }), /*#__PURE__*/jsxRuntime.jsx("p", {
27157
- className: "text-xs opacity-50",
27158
- children: "Spawn a local command as a child process"
27133
+ className: "text-sm opacity-50",
27134
+ children: "A name to identify this MCP server (e.g., \"My Custom Server\")"
27135
+ }), /*#__PURE__*/jsxRuntime.jsx(DashReact.InputText, {
27136
+ value: providerName,
27137
+ onChange: function onChange(value) {
27138
+ setProviderName(value);
27139
+ if (formErrors.providerName && value !== null && value !== void 0 && value.trim()) {
27140
+ setFormErrors(function (prev) {
27141
+ var next = _objectSpread$5({}, prev);
27142
+ delete next.providerName;
27143
+ return next;
27144
+ });
27145
+ }
27146
+ },
27147
+ placeholder: "Enter provider name"
27148
+ }), formErrors.providerName && /*#__PURE__*/jsxRuntime.jsx("p", {
27149
+ className: "text-sm text-red-400",
27150
+ children: formErrors.providerName
27159
27151
  })]
27160
- }), /*#__PURE__*/jsxRuntime.jsxs(DashReact.Card2, {
27161
- hover: true,
27162
- selected: transport === "streamable_http",
27163
- onClick: function onClick() {
27164
- return setTransport("streamable_http");
27165
- },
27166
- className: "text-left",
27167
- children: [/*#__PURE__*/jsxRuntime.jsxs("div", {
27168
- className: "flex items-center gap-2 mb-1",
27169
- children: [/*#__PURE__*/jsxRuntime.jsx(DashReact.Icon2, {
27170
- icon: "globe"
27171
- }), /*#__PURE__*/jsxRuntime.jsx("span", {
27172
- className: "font-semibold text-sm",
27173
- children: "Remote Server (HTTP)"
27174
- })]
27175
- }), /*#__PURE__*/jsxRuntime.jsx("p", {
27176
- className: "text-xs opacity-50",
27177
- children: "Connect to a remote MCP server via HTTP"
27152
+ }), /*#__PURE__*/jsxRuntime.jsxs("div", {
27153
+ className: "flex items-center gap-1",
27154
+ children: [/*#__PURE__*/jsxRuntime.jsx("button", {
27155
+ onClick: function onClick() {
27156
+ if (viewMode === "json") handleSwitchToForm();
27157
+ },
27158
+ className: "px-3 py-1 text-xs font-medium rounded-l transition-colors ".concat(viewMode === "form" ? "bg-white/10 text-white" : "text-white/50 hover:text-white/70"),
27159
+ children: "Form"
27160
+ }), /*#__PURE__*/jsxRuntime.jsx("button", {
27161
+ onClick: function onClick() {
27162
+ if (viewMode === "form") handleSwitchToJson();
27163
+ },
27164
+ className: "px-3 py-1 text-xs font-medium rounded-r transition-colors ".concat(viewMode === "json" ? "bg-white/10 text-white" : "text-white/50 hover:text-white/70"),
27165
+ children: "JSON"
27178
27166
  })]
27179
- })]
27180
- })]
27181
- }), transport === "stdio" && /*#__PURE__*/jsxRuntime.jsxs("div", {
27182
- className: "space-y-4",
27183
- children: [/*#__PURE__*/jsxRuntime.jsx("div", {
27184
- className: "border-t border-white/10 pt-4",
27185
- children: /*#__PURE__*/jsxRuntime.jsx("p", {
27186
- className: "text-xs font-semibold opacity-40 uppercase tracking-wider",
27187
- children: "Process Configuration"
27188
- })
27189
- }), /*#__PURE__*/jsxRuntime.jsxs("div", {
27190
- className: "flex flex-col gap-2",
27191
- children: [/*#__PURE__*/jsxRuntime.jsx(DashReact.FormLabel, {
27192
- label: "Command",
27193
- required: true
27194
- }), /*#__PURE__*/jsxRuntime.jsx("p", {
27195
- className: "text-sm opacity-50",
27196
- children: "The executable to run (e.g., npx, node, python)"
27197
- }), /*#__PURE__*/jsxRuntime.jsx(DashReact.InputText, {
27198
- value: command,
27199
- onChange: function onChange(value) {
27200
- setCommand(value);
27201
- if (formErrors.command && value !== null && value !== void 0 && value.trim()) {
27202
- setFormErrors(function (prev) {
27203
- var next = _objectSpread$5({}, prev);
27204
- delete next.command;
27205
- return next;
27206
- });
27207
- }
27208
- },
27209
- placeholder: "e.g., npx"
27210
- }), formErrors.command && /*#__PURE__*/jsxRuntime.jsx("p", {
27167
+ }), jsonError && /*#__PURE__*/jsxRuntime.jsx("p", {
27211
27168
  className: "text-sm text-red-400",
27212
- children: formErrors.command
27213
- })]
27214
- }), /*#__PURE__*/jsxRuntime.jsxs("div", {
27215
- className: "flex flex-col gap-2",
27216
- children: [/*#__PURE__*/jsxRuntime.jsx(DashReact.FormLabel, {
27217
- label: "Arguments"
27218
- }), /*#__PURE__*/jsxRuntime.jsx("p", {
27219
- className: "text-sm opacity-50",
27220
- children: "Space-separated arguments passed to the command"
27221
- }), /*#__PURE__*/jsxRuntime.jsx(DashReact.InputText, {
27222
- value: args,
27223
- onChange: setArgs,
27224
- placeholder: "e.g., -y @modelcontextprotocol/server-github"
27225
- })]
27226
- }), /*#__PURE__*/jsxRuntime.jsxs("div", {
27227
- className: "space-y-3",
27228
- children: [/*#__PURE__*/jsxRuntime.jsx("div", {
27229
- className: "flex items-center justify-between",
27230
- children: /*#__PURE__*/jsxRuntime.jsxs("div", {
27231
- children: [/*#__PURE__*/jsxRuntime.jsx(DashReact.FormLabel, {
27232
- label: "Environment Variable Mapping"
27233
- }), /*#__PURE__*/jsxRuntime.jsx("p", {
27234
- className: "text-sm opacity-50 mt-1",
27235
- children: "Map environment variables to credential fields"
27169
+ children: jsonError
27170
+ }), viewMode === "json" && /*#__PURE__*/jsxRuntime.jsxs("div", {
27171
+ className: "space-y-2",
27172
+ children: [/*#__PURE__*/jsxRuntime.jsx("p", {
27173
+ className: "text-xs font-semibold opacity-40 uppercase tracking-wider",
27174
+ children: "MCP Server Configuration (JSON)"
27175
+ }), /*#__PURE__*/jsxRuntime.jsx("p", {
27176
+ className: "text-sm opacity-50",
27177
+ children: "Paste a standard MCP config JSON (compatible with Claude Desktop, Cursor, etc.)"
27178
+ }), /*#__PURE__*/jsxRuntime.jsx(DashReact.CodeEditorInline, {
27179
+ code: jsonText,
27180
+ setCode: function setCode(val) {
27181
+ setJsonText(val);
27182
+ setJsonError(null);
27183
+ },
27184
+ language: "json",
27185
+ placeholder: '{\n "type": "stdio",\n "command": "npx",\n "args": ["-y", "package-name"],\n "env": {\n "API_KEY": "${API_KEY}"\n }\n}'
27186
+ })]
27187
+ }), viewMode === "form" && /*#__PURE__*/jsxRuntime.jsxs(jsxRuntime.Fragment, {
27188
+ children: [/*#__PURE__*/jsxRuntime.jsxs("div", {
27189
+ className: "space-y-2",
27190
+ children: [/*#__PURE__*/jsxRuntime.jsx("p", {
27191
+ className: "text-xs font-semibold opacity-40 uppercase tracking-wider",
27192
+ children: "Transport Type"
27193
+ }), /*#__PURE__*/jsxRuntime.jsxs("div", {
27194
+ className: "grid grid-cols-2 gap-3",
27195
+ children: [/*#__PURE__*/jsxRuntime.jsxs(DashReact.Card2, {
27196
+ hover: true,
27197
+ selected: transport === "stdio",
27198
+ onClick: function onClick() {
27199
+ return setTransport("stdio");
27200
+ },
27201
+ className: "text-left",
27202
+ children: [/*#__PURE__*/jsxRuntime.jsxs("div", {
27203
+ className: "flex items-center gap-2 mb-1",
27204
+ children: [/*#__PURE__*/jsxRuntime.jsx(DashReact.Icon2, {
27205
+ icon: "terminal"
27206
+ }), /*#__PURE__*/jsxRuntime.jsx("span", {
27207
+ className: "font-semibold text-sm",
27208
+ children: "Local Process (stdio)"
27209
+ })]
27210
+ }), /*#__PURE__*/jsxRuntime.jsx("p", {
27211
+ className: "text-xs opacity-50",
27212
+ children: "Spawn a local command as a child process"
27213
+ })]
27214
+ }), /*#__PURE__*/jsxRuntime.jsxs(DashReact.Card2, {
27215
+ hover: true,
27216
+ selected: transport === "streamable_http",
27217
+ onClick: function onClick() {
27218
+ return setTransport("streamable_http");
27219
+ },
27220
+ className: "text-left",
27221
+ children: [/*#__PURE__*/jsxRuntime.jsxs("div", {
27222
+ className: "flex items-center gap-2 mb-1",
27223
+ children: [/*#__PURE__*/jsxRuntime.jsx(DashReact.Icon2, {
27224
+ icon: "globe"
27225
+ }), /*#__PURE__*/jsxRuntime.jsx("span", {
27226
+ className: "font-semibold text-sm",
27227
+ children: "Remote Server (HTTP)"
27228
+ })]
27229
+ }), /*#__PURE__*/jsxRuntime.jsx("p", {
27230
+ className: "text-xs opacity-50",
27231
+ children: "Connect to a remote MCP server via HTTP"
27232
+ })]
27233
+ })]
27236
27234
  })]
27237
- })
27238
- }), envMappingRows.map(function (row) {
27239
- return /*#__PURE__*/jsxRuntime.jsxs("div", {
27240
- className: "flex items-center gap-2",
27235
+ }), transport === "stdio" && /*#__PURE__*/jsxRuntime.jsxs("div", {
27236
+ className: "space-y-4",
27241
27237
  children: [/*#__PURE__*/jsxRuntime.jsx("div", {
27242
- className: "flex-1",
27243
- children: /*#__PURE__*/jsxRuntime.jsx(DashReact.InputText, {
27244
- value: row.envVar,
27245
- onChange: function onChange(value) {
27246
- return updateEnvRow(row.id, "envVar", value);
27247
- },
27248
- placeholder: "ENV_VAR_NAME"
27238
+ className: "border-t border-white/10 pt-4",
27239
+ children: /*#__PURE__*/jsxRuntime.jsx("p", {
27240
+ className: "text-xs font-semibold opacity-40 uppercase tracking-wider",
27241
+ children: "Process Configuration"
27249
27242
  })
27250
- }), /*#__PURE__*/jsxRuntime.jsx("span", {
27251
- className: "opacity-30 text-sm shrink-0",
27252
- children: "\u2192"
27253
- }), /*#__PURE__*/jsxRuntime.jsx("div", {
27254
- className: "flex-1",
27255
- children: /*#__PURE__*/jsxRuntime.jsx(DashReact.InputText, {
27256
- value: row.credField,
27243
+ }), /*#__PURE__*/jsxRuntime.jsxs("div", {
27244
+ className: "flex flex-col gap-2",
27245
+ children: [/*#__PURE__*/jsxRuntime.jsx(DashReact.FormLabel, {
27246
+ label: "Command",
27247
+ required: true
27248
+ }), /*#__PURE__*/jsxRuntime.jsx("p", {
27249
+ className: "text-sm opacity-50",
27250
+ children: "The executable to run (e.g., npx, node, python)"
27251
+ }), /*#__PURE__*/jsxRuntime.jsx(DashReact.InputText, {
27252
+ value: command,
27257
27253
  onChange: function onChange(value) {
27258
- return updateEnvRow(row.id, "credField", value);
27254
+ setCommand(value);
27255
+ if (formErrors.command && value !== null && value !== void 0 && value.trim()) {
27256
+ setFormErrors(function (prev) {
27257
+ var next = _objectSpread$5({}, prev);
27258
+ delete next.command;
27259
+ return next;
27260
+ });
27261
+ }
27259
27262
  },
27260
- placeholder: "credentialField"
27261
- })
27262
- }), /*#__PURE__*/jsxRuntime.jsx("button", {
27263
- onClick: function onClick() {
27264
- return removeEnvRow(row.id);
27265
- },
27266
- className: "text-gray-500 hover:text-red-400 transition-colors shrink-0",
27267
- children: /*#__PURE__*/jsxRuntime.jsx(DashReact.FontAwesomeIcon, {
27268
- icon: "times",
27269
- className: "text-sm"
27270
- })
27271
- })]
27272
- }, row.id);
27273
- }), /*#__PURE__*/jsxRuntime.jsxs("button", {
27274
- onClick: addEnvRow,
27275
- className: "text-sm text-blue-400 hover:text-blue-300 transition-colors flex items-center gap-1",
27276
- children: [/*#__PURE__*/jsxRuntime.jsx(DashReact.FontAwesomeIcon, {
27277
- icon: "plus",
27278
- className: "text-xs"
27279
- }), /*#__PURE__*/jsxRuntime.jsx("span", {
27280
- children: "Add Environment Variable"
27281
- })]
27282
- })]
27283
- })]
27284
- }), transport === "streamable_http" && /*#__PURE__*/jsxRuntime.jsxs("div", {
27285
- className: "space-y-4",
27286
- children: [/*#__PURE__*/jsxRuntime.jsx("div", {
27287
- className: "border-t border-white/10 pt-4",
27288
- children: /*#__PURE__*/jsxRuntime.jsx("p", {
27289
- className: "text-xs font-semibold opacity-40 uppercase tracking-wider",
27290
- children: "Server Configuration"
27291
- })
27292
- }), /*#__PURE__*/jsxRuntime.jsxs("div", {
27293
- className: "flex flex-col gap-2",
27294
- children: [/*#__PURE__*/jsxRuntime.jsx(DashReact.FormLabel, {
27295
- label: "Server URL",
27296
- required: true
27297
- }), /*#__PURE__*/jsxRuntime.jsxs("p", {
27298
- className: "text-sm opacity-50",
27299
- children: ["Use", " ", /*#__PURE__*/jsxRuntime.jsx("code", {
27300
- className: "text-xs bg-white/10 px-1 py-0.5 rounded",
27301
- children: "{{fieldName}}"
27302
- }), " ", "for values provided as credentials"]
27303
- }), /*#__PURE__*/jsxRuntime.jsx(DashReact.InputText, {
27304
- value: url,
27305
- onChange: function onChange(value) {
27306
- setUrl(value);
27307
- if (formErrors.url && value !== null && value !== void 0 && value.trim()) {
27308
- setFormErrors(function (prev) {
27309
- var next = _objectSpread$5({}, prev);
27310
- delete next.url;
27311
- return next;
27312
- });
27313
- }
27314
- },
27315
- placeholder: "e.g., https://mcp.example.com/sse"
27316
- }), formErrors.url && /*#__PURE__*/jsxRuntime.jsx("p", {
27317
- className: "text-sm text-red-400",
27318
- children: formErrors.url
27319
- })]
27320
- }), /*#__PURE__*/jsxRuntime.jsxs("div", {
27321
- className: "space-y-3",
27322
- children: [/*#__PURE__*/jsxRuntime.jsxs("div", {
27323
- children: [/*#__PURE__*/jsxRuntime.jsx(DashReact.FormLabel, {
27324
- label: "Request Headers"
27325
- }), /*#__PURE__*/jsxRuntime.jsxs("p", {
27326
- className: "text-sm opacity-50 mt-1",
27327
- children: ["Use", " ", /*#__PURE__*/jsxRuntime.jsx("code", {
27328
- className: "text-xs bg-white/10 px-1 py-0.5 rounded",
27329
- children: "{{fieldName}}"
27330
- }), " ", "in values for credential placeholders"]
27331
- })]
27332
- }), headerRows.map(function (row) {
27333
- return /*#__PURE__*/jsxRuntime.jsxs("div", {
27334
- className: "flex items-center gap-2",
27263
+ placeholder: "e.g., npx"
27264
+ }), formErrors.command && /*#__PURE__*/jsxRuntime.jsx("p", {
27265
+ className: "text-sm text-red-400",
27266
+ children: formErrors.command
27267
+ })]
27268
+ }), /*#__PURE__*/jsxRuntime.jsxs("div", {
27269
+ className: "flex flex-col gap-2",
27270
+ children: [/*#__PURE__*/jsxRuntime.jsx(DashReact.FormLabel, {
27271
+ label: "Arguments"
27272
+ }), /*#__PURE__*/jsxRuntime.jsx("p", {
27273
+ className: "text-sm opacity-50",
27274
+ children: "Space-separated arguments passed to the command"
27275
+ }), /*#__PURE__*/jsxRuntime.jsx(DashReact.InputText, {
27276
+ value: args,
27277
+ onChange: setArgs,
27278
+ placeholder: "e.g., -y @modelcontextprotocol/server-github"
27279
+ })]
27280
+ }), /*#__PURE__*/jsxRuntime.jsxs("div", {
27281
+ className: "space-y-3",
27282
+ children: [/*#__PURE__*/jsxRuntime.jsx("div", {
27283
+ className: "flex items-center justify-between",
27284
+ children: /*#__PURE__*/jsxRuntime.jsxs("div", {
27285
+ children: [/*#__PURE__*/jsxRuntime.jsx(DashReact.FormLabel, {
27286
+ label: "Environment Variable Mapping"
27287
+ }), /*#__PURE__*/jsxRuntime.jsx("p", {
27288
+ className: "text-sm opacity-50 mt-1",
27289
+ children: "Map environment variables to credential fields"
27290
+ })]
27291
+ })
27292
+ }), envMappingRows.map(function (row) {
27293
+ return /*#__PURE__*/jsxRuntime.jsxs("div", {
27294
+ className: "flex items-center gap-2",
27295
+ children: [/*#__PURE__*/jsxRuntime.jsx("div", {
27296
+ className: "flex-1",
27297
+ children: /*#__PURE__*/jsxRuntime.jsx(DashReact.InputText, {
27298
+ value: row.envVar,
27299
+ onChange: function onChange(value) {
27300
+ return updateEnvRow(row.id, "envVar", value);
27301
+ },
27302
+ placeholder: "ENV_VAR_NAME"
27303
+ })
27304
+ }), /*#__PURE__*/jsxRuntime.jsx("span", {
27305
+ className: "opacity-30 text-sm shrink-0",
27306
+ children: "\u2192"
27307
+ }), /*#__PURE__*/jsxRuntime.jsx("div", {
27308
+ className: "flex-1",
27309
+ children: /*#__PURE__*/jsxRuntime.jsx(DashReact.InputText, {
27310
+ value: row.credField,
27311
+ onChange: function onChange(value) {
27312
+ return updateEnvRow(row.id, "credField", value);
27313
+ },
27314
+ placeholder: "credentialField"
27315
+ })
27316
+ }), /*#__PURE__*/jsxRuntime.jsx("button", {
27317
+ onClick: function onClick() {
27318
+ return removeEnvRow(row.id);
27319
+ },
27320
+ className: "text-gray-500 hover:text-red-400 transition-colors shrink-0",
27321
+ children: /*#__PURE__*/jsxRuntime.jsx(DashReact.FontAwesomeIcon, {
27322
+ icon: "times",
27323
+ className: "text-sm"
27324
+ })
27325
+ })]
27326
+ }, row.id);
27327
+ }), /*#__PURE__*/jsxRuntime.jsxs("button", {
27328
+ onClick: addEnvRow,
27329
+ className: "text-sm text-blue-400 hover:text-blue-300 transition-colors flex items-center gap-1",
27330
+ children: [/*#__PURE__*/jsxRuntime.jsx(DashReact.FontAwesomeIcon, {
27331
+ icon: "plus",
27332
+ className: "text-xs"
27333
+ }), /*#__PURE__*/jsxRuntime.jsx("span", {
27334
+ children: "Add Environment Variable"
27335
+ })]
27336
+ })]
27337
+ })]
27338
+ }), transport === "streamable_http" && /*#__PURE__*/jsxRuntime.jsxs("div", {
27339
+ className: "space-y-4",
27335
27340
  children: [/*#__PURE__*/jsxRuntime.jsx("div", {
27336
- className: "flex-1",
27337
- children: /*#__PURE__*/jsxRuntime.jsx(DashReact.InputText, {
27338
- value: row.headerName,
27339
- onChange: function onChange(value) {
27340
- return updateHeaderRow(row.id, "headerName", value);
27341
- },
27342
- placeholder: "Header-Name"
27341
+ className: "border-t border-white/10 pt-4",
27342
+ children: /*#__PURE__*/jsxRuntime.jsx("p", {
27343
+ className: "text-xs font-semibold opacity-40 uppercase tracking-wider",
27344
+ children: "Server Configuration"
27343
27345
  })
27344
- }), /*#__PURE__*/jsxRuntime.jsx("span", {
27345
- className: "opacity-30 text-sm shrink-0",
27346
- children: ":"
27347
- }), /*#__PURE__*/jsxRuntime.jsx("div", {
27348
- className: "flex-1",
27349
- children: /*#__PURE__*/jsxRuntime.jsx(DashReact.InputText, {
27350
- value: row.headerValue,
27346
+ }), /*#__PURE__*/jsxRuntime.jsxs("div", {
27347
+ className: "flex flex-col gap-2",
27348
+ children: [/*#__PURE__*/jsxRuntime.jsx(DashReact.FormLabel, {
27349
+ label: "Server URL",
27350
+ required: true
27351
+ }), /*#__PURE__*/jsxRuntime.jsxs("p", {
27352
+ className: "text-sm opacity-50",
27353
+ children: ["Use", " ", /*#__PURE__*/jsxRuntime.jsx("code", {
27354
+ className: "text-xs bg-white/10 px-1 py-0.5 rounded",
27355
+ children: "{{fieldName}}"
27356
+ }), " ", "for values provided as credentials"]
27357
+ }), /*#__PURE__*/jsxRuntime.jsx(DashReact.InputText, {
27358
+ value: url,
27351
27359
  onChange: function onChange(value) {
27352
- return updateHeaderRow(row.id, "headerValue", value);
27360
+ setUrl(value);
27361
+ if (formErrors.url && value !== null && value !== void 0 && value.trim()) {
27362
+ setFormErrors(function (prev) {
27363
+ var next = _objectSpread$5({}, prev);
27364
+ delete next.url;
27365
+ return next;
27366
+ });
27367
+ }
27353
27368
  },
27354
- placeholder: "Bearer {{apiKey}}"
27355
- })
27356
- }), /*#__PURE__*/jsxRuntime.jsx("button", {
27357
- onClick: function onClick() {
27358
- return removeHeaderRow(row.id);
27359
- },
27360
- className: "text-gray-500 hover:text-red-400 transition-colors shrink-0",
27361
- children: /*#__PURE__*/jsxRuntime.jsx(DashReact.FontAwesomeIcon, {
27362
- icon: "times",
27363
- className: "text-sm"
27364
- })
27369
+ placeholder: "e.g., https://mcp.example.com/sse"
27370
+ }), formErrors.url && /*#__PURE__*/jsxRuntime.jsx("p", {
27371
+ className: "text-sm text-red-400",
27372
+ children: formErrors.url
27373
+ })]
27374
+ }), /*#__PURE__*/jsxRuntime.jsxs("div", {
27375
+ className: "space-y-3",
27376
+ children: [/*#__PURE__*/jsxRuntime.jsxs("div", {
27377
+ children: [/*#__PURE__*/jsxRuntime.jsx(DashReact.FormLabel, {
27378
+ label: "Request Headers"
27379
+ }), /*#__PURE__*/jsxRuntime.jsxs("p", {
27380
+ className: "text-sm opacity-50 mt-1",
27381
+ children: ["Use", " ", /*#__PURE__*/jsxRuntime.jsx("code", {
27382
+ className: "text-xs bg-white/10 px-1 py-0.5 rounded",
27383
+ children: "{{fieldName}}"
27384
+ }), " ", "in values for credential placeholders"]
27385
+ })]
27386
+ }), headerRows.map(function (row) {
27387
+ return /*#__PURE__*/jsxRuntime.jsxs("div", {
27388
+ className: "flex items-center gap-2",
27389
+ children: [/*#__PURE__*/jsxRuntime.jsx("div", {
27390
+ className: "flex-1",
27391
+ children: /*#__PURE__*/jsxRuntime.jsx(DashReact.InputText, {
27392
+ value: row.headerName,
27393
+ onChange: function onChange(value) {
27394
+ return updateHeaderRow(row.id, "headerName", value);
27395
+ },
27396
+ placeholder: "Header-Name"
27397
+ })
27398
+ }), /*#__PURE__*/jsxRuntime.jsx("span", {
27399
+ className: "opacity-30 text-sm shrink-0",
27400
+ children: ":"
27401
+ }), /*#__PURE__*/jsxRuntime.jsx("div", {
27402
+ className: "flex-1",
27403
+ children: /*#__PURE__*/jsxRuntime.jsx(DashReact.InputText, {
27404
+ value: row.headerValue,
27405
+ onChange: function onChange(value) {
27406
+ return updateHeaderRow(row.id, "headerValue", value);
27407
+ },
27408
+ placeholder: "Bearer {{apiKey}}"
27409
+ })
27410
+ }), /*#__PURE__*/jsxRuntime.jsx("button", {
27411
+ onClick: function onClick() {
27412
+ return removeHeaderRow(row.id);
27413
+ },
27414
+ className: "text-gray-500 hover:text-red-400 transition-colors shrink-0",
27415
+ children: /*#__PURE__*/jsxRuntime.jsx(DashReact.FontAwesomeIcon, {
27416
+ icon: "times",
27417
+ className: "text-sm"
27418
+ })
27419
+ })]
27420
+ }, row.id);
27421
+ }), /*#__PURE__*/jsxRuntime.jsxs("button", {
27422
+ onClick: addHeaderRow,
27423
+ className: "text-sm text-blue-400 hover:text-blue-300 transition-colors flex items-center gap-1",
27424
+ children: [/*#__PURE__*/jsxRuntime.jsx(DashReact.FontAwesomeIcon, {
27425
+ icon: "plus",
27426
+ className: "text-xs"
27427
+ }), /*#__PURE__*/jsxRuntime.jsx("span", {
27428
+ children: "Add Header"
27429
+ })]
27430
+ })]
27431
+ })]
27432
+ }), formFields.length > 0 && /*#__PURE__*/jsxRuntime.jsxs(jsxRuntime.Fragment, {
27433
+ children: [/*#__PURE__*/jsxRuntime.jsxs("div", {
27434
+ className: "border-t border-white/10 pt-4",
27435
+ children: [/*#__PURE__*/jsxRuntime.jsx("p", {
27436
+ className: "text-xs font-semibold opacity-40 uppercase tracking-wider",
27437
+ children: "Credentials"
27438
+ }), /*#__PURE__*/jsxRuntime.jsx("p", {
27439
+ className: "text-sm opacity-50 mt-1",
27440
+ children: "Values for the fields referenced in your configuration above"
27441
+ })]
27442
+ }), formFields.map(function (field) {
27443
+ return /*#__PURE__*/jsxRuntime.jsxs("div", {
27444
+ className: "flex flex-col gap-2",
27445
+ children: [/*#__PURE__*/jsxRuntime.jsx(DashReact.FormLabel, {
27446
+ label: field.displayName,
27447
+ required: field.required
27448
+ }), /*#__PURE__*/jsxRuntime.jsxs("div", {
27449
+ className: "flex gap-2",
27450
+ children: [/*#__PURE__*/jsxRuntime.jsx("div", {
27451
+ className: "flex-1",
27452
+ children: /*#__PURE__*/jsxRuntime.jsx(DashReact.InputText, {
27453
+ type: field.secret ? "password" : "text",
27454
+ value: credentialData[field.key] || "",
27455
+ onChange: function onChange(value) {
27456
+ return handleCredentialChange(field.key, value);
27457
+ },
27458
+ placeholder: field.type === "file" ? "Select a file..." : "Enter ".concat(field.displayName.toLowerCase())
27459
+ })
27460
+ }), field.type === "file" && /*#__PURE__*/jsxRuntime.jsx("button", {
27461
+ onClick: /*#__PURE__*/_asyncToGenerator(/*#__PURE__*/_regeneratorRuntime.mark(function _callee() {
27462
+ var filepath;
27463
+ return _regeneratorRuntime.wrap(function (_context) {
27464
+ while (1) switch (_context.prev = _context.next) {
27465
+ case 0:
27466
+ _context.next = 1;
27467
+ return window.mainApi.dialog.chooseFile(true, ["json"]);
27468
+ case 1:
27469
+ filepath = _context.sent;
27470
+ if (filepath) handleCredentialChange(field.key, filepath);
27471
+ case 2:
27472
+ case "end":
27473
+ return _context.stop();
27474
+ }
27475
+ }, _callee);
27476
+ })),
27477
+ className: "px-3 py-1.5 text-sm rounded bg-white/10 hover:bg-white/20 transition-colors",
27478
+ children: "Browse"
27479
+ })]
27480
+ }), formErrors[field.key] && /*#__PURE__*/jsxRuntime.jsx("p", {
27481
+ className: "text-sm text-red-400",
27482
+ children: formErrors[field.key]
27483
+ })]
27484
+ }, field.key);
27365
27485
  })]
27366
- }, row.id);
27367
- }), /*#__PURE__*/jsxRuntime.jsxs("button", {
27368
- onClick: addHeaderRow,
27369
- className: "text-sm text-blue-400 hover:text-blue-300 transition-colors flex items-center gap-1",
27370
- children: [/*#__PURE__*/jsxRuntime.jsx(DashReact.FontAwesomeIcon, {
27371
- icon: "plus",
27372
- className: "text-xs"
27373
- }), /*#__PURE__*/jsxRuntime.jsx("span", {
27374
- children: "Add Header"
27375
27486
  })]
27376
27487
  })]
27377
- })]
27378
- }), formFields.length > 0 && /*#__PURE__*/jsxRuntime.jsxs(jsxRuntime.Fragment, {
27379
- children: [/*#__PURE__*/jsxRuntime.jsxs("div", {
27380
- className: "border-t border-white/10 pt-4",
27381
- children: [/*#__PURE__*/jsxRuntime.jsx("p", {
27382
- className: "text-xs font-semibold opacity-40 uppercase tracking-wider",
27383
- children: "Credentials"
27384
- }), /*#__PURE__*/jsxRuntime.jsx("p", {
27385
- className: "text-sm opacity-50 mt-1",
27386
- children: "Values for the fields referenced in your configuration above"
27387
- })]
27388
- }), formFields.map(function (field) {
27389
- return /*#__PURE__*/jsxRuntime.jsxs("div", {
27390
- className: "flex flex-col gap-2",
27391
- children: [/*#__PURE__*/jsxRuntime.jsx(DashReact.FormLabel, {
27392
- label: field.displayName,
27393
- required: field.required
27394
- }), /*#__PURE__*/jsxRuntime.jsxs("div", {
27395
- className: "flex gap-2",
27396
- children: [/*#__PURE__*/jsxRuntime.jsx("div", {
27397
- className: "flex-1",
27398
- children: /*#__PURE__*/jsxRuntime.jsx(DashReact.InputText, {
27399
- type: field.secret ? "password" : "text",
27400
- value: credentialData[field.key] || "",
27401
- onChange: function onChange(value) {
27402
- return handleCredentialChange(field.key, value);
27403
- },
27404
- placeholder: field.type === "file" ? "Select a file..." : "Enter ".concat(field.displayName.toLowerCase())
27405
- })
27406
- }), field.type === "file" && /*#__PURE__*/jsxRuntime.jsx("button", {
27407
- onClick: /*#__PURE__*/_asyncToGenerator(/*#__PURE__*/_regeneratorRuntime.mark(function _callee() {
27408
- var filepath;
27409
- return _regeneratorRuntime.wrap(function (_context) {
27410
- while (1) switch (_context.prev = _context.next) {
27411
- case 0:
27412
- _context.next = 1;
27413
- return window.mainApi.dialog.chooseFile(true, ["json"]);
27414
- case 1:
27415
- filepath = _context.sent;
27416
- if (filepath) handleCredentialChange(field.key, filepath);
27417
- case 2:
27418
- case "end":
27419
- return _context.stop();
27420
- }
27421
- }, _callee);
27422
- })),
27423
- className: "px-3 py-1.5 text-sm rounded bg-white/10 hover:bg-white/20 transition-colors",
27424
- children: "Browse"
27425
- })]
27426
- }), formErrors[field.key] && /*#__PURE__*/jsxRuntime.jsx("p", {
27427
- className: "text-sm text-red-400",
27428
- children: formErrors[field.key]
27488
+ })
27489
+ }), /*#__PURE__*/jsxRuntime.jsx(DashReact.Stepper.Step, {
27490
+ label: "Test",
27491
+ description: "Verify connection",
27492
+ children: /*#__PURE__*/jsxRuntime.jsxs("div", {
27493
+ className: "flex-1 min-h-0 overflow-y-auto pb-4 space-y-5",
27494
+ children: [/*#__PURE__*/jsxRuntime.jsxs("div", {
27495
+ className: "flex flex-col items-center justify-center py-8 space-y-4",
27496
+ children: [/*#__PURE__*/jsxRuntime.jsx("p", {
27497
+ className: "text-sm opacity-60 text-center",
27498
+ children: "Test the connection to verify your configuration is correct."
27499
+ }), /*#__PURE__*/jsxRuntime.jsx(DashReact.Button, {
27500
+ title: isTesting ? "Testing..." : "Test Connection",
27501
+ onClick: handleTestConnection,
27502
+ size: "md"
27429
27503
  })]
27430
- }, field.key);
27431
- })]
27504
+ }), testResult && /*#__PURE__*/jsxRuntime.jsx("div", {
27505
+ className: "p-3 rounded-lg text-sm ".concat(testResult.success ? "bg-green-900/30 border border-green-700 text-green-300" : "bg-red-900/30 border border-red-700 text-red-300"),
27506
+ children: /*#__PURE__*/jsxRuntime.jsxs("div", {
27507
+ className: "flex items-center gap-2",
27508
+ children: [/*#__PURE__*/jsxRuntime.jsx(DashReact.FontAwesomeIcon, {
27509
+ icon: testResult.success ? "circle-check" : "circle-exclamation"
27510
+ }), /*#__PURE__*/jsxRuntime.jsx("span", {
27511
+ children: testResult.message
27512
+ })]
27513
+ })
27514
+ })]
27515
+ })
27516
+ }), /*#__PURE__*/jsxRuntime.jsx(DashReact.Stepper.Step, {
27517
+ label: "Tools",
27518
+ description: "Select allowed tools",
27519
+ children: /*#__PURE__*/jsxRuntime.jsx("div", {
27520
+ className: "flex-1 min-h-0 overflow-y-auto pb-4 space-y-5",
27521
+ children: testResult !== null && testResult !== void 0 && testResult.success && ((_testResult$tools = testResult.tools) === null || _testResult$tools === void 0 ? void 0 : _testResult$tools.length) > 0 && selectedTools ? /*#__PURE__*/jsxRuntime.jsx(ToolSelector, {
27522
+ tools: testResult.tools,
27523
+ selectedTools: selectedTools,
27524
+ onSelectionChange: setSelectedTools
27525
+ }) : /*#__PURE__*/jsxRuntime.jsx("div", {
27526
+ className: "text-center py-8 opacity-50",
27527
+ children: "No tools available. Go back and test the connection first."
27528
+ })
27529
+ })
27432
27530
  })]
27433
- }), testResult && /*#__PURE__*/jsxRuntime.jsx("div", {
27434
- className: "p-3 rounded-lg text-sm ".concat(testResult.success ? "bg-green-900/30 border border-green-700 text-green-300" : "bg-red-900/30 border border-red-700 text-red-300"),
27435
- children: /*#__PURE__*/jsxRuntime.jsxs("div", {
27436
- className: "flex items-center gap-2",
27437
- children: [/*#__PURE__*/jsxRuntime.jsx(DashReact.FontAwesomeIcon, {
27438
- icon: testResult.success ? "circle-check" : "circle-exclamation"
27439
- }), /*#__PURE__*/jsxRuntime.jsx("span", {
27440
- children: testResult.message
27441
- })]
27442
- })
27443
- }), (testResult === null || testResult === void 0 ? void 0 : testResult.success) && ((_testResult$tools = testResult.tools) === null || _testResult$tools === void 0 ? void 0 : _testResult$tools.length) > 0 && selectedTools && /*#__PURE__*/jsxRuntime.jsx(ToolSelector, {
27444
- tools: testResult.tools,
27445
- selectedTools: selectedTools,
27446
- onSelectionChange: setSelectedTools
27447
- })]
27531
+ })
27448
27532
  }), /*#__PURE__*/jsxRuntime.jsxs("div", {
27449
- className: "flex-shrink-0 flex flex-row justify-end gap-2 px-6 py-4 border-t border-white/10",
27450
- children: [/*#__PURE__*/jsxRuntime.jsx(DashReact.Button, {
27451
- title: "Cancel",
27452
- onClick: onBack,
27453
- size: "sm"
27454
- }), /*#__PURE__*/jsxRuntime.jsx(DashReact.Button, {
27455
- title: isTesting ? "Testing..." : "Test Connection",
27456
- onClick: handleTestConnection,
27457
- size: "sm"
27458
- }), /*#__PURE__*/jsxRuntime.jsx(DashReact.Button, {
27459
- title: isEditMode ? "Save Changes" : "Save MCP Server",
27460
- onClick: handleSave,
27461
- size: "sm"
27533
+ className: "flex-shrink-0 flex flex-row items-center px-6 py-4 border-t border-white/10",
27534
+ children: [/*#__PURE__*/jsxRuntime.jsxs("div", {
27535
+ className: "flex flex-row gap-2",
27536
+ children: [wizardStep === 0 && /*#__PURE__*/jsxRuntime.jsx(DashReact.Button, {
27537
+ title: "Cancel",
27538
+ onClick: onBack,
27539
+ size: "sm"
27540
+ }), wizardStep > 0 && /*#__PURE__*/jsxRuntime.jsx(DashReact.Button, {
27541
+ title: "Back",
27542
+ onClick: function onClick() {
27543
+ return setWizardStep(wizardStep - 1);
27544
+ },
27545
+ size: "sm"
27546
+ })]
27547
+ }), /*#__PURE__*/jsxRuntime.jsx("div", {
27548
+ className: "flex-1 text-center",
27549
+ children: /*#__PURE__*/jsxRuntime.jsxs("span", {
27550
+ className: "text-xs opacity-40",
27551
+ children: ["Step ", wizardStep + 1, " of 3"]
27552
+ })
27553
+ }), /*#__PURE__*/jsxRuntime.jsxs("div", {
27554
+ className: "flex flex-row gap-2",
27555
+ children: [wizardStep === 0 && /*#__PURE__*/jsxRuntime.jsx(DashReact.Button, {
27556
+ title: "Next",
27557
+ onClick: function onClick() {
27558
+ return handleWizardStepChange(1);
27559
+ },
27560
+ size: "sm"
27561
+ }), wizardStep === 1 && /*#__PURE__*/jsxRuntime.jsxs(jsxRuntime.Fragment, {
27562
+ children: [/*#__PURE__*/jsxRuntime.jsx(DashReact.Button, {
27563
+ title: isTesting ? "Testing..." : "Test Connection",
27564
+ onClick: handleTestConnection,
27565
+ size: "sm"
27566
+ }), /*#__PURE__*/jsxRuntime.jsx(DashReact.Button, {
27567
+ title: "Next",
27568
+ onClick: function onClick() {
27569
+ return handleWizardStepChange(2);
27570
+ },
27571
+ disabled: !(testResult !== null && testResult !== void 0 && testResult.success) && !(isEditMode && initialAllowedTools),
27572
+ size: "sm"
27573
+ })]
27574
+ }), wizardStep === 2 && /*#__PURE__*/jsxRuntime.jsx(DashReact.Button, {
27575
+ title: isEditMode ? "Save Changes" : "Save MCP Server",
27576
+ onClick: handleSave,
27577
+ size: "sm"
27578
+ })]
27462
27579
  })]
27463
27580
  })]
27464
27581
  });
@@ -27545,30 +27662,34 @@ var McpCatalogDetail = function McpCatalogDetail(_ref) {
27545
27662
  _useState20 = _slicedToArray(_useState19, 2),
27546
27663
  selectedTools = _useState20[0],
27547
27664
  setSelectedTools = _useState20[1];
27665
+ var _useState21 = React.useState(0),
27666
+ _useState22 = _slicedToArray(_useState21, 2),
27667
+ wizardStep = _useState22[0],
27668
+ setWizardStep = _useState22[1];
27548
27669
 
27549
27670
  // Configuration form state
27550
- var _useState21 = React.useState(""),
27551
- _useState22 = _slicedToArray(_useState21, 2),
27552
- providerName = _useState22[0],
27553
- setProviderName = _useState22[1];
27554
- var _useState23 = React.useState({}),
27671
+ var _useState23 = React.useState(""),
27555
27672
  _useState24 = _slicedToArray(_useState23, 2),
27556
- credentialData = _useState24[0],
27557
- setCredentialData = _useState24[1];
27673
+ providerName = _useState24[0],
27674
+ setProviderName = _useState24[1];
27558
27675
  var _useState25 = React.useState({}),
27559
27676
  _useState26 = _slicedToArray(_useState25, 2),
27560
- formErrors = _useState26[0],
27561
- setFormErrors = _useState26[1];
27677
+ credentialData = _useState26[0],
27678
+ setCredentialData = _useState26[1];
27679
+ var _useState27 = React.useState({}),
27680
+ _useState28 = _slicedToArray(_useState27, 2),
27681
+ formErrors = _useState28[0],
27682
+ setFormErrors = _useState28[1];
27562
27683
 
27563
27684
  // Advanced config row state
27564
- var _useState27 = React.useState([]),
27565
- _useState28 = _slicedToArray(_useState27, 2),
27566
- envMappingRows = _useState28[0],
27567
- setEnvMappingRows = _useState28[1];
27568
27685
  var _useState29 = React.useState([]),
27569
27686
  _useState30 = _slicedToArray(_useState29, 2),
27570
- headerRows = _useState30[0],
27571
- setHeaderRows = _useState30[1];
27687
+ envMappingRows = _useState30[0],
27688
+ setEnvMappingRows = _useState30[1];
27689
+ var _useState31 = React.useState([]),
27690
+ _useState32 = _slicedToArray(_useState31, 2),
27691
+ headerRows = _useState32[0],
27692
+ setHeaderRows = _useState32[1];
27572
27693
  var rowIdRef = React.useRef(0);
27573
27694
  var nextRowId = function nextRowId() {
27574
27695
  return "cat_".concat(++rowIdRef.current);
@@ -27609,6 +27730,25 @@ var McpCatalogDetail = function McpCatalogDetail(_ref) {
27609
27730
  });
27610
27731
  });
27611
27732
 
27733
+ // Wizard step navigation with validation gates
27734
+ var handleWizardStepChange = function handleWizardStepChange(newStep) {
27735
+ // Allow backward navigation freely
27736
+ if (newStep < wizardStep) {
27737
+ setWizardStep(newStep);
27738
+ return;
27739
+ }
27740
+ // Step 0→1: validate the configure form + auth gate
27741
+ if (wizardStep === 0 && newStep >= 1) {
27742
+ if (!validateForm()) return;
27743
+ if (selectedServer !== null && selectedServer !== void 0 && selectedServer.authCommand && !(authResult !== null && authResult !== void 0 && authResult.success)) return;
27744
+ }
27745
+ // Step 1→2: require successful test
27746
+ if (wizardStep === 1 && newStep >= 2) {
27747
+ if (!(testResult !== null && testResult !== void 0 && testResult.success)) return;
27748
+ }
27749
+ setWizardStep(newStep);
27750
+ };
27751
+
27612
27752
  // Handle server selection -> show configuration form
27613
27753
  var handleSelectServer = function handleSelectServer(server) {
27614
27754
  var _server$mcpConfig, _server$mcpConfig2;
@@ -27619,6 +27759,7 @@ var McpCatalogDetail = function McpCatalogDetail(_ref) {
27619
27759
  setProviderName(server.name);
27620
27760
  setCredentialData({});
27621
27761
  setFormErrors({});
27762
+ setWizardStep(0);
27622
27763
  setEnvMappingRows(envMappingToRows((_server$mcpConfig = server.mcpConfig) === null || _server$mcpConfig === void 0 ? void 0 : _server$mcpConfig.envMapping, nextRowId));
27623
27764
  setHeaderRows(headerTemplateToRows((_server$mcpConfig2 = server.mcpConfig) === null || _server$mcpConfig2 === void 0 ? void 0 : _server$mcpConfig2.headerTemplate, nextRowId));
27624
27765
  };
@@ -27749,6 +27890,7 @@ var McpCatalogDetail = function McpCatalogDetail(_ref) {
27749
27890
  setFormErrors({});
27750
27891
  setEnvMappingRows([]);
27751
27892
  setHeaderRows([]);
27893
+ setWizardStep(0);
27752
27894
  };
27753
27895
 
27754
27896
  // Prune credential data when form fields change (advanced config removed a field)
@@ -27776,205 +27918,281 @@ var McpCatalogDetail = function McpCatalogDetail(_ref) {
27776
27918
  });
27777
27919
  }
27778
27920
 
27779
- // ── Stage 2: Configuration Form ──
27921
+ // ── Stage 2: Configuration Form (3-step Stepper) ──
27780
27922
  if (isConfiguring && selectedServer) {
27781
27923
  var _testResult$tools;
27782
27924
  return /*#__PURE__*/jsxRuntime.jsxs("div", {
27783
27925
  className: "flex flex-col flex-1 min-h-0",
27784
27926
  children: [/*#__PURE__*/jsxRuntime.jsxs("div", {
27785
- className: "flex-1 min-h-0 overflow-y-auto p-6 space-y-5",
27786
- children: [/*#__PURE__*/jsxRuntime.jsxs("div", {
27787
- className: "flex items-center gap-3",
27788
- children: [/*#__PURE__*/jsxRuntime.jsx("button", {
27789
- onClick: handleBack,
27790
- className: "text-gray-400 hover:text-gray-200 transition-colors",
27791
- children: /*#__PURE__*/jsxRuntime.jsx(DashReact.FontAwesomeIcon, {
27792
- icon: "arrow-left",
27793
- className: "text-lg"
27794
- })
27795
- }), /*#__PURE__*/jsxRuntime.jsxs("div", {
27796
- children: [/*#__PURE__*/jsxRuntime.jsx(DashReact.SubHeading3, {
27797
- title: "Configure ".concat(selectedServer.name),
27798
- padding: false
27799
- }), /*#__PURE__*/jsxRuntime.jsx("p", {
27800
- className: "text-sm opacity-50 mt-1",
27801
- children: selectedServer.description || "Configure the MCP server connection"
27802
- })]
27803
- })]
27804
- }), /*#__PURE__*/jsxRuntime.jsxs("div", {
27805
- className: "bg-white/5 border border-white/10 rounded-lg p-4 space-y-3",
27806
- children: [/*#__PURE__*/jsxRuntime.jsx("p", {
27807
- className: "text-xs font-semibold opacity-40 uppercase tracking-wider",
27808
- children: "MCP Server Connection"
27809
- }), /*#__PURE__*/jsxRuntime.jsxs("div", {
27810
- className: "space-y-2 text-sm",
27811
- children: [/*#__PURE__*/jsxRuntime.jsxs("div", {
27812
- className: "flex gap-2",
27813
- children: [/*#__PURE__*/jsxRuntime.jsx("span", {
27814
- className: "opacity-50 w-24 shrink-0",
27815
- children: "Transport:"
27816
- }), /*#__PURE__*/jsxRuntime.jsx(DashReact.Tag, {
27817
- text: effectiveMcpConfig.transport === "streamable_http" ? "Streamable HTTP" : "stdio"
27818
- })]
27819
- }), effectiveMcpConfig.transport === "streamable_http" ? /*#__PURE__*/jsxRuntime.jsxs("div", {
27820
- className: "flex gap-2",
27821
- children: [/*#__PURE__*/jsxRuntime.jsx("span", {
27822
- className: "opacity-50 w-24 shrink-0",
27823
- children: "Endpoint:"
27824
- }), /*#__PURE__*/jsxRuntime.jsx("span", {
27825
- className: "text-xs opacity-70",
27826
- children: "Remote hosted server (URL provided below)"
27827
- })]
27828
- }) : /*#__PURE__*/jsxRuntime.jsxs(jsxRuntime.Fragment, {
27829
- children: [/*#__PURE__*/jsxRuntime.jsxs("div", {
27830
- className: "flex gap-2",
27831
- children: [/*#__PURE__*/jsxRuntime.jsx("span", {
27832
- className: "opacity-50 w-24 shrink-0",
27833
- children: "Command:"
27834
- }), /*#__PURE__*/jsxRuntime.jsxs("code", {
27835
- className: "text-xs bg-white/5 px-2 py-0.5 rounded",
27836
- children: [effectiveMcpConfig.command, " ", (effectiveMcpConfig.args || []).join(" ")]
27837
- })]
27838
- }), effectiveMcpConfig.envMapping && Object.keys(effectiveMcpConfig.envMapping).length > 0 && /*#__PURE__*/jsxRuntime.jsxs("div", {
27839
- className: "flex gap-2",
27840
- children: [/*#__PURE__*/jsxRuntime.jsx("span", {
27841
- className: "opacity-50 w-24 shrink-0",
27842
- children: "Env Vars:"
27843
- }), /*#__PURE__*/jsxRuntime.jsx("span", {
27844
- className: "text-xs opacity-70",
27845
- children: Object.keys(effectiveMcpConfig.envMapping).join(", ")
27846
- })]
27847
- })]
27848
- })]
27849
- })]
27850
- }), /*#__PURE__*/jsxRuntime.jsx(AdvancedMcpConfig, {
27851
- transport: effectiveMcpConfig.transport || "stdio",
27852
- envMappingRows: envMappingRows,
27853
- onEnvMappingRowsChange: setEnvMappingRows,
27854
- headerRows: headerRows,
27855
- onHeaderRowsChange: setHeaderRows
27927
+ className: "flex items-center gap-3 px-6 pt-6 pb-2",
27928
+ children: [/*#__PURE__*/jsxRuntime.jsx("button", {
27929
+ onClick: handleBack,
27930
+ className: "text-gray-400 hover:text-gray-200 transition-colors",
27931
+ children: /*#__PURE__*/jsxRuntime.jsx(DashReact.FontAwesomeIcon, {
27932
+ icon: "arrow-left",
27933
+ className: "text-lg"
27934
+ })
27856
27935
  }), /*#__PURE__*/jsxRuntime.jsxs("div", {
27857
- className: "flex flex-col gap-2",
27858
- children: [/*#__PURE__*/jsxRuntime.jsx(DashReact.FormLabel, {
27859
- label: "Provider Name",
27860
- required: true
27936
+ children: [/*#__PURE__*/jsxRuntime.jsx(DashReact.SubHeading3, {
27937
+ title: "Configure ".concat(selectedServer.name),
27938
+ padding: false
27861
27939
  }), /*#__PURE__*/jsxRuntime.jsx("p", {
27862
- className: "text-sm opacity-50",
27863
- children: "A name to identify this MCP server instance (e.g., \"Algolia Production\")"
27864
- }), /*#__PURE__*/jsxRuntime.jsx(DashReact.InputText, {
27865
- value: providerName,
27866
- onChange: function onChange(value) {
27867
- setProviderName(value);
27868
- if (formErrors.providerName && value !== null && value !== void 0 && value.trim()) {
27869
- setFormErrors(function (prev) {
27870
- var next = _objectSpread$4({}, prev);
27871
- delete next.providerName;
27872
- return next;
27873
- });
27874
- }
27875
- },
27876
- placeholder: "Enter provider name"
27877
- }), formErrors.providerName && /*#__PURE__*/jsxRuntime.jsx("p", {
27878
- className: "text-sm text-red-400",
27879
- children: formErrors.providerName
27940
+ className: "text-sm opacity-50 mt-1",
27941
+ children: selectedServer.description || "Configure the MCP server connection"
27880
27942
  })]
27881
- }), formFields.length > 0 && /*#__PURE__*/jsxRuntime.jsxs(jsxRuntime.Fragment, {
27882
- children: [/*#__PURE__*/jsxRuntime.jsx("div", {
27883
- className: "border-t border-white/10 pt-4",
27884
- children: /*#__PURE__*/jsxRuntime.jsx("p", {
27885
- className: "text-xs font-semibold opacity-40 uppercase tracking-wider",
27886
- children: effectiveMcpConfig.transport === "streamable_http" ? "Server Configuration" : "Authentication"
27887
- })
27888
- }), formFields.map(function (field) {
27889
- return /*#__PURE__*/jsxRuntime.jsxs("div", {
27890
- className: "flex flex-col gap-2",
27891
- children: [/*#__PURE__*/jsxRuntime.jsx(DashReact.FormLabel, {
27892
- label: field.displayName,
27893
- required: field.required
27894
- }), field.instructions && /*#__PURE__*/jsxRuntime.jsx("p", {
27895
- className: "text-sm opacity-50",
27896
- children: field.instructions
27943
+ })]
27944
+ }), /*#__PURE__*/jsxRuntime.jsx("div", {
27945
+ className: "flex-1 min-h-0 flex flex-col",
27946
+ children: /*#__PURE__*/jsxRuntime.jsxs(DashReact.Stepper, {
27947
+ activeStep: wizardStep,
27948
+ onStepChange: handleWizardStepChange,
27949
+ showNavigation: false,
27950
+ className: "flex-1 min-h-0 flex flex-col px-6 pt-4",
27951
+ children: [/*#__PURE__*/jsxRuntime.jsx(DashReact.Stepper.Step, {
27952
+ label: "Configure",
27953
+ description: "Name & credentials",
27954
+ children: /*#__PURE__*/jsxRuntime.jsxs("div", {
27955
+ className: "flex-1 min-h-0 overflow-y-auto pb-4 space-y-5",
27956
+ children: [/*#__PURE__*/jsxRuntime.jsxs("div", {
27957
+ className: "bg-white/5 border border-white/10 rounded-lg p-4 space-y-3",
27958
+ children: [/*#__PURE__*/jsxRuntime.jsx("p", {
27959
+ className: "text-xs font-semibold opacity-40 uppercase tracking-wider",
27960
+ children: "MCP Server Connection"
27961
+ }), /*#__PURE__*/jsxRuntime.jsxs("div", {
27962
+ className: "space-y-2 text-sm",
27963
+ children: [/*#__PURE__*/jsxRuntime.jsxs("div", {
27964
+ className: "flex gap-2",
27965
+ children: [/*#__PURE__*/jsxRuntime.jsx("span", {
27966
+ className: "opacity-50 w-24 shrink-0",
27967
+ children: "Transport:"
27968
+ }), /*#__PURE__*/jsxRuntime.jsx(DashReact.Tag, {
27969
+ text: effectiveMcpConfig.transport === "streamable_http" ? "Streamable HTTP" : "stdio"
27970
+ })]
27971
+ }), effectiveMcpConfig.transport === "streamable_http" ? /*#__PURE__*/jsxRuntime.jsxs("div", {
27972
+ className: "flex gap-2",
27973
+ children: [/*#__PURE__*/jsxRuntime.jsx("span", {
27974
+ className: "opacity-50 w-24 shrink-0",
27975
+ children: "Endpoint:"
27976
+ }), /*#__PURE__*/jsxRuntime.jsx("span", {
27977
+ className: "text-xs opacity-70",
27978
+ children: "Remote hosted server (URL provided below)"
27979
+ })]
27980
+ }) : /*#__PURE__*/jsxRuntime.jsxs(jsxRuntime.Fragment, {
27981
+ children: [/*#__PURE__*/jsxRuntime.jsxs("div", {
27982
+ className: "flex gap-2",
27983
+ children: [/*#__PURE__*/jsxRuntime.jsx("span", {
27984
+ className: "opacity-50 w-24 shrink-0",
27985
+ children: "Command:"
27986
+ }), /*#__PURE__*/jsxRuntime.jsxs("code", {
27987
+ className: "text-xs bg-white/5 px-2 py-0.5 rounded",
27988
+ children: [effectiveMcpConfig.command, " ", (effectiveMcpConfig.args || []).join(" ")]
27989
+ })]
27990
+ }), effectiveMcpConfig.envMapping && Object.keys(effectiveMcpConfig.envMapping).length > 0 && /*#__PURE__*/jsxRuntime.jsxs("div", {
27991
+ className: "flex gap-2",
27992
+ children: [/*#__PURE__*/jsxRuntime.jsx("span", {
27993
+ className: "opacity-50 w-24 shrink-0",
27994
+ children: "Env Vars:"
27995
+ }), /*#__PURE__*/jsxRuntime.jsx("span", {
27996
+ className: "text-xs opacity-70",
27997
+ children: Object.keys(effectiveMcpConfig.envMapping).join(", ")
27998
+ })]
27999
+ })]
28000
+ })]
28001
+ })]
28002
+ }), /*#__PURE__*/jsxRuntime.jsx(AdvancedMcpConfig, {
28003
+ transport: effectiveMcpConfig.transport || "stdio",
28004
+ envMappingRows: envMappingRows,
28005
+ onEnvMappingRowsChange: setEnvMappingRows,
28006
+ headerRows: headerRows,
28007
+ onHeaderRowsChange: setHeaderRows
27897
28008
  }), /*#__PURE__*/jsxRuntime.jsxs("div", {
27898
- className: "flex gap-2",
28009
+ className: "flex flex-col gap-2",
28010
+ children: [/*#__PURE__*/jsxRuntime.jsx(DashReact.FormLabel, {
28011
+ label: "Provider Name",
28012
+ required: true
28013
+ }), /*#__PURE__*/jsxRuntime.jsx("p", {
28014
+ className: "text-sm opacity-50",
28015
+ children: "A name to identify this MCP server instance (e.g., \"Algolia Production\")"
28016
+ }), /*#__PURE__*/jsxRuntime.jsx(DashReact.InputText, {
28017
+ value: providerName,
28018
+ onChange: function onChange(value) {
28019
+ setProviderName(value);
28020
+ if (formErrors.providerName && value !== null && value !== void 0 && value.trim()) {
28021
+ setFormErrors(function (prev) {
28022
+ var next = _objectSpread$4({}, prev);
28023
+ delete next.providerName;
28024
+ return next;
28025
+ });
28026
+ }
28027
+ },
28028
+ placeholder: "Enter provider name"
28029
+ }), formErrors.providerName && /*#__PURE__*/jsxRuntime.jsx("p", {
28030
+ className: "text-sm text-red-400",
28031
+ children: formErrors.providerName
28032
+ })]
28033
+ }), formFields.length > 0 && /*#__PURE__*/jsxRuntime.jsxs(jsxRuntime.Fragment, {
27899
28034
  children: [/*#__PURE__*/jsxRuntime.jsx("div", {
27900
- className: "flex-1",
27901
- children: /*#__PURE__*/jsxRuntime.jsx(DashReact.InputText, {
27902
- type: field.secret ? "password" : "text",
27903
- value: credentialData[field.key] || "",
27904
- onChange: function onChange(value) {
27905
- return handleCredentialChange(field.key, value);
27906
- },
27907
- placeholder: field.type === "file" ? "Select a file..." : "Enter ".concat(field.displayName.toLowerCase())
28035
+ className: "border-t border-white/10 pt-4",
28036
+ children: /*#__PURE__*/jsxRuntime.jsx("p", {
28037
+ className: "text-xs font-semibold opacity-40 uppercase tracking-wider",
28038
+ children: effectiveMcpConfig.transport === "streamable_http" ? "Server Configuration" : "Authentication"
27908
28039
  })
27909
- }), field.type === "file" && /*#__PURE__*/jsxRuntime.jsx("button", {
27910
- onClick: /*#__PURE__*/_asyncToGenerator(/*#__PURE__*/_regeneratorRuntime.mark(function _callee() {
27911
- var filepath;
27912
- return _regeneratorRuntime.wrap(function (_context) {
27913
- while (1) switch (_context.prev = _context.next) {
27914
- case 0:
27915
- _context.next = 1;
27916
- return window.mainApi.dialog.chooseFile(true, ["json"]);
27917
- case 1:
27918
- filepath = _context.sent;
27919
- if (filepath) handleCredentialChange(field.key, filepath);
27920
- case 2:
27921
- case "end":
27922
- return _context.stop();
27923
- }
27924
- }, _callee);
27925
- })),
27926
- className: "px-3 py-1.5 text-sm rounded bg-white/10 hover:bg-white/20 transition-colors",
27927
- children: "Browse"
28040
+ }), formFields.map(function (field) {
28041
+ return /*#__PURE__*/jsxRuntime.jsxs("div", {
28042
+ className: "flex flex-col gap-2",
28043
+ children: [/*#__PURE__*/jsxRuntime.jsx(DashReact.FormLabel, {
28044
+ label: field.displayName,
28045
+ required: field.required
28046
+ }), field.instructions && /*#__PURE__*/jsxRuntime.jsx("p", {
28047
+ className: "text-sm opacity-50",
28048
+ children: field.instructions
28049
+ }), /*#__PURE__*/jsxRuntime.jsxs("div", {
28050
+ className: "flex gap-2",
28051
+ children: [/*#__PURE__*/jsxRuntime.jsx("div", {
28052
+ className: "flex-1",
28053
+ children: /*#__PURE__*/jsxRuntime.jsx(DashReact.InputText, {
28054
+ type: field.secret ? "password" : "text",
28055
+ value: credentialData[field.key] || "",
28056
+ onChange: function onChange(value) {
28057
+ return handleCredentialChange(field.key, value);
28058
+ },
28059
+ placeholder: field.type === "file" ? "Select a file..." : "Enter ".concat(field.displayName.toLowerCase())
28060
+ })
28061
+ }), field.type === "file" && /*#__PURE__*/jsxRuntime.jsx("button", {
28062
+ onClick: /*#__PURE__*/_asyncToGenerator(/*#__PURE__*/_regeneratorRuntime.mark(function _callee() {
28063
+ var filepath;
28064
+ return _regeneratorRuntime.wrap(function (_context) {
28065
+ while (1) switch (_context.prev = _context.next) {
28066
+ case 0:
28067
+ _context.next = 1;
28068
+ return window.mainApi.dialog.chooseFile(true, ["json"]);
28069
+ case 1:
28070
+ filepath = _context.sent;
28071
+ if (filepath) handleCredentialChange(field.key, filepath);
28072
+ case 2:
28073
+ case "end":
28074
+ return _context.stop();
28075
+ }
28076
+ }, _callee);
28077
+ })),
28078
+ className: "px-3 py-1.5 text-sm rounded bg-white/10 hover:bg-white/20 transition-colors",
28079
+ children: "Browse"
28080
+ })]
28081
+ }), formErrors[field.key] && /*#__PURE__*/jsxRuntime.jsx("p", {
28082
+ className: "text-sm text-red-400",
28083
+ children: formErrors[field.key]
28084
+ })]
28085
+ }, field.key);
27928
28086
  })]
27929
- }), formErrors[field.key] && /*#__PURE__*/jsxRuntime.jsx("p", {
27930
- className: "text-sm text-red-400",
27931
- children: formErrors[field.key]
28087
+ }), authResult && /*#__PURE__*/jsxRuntime.jsx("div", {
28088
+ className: "p-3 rounded-lg text-sm ".concat(authResult.success ? "bg-green-900/30 border border-green-700 text-green-300" : "bg-red-900/30 border border-red-700 text-red-300"),
28089
+ children: /*#__PURE__*/jsxRuntime.jsxs("div", {
28090
+ className: "flex items-center gap-2",
28091
+ children: [/*#__PURE__*/jsxRuntime.jsx(DashReact.FontAwesomeIcon, {
28092
+ icon: authResult.success ? "circle-check" : "circle-exclamation"
28093
+ }), /*#__PURE__*/jsxRuntime.jsx("span", {
28094
+ children: authResult.message
28095
+ })]
28096
+ })
27932
28097
  })]
27933
- }, field.key);
28098
+ })
28099
+ }), /*#__PURE__*/jsxRuntime.jsx(DashReact.Stepper.Step, {
28100
+ label: "Test",
28101
+ description: "Verify connection",
28102
+ children: /*#__PURE__*/jsxRuntime.jsxs("div", {
28103
+ className: "flex-1 min-h-0 overflow-y-auto pb-4 space-y-5",
28104
+ children: [/*#__PURE__*/jsxRuntime.jsxs("div", {
28105
+ className: "flex flex-col items-center justify-center py-8 space-y-4",
28106
+ children: [/*#__PURE__*/jsxRuntime.jsx("p", {
28107
+ className: "text-sm opacity-60 text-center",
28108
+ children: "Test the connection to verify your configuration is correct."
28109
+ }), /*#__PURE__*/jsxRuntime.jsx(DashReact.Button, {
28110
+ title: isTesting ? "Testing..." : "Test Connection",
28111
+ onClick: handleTestConnection,
28112
+ size: "md"
28113
+ })]
28114
+ }), testResult && /*#__PURE__*/jsxRuntime.jsx("div", {
28115
+ className: "p-3 rounded-lg text-sm ".concat(testResult.success ? "bg-green-900/30 border border-green-700 text-green-300" : "bg-red-900/30 border border-red-700 text-red-300"),
28116
+ children: /*#__PURE__*/jsxRuntime.jsxs("div", {
28117
+ className: "flex items-center gap-2",
28118
+ children: [/*#__PURE__*/jsxRuntime.jsx(DashReact.FontAwesomeIcon, {
28119
+ icon: testResult.success ? "circle-check" : "circle-exclamation"
28120
+ }), /*#__PURE__*/jsxRuntime.jsx("span", {
28121
+ children: testResult.message
28122
+ })]
28123
+ })
28124
+ })]
28125
+ })
28126
+ }), /*#__PURE__*/jsxRuntime.jsx(DashReact.Stepper.Step, {
28127
+ label: "Tools",
28128
+ description: "Select allowed tools",
28129
+ children: /*#__PURE__*/jsxRuntime.jsx("div", {
28130
+ className: "flex-1 min-h-0 overflow-y-auto pb-4 space-y-5",
28131
+ children: testResult !== null && testResult !== void 0 && testResult.success && ((_testResult$tools = testResult.tools) === null || _testResult$tools === void 0 ? void 0 : _testResult$tools.length) > 0 && selectedTools ? /*#__PURE__*/jsxRuntime.jsx(ToolSelector, {
28132
+ tools: testResult.tools,
28133
+ selectedTools: selectedTools,
28134
+ onSelectionChange: setSelectedTools
28135
+ }) : /*#__PURE__*/jsxRuntime.jsx("div", {
28136
+ className: "text-center py-8 opacity-50",
28137
+ children: "No tools available. Go back and test the connection first."
28138
+ })
28139
+ })
27934
28140
  })]
27935
- }), authResult && /*#__PURE__*/jsxRuntime.jsx("div", {
27936
- className: "p-3 rounded-lg text-sm ".concat(authResult.success ? "bg-green-900/30 border border-green-700 text-green-300" : "bg-red-900/30 border border-red-700 text-red-300"),
27937
- children: /*#__PURE__*/jsxRuntime.jsxs("div", {
27938
- className: "flex items-center gap-2",
27939
- children: [/*#__PURE__*/jsxRuntime.jsx(DashReact.FontAwesomeIcon, {
27940
- icon: authResult.success ? "circle-check" : "circle-exclamation"
27941
- }), /*#__PURE__*/jsxRuntime.jsx("span", {
27942
- children: authResult.message
27943
- })]
28141
+ })
28142
+ }), /*#__PURE__*/jsxRuntime.jsxs("div", {
28143
+ className: "flex-shrink-0 flex flex-row items-center px-6 py-4 border-t border-white/10",
28144
+ children: [/*#__PURE__*/jsxRuntime.jsxs("div", {
28145
+ className: "flex flex-row gap-2",
28146
+ children: [wizardStep === 0 && /*#__PURE__*/jsxRuntime.jsx(DashReact.Button, {
28147
+ title: "Cancel",
28148
+ onClick: onCancel,
28149
+ size: "sm"
28150
+ }), wizardStep > 0 && /*#__PURE__*/jsxRuntime.jsx(DashReact.Button, {
28151
+ title: "Back",
28152
+ onClick: function onClick() {
28153
+ return setWizardStep(wizardStep - 1);
28154
+ },
28155
+ size: "sm"
28156
+ })]
28157
+ }), /*#__PURE__*/jsxRuntime.jsx("div", {
28158
+ className: "flex-1 text-center",
28159
+ children: /*#__PURE__*/jsxRuntime.jsxs("span", {
28160
+ className: "text-xs opacity-40",
28161
+ children: ["Step ", wizardStep + 1, " of 3"]
27944
28162
  })
27945
- }), testResult && /*#__PURE__*/jsxRuntime.jsx("div", {
27946
- className: "p-3 rounded-lg text-sm ".concat(testResult.success ? "bg-green-900/30 border border-green-700 text-green-300" : "bg-red-900/30 border border-red-700 text-red-300"),
27947
- children: /*#__PURE__*/jsxRuntime.jsxs("div", {
27948
- className: "flex items-center gap-2",
27949
- children: [/*#__PURE__*/jsxRuntime.jsx(DashReact.FontAwesomeIcon, {
27950
- icon: testResult.success ? "circle-check" : "circle-exclamation"
27951
- }), /*#__PURE__*/jsxRuntime.jsx("span", {
27952
- children: testResult.message
28163
+ }), /*#__PURE__*/jsxRuntime.jsxs("div", {
28164
+ className: "flex flex-row gap-2",
28165
+ children: [wizardStep === 0 && /*#__PURE__*/jsxRuntime.jsxs(jsxRuntime.Fragment, {
28166
+ children: [(selectedServer === null || selectedServer === void 0 ? void 0 : selectedServer.authCommand) && /*#__PURE__*/jsxRuntime.jsx(DashReact.Button, {
28167
+ title: isAuthorizing ? "Authorizing..." : "Authorize",
28168
+ onClick: handleAuthorize,
28169
+ size: "sm"
28170
+ }), /*#__PURE__*/jsxRuntime.jsx(DashReact.Button, {
28171
+ title: "Next",
28172
+ onClick: function onClick() {
28173
+ return handleWizardStepChange(1);
28174
+ },
28175
+ disabled: (selectedServer === null || selectedServer === void 0 ? void 0 : selectedServer.authCommand) && !(authResult !== null && authResult !== void 0 && authResult.success),
28176
+ size: "sm"
27953
28177
  })]
27954
- })
27955
- }), (testResult === null || testResult === void 0 ? void 0 : testResult.success) && ((_testResult$tools = testResult.tools) === null || _testResult$tools === void 0 ? void 0 : _testResult$tools.length) > 0 && selectedTools && /*#__PURE__*/jsxRuntime.jsx(ToolSelector, {
27956
- tools: testResult.tools,
27957
- selectedTools: selectedTools,
27958
- onSelectionChange: setSelectedTools
27959
- })]
27960
- }), /*#__PURE__*/jsxRuntime.jsxs("div", {
27961
- className: "flex-shrink-0 flex flex-row justify-end gap-2 px-6 py-4 border-t border-white/10",
27962
- children: [/*#__PURE__*/jsxRuntime.jsx(DashReact.Button, {
27963
- title: "Cancel",
27964
- onClick: onCancel,
27965
- size: "sm"
27966
- }), (selectedServer === null || selectedServer === void 0 ? void 0 : selectedServer.authCommand) && /*#__PURE__*/jsxRuntime.jsx(DashReact.Button, {
27967
- title: isAuthorizing ? "Authorizing..." : "Authorize",
27968
- onClick: handleAuthorize,
27969
- size: "sm"
27970
- }), /*#__PURE__*/jsxRuntime.jsx(DashReact.Button, {
27971
- title: isTesting ? "Testing..." : "Test Connection",
27972
- onClick: handleTestConnection,
27973
- size: "sm"
27974
- }), /*#__PURE__*/jsxRuntime.jsx(DashReact.Button, {
27975
- title: "Save MCP Server",
27976
- onClick: handleSaveProvider,
27977
- size: "sm"
28178
+ }), wizardStep === 1 && /*#__PURE__*/jsxRuntime.jsxs(jsxRuntime.Fragment, {
28179
+ children: [/*#__PURE__*/jsxRuntime.jsx(DashReact.Button, {
28180
+ title: isTesting ? "Testing..." : "Test Connection",
28181
+ onClick: handleTestConnection,
28182
+ size: "sm"
28183
+ }), /*#__PURE__*/jsxRuntime.jsx(DashReact.Button, {
28184
+ title: "Next",
28185
+ onClick: function onClick() {
28186
+ return handleWizardStepChange(2);
28187
+ },
28188
+ disabled: !(testResult !== null && testResult !== void 0 && testResult.success),
28189
+ size: "sm"
28190
+ })]
28191
+ }), wizardStep === 2 && /*#__PURE__*/jsxRuntime.jsx(DashReact.Button, {
28192
+ title: "Save MCP Server",
28193
+ onClick: handleSaveProvider,
28194
+ size: "sm"
28195
+ })]
27978
28196
  })]
27979
28197
  })]
27980
28198
  });