import * as Ariakit from '@ariakit/react'; import { Check } from 'lucide-react'; import { MCPIcon } from '@librechat/client'; import type { MCPServerDefinition } from '~/hooks/MCP/useMCPServerManager'; import type { MCPServerStatusIconProps } from './MCPServerStatusIcon'; import MCPServerStatusIcon from './MCPServerStatusIcon'; import { getStatusColor, getStatusTextKey, shouldShowActionButton, type ConnectionStatusMap, } from './mcpServerUtils'; import { useLocalize } from '~/hooks'; import { cn } from '~/utils'; interface MCPServerMenuItemProps { server: MCPServerDefinition; isSelected: boolean; connectionStatus?: ConnectionStatusMap; isInitializing?: (serverName: string) => boolean; statusIconProps?: MCPServerStatusIconProps | null; onToggle: (serverName: string) => void; } export default function MCPServerMenuItem({ server, isSelected, connectionStatus, isInitializing, statusIconProps, onToggle, }: MCPServerMenuItemProps) { const localize = useLocalize(); const displayName = server.config?.title || server.serverName; const statusColor = getStatusColor(server.serverName, connectionStatus, isInitializing); const statusTextKey = getStatusTextKey(server.serverName, connectionStatus, isInitializing); const statusText = localize(statusTextKey as Parameters[0]); const showActionButton = shouldShowActionButton(statusIconProps); // Include status in aria-label so screen readers announce it const accessibleLabel = `${displayName}, ${statusText}`; return ( onToggle(server.serverName)} aria-label={accessibleLabel} className={cn( 'group flex w-full cursor-pointer items-center gap-3 rounded-lg px-2.5 py-2', 'outline-none transition-all duration-150', 'hover:bg-surface-hover data-[active-item]:bg-surface-hover', isSelected && 'bg-surface-active-alt', )} > {/* Server Icon with Status Dot */}
{server.config?.iconPath ? ( {displayName} ) : (
)} {/* Status dot - decorative, status is announced via aria-label on MenuItem */} {/* Server Info */}
{displayName}
{server.config?.description && (

{server.config.description}

)}
{/* Action Button - only show when actionable */} {showActionButton && statusIconProps && (
e.stopPropagation()}>
)} {/* Selection Indicator - purely visual, state conveyed by aria-checked on MenuItem */} ); }