"use client"; import { useState } from "react"; import { X, Upload, CheckCircle, AlertCircle, Loader2 } from "lucide-react"; interface MCPManualInstallModalProps { isOpen: boolean; onClose: () => void; onSuccess?: (mcpId: string) => void; } export function MCPManualInstallModal({ isOpen, onClose, onSuccess, }: MCPManualInstallModalProps) { const [configJson, setConfigJson] = useState(""); const [mcpId, setMcpId] = useState(""); const [isInstalling, setIsInstalling] = useState(false); const [error, setError] = useState(null); const [validationError, setValidationError] = useState(null); const [parsedConfig, setParsedConfig] = useState(null); // Validar JSON enquanto digita const handleConfigChange = (value: string) => { setConfigJson(value); setValidationError(null); setParsedConfig(null); if (!value.trim()) { return; } try { const parsed = JSON.parse(value); setParsedConfig(parsed); // Validar estrutura básica if (parsed.mcpServers) { const serverNames = Object.keys(parsed.mcpServers); if (serverNames.length === 0) { setValidationError("No MCP server found in configuration"); return; } const firstServer = parsed.mcpServers[serverNames[0]]; if (!firstServer.command) { setValidationError("Missing required field: command"); return; } // Auto-preencher ID se estiver vazio if (!mcpId) { setMcpId(serverNames[0]); } } else { // Formato direto if (!parsed.command) { setValidationError("Missing required field: command"); return; } } } catch (err: any) { setValidationError(`Invalid JSON: ${err.message}`); } }; const handleInstall = async () => { if (!configJson.trim()) { setError("Configuration is required"); return; } if (validationError) { setError("Please fix validation errors before installing"); return; } setIsInstalling(true); setError(null); try { const response = await fetch("/api/mcp/install-manual", { method: "POST", headers: { "Content-Type": "application/json" }, body: JSON.stringify({ config: parsedConfig, mcpId: mcpId || undefined, enableLogs: true, }), }); const data = await response.json(); if (data.success) { console.log(`✅ Manual installation started for ${data.mcpId}`); onSuccess?.(data.mcpId); onClose(); // Reset form setConfigJson(""); setMcpId(""); setParsedConfig(null); } else { setError(data.error || "Failed to start installation"); } } catch (err: any) { console.error("Error installing MCP:", err); setError(err.message || "Failed to start installation"); } finally { setIsInstalling(false); } }; const handlePasteExample = () => { const example = `{ "mcpServers": { "time-server": { "command": "npx", "args": ["@mcpcentral/mcp-time"] } } }`; setConfigJson(example); handleConfigChange(example); }; if (!isOpen) return null; return (
{/* Header */}

Install MCP Manually

{/* Content */}
{/* Description */}

How to use

Paste your MCP server configuration in Claude Desktop format (claude_desktop_config.json). You can install custom MCPs or MCPs not available in the marketplace.

{/* MCP ID (optional) */}
setMcpId(e.target.value)} placeholder="my-custom-mcp (auto-detected if empty)" className="w-full px-4 py-2 border border-gray-300 dark:border-gray-600 rounded-lg bg-white dark:bg-gray-700 text-gray-900 dark:text-white focus:ring-2 focus:ring-blue-500 focus:border-transparent" />
{/* Configuration JSON */}