@@ -19,7 +19,7 @@ import { useMemo, useState } from 'react';
1919import { makeStyles } from '@material-ui/core' ;
2020import ModeEditOutlineOutlinedIcon from '@mui/icons-material/ModeEditOutlineOutlined' ;
2121import Typography from '@mui/material/Typography' ;
22- import { Button , Switch , Title } from '@patternfly/react-core' ;
22+ import { Button , Switch , Title , Tooltip } from '@patternfly/react-core' ;
2323import {
2424 CheckCircleIcon ,
2525 ExclamationCircleIcon ,
@@ -31,14 +31,15 @@ import {
3131} from '@patternfly/react-icons' ;
3232import { Table , Tbody , Td , Th , Thead , Tr } from '@patternfly/react-table' ;
3333
34- type ServerStatus = 'tokenRequired' | 'disabled' | 'ok' | 'failed' ;
34+ type ServerStatus = 'tokenRequired' | 'disabled' | 'ok' | 'failed' | 'unknown' ;
3535
3636type McpServer = {
3737 id : string ;
3838 name : string ;
3939 enabled : boolean ;
4040 status : ServerStatus ;
4141 detail : string ;
42+ errorMessage ?: string ;
4243} ;
4344
4445type McpServersSettingsProps = {
@@ -80,7 +81,7 @@ const useStyles = makeStyles(theme => ({
8081 paddingLeft : 0 ,
8182 paddingTop : 0 ,
8283 paddingBottom : 0 ,
83- marginLeft : 0 ,
84+ marginLeft : '-0.85rem' ,
8485 fontWeight : 600 ,
8586 fontSize : '0.75rem' ,
8687 lineHeight : '1.25rem' ,
@@ -164,7 +165,7 @@ const INITIAL_SERVERS: McpServer[] = [
164165 {
165166 id : 'github' ,
166167 name : 'Github' ,
167- enabled : false ,
168+ enabled : true ,
168169 status : 'tokenRequired' ,
169170 detail : 'Token required' ,
170171 } ,
@@ -185,9 +186,11 @@ const INITIAL_SERVERS: McpServer[] = [
185186 {
186187 id : 'kubernetes' ,
187188 name : 'Kubernetes' ,
188- enabled : false ,
189+ enabled : true ,
189190 status : 'failed' ,
190- detail : '5 tools' ,
191+ detail : '4 tools' ,
192+ errorMessage :
193+ 'Token authentication failed, click edit to configure it again' ,
191194 } ,
192195 {
193196 id : 'developerhub' ,
@@ -213,7 +216,7 @@ const INITIAL_SERVERS: McpServer[] = [
213216 {
214217 id : 'figma' ,
215218 name : 'Figma' ,
216- enabled : false ,
219+ enabled : true ,
217220 status : 'failed' ,
218221 detail : 'Failed' ,
219222 } ,
@@ -227,6 +230,24 @@ const getStatusIcon = (status: ServerStatus, className: string) => {
227230 return < CheckCircleIcon className = { className } /> ;
228231} ;
229232
233+ const getDisplayStatus = ( server : McpServer ) : ServerStatus => {
234+ if ( ! server . enabled ) return 'disabled' ;
235+ if ( server . status === 'tokenRequired' ) return 'tokenRequired' ;
236+ if ( server . status === 'failed' ) return 'failed' ;
237+ if ( server . status === 'ok' ) return 'ok' ;
238+ return 'unknown' ;
239+ } ;
240+
241+ const getDisplayDetail = (
242+ server : McpServer ,
243+ displayStatus : ServerStatus ,
244+ ) : string => {
245+ if ( displayStatus === 'disabled' ) return 'Disabled' ;
246+ if ( displayStatus === 'tokenRequired' ) return 'Token required' ;
247+ if ( displayStatus === 'failed' ) return server . detail || 'Failed' ;
248+ return server . detail ;
249+ } ;
250+
230251export const McpServersSettings = ( {
231252 onClose,
232253 backgroundColor,
@@ -295,32 +316,50 @@ export const McpServersSettings = ({
295316 </ Thead >
296317 < Tbody >
297318 { sortedServers . map ( server => {
319+ const displayStatus = getDisplayStatus ( server ) ;
320+ const displayDetail = getDisplayDetail ( server , displayStatus ) ;
298321 let statusClass = classes . statusWarn ;
299- if ( server . status === 'ok' ) {
322+ if ( displayStatus === 'ok' ) {
300323 statusClass = classes . statusOk ;
301- } else if ( server . status === 'tokenRequired' ) {
324+ } else if ( displayStatus === 'tokenRequired' ) {
302325 statusClass = classes . statusToken ;
303- } else if ( server . status === 'disabled' ) {
326+ } else if ( displayStatus === 'disabled' ) {
304327 statusClass = classes . statusDisabled ;
305328 }
306329
307330 return (
308331 < Tr key = { server . id } >
309332 < Td width = { 10 } className = { classes . toggleCell } >
310- < Switch
311- id = { `mcp-switch-${ server . id } ` }
312- aria-label = { `Toggle ${ server . name } ` }
313- isChecked = { server . enabled }
314- onChange = { ( _event , checked ) =>
315- setServers ( prev =>
316- prev . map ( item =>
317- item . id === server . id
318- ? { ...item , enabled : checked }
319- : item ,
320- ) ,
321- )
322- }
323- />
333+ { ( ( ) => {
334+ const isUnavailable =
335+ server . status === 'failed' ||
336+ server . status === 'tokenRequired' ;
337+ const isChecked = isUnavailable ? false : server . enabled ;
338+
339+ return (
340+ < Switch
341+ id = { `mcp-switch-${ server . id } ` }
342+ aria-label = { `Toggle ${ server . name } ` }
343+ isChecked = { isChecked }
344+ isDisabled = { isUnavailable }
345+ onChange = { ( _event , checked ) =>
346+ setServers ( prev =>
347+ prev . map ( item =>
348+ item . id === server . id
349+ ? {
350+ ...item ,
351+ enabled : checked ,
352+ ...( checked && item . status === 'disabled'
353+ ? { status : 'ok' , detail : '5 tools' }
354+ : { } ) ,
355+ }
356+ : item ,
357+ ) ,
358+ )
359+ }
360+ />
361+ ) ;
362+ } ) ( ) }
324363 </ Td >
325364 < Td
326365 width = { 35 }
@@ -332,13 +371,24 @@ export const McpServersSettings = ({
332371 </ Td >
333372 < Td width = { 40 } className = { classes . statusColumnCell } >
334373 < div className = { classes . statusCell } >
335- { getStatusIcon ( server . status , statusClass ) }
336- < Typography
337- component = "span"
338- className = { classes . statusValue }
339- >
340- { server . detail }
341- </ Typography >
374+ { getStatusIcon ( displayStatus , statusClass ) }
375+ { displayStatus === 'failed' && server . errorMessage ? (
376+ < Tooltip content = { server . errorMessage } >
377+ < Typography
378+ component = "span"
379+ className = { classes . statusValue }
380+ >
381+ { displayDetail }
382+ </ Typography >
383+ </ Tooltip >
384+ ) : (
385+ < Typography
386+ component = "span"
387+ className = { classes . statusValue }
388+ >
389+ { displayDetail }
390+ </ Typography >
391+ ) }
342392 </ div >
343393 </ Td >
344394 < Td width = { 15 } isActionCell style = { { textAlign : 'right' } } >
0 commit comments