@@ -54,6 +54,17 @@ export class McpHub {
5454 connections : McpConnection [ ] = [ ]
5555 isConnecting : boolean = false
5656
57+ // Store notifications for display in chat
58+ private pendingNotifications : Array < {
59+ serverName : string
60+ level : string
61+ message : string
62+ timestamp : number
63+ } > = [ ]
64+
65+ // Callback for sending notifications to active task
66+ private notificationCallback ?: ( serverName : string , level : string , message : string ) => void
67+
5768 constructor (
5869 getMcpServersPath : ( ) => Promise < string > ,
5970 getSettingsDirectoryPath : ( ) => Promise < string > ,
@@ -321,6 +332,100 @@ export class McpHub {
321332 connection . server . status = "connected"
322333 connection . server . error = ""
323334
335+ // Register notification handler for real-time messages
336+ console . log ( `[MCP Debug] Setting up notification handlers for server: ${ name } ` )
337+ console . log ( `[MCP Debug] Client instance:` , connection . client )
338+ console . log ( `[MCP Debug] Transport type:` , config . type )
339+
340+ // Try to set notification handler using the client's method
341+ try {
342+ // Import the notification schema from MCP SDK
343+ const { z } = await import ( "zod" )
344+
345+ // Define the notification schema for notifications/message
346+ const NotificationMessageSchema = z . object ( {
347+ method : z . literal ( "notifications/message" ) ,
348+ params : z
349+ . object ( {
350+ level : z . enum ( [ "debug" , "info" , "warning" , "error" ] ) . optional ( ) ,
351+ logger : z . string ( ) . optional ( ) ,
352+ data : z . string ( ) . optional ( ) ,
353+ message : z . string ( ) . optional ( ) ,
354+ } )
355+ . optional ( ) ,
356+ } )
357+
358+ // Set the notification handler
359+ connection . client . setNotificationHandler ( NotificationMessageSchema as any , async ( notification : any ) => {
360+ console . log ( `[MCP Notification] ${ name } :` , JSON . stringify ( notification , null , 2 ) )
361+
362+ const params = notification . params || { }
363+ const level = params . level || "info"
364+ const data = params . data || params . message || ""
365+ const logger = params . logger || ""
366+
367+ console . log ( `[MCP Message Notification] ${ name } : level=${ level } , data=${ data } , logger=${ logger } ` )
368+
369+ // Format the message
370+ const message = logger ? `[${ logger } ] ${ data } ` : data
371+
372+ // Send notification directly to active task if callback is set
373+ if ( this . notificationCallback ) {
374+ console . log ( `[MCP Debug] Sending notification to active task: ${ message } ` )
375+ this . notificationCallback ( name , level , message )
376+ } else {
377+ // Fallback: store for later retrieval
378+ console . log ( `[MCP Debug] No active task, storing notification: ${ message } ` )
379+ this . pendingNotifications . push ( {
380+ serverName : name ,
381+ level,
382+ message,
383+ timestamp : Date . now ( ) ,
384+ } )
385+ }
386+
387+ // Also show as VS Code notification for now (can be removed later if desired)
388+ switch ( level ) {
389+ case "error" :
390+ vscode . window . showErrorMessage ( `MCP ${ name } : ${ message } ` )
391+ break
392+ case "warning" :
393+ vscode . window . showWarningMessage ( `MCP ${ name } : ${ message } ` )
394+ break
395+ default :
396+ vscode . window . showInformationMessage ( `MCP ${ name } : ${ message } ` )
397+ }
398+
399+ // Forward to webview if available
400+ if ( this . postMessageToWebview ) {
401+ await this . postMessageToWebview ( {
402+ type : "mcpNotification" ,
403+ serverName : name ,
404+ notification : {
405+ level,
406+ data,
407+ logger,
408+ timestamp : Date . now ( ) ,
409+ } ,
410+ } as any )
411+ }
412+ } )
413+ console . log ( `[MCP Debug] Successfully set notifications/message handler for ${ name } ` )
414+
415+ // Also set a fallback handler for any other notification types
416+ connection . client . fallbackNotificationHandler = async ( notification : any ) => {
417+ console . log ( `[MCP Fallback Notification] ${ name } :` , JSON . stringify ( notification , null , 2 ) )
418+
419+ // Show in VS Code for visibility
420+ vscode . window . showInformationMessage (
421+ `MCP ${ name } : ${ notification . method || "unknown" } - ${ JSON . stringify ( notification . params || { } ) } ` ,
422+ )
423+ }
424+ console . log ( `[MCP Debug] Successfully set fallback notification handler for ${ name } ` )
425+ } catch ( error ) {
426+ console . error ( `[MCP Debug] Error setting notification handlers for ${ name } :` , error )
427+ }
428+
324429 // Initial fetch of tools and resources
325430 connection . server . tools = await this . fetchToolsList ( name )
326431 connection . server . resources = await this . fetchResourcesList ( name )
@@ -949,6 +1054,38 @@ export class McpHub {
9491054 }
9501055 }
9511056
1057+ /**
1058+ * Get and clear pending notifications
1059+ * @returns Array of pending notifications
1060+ */
1061+ getPendingNotifications ( ) : Array < {
1062+ serverName : string
1063+ level : string
1064+ message : string
1065+ timestamp : number
1066+ } > {
1067+ const notifications = [ ...this . pendingNotifications ]
1068+ this . pendingNotifications = [ ]
1069+ return notifications
1070+ }
1071+
1072+ /**
1073+ * Set the notification callback for real-time notifications
1074+ * @param callback Function to call when notifications arrive
1075+ */
1076+ setNotificationCallback ( callback : ( serverName : string , level : string , message : string ) => void ) : void {
1077+ this . notificationCallback = callback
1078+ console . log ( "[MCP Debug] Notification callback set" )
1079+ }
1080+
1081+ /**
1082+ * Clear the notification callback
1083+ */
1084+ clearNotificationCallback ( ) : void {
1085+ this . notificationCallback = undefined
1086+ console . log ( "[MCP Debug] Notification callback cleared" )
1087+ }
1088+
9521089 async dispose ( ) : Promise < void > {
9531090 this . removeAllFileWatchers ( )
9541091 for ( const connection of this . connections ) {
0 commit comments