1- import { McpServer , ToolCallback } from "@modelcontextprotocol/sdk/server/mcp.js " ;
2- import { z , ZodNever , ZodRawShape } from "zod " ;
3- import { CallToolResult } from "@modelcontextprotocol/sdk/types.js" ;
1+ import { z , type ZodRawShape , type ZodNever } from "zod " ;
2+ import type { McpServer , ToolCallback } from "@modelcontextprotocol/sdk/server/mcp.js " ;
3+ import type { CallToolResult } from "@modelcontextprotocol/sdk/types.js" ;
44import { Session } from "../session.js" ;
55import logger from "../logger.js" ;
66import { mongoLogId } from "mongodb-log-writer" ;
7+ < < < << << HEAD
78import config from "../config.js" ;
9+ === === =
10+ import { Telemetry } from "../telemetry/telemetry.js" ;
11+ >>> >>> > 61e295 a ( wip )
812
913export type ToolArgs < Args extends ZodRawShape > = z . objectOutputType < Args , ZodNever > ;
1014
1115export type OperationType = "metadata" | "read" | "create" | "delete" | "update" | "cluster" ;
1216export type ToolCategory = "mongodb" | "atlas" ;
1317
1418export abstract class ToolBase {
19+ < << << << HEAD
1520 protected abstract name : string ;
1621
1722 protected abstract category : ToolCategory ;
@@ -21,37 +26,57 @@ export abstract class ToolBase {
2126 protected abstract description : string ;
2227
2328 protected abstract argsShape : ZodRawShape ;
29+ === === =
30+ protected abstract readonly name : string ;
31+ protected abstract readonly description : string ;
32+ protected abstract readonly argsShape : ZodRawShape ;
33+ > >>> >>> 61e295 a ( wip )
2434
2535 protected abstract category : string ;
36+ private readonly telemetry : Telemetry ;
2637
2738 protected abstract execute ( ...args : Parameters < ToolCallback < typeof this . argsShape > > ) : Promise < CallToolResult > ;
2839
29- protected constructor ( protected session : Session ) { }
40+ protected constructor ( protected session : Session ) {
41+ this . telemetry = new Telemetry ( session ) ;
42+ }
3043
3144 public register ( server : McpServer ) : void {
3245 if ( ! this . verifyAllowed ( ) ) {
3346 return ;
3447 }
3548
3649 const callback : ToolCallback < typeof this . argsShape > = async ( ...args ) => {
50+ const startTime = Date . now ( ) ;
3751 try {
3852 logger . debug (
3953 mongoLogId ( 1_000_006 ) ,
4054 "tool" ,
4155 `Executing ${ this . name } with args: ${ JSON . stringify ( args ) } `
4256 ) ;
4357
44- return await this . execute ( ...args ) ;
58+ const result = await this . execute ( ...args ) ;
59+ await this . telemetry . emitToolEvent ( this . name , this . category , startTime , "success" ) ;
60+ return result ;
4561 } catch ( error : unknown ) {
4662 logger . error ( mongoLogId ( 1_000_000 ) , "tool" , `Error executing ${ this . name } : ${ error as string } ` ) ;
4763
64+ await this . telemetry . emitToolEvent (
65+ this . name ,
66+ this . category ,
67+ startTime ,
68+ "failure" ,
69+ error instanceof Error ? error : new Error ( String ( error ) )
70+ ) ;
71+
4872 return await this . handleError ( error ) ;
4973 }
5074 } ;
5175
5276 server . tool ( this . name , this . description , this . argsShape , callback ) ;
5377 }
5478
79+ < << << << HEAD
5580 // Checks if a tool is allowed to run based on the config
5681 private verifyAllowed ( ) : boolean {
5782 let errorClarification : string | undefined ;
@@ -76,6 +101,8 @@ export abstract class ToolBase {
76101 return true ;
77102 }
78103
104+ === === =
105+ >>> >>> > 61e295 a ( wip )
79106 // This method is intended to be overridden by subclasses to handle errors
80107 protected handleError ( error : unknown ) : Promise < CallToolResult > | CallToolResult {
81108 return {
0 commit comments