"use client"; import { Check, Copy } from "lucide-react"; import { useState } from "react"; import { Button } from "@/components/ui/button"; import { Tabs, TabsContent, TabsList, TabsTrigger } from "@/components/ui/tabs"; import { API_KEY_PLACEHOLDER, DEFAULT_SERVER_DIR, MCP_CLIENTS, type McpSnippetOptions, type McpTransport, REMOTE_URL, } from "@/lib/mcp/clients"; function CopyButton({ text }: { text: string }) { const [copied, setCopied] = useState(false); const handleCopy = async () => { try { await navigator.clipboard.writeText(text); setCopied(true); setTimeout(() => setCopied(false), 2000); } catch { // Clipboard unavailable (permissions/insecure context); nothing to recover. } }; return ( {copied ? : } {copied ? "Copied" : "Copy"} ); } const TRANSPORTS: { id: McpTransport; label: string; hint: string }[] = [ { id: "remote", label: "Hosted", hint: "mcp.surfsense.com — nothing to install" }, { id: "stdio", label: "Self-host", hint: "run the server against your own backend" }, ]; /** * Per-agent MCP setup instructions as tabs: pick a client, then Hosted or * Self-host, and copy its exact config. Used on the /mcp-server marketing page * and in the API playground; `options` fills in real values where the caller * has them. */ export function AgentSetupTabs({ options }: { options?: Partial }) { const [transport, setTransport] = useState("remote"); const resolved: McpSnippetOptions = { remoteUrl: options?.remoteUrl || REMOTE_URL, apiKey: options?.apiKey || API_KEY_PLACEHOLDER, baseUrl: options?.baseUrl || "https://api.surfsense.com", serverDir: options?.serverDir || DEFAULT_SERVER_DIR, }; const active = TRANSPORTS.find((t) => t.id === transport) ?? TRANSPORTS[0]; return ( {TRANSPORTS.map((t) => ( setTransport(t.id)} aria-pressed={t.id === transport} > {t.label} ))} {active.hint} {MCP_CLIENTS.map((client) => ( {client.label} ))} {MCP_CLIENTS.map((client) => { const snippet = client[transport]; const config = snippet.build(resolved); return ( {snippet.steps.map((step) => ( {step} ))} {snippet.configFile} {config} ); })} ); }
{snippet.configFile}
{config}