Skip to content

Commit 0e4dab5

Browse files
committed
fix: emitting amazonq_mcpConfig metric from init function of mcpManager.
1 parent 2667566 commit 0e4dab5

File tree

3 files changed

+64
-5
lines changed

3 files changed

+64
-5
lines changed

server/aws-lsp-codewhisperer/src/language-server/agenticChat/tools/mcp/mcpManager.ts

Lines changed: 52 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,9 @@
44
*/
55

66
import type { Features } from '@aws/language-server-runtimes/server-interface/server'
7+
import { ChatTelemetryEventName } from '../../../../shared/telemetry/types'
8+
import { ChatTelemetryController } from '../../../chat/telemetry/chatTelemetryController'
9+
import { getGlobalMcpConfigPath } from './mcpUtils'
710
import { Client } from '@modelcontextprotocol/sdk/client/index.js'
811
import { StdioClientTransport } from '@modelcontextprotocol/sdk/client/stdio.js'
912
import {
@@ -45,7 +48,10 @@ export class McpManager {
4548
private constructor(
4649
private configPaths: string[],
4750
private personaPaths: string[],
48-
private features: Pick<Features, 'logging' | 'workspace' | 'lsp'>
51+
private features: Pick<
52+
Features,
53+
'logging' | 'workspace' | 'lsp' | 'telemetry' | 'credentialsProvider' | 'runtime'
54+
>
4955
) {
5056
this.mcpTools = []
5157
this.clients = new Map<string, Client>()
@@ -61,16 +67,60 @@ export class McpManager {
6167
/**
6268
* Initialize or return existing manager, then discover all servers.
6369
*/
70+
#telemetryController?: ChatTelemetryController
71+
6472
public static async init(
6573
configPaths: string[],
6674
personaPaths: string[],
67-
features: Pick<Features, 'logging' | 'workspace' | 'lsp'>
75+
features: Pick<Features, 'logging' | 'workspace' | 'lsp' | 'telemetry' | 'credentialsProvider' | 'runtime'>
6876
): Promise<McpManager> {
6977
if (!McpManager.#instance) {
7078
const mgr = new McpManager(configPaths, personaPaths, features)
7179
McpManager.#instance = mgr
7280
await mgr.discoverAllServers()
7381
features.logging.info(`MCP: discovered ${mgr.mcpTools.length} tools across all servers`)
82+
83+
// Emit MCP configuration metrics
84+
const serverConfigs = mgr.getAllServerConfigs()
85+
const activeServers = Array.from(serverConfigs.entries()).filter(([name, _]) => !mgr.isServerDisabled(name))
86+
87+
// Count global vs project servers
88+
const globalServers = Array.from(serverConfigs.entries()).filter(
89+
([_, config]) =>
90+
config?.__configPath__ === getGlobalMcpConfigPath(features.workspace.fs.getUserHomeDir())
91+
).length
92+
const projectServers = serverConfigs.size - globalServers
93+
94+
// Count tools by permission
95+
let toolsAlwaysAllowed = 0
96+
let toolsDenied = 0
97+
98+
for (const [serverName, _] of activeServers) {
99+
const toolsWithPermissions = mgr.getAllToolsWithPermissions(serverName)
100+
toolsWithPermissions.forEach(item => {
101+
if (item.permission === McpPermissionType.alwaysAllow) {
102+
toolsAlwaysAllowed++
103+
} else if (item.permission === McpPermissionType.deny) {
104+
toolsDenied++
105+
}
106+
})
107+
}
108+
109+
// Emit MCP configuration metrics
110+
if (features.telemetry) {
111+
features.telemetry.emitMetric({
112+
name: ChatTelemetryEventName.MCPConfig,
113+
data: {
114+
credentialStartUrl: features.credentialsProvider?.getConnectionMetadata()?.sso?.startUrl,
115+
languageServerVersion: features.runtime?.serverInfo.version,
116+
numActiveServers: activeServers.length,
117+
numGlobalServers: globalServers,
118+
numProjectServers: projectServers,
119+
numToolsAlwaysAllowed: toolsAlwaysAllowed,
120+
numToolsDenied: toolsDenied,
121+
},
122+
})
123+
}
74124
}
75125
return McpManager.#instance
76126
}

server/aws-lsp-codewhisperer/src/language-server/agenticChat/tools/mcp/mcpTool.test.ts

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,9 +20,11 @@ describe('McpTool', () => {
2020
},
2121
},
2222
lsp: {},
23+
credentialsProvider: {},
24+
telemetry: { record: () => {} },
2325
} as unknown as Pick<
2426
import('@aws/language-server-runtimes/server-interface/server').Features,
25-
'logging' | 'workspace' | 'lsp'
27+
'logging' | 'workspace' | 'lsp' | 'credentialsProvider' | 'telemetry' | 'runtime'
2628
>
2729

2830
const definition: McpToolDefinition = {

server/aws-lsp-codewhisperer/src/language-server/agenticChat/tools/toolServer.ts

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -82,7 +82,7 @@ export const LspToolsServer: Server = ({ workspace, logging, lsp, agent }) => {
8282
return () => {}
8383
}
8484

85-
export const McpToolsServer: Server = ({ credentialsProvider, workspace, logging, lsp, agent }) => {
85+
export const McpToolsServer: Server = ({ credentialsProvider, workspace, logging, lsp, agent, telemetry, runtime }) => {
8686
const registered: Record<string, string[]> = {}
8787

8888
const allNamespacedTools = new Set<string>()
@@ -141,7 +141,14 @@ export const McpToolsServer: Server = ({ credentialsProvider, workspace, logging
141141
const globalPersonaPath = getGlobalPersonaConfigPath(workspace.fs.getUserHomeDir())
142142
const allPersonaPaths = [...wsPersonaPaths, globalPersonaPath]
143143

144-
const mgr = await McpManager.init(allConfigPaths, allPersonaPaths, { logging, workspace, lsp })
144+
const mgr = await McpManager.init(allConfigPaths, allPersonaPaths, {
145+
logging,
146+
workspace,
147+
lsp,
148+
telemetry,
149+
credentialsProvider,
150+
runtime,
151+
})
145152

146153
// Clear tool name mapping before registering all tools to avoid conflicts from previous registrations
147154
McpManager.instance.clearToolNameMapping()

0 commit comments

Comments
 (0)