@@ -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