import * as React from "react"; import { Braces, Plus, Trash2 } from "lucide-react"; import { useTranslation } from "react-i18next"; import { connectMcpServer } from "@/api"; import { Button } from "@/components/ui/button"; import { Dialog } from "@/components/ui/dialog"; import { Input } from "@/components/ui/input"; import { toast } from "@/components/ui/toaster"; import type { JSONObject } from "@/types"; interface ConnectMcpServerDialogProps { open: boolean; onOpenChange: (open: boolean) => void; onCreated: () => void; } export function ConnectMcpServerDialog({ open, onOpenChange, onCreated }: ConnectMcpServerDialogProps) { const { t } = useTranslation(); const [serverName, setServerName] = React.useState(""); const [url, setUrl] = React.useState(""); const [rawConfig, setRawConfig] = React.useState(""); const [headers, setHeaders] = React.useState>([]); const [timeout, setTimeout] = React.useState("30"); const [submitting, setSubmitting] = React.useState(false); function reset() { setServerName(""); setUrl(""); setRawConfig(""); setHeaders([]); setTimeout("30"); } function addHeader() { setHeaders([...headers, { key: "", value: "" }]); } function removeHeader(index: number) { setHeaders(headers.filter((_, i) => i !== index)); } function updateHeader(index: number, field: "key" | "value", value: string) { const updated = [...headers]; const current = updated[index]; if (current) { updated[index] = { ...current, [field]: value }; setHeaders(updated); } } async function submit(event: React.FormEvent) { event.preventDefault(); const pastedConfig = parseConfig(rawConfig); if (rawConfig.trim() && !pastedConfig) { toast.error(t("tools.invalidMcpConfig")); return; } if (!pastedConfig && (!serverName.trim() || !url.trim())) return; const headersObj: Record = {}; for (const h of headers) { if (h.key.trim() && h.value.trim()) { headersObj[h.key.trim()] = h.value.trim(); } } setSubmitting(true); try { await connectMcpServer({ name: serverName.trim() || undefined, config: pastedConfig ?? { transport: "sse", server_name: serverName.trim(), url: url.trim(), headers: headersObj, timeout_seconds: Number(timeout) || null, }, }); toast.success(t("tools.mcpConnected")); onOpenChange(false); reset(); onCreated(); } catch (err) { toast.error(err instanceof Error ? err.message : t("tools.failedToConnectMcp")); } finally { setSubmitting(false); } } return (