Skip to content

Commit 64ea469

Browse files
committed
fix: load tabs list independently of /clients
A /clients failure (404 on older servers) was thrown inside the same try block as the /tabs fetch, so the tabs list never loaded. The two sections now load independently: /tabs drives the offline banner and poll backoff, and a missing /clients endpoint just marks that section as unavailable with an update hint.
1 parent a4b2a3d commit 64ea469

1 file changed

Lines changed: 33 additions & 19 deletions

File tree

website/clients.html

Lines changed: 33 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -375,28 +375,14 @@ <h2>API Console</h2>
375375

376376
async function loadHome() {
377377
clearTimeout(refreshTimer);
378+
379+
// The two sections load independently: /tabs exists on every server
380+
// version and drives the offline banner; /clients may 404 on older
381+
// servers and must not take the tabs list down with it.
378382
try {
379-
const clients = await api('GET', '/clients') || [];
383+
const tabs = await api('GET', '/tabs') || [];
380384
byId('offline-banner').style.display = 'none';
381385
refreshDelay = REFRESH_INTERVAL;
382-
const clientsKey = JSON.stringify(clients.map(c =>
383-
[c.id, c.type, c.clientInfo?.name, c.clientInfo?.version, c.initialized]));
384-
if (clientsKey !== renderedClientsKey) {
385-
renderedClientsKey = clientsKey;
386-
document.querySelector('#clients-table tbody').replaceChildren(...clients.map(c =>
387-
el('tr', {}, [
388-
el('td', { className: 'mono', textContent: c.id }),
389-
el('td', { textContent: c.type || '' }),
390-
el('td', { textContent: c.clientInfo?.name || '—' }),
391-
el('td', { textContent: c.clientInfo?.version || '—' }),
392-
el('td', { textContent: c.initialized ? 'yes' : 'no' })
393-
])
394-
));
395-
show(byId('clients-table'), clients.length > 0);
396-
show(byId('clients-empty'), clients.length === 0);
397-
}
398-
399-
const tabs = await api('GET', '/tabs') || [];
400386
const tabsKey = JSON.stringify(tabs.map(tab =>
401387
[tab.tabId, tab.title, tab.url, tab.browser, tab.connectedAt]));
402388
if (tabsKey !== renderedTabsKey) {
@@ -418,6 +404,34 @@ <h2>API Console</h2>
418404
// Back off while the server is unreachable
419405
refreshDelay = Math.min(refreshDelay * 2, REFRESH_MAX);
420406
}
407+
408+
try {
409+
const clients = await api('GET', '/clients') || [];
410+
const clientsKey = JSON.stringify(clients.map(c =>
411+
[c.id, c.type, c.clientInfo?.name, c.clientInfo?.version, c.initialized]));
412+
if (clientsKey !== renderedClientsKey) {
413+
renderedClientsKey = clientsKey;
414+
document.querySelector('#clients-table tbody').replaceChildren(...clients.map(c =>
415+
el('tr', {}, [
416+
el('td', { className: 'mono', textContent: c.id }),
417+
el('td', { textContent: c.type || '' }),
418+
el('td', { textContent: c.clientInfo?.name || '—' }),
419+
el('td', { textContent: c.clientInfo?.version || '—' }),
420+
el('td', { textContent: c.initialized ? 'yes' : 'no' })
421+
])
422+
));
423+
byId('clients-empty').textContent = 'No MCP clients connected.';
424+
show(byId('clients-table'), clients.length > 0);
425+
show(byId('clients-empty'), clients.length === 0);
426+
}
427+
} catch {
428+
// Older servers don't have /clients
429+
renderedClientsKey = null;
430+
show(byId('clients-table'), false);
431+
byId('clients-empty').textContent = 'Not available on this server version - update kapture-mcp to see connected MCP clients.';
432+
show(byId('clients-empty'), true);
433+
}
434+
421435
scheduleRefresh();
422436
}
423437

0 commit comments

Comments
 (0)