diff --git a/src/renderer/src/components/settings/McpConfigFileRow.tsx b/src/renderer/src/components/settings/McpConfigFileRow.tsx new file mode 100644 index 000000000..7f640800e --- /dev/null +++ b/src/renderer/src/components/settings/McpConfigFileRow.tsx @@ -0,0 +1,117 @@ +import { AlertCircle, CheckCircle2 } from 'lucide-react' +import type { McpConfigInspection } from '../../../../shared/mcp-config' +import { Button } from '../ui/button' + +export type LoadedMcpConfigInspection = McpConfigInspection & { + absolutePath: string + readError?: string +} + +type McpConfigFileRowProps = { + config: LoadedMcpConfigInspection + onOpen: (config: LoadedMcpConfigInspection) => void +} + +function statusLabel(config: LoadedMcpConfigInspection): string { + if (config.readError) { + return 'Unreadable' + } + if (config.status === 'missing') { + return 'Not found' + } + if (config.status === 'invalid') { + return 'Invalid JSON' + } + if (config.servers.length === 0) { + return 'No servers' + } + return `${config.servers.length} server${config.servers.length === 1 ? '' : 's'}` +} + +function statusClassName(config: LoadedMcpConfigInspection): string { + if (config.readError || config.status === 'invalid') { + return 'border-destructive/30 bg-destructive/10 text-destructive' + } + if (config.status === 'valid' && config.servers.length > 0) { + return 'border-border/60 bg-background text-foreground' + } + return 'border-border/60 bg-muted/60 text-muted-foreground' +} + +function serverDetailLabel(server: LoadedMcpConfigInspection['servers'][number]): string { + if (server.transport === 'http') { + return server.url ?? 'HTTP server' + } + if (server.transport === 'stdio') { + return server.command ?? 'stdio server' + } + return server.issue ?? 'Invalid server' +} + +export function McpConfigFileRow({ config, onOpen }: McpConfigFileRowProps): React.JSX.Element { + return ( +
{config.candidate.label}
++ {config.candidate.relativePath} +
+{config.readError ?? config.error}
+ ) : null} + + {config.servers.length > 0 ? ( ++ {serverDetailLabel(server)} +
+ {server.env && Object.keys(server.env).length > 0 ? ( ++ env:{' '} + {Object.entries(server.env) + .map(([key, value]) => `${key}=${value}`) + .join(', ')} +
+ ) : null} +{config.candidate.label}
-- {config.candidate.relativePath} -
-- {config.readError ?? config.error} -
- ) : null} - - {config.servers.length > 0 ? ( -- {serverDetailLabel(server)} -
- {server.env && Object.keys(server.env).length > 0 ? ( -- env:{' '} - {Object.entries(server.env) - .map(([key, value]) => `${key}=${value}`) - .join(', ')} -
- ) : null} -Checked