// MCP Servers — connection list + detail with health, capabilities, and logs. const MCP_SERVERS = [ { id: 'github', name: 'GitHub', transport: 'http', url: 'https://mcp.github.com/v1', status: 'connected', tools: 18, prompts: 4, resources: 12, latency: 84, version: '1.4.2', auth: 'oauth', scope: 'org/wizemann' }, { id: 'linear', name: 'Linear', transport: 'http', url: 'https://mcp.linear.app/sse', status: 'connected', tools: 9, prompts: 0, resources: 6, latency: 142, version: '0.9.1', auth: 'oauth', scope: 'wizemann' }, { id: 'slack', name: 'Slack', transport: 'http', url: 'https://mcp.slack.com/v1', status: 'auth-required', tools: 0, prompts: 0, resources: 0, latency: null, version: '—', auth: 'oauth', scope: '—' }, { id: 'postgres-prod', name: 'Postgres (prod, ro)', transport: 'stdio', url: 'mcp-postgres --readonly', status: 'connected', tools: 4, prompts: 0, resources: 28, latency: 12, version: '2.1.0', auth: 'env', scope: 'prod-replica' }, { id: 'figma', name: 'Figma', transport: 'http', url: 'https://mcp.figma.com/v1', status: 'connected', tools: 6, prompts: 2, resources: 0, latency: 210, version: '0.4.0', auth: 'oauth', scope: 'wizemann-design' }, { id: 'notion', name: 'Notion', transport: 'http', url: 'https://mcp.notion.so/v1', status: 'error', tools: 0, prompts: 0, resources: 0, latency: null, version: '—', auth: 'oauth', scope: '—', error: 'TLS handshake failed (timeout 5s)' }, { id: 'sentry', name: 'Sentry', transport: 'http', url: 'https://mcp.sentry.io/v1', status: 'disabled', tools: 0, prompts: 0, resources: 0, latency: null, version: '—', auth: 'token', scope: 'wizemann' }, ]; const STATUS_TONES = { 'connected': { tone: 'green', label: 'connected' }, 'auth-required': { tone: 'amber', label: 'auth required' }, 'error': { tone: 'red', label: 'error' }, 'disabled': { tone: 'gray', label: 'disabled' }, }; function MCPServers() { const [active, setActive] = React.useState('github'); const server = MCP_SERVERS.find(s => s.id === active); React.useEffect(() => { requestAnimationFrame(() => window.lucide && window.lucide.createIcons()); }); return (
Reconnect allAdd server} />
{MCP_SERVERS.map(s => setActive(s.id)} />)}
Browse marketplace
); } function MCPRow({ s, active, onClick }) { const status = STATUS_TONES[s.status]; const [hover, setHover] = React.useState(false); return (
setHover(true)} onMouseLeave={() => setHover(false)} style={{ padding: '11px 12px', borderRadius: 7, cursor: 'pointer', marginBottom: 2, background: active ? 'var(--accent-tint)' : (hover ? 'var(--bg-quaternary)' : 'transparent'), }}>
{s.name}
{s.transport} · {s.tools} tools · {s.prompts} prompts
); } function ServerGlyph({ id, size = 22 }) { const palette = { github: '#1F1B16', linear: '#5E6AD2', slack: '#611F69', 'postgres-prod': '#336791', figma: '#F24E1E', notion: '#191919', sentry: '#362D59', }; const letter = id[0].toUpperCase(); return (
{letter}
); } function MCPDetail({ server }) { const status = STATUS_TONES[server.status]; return ( <>
{server.name}
{status.label} v{server.version}
{server.url}
Reconnect
{server.error && (
Connection failed
{server.error}
)}
{server.transport}} /> Manage} /> Edit} last /> Disconnect} last /> ); } function CapRow({ icon, name, kind, desc, last }) { const tones = { tool: 'blue', prompt: 'purple', resource: 'green' }; return (
{name}
{desc}
{kind}
); } function LogLine({ when, level, msg, last }) { const tones = { info: 'var(--fg-faint)', warn: 'var(--amber-500)', error: 'var(--red-500)' }; return (
{when} {level} {msg}
); } window.MCPServers = MCPServers;