import figures from 'figures' import React, { useEffect, useState } from 'react' import type { CommandResultDisplay } from '../../commands.js' import { Box, color, Text, useTheme } from '../../ink.js' import { useMcpReconnect } from '../../services/mcp/MCPConnectionManager.js' import { useAppStateStore } from '../../state/AppState.js' import { Spinner } from '../Spinner.js' type Props = { serverName: string onComplete: ( result?: string, options?: { display?: CommandResultDisplay }, ) => void } export function MCPReconnect({ serverName, onComplete, }: Props): React.ReactNode { const [theme] = useTheme() const store = useAppStateStore() const reconnectMcpServer = useMcpReconnect() const [isReconnecting, setIsReconnecting] = useState(true) const [error, setError] = useState(null) useEffect(() => { async function attemptReconnect() { try { // Check if server exists. Read via store.getState() instead of a // reactive selector so this effect does not re-fire when // reconnectMcpServer updates mcp.clients via onConnectionAttempt. const server = store .getState() .mcp.clients.find(c => c.name === serverName) if (!server) { setError(`MCP server "${serverName}" not found`) setIsReconnecting(false) onComplete(`MCP server "${serverName}" not found`) return } // Attempt reconnection const result = await reconnectMcpServer(serverName) switch (result.client.type) { case 'connected': setIsReconnecting(false) onComplete(`Successfully reconnected to ${serverName}`) break case 'needs-auth': setError(`${serverName} requires authentication`) setIsReconnecting(false) onComplete( `${serverName} requires authentication. Use /mcp to authenticate.`, ) break case 'pending': case 'failed': case 'disabled': setError(`Failed to reconnect to ${serverName}`) setIsReconnecting(false) onComplete(`Failed to reconnect to ${serverName}`) break } } catch (err) { // Only catch actual errors (like server not found) const errorMessage = err instanceof Error ? err.message : String(err) setError(errorMessage) setIsReconnecting(false) onComplete(`Error: ${errorMessage}`) } } void attemptReconnect() }, [serverName, reconnectMcpServer, store, onComplete]) if (isReconnecting) { return ( Reconnecting to {serverName} Establishing connection to MCP server ) } if (error) { return ( {color('error', theme)(figures.cross)} Failed to reconnect to {serverName} Error: {error} ) } return null }