import React, { useState, useEffect } from 'react'; import { motion, AnimatePresence } from 'framer-motion'; import { Loader2, CheckCircle2, XCircle, ChevronDown, ChevronUp, Wrench, Sparkles, Zap } from 'lucide-react'; interface MCPToolExecutionProps { toolName: string; toolIcon?: string; action: string; status: 'pending' | 'running' | 'success' | 'error' | 'permission_required'; progress?: number; details?: string[]; result?: string; error?: string; onAllow?: () => void; onDeny?: () => void; duration?: number; } /** * Claude-style MCP Tool Execution Component * Shows animated tool execution with progress, details, and permission requests */ const MCPToolExecution: React.FC = ({ toolName, toolIcon = '🔧', action, status, progress = 0, details = [], result, error, onAllow, onDeny, duration }) => { const [expanded, setExpanded] = useState(false); const [currentDetailIndex, setCurrentDetailIndex] = useState(0); // Animate through details when running useEffect(() => { if (status === 'running' && details.length > 1) { const interval = setInterval(() => { setCurrentDetailIndex(prev => (prev + 1) % details.length); }, 1500); return () => clearInterval(interval); } }, [status, details.length]); const getStatusColor = () => { switch (status) { case 'running': return 'border-green-500 bg-green-500/10'; case 'success': return 'border-green-500 bg-green-500/10'; case 'error': return 'border-red-500 bg-red-500/10'; case 'permission_required': return 'border-amber-500 bg-amber-500/10'; default: return 'border-gray-600 bg-gray-800/50'; } }; const getStatusIcon = () => { switch (status) { case 'running': return ; case 'success': return ; case 'error': return ; case 'permission_required': return ; default: return
; } }; return ( {/* Header */}
{/* Tool Icon with animation */} {toolIcon} {/* Main Content */}
{toolName} {getStatusIcon()}
{status === 'running' && details.length > 0 ? details[currentDetailIndex] : action}
{/* Duration/Progress */} {status === 'success' && duration && (
{(duration / 1000).toFixed(1)}s
)} {/* Expand Button */} {(details.length > 0 || result) && ( )}
{/* Progress Bar */} {status === 'running' && ( 0 ? `${progress}%` : '100%' }} transition={progress > 0 ? { duration: 0.3 } : { duration: 1.5, repeat: Infinity, ease: 'easeInOut' }} style={progress === 0 ? { animation: 'shimmer 1.5s infinite', background: 'linear-gradient(90deg, transparent, rgba(45, 212, 191, 0.5), transparent)', backgroundSize: '200% 100%' } : {}} /> )} {/* Permission Request */} {status === 'permission_required' && ( )} {/* Expanded Details */} {expanded && (
{/* Details List */} {details.length > 0 && (
{details.map((detail, idx) => (
{detail}
))}
)} {/* Result */} {result && (
{result}
)} {/* Error */} {error && (
{error}
)}
)} ); }; /** * MCP Tool Chain Component * Shows multiple tools working together in sequence */ interface MCPToolChainProps { tools: Array<{ name: string; icon: string; status: 'pending' | 'running' | 'success' | 'error'; action: string; }>; title?: string; } export const MCPToolChain: React.FC = ({ tools, title }) => { return (
{title && (
{title}
)}
{tools.map((tool, idx) => ( {tool.icon} {tool.name} {tool.status === 'running' && ( )} {tool.status === 'success' && ( )} {/* Arrow between tools */} {idx < tools.length - 1 && ( → )} ))}
); }; /** * MCP Execution Summary * Shows after all tools complete */ interface MCPSummaryProps { toolsUsed: number; totalDuration: number; results: string[]; } export const MCPExecutionSummary: React.FC = ({ toolsUsed, totalDuration, results }) => { return (

Tools Completed

{toolsUsed} tools • {(totalDuration / 1000).toFixed(1)}s total

{results.length > 0 && (
{results.map((r, idx) => (

✓ {r}

))}
)}
); }; export default MCPToolExecution;