import React, { useState } from "react"; import { discoverOAuthEndpoints, startOAuthFlow } from "../services/oauth"; import { Plus, Server, Wifi, WifiOff, Trash2, TestTube } from "lucide-react"; import { useMCP } from "../hooks/useMCP"; import type { MCPServerConfig } from "../types/mcp"; import { STORAGE_KEYS, DEFAULTS } from "../config/constants"; interface MCPServerManagerProps { isOpen: boolean; onClose: () => void; } export const MCPServerManager: React.FC = ({ isOpen, onClose, }) => { const { mcpState, addServer, removeServer, connectToServer, disconnectFromServer, testConnection, } = useMCP(); const [showAddForm, setShowAddForm] = useState(false); const [testingConnection, setTestingConnection] = useState( null ); const [notification, setNotification] = useState<{ message: string; type: 'success' | 'error'; } | null>(null); const [newServer, setNewServer] = useState>({ name: "", url: "", enabled: true, transport: "streamable-http", auth: { type: "bearer", }, }); if (!isOpen) return null; const handleAddServer = async () => { if (!newServer.name || !newServer.url) return; const serverConfig: MCPServerConfig = { ...newServer, id: `server_${Date.now()}`, }; // Persist name and transport for OAuth flow localStorage.setItem(STORAGE_KEYS.MCP_SERVER_NAME, newServer.name); localStorage.setItem(STORAGE_KEYS.MCP_SERVER_TRANSPORT, newServer.transport); try { await addServer(serverConfig); setNewServer({ name: "", url: "", enabled: true, transport: "streamable-http", auth: { type: "bearer", }, }); setShowAddForm(false); } catch (error) { setNotification({ message: `Failed to add server: ${error instanceof Error ? error.message : 'Unknown error'}`, type: 'error' }); setTimeout(() => setNotification(null), DEFAULTS.OAUTH_ERROR_TIMEOUT); } }; const handleTestConnection = async (config: MCPServerConfig) => { setTestingConnection(config.id); try { const success = await testConnection(config); if (success) { setNotification({ message: "Connection test successful!", type: 'success' }); } else { setNotification({ message: "Connection test failed. Please check your configuration.", type: 'error' }); } } catch (error) { setNotification({ message: `Connection test failed: ${error}`, type: 'error' }); } finally { setTestingConnection(null); // Auto-hide notification after 3 seconds setTimeout(() => setNotification(null), DEFAULTS.NOTIFICATION_TIMEOUT); } }; const handleToggleConnection = async ( serverId: string, isConnected: boolean ) => { try { if (isConnected) { await disconnectFromServer(serverId); } else { await connectToServer(serverId); } } catch (error) { setNotification({ message: `Failed to toggle connection: ${error instanceof Error ? error.message : 'Unknown error'}`, type: 'error' }); setTimeout(() => setNotification(null), DEFAULTS.OAUTH_ERROR_TIMEOUT); } }; return (

MCP Server Manager

{/* Add Server Button */}
{/* Add Server Form */} {showAddForm && (

Add New MCP Server

setNewServer({ ...newServer, name: e.target.value }) } className="w-full bg-gray-600 text-white rounded px-3 py-2" placeholder="My MCP Server" />
setNewServer({ ...newServer, url: e.target.value }) } className="w-full bg-gray-600 text-white rounded px-3 py-2" placeholder="http://localhost:3000/mcp" />
{/* Auth-specific fields */} {newServer.auth?.type === "bearer" && (
setNewServer({ ...newServer, auth: { ...newServer.auth!, token: e.target.value }, }) } className="w-full bg-gray-600 text-white rounded px-3 py-2" placeholder="your-bearer-token" />
)} {newServer.auth?.type === "basic" && ( <>
setNewServer({ ...newServer, auth: { ...newServer.auth!, username: e.target.value, }, }) } className="w-full bg-gray-600 text-white rounded px-3 py-2" placeholder="username" />
setNewServer({ ...newServer, auth: { ...newServer.auth!, password: e.target.value, }, }) } className="w-full bg-gray-600 text-white rounded px-3 py-2" placeholder="password" />
)} {newServer.auth?.type === "oauth" && (

You will be redirected to authorize this app with the MCP server.

)}
setNewServer({ ...newServer, enabled: e.target.checked }) } className="rounded" />
)} {/* Server List */}

Configured Servers

{Object.values(mcpState.servers).length === 0 ? (
No MCP servers configured. Add one to get started!
) : ( Object.values(mcpState.servers).map((connection) => (

{connection.config.name}

{connection.config.url}

Transport: {connection.config.transport} {connection.config.auth && ` • Auth: ${connection.config.auth.type}`} {connection.isConnected && ` • ${connection.tools.length} tools available`}

{/* Test Connection */} {/* Connect/Disconnect */} {/* Remove Server */}
{connection.lastError && (
Error: {connection.lastError}
)} {connection.isConnected && connection.tools.length > 0 && (
Available Tools ({connection.tools.length})
{connection.tools.map((tool) => (
• {tool.name} -{" "} {tool.description || "No description"}
))}
)}
)) )}
{mcpState.error && (
Error: {mcpState.error}
)} {notification && (
{notification.message}
)}
); };