import React, { useState, useEffect } from 'react' import { FiWifi, FiWifiOff, FiServer, FiTool, FiCheck, FiX, FiRefreshCw } from 'react-icons/fi' import { Card } from '../ui/Card' import { Button } from '../ui/Button' import Typography from '../ui/Typography' import { cn } from '../../lib/utils' interface MCPConnectionTesterProps { serverId: string serverName: string onTest: () => Promise result?: { success: boolean error?: string details?: { version?: string tools?: number capabilities?: string[] } } loading?: boolean } enum TestStage { Idle, Connecting, Authenticating, LoadingTools, Complete } interface TestProgress { stage: TestStage message: string progress: number } /** * Enhanced MCP Connection Tester with progress tracking */ export const MCPConnectionTester: React.FC = ({ serverId, serverName, onTest, result, loading = false }) => { const [testProgress, setTestProgress] = useState({ stage: TestStage.Idle, message: '', progress: 0 }) const [isRetrying, setIsRetrying] = useState(false) const [retryCount, setRetryCount] = useState(0) useEffect(() => { if (loading) { simulateTestProgress() } else { setTestProgress({ stage: TestStage.Idle, message: '', progress: 0 }) } }, [loading]) const simulateTestProgress = () => { const stages = [ { stage: TestStage.Connecting, message: 'Establishing connection...', progress: 25 }, { stage: TestStage.Authenticating, message: 'Authenticating...', progress: 50 }, { stage: TestStage.LoadingTools, message: 'Loading available tools...', progress: 75 }, { stage: TestStage.Complete, message: 'Connection test complete', progress: 100 } ] stages.forEach((stage, index) => { setTimeout(() => { if (loading) { setTestProgress(stage) } }, index * 1000) }) } const handleTest = async () => { setRetryCount(0) await onTest() } const handleRetry = async () => { setIsRetrying(true) setRetryCount(prev => prev + 1) const delay = Math.min(1000 * Math.pow(2, retryCount), 10000) setTimeout(async () => { await onTest() setIsRetrying(false) }, delay) } const getStageIcon = (stage: TestStage) => { switch (stage) { case TestStage.Connecting: return case TestStage.Authenticating: return case TestStage.LoadingTools: return case TestStage.Complete: if (result?.success) { return } return default: return } } const getProgressColor = () => { if (testProgress.stage === TestStage.Complete) { if (result?.success) { return 'bg-green-500' } return 'bg-red-500' } return 'bg-brand-blue' } return (
Connection Test Testing connection to {serverName}
{(loading || testProgress.stage !== TestStage.Idle) && (
{ if (testProgress.stage === TestStage.Complete && result?.success) { return "bg-green-100 dark:bg-green-900/20 text-green-600"; } if (testProgress.stage === TestStage.Complete && !result?.success) { return "bg-red-100 dark:bg-red-900/20 text-red-600"; } return "bg-brand-blue/10 text-brand-blue"; })() )}> {getStageIcon(testProgress.stage)}
{testProgress.message} {testProgress.stage === TestStage.Complete && result && ( {result.success ? 'Connection successful' : result.error || 'Connection failed'} )}
{[ { stage: TestStage.Connecting, label: 'Connect' }, { stage: TestStage.Authenticating, label: 'Authenticate' }, { stage: TestStage.LoadingTools, label: 'Load Tools' }, { stage: TestStage.Complete, label: 'Complete' } ].map((step) => (
= step.stage ? "text-gray-900 dark:text-white font-medium" : "text-gray-400 dark:text-gray-500" )} > {step.label}
))}
)} {result && testProgress.stage === TestStage.Complete && (
{result.success && result.details ? (
Connection Successful
{result.details.version && (
Version: {result.details.version}
)} {result.details.tools !== undefined && (
Available Tools: {result.details.tools}
)} {result.details.capabilities && result.details.capabilities.length > 0 && (
Capabilities:
{result.details.capabilities.map((cap, index) => ( {cap} ))}
)}
) : (
Connection Failed {result.error || 'Unable to connect to the server'} {retryCount > 0 && ( Retry attempt {retryCount} failed. Next retry in {Math.min(1000 * Math.pow(2, retryCount), 10000) / 1000}s )}
)}
)}
{!loading && testProgress.stage === TestStage.Idle && ( )} {result && !result.success && !loading && !isRetrying && ( )} {isRetrying && ( )}
) }