@@ -31,6 +31,7 @@ import {
3131 Hammer ,
3232 Hash ,
3333 MessageSquare ,
34+ BarChart ,
3435} from "lucide-react" ;
3536
3637import { toast } from "react-toastify" ;
@@ -45,6 +46,7 @@ import RootsTab from "./components/RootsTab";
4546import SamplingTab , { PendingRequest } from "./components/SamplingTab" ;
4647import Sidebar from "./components/Sidebar" ;
4748import ToolsTab from "./components/ToolsTab" ;
49+ import StatsTab from "./components/StatsTab" ;
4850
4951const params = new URLSearchParams ( window . location . search ) ;
5052const PROXY_PORT = params . get ( "proxyPort" ) ?? "3000" ;
@@ -123,22 +125,6 @@ const MainApp = () => {
123125 const nextRequestId = useRef ( 0 ) ;
124126 const rootsRef = useRef < Root [ ] > ( [ ] ) ;
125127
126- const handleApproveSampling = ( id : number , result : CreateMessageResult ) => {
127- setPendingSampleRequests ( ( prev ) => {
128- const request = prev . find ( ( r ) => r . id === id ) ;
129- request ?. resolve ( result ) ;
130- return prev . filter ( ( r ) => r . id !== id ) ;
131- } ) ;
132- } ;
133-
134- const handleRejectSampling = ( id : number ) => {
135- setPendingSampleRequests ( ( prev ) => {
136- const request = prev . find ( ( r ) => r . id === id ) ;
137- request ?. reject ( new Error ( "Sampling request rejected" ) ) ;
138- return prev . filter ( ( r ) => r . id !== id ) ;
139- } ) ;
140- } ;
141-
142128 const [ selectedResource , setSelectedResource ] = useState < Resource | null > (
143129 null ,
144130 ) ;
@@ -195,7 +181,7 @@ const MainApp = () => {
195181 ...prev ,
196182 {
197183 id : nextRequestId . current ++ ,
198- request : request as any ,
184+ request : request as unknown ,
199185 resolve : resolve as ( result : CreateMessageResult ) => void ,
200186 reject : reject as ( error : Error ) => void
201187 } as PendingRequest & {
@@ -248,23 +234,42 @@ const MainApp = () => {
248234 fetch ( `${ PROXY_SERVER_URL } /config` )
249235 . then ( ( response ) => response . json ( ) )
250236 . then ( ( data ) => {
251- setEnv ( data . defaultEnvironment ) ;
237+ setEnv ( data . defaultEnvironment || { } ) ;
252238 if ( data . defaultCommand ) {
253239 setCommand ( data . defaultCommand ) ;
254240 }
255241 if ( data . defaultArgs ) {
256242 setArgs ( data . defaultArgs ) ;
257243 }
258244 } )
259- . catch ( ( error ) =>
260- console . error ( "Error fetching default environment:" , error ) ,
261- ) ;
245+ . catch ( ( error ) => {
246+ console . error ( "Error fetching default environment:" , error ) ;
247+ // Set default empty environment to prevent UI blocking
248+ setEnv ( { } ) ;
249+ } ) ;
262250 } , [ ] ) ;
263251
264252 useEffect ( ( ) => {
265253 rootsRef . current = roots ;
266254 } , [ roots ] ) ;
267255
256+ useEffect ( ( ) => {
257+ console . log ( `[App] Connection status changed to: ${ connectionStatus } ` ) ;
258+ console . log ( `[App] Connection details - status: ${ connectionStatus } , serverCapabilities: ${ ! ! serverCapabilities } , mcpClient: ${ ! ! mcpClient } ` ) ;
259+
260+ if ( connectionStatus === "connected" && mcpClient && ! serverCapabilities ) {
261+ console . log ( "[App] Connection is established, but missing capabilities" ) ;
262+ try {
263+ // Only log capabilities here, don't attempt to set them
264+ // as we don't have the setter in this component
265+ const caps = mcpClient . getServerCapabilities ( ) ;
266+ console . log ( "[App] Retrieved capabilities directly:" , caps ) ;
267+ } catch ( e ) {
268+ console . error ( "[App] Error retrieving capabilities:" , e ) ;
269+ }
270+ }
271+ } , [ connectionStatus , serverCapabilities , mcpClient ] ) ;
272+
268273 useEffect ( ( ) => {
269274 if ( ! window . location . hash ) {
270275 window . location . hash = "resources" ;
@@ -443,6 +448,23 @@ const MainApp = () => {
443448 setLogLevel ( level ) ;
444449 } ;
445450
451+ const handleApproveSampling = ( id : number , result : CreateMessageResult ) => {
452+ setPendingSampleRequests ( ( prev ) => {
453+ const request = prev . find ( ( r ) => r . id === id ) ;
454+ request ?. resolve ( result ) ;
455+ return prev . filter ( ( r ) => r . id !== id ) ;
456+ } ) ;
457+ } ;
458+
459+ const handleRejectSampling = ( id : number ) => {
460+ setPendingSampleRequests ( ( prev ) => {
461+ const request = prev . find ( ( r ) => r . id === id ) ;
462+ request ?. reject ( new Error ( "Sampling request rejected" ) ) ;
463+ return prev . filter ( ( r ) => r . id !== id ) ;
464+ } ) ;
465+ } ;
466+
467+
446468 return (
447469 < div className = "flex h-screen bg-background" >
448470 < Sidebar
@@ -469,10 +491,10 @@ const MainApp = () => {
469491 />
470492 < div className = "flex-1 flex flex-col overflow-hidden" >
471493 < div className = "flex-1 overflow-auto" >
472- { mcpClient ? (
494+ { connectionStatus === "connected" && serverCapabilities ? (
473495 < Tabs
474496 defaultValue = {
475- Object . keys ( serverCapabilities ?? { } ) . includes (
497+ Object . keys ( serverCapabilities ) . includes (
476498 window . location . hash . slice ( 1 ) ,
477499 )
478500 ? window . location . hash . slice ( 1 )
@@ -526,6 +548,10 @@ const MainApp = () => {
526548 < FolderTree className = "w-4 h-4 mr-2" />
527549 Roots
528550 </ TabsTrigger >
551+ < TabsTrigger value = "stats" >
552+ < BarChart className = "w-4 h-4 mr-2" />
553+ Stats
554+ </ TabsTrigger >
529555 </ TabsList >
530556
531557 < div className = "w-full" >
@@ -656,10 +682,27 @@ const MainApp = () => {
656682 setRoots = { setRoots }
657683 onRootsChange = { handleRootsChange }
658684 />
685+ < StatsTab mcpClient = { mcpClient } />
659686 </ >
660687 ) }
661688 </ div >
662689 </ Tabs >
690+ ) : connectionStatus === "connected" && mcpClient ? (
691+ < div className = "flex flex-col items-center justify-center h-full gap-4" >
692+ < p className = "text-lg text-gray-500" >
693+ Connected to MCP server but waiting for capabilities...
694+ </ p >
695+ < button
696+ className = "px-4 py-2 bg-blue-500 text-white rounded hover:bg-blue-600"
697+ onClick = { ( ) => {
698+ // Attempt to reconnect instead of directly setting capabilities
699+ toast . info ( "Attempting to reconnect..." ) ;
700+ connectMcpServer ( ) ;
701+ } }
702+ >
703+ Reconnect
704+ </ button >
705+ </ div >
663706 ) : (
664707 < div className = "flex items-center justify-center h-full" >
665708 < p className = "text-lg text-gray-500" >
0 commit comments