import '../shared/base.css'; import { App } from '@modelcontextprotocol/ext-apps'; interface CompareResponse { provider: string; nickname: string; model: string; content: string; latency: number; tokens: { prompt: number; completion: number; total: number } | null; error?: string; } const app = new App({ name: 'CompareDucks', version: '1.0.0' }, {}); app.ontoolresult = (params) => { const container = document.getElementById('app')!; if (params.isError) { container.innerHTML = `
Tool execution failed
`; return; } // Parse JSON from second content item const content = params.content; if (!content || !Array.isArray(content) || content.length < 2) { container.innerHTML = `
No structured data received
`; return; } try { const data: CompareResponse[] = JSON.parse((content[1] as { type: string; text: string }).text); render(data); } catch { container.innerHTML = `
Failed to parse response data
`; } }; function render(responses: CompareResponse[]) { const container = document.getElementById('app')!; const successCount = responses.filter((r) => !r.error).length; let html = `
${successCount}/${responses.length} ducks responded successfully
`; html += `
`; for (const r of responses) { const isError = !!r.error; const latencyClass = r.latency < 2000 ? 'fast' : r.latency < 5000 ? 'medium' : 'slow'; html += `
`; html += `
`; html += `${esc(r.nickname)}`; html += `${esc(r.provider)}`; html += `
`; if (!isError) { html += `
`; html += `${esc(r.model)}`; if (r.tokens) { html += `${r.tokens.total} tokens`; } html += `
`; html += `
`; html += `
${r.latency}ms
`; html += `
${esc(r.content)}
`; } else { html += `
${esc(r.content)}
`; } html += `
`; } html += `
`; container.innerHTML = html; } function esc(s: string): string { const d = document.createElement('div'); d.textContent = s; return d.innerHTML; } app.connect().catch(console.error);