@@ -11,6 +11,10 @@ export type ToolArgs<Args extends ZodRawShape> = z.objectOutputType<Args, ZodNev
11
11
12
12
export type OperationType = "metadata" | "read" | "create" | "delete" | "update" ;
13
13
export type ToolCategory = "mongodb" | "atlas" ;
14
+ export type TelemetryToolMetadata = {
15
+ projectId ?: string ;
16
+ orgId ?: string ;
17
+ } ;
14
18
15
19
export abstract class ToolBase {
16
20
protected abstract name : string ;
@@ -31,28 +35,6 @@ export abstract class ToolBase {
31
35
protected readonly telemetry : Telemetry
32
36
) { }
33
37
34
- /**
35
- * Creates and emits a tool telemetry event
36
- * @param startTime - Start time in milliseconds
37
- * @param result - Whether the command succeeded or failed
38
- * @param error - Optional error if the command failed
39
- */
40
- private async emitToolEvent ( startTime : number , result : CallToolResult ) : Promise < void > {
41
- const duration = Date . now ( ) - startTime ;
42
- const event : ToolEvent = {
43
- timestamp : new Date ( ) . toISOString ( ) ,
44
- source : "mdbmcp" ,
45
- properties : {
46
- command : this . name ,
47
- category : this . category ,
48
- component : "tool" ,
49
- duration_ms : duration ,
50
- result : result . isError ? "failure" : "success" ,
51
- } ,
52
- } ;
53
- await this . telemetry . emitEvents ( [ event ] ) ;
54
- }
55
-
56
38
public register ( server : McpServer ) : void {
57
39
if ( ! this . verifyAllowed ( ) ) {
58
40
return ;
@@ -64,12 +46,12 @@ export abstract class ToolBase {
64
46
logger . debug ( LogId . toolExecute , "tool" , `Executing ${ this . name } with args: ${ JSON . stringify ( args ) } ` ) ;
65
47
66
48
const result = await this . execute ( ...args ) ;
67
- await this . emitToolEvent ( startTime , result ) ;
49
+ await this . emitToolEvent ( startTime , result , ... args ) . catch ( ( ) => { } ) ;
68
50
return result ;
69
51
} catch ( error : unknown ) {
70
52
logger . error ( LogId . toolExecuteFailure , "tool" , `Error executing ${ this . name } : ${ error as string } ` ) ;
71
53
const toolResult = await this . handleError ( error , args [ 0 ] as ToolArgs < typeof this . argsShape > ) ;
72
- await this . emitToolEvent ( startTime , toolResult ) . catch ( ( ) => { } ) ;
54
+ await this . emitToolEvent ( startTime , toolResult , ... args ) . catch ( ( ) => { } ) ;
73
55
return toolResult ;
74
56
}
75
57
} ;
@@ -149,4 +131,47 @@ export abstract class ToolBase {
149
131
] ,
150
132
} ;
151
133
}
134
+
135
+ protected abstract resolveTelemetryMetadata (
136
+ ...args : Parameters < ToolCallback < typeof this . argsShape > >
137
+ ) : TelemetryToolMetadata ;
138
+
139
+ /**
140
+ * Creates and emits a tool telemetry event
141
+ * @param startTime - Start time in milliseconds
142
+ * @param result - Whether the command succeeded or failed
143
+ * @param args - The arguments passed to the tool
144
+ */
145
+ private async emitToolEvent (
146
+ startTime : number ,
147
+ result : CallToolResult ,
148
+ ...args : Parameters < ToolCallback < typeof this . argsShape > >
149
+ ) : Promise < void > {
150
+ if ( ! this . telemetry . isTelemetryEnabled ( ) ) {
151
+ return ;
152
+ }
153
+ const duration = Date . now ( ) - startTime ;
154
+ const metadata = this . resolveTelemetryMetadata ( ...args ) ;
155
+ const event : ToolEvent = {
156
+ timestamp : new Date ( ) . toISOString ( ) ,
157
+ source : "mdbmcp" ,
158
+ properties : {
159
+ command : this . name ,
160
+ category : this . category ,
161
+ component : "tool" ,
162
+ duration_ms : duration ,
163
+ result : result . isError ? "failure" : "success" ,
164
+ } ,
165
+ } ;
166
+
167
+ if ( metadata ?. orgId ) {
168
+ event . properties . org_id = metadata . orgId ;
169
+ }
170
+
171
+ if ( metadata ?. projectId ) {
172
+ event . properties . project_id = metadata . projectId ;
173
+ }
174
+
175
+ await this . telemetry . emitEvents ( [ event ] ) ;
176
+ }
152
177
}
0 commit comments