11import { Features } from '../../../types'
22import { MCP_SERVER_STATUS_CHANGED , McpManager } from './mcpManager'
3+ import { ChatTelemetryController } from '../../../chat/telemetry/chatTelemetryController'
34import {
45 DetailedListGroup ,
56 DetailedListItem ,
@@ -22,6 +23,7 @@ import {
2223 McpServerRuntimeState ,
2324 McpServerStatus ,
2425} from './mcpTypes'
26+ import { TelemetryService } from '../../../../shared/telemetry/telemetryService'
2527
2628interface PermissionOption {
2729 label : string
@@ -33,12 +35,14 @@ export class McpEventHandler {
3335 #eventListenerRegistered: boolean
3436 #currentEditingServerName: string | undefined
3537 #shouldDisplayListMCPServers: boolean
38+ #telemetryController: ChatTelemetryController
3639
37- constructor ( features : Features ) {
40+ constructor ( features : Features , telemetryService : TelemetryService ) {
3841 this . #features = features
3942 this . #eventListenerRegistered = false
4043 this . #currentEditingServerName = undefined
4144 this . #shouldDisplayListMCPServers = true
45+ this . #telemetryController = new ChatTelemetryController ( features , telemetryService )
4246 }
4347
4448 /**
@@ -636,12 +640,41 @@ export class McpEventHandler {
636640 if ( serverName !== originalServerName ) {
637641 await McpManager . instance . removeServer ( originalServerName )
638642 await McpManager . instance . addServer ( serverName , config , configPath , personaPath )
643+ // Emit server initialize event after adding server
644+ this . #telemetryController?. emitMCPServerInitializeEvent ( {
645+ source : 'addServer' ,
646+ command : config . command ,
647+ enabled : true ,
648+ numTools : McpManager . instance . getAllToolsWithPermissions ( serverName ) . length ,
649+ scope : params . optionsValues [ 'scope' ] === 'global' ? 'global' : 'workspace' ,
650+ transportType : 'stdio' ,
651+ languageServerVersion : this . #features. runtime . serverInfo . version ,
652+ } )
639653 } else {
640654 await McpManager . instance . updateServer ( serverName , config , configPath )
655+ // Emit server initialize event after updating server
656+ this . #telemetryController?. emitMCPServerInitializeEvent ( {
657+ source : 'updateServer' ,
658+ command : config . command ,
659+ enabled : true ,
660+ numTools : McpManager . instance . getAllToolsWithPermissions ( serverName ) . length ,
661+ scope : params . optionsValues [ 'scope' ] === 'global' ? 'global' : 'workspace' ,
662+ transportType : 'stdio' ,
663+ languageServerVersion : this . #features. runtime . serverInfo . version ,
664+ } )
641665 }
642666 } else {
643667 // Create new server
644668 await McpManager . instance . addServer ( serverName , config , configPath , personaPath )
669+ this . #telemetryController?. emitMCPServerInitializeEvent ( {
670+ source : 'addServer' ,
671+ command : config . command ,
672+ enabled : true ,
673+ numTools : McpManager . instance . getAllToolsWithPermissions ( serverName ) . length ,
674+ scope : params . optionsValues [ 'scope' ] === 'global' ? 'global' : 'workspace' ,
675+ transportType : 'stdio' ,
676+ languageServerVersion : this . #features. runtime . serverInfo . version ,
677+ } )
645678 }
646679
647680 this . #currentEditingServerName = undefined
@@ -980,20 +1013,99 @@ export class McpEventHandler {
9801013 const mcpServerPermission = await this . #processPermissionUpdates( updatedPermissionConfig )
9811014
9821015 await McpManager . instance . updateServerPermission ( serverName , mcpServerPermission )
1016+
1017+ // Get server config to emit telemetry
1018+ const serverConfig = McpManager . instance . getAllServerConfigs ( ) . get ( serverName )
1019+ if ( serverConfig ) {
1020+ // Emit server initialize event after permission change
1021+ this . #telemetryController?. emitMCPServerInitializeEvent ( {
1022+ source : 'updatePermission' ,
1023+ command : serverConfig . command ,
1024+ enabled : true ,
1025+ numTools : McpManager . instance . getAllToolsWithPermissions ( serverName ) . length ,
1026+ scope :
1027+ serverConfig ?. __configPath__ ===
1028+ getGlobalMcpConfigPath ( this . #features. workspace . fs . getUserHomeDir ( ) )
1029+ ? 'global'
1030+ : 'workspace' ,
1031+ transportType : 'stdio' ,
1032+ languageServerVersion : this . #features. runtime . serverInfo . version ,
1033+ } )
1034+ }
9831035 return { id : params . id }
9841036 } catch ( error ) {
9851037 this . #features. logging . error ( `Failed to update MCP permissions: ${ error } ` )
9861038 return { id : params . id }
9871039 }
9881040 }
9891041
1042+ #emitMCPConfigEvent( ) {
1043+ // Emit MCP config event after reinitialization
1044+ const mcpManager = McpManager . instance
1045+ const serverConfigs = mcpManager . getAllServerConfigs ( )
1046+ const activeServers = Array . from ( serverConfigs . entries ( ) ) . filter (
1047+ ( [ name , _ ] ) => ! mcpManager . isServerDisabled ( name )
1048+ )
1049+
1050+ // Count global vs project servers
1051+ const globalServers = Array . from ( serverConfigs . entries ( ) ) . filter (
1052+ ( [ _ , config ] ) =>
1053+ config ?. __configPath__ === getGlobalMcpConfigPath ( this . #features. workspace . fs . getUserHomeDir ( ) )
1054+ ) . length
1055+ const projectServers = serverConfigs . size - globalServers
1056+
1057+ // Count tools by permission
1058+ let toolsAlwaysAllowed = 0
1059+ let toolsDenied = 0
1060+
1061+ for ( const [ serverName , _ ] of activeServers ) {
1062+ const toolsWithPermissions = mcpManager . getAllToolsWithPermissions ( serverName )
1063+ toolsWithPermissions . forEach ( item => {
1064+ if ( item . permission === McpPermissionType . alwaysAllow ) {
1065+ toolsAlwaysAllowed ++
1066+ } else if ( item . permission === McpPermissionType . deny ) {
1067+ toolsDenied ++
1068+ }
1069+ } )
1070+ }
1071+
1072+ this . #telemetryController?. emitMCPConfigEvent ( {
1073+ numActiveServers : activeServers . length ,
1074+ numGlobalServers : globalServers ,
1075+ numProjectServers : projectServers ,
1076+ numToolsAlwaysAllowed : toolsAlwaysAllowed ,
1077+ numToolsDenied : toolsDenied ,
1078+ languageServerVersion : this . #features. runtime . serverInfo . version ,
1079+ } )
1080+
1081+ // Emit server initialize events for all active servers
1082+ for ( const [ serverName , config ] of serverConfigs . entries ( ) ) {
1083+ const enabled = ! mcpManager . isServerDisabled ( serverName )
1084+ if ( enabled ) {
1085+ this . #telemetryController?. emitMCPServerInitializeEvent ( {
1086+ source : 'reload' ,
1087+ command : config . command ,
1088+ enabled,
1089+ numTools : mcpManager . getAllToolsWithPermissions ( serverName ) . length ,
1090+ scope :
1091+ config ?. __configPath__ === getGlobalMcpConfigPath ( this . #features. workspace . fs . getUserHomeDir ( ) )
1092+ ? 'global'
1093+ : 'workspace' ,
1094+ transportType : 'stdio' ,
1095+ languageServerVersion : this . #features. runtime . serverInfo . version ,
1096+ } )
1097+ }
1098+ }
1099+ }
1100+
9901101 /**
9911102 * Handled refresh MCP list events
9921103 */
9931104 async #handleRefreshMCPList( params : McpServerClickParams ) {
9941105 this . #shouldDisplayListMCPServers = true
9951106 try {
9961107 await McpManager . instance . reinitializeMcpServers ( )
1108+ this . #emitMCPConfigEvent( )
9971109 return {
9981110 id : params . id ,
9991111 }
0 commit comments