@@ -39,6 +39,7 @@ import {
3939 ReadResourceResult ,
4040 ServerRequest ,
4141 ServerNotification ,
42+ ToolAnnotations ,
4243} from "../types.js" ;
4344import { Completable , CompletableDef } from "./completable.js" ;
4445import { UriTemplate , Variables } from "../shared/uriTemplate.js" ;
@@ -118,6 +119,7 @@ export class McpServer {
118119 strictUnions : true ,
119120 } ) as Tool [ "inputSchema" ] )
120121 : EMPTY_OBJECT_JSON_SCHEMA ,
122+ annotations : tool . annotations ,
121123 } ;
122124 } ,
123125 ) ,
@@ -605,44 +607,103 @@ export class McpServer {
605607 tool ( name : string , description : string , cb : ToolCallback ) : RegisteredTool ;
606608
607609 /**
608- * Registers a tool `name` accepting the given arguments, which must be an object containing named properties associated with Zod schemas. When the client calls it, the function will be run with the parsed and validated arguments.
610+ * Registers a tool taking either a parameter schema for validation or annotations for additional metadata.
611+ * This unified overload handles both `tool(name, paramsSchema, cb)` and `tool(name, annotations, cb)` cases.
612+ *
613+ * Note: We use a union type for the second parameter because TypeScript cannot reliably disambiguate
614+ * between ToolAnnotations and ZodRawShape during overload resolution, as both are plain object types.
609615 */
610616 tool < Args extends ZodRawShape > (
611617 name : string ,
612- paramsSchema : Args ,
618+ paramsSchemaOrAnnotations : Args | ToolAnnotations ,
613619 cb : ToolCallback < Args > ,
614620 ) : RegisteredTool ;
615621
616622 /**
617- * Registers a tool `name` (with a description) accepting the given arguments, which must be an object containing named properties associated with Zod schemas. When the client calls it, the function will be run with the parsed and validated arguments.
623+ * Registers a tool `name` (with a description) taking either parameter schema or annotations.
624+ * This unified overload handles both `tool(name, description, paramsSchema, cb)` and
625+ * `tool(name, description, annotations, cb)` cases.
626+ *
627+ * Note: We use a union type for the third parameter because TypeScript cannot reliably disambiguate
628+ * between ToolAnnotations and ZodRawShape during overload resolution, as both are plain object types.
629+ */
630+ tool < Args extends ZodRawShape > (
631+ name : string ,
632+ description : string ,
633+ paramsSchemaOrAnnotations : Args | ToolAnnotations ,
634+ cb : ToolCallback < Args > ,
635+ ) : RegisteredTool ;
636+
637+ /**
638+ * Registers a tool with both parameter schema and annotations.
639+ */
640+ tool < Args extends ZodRawShape > (
641+ name : string ,
642+ paramsSchema : Args ,
643+ annotations : ToolAnnotations ,
644+ cb : ToolCallback < Args > ,
645+ ) : RegisteredTool ;
646+
647+ /**
648+ * Registers a tool with description, parameter schema, and annotations.
618649 */
619650 tool < Args extends ZodRawShape > (
620651 name : string ,
621652 description : string ,
622653 paramsSchema : Args ,
654+ annotations : ToolAnnotations ,
623655 cb : ToolCallback < Args > ,
624656 ) : RegisteredTool ;
625657
626658 tool ( name : string , ...rest : unknown [ ] ) : RegisteredTool {
627659 if ( this . _registeredTools [ name ] ) {
628660 throw new Error ( `Tool ${ name } is already registered` ) ;
629661 }
662+
663+ // Helper to check if an object is a Zod schema (ZodRawShape)
664+ const isZodRawShape = ( obj : unknown ) : obj is ZodRawShape => {
665+ if ( typeof obj !== "object" || obj === null ) return false ;
666+ // Check that at least one property is a ZodType instance
667+ return Object . values ( obj as object ) . some ( v => v instanceof ZodType ) ;
668+ } ;
630669
631670 let description : string | undefined ;
632671 if ( typeof rest [ 0 ] === "string" ) {
633672 description = rest . shift ( ) as string ;
634673 }
635674
636675 let paramsSchema : ZodRawShape | undefined ;
676+ let annotations : ToolAnnotations | undefined ;
677+
678+ // Handle the different overload combinations
637679 if ( rest . length > 1 ) {
638- paramsSchema = rest . shift ( ) as ZodRawShape ;
680+ // We have at least two more args before the callback
681+ const firstArg = rest [ 0 ] ;
682+
683+ if ( isZodRawShape ( firstArg ) ) {
684+ // We have a params schema as the first arg
685+ paramsSchema = rest . shift ( ) as ZodRawShape ;
686+
687+ // Check if the next arg is potentially annotations
688+ if ( rest . length > 1 && typeof rest [ 0 ] === "object" && rest [ 0 ] !== null && ! ( isZodRawShape ( rest [ 0 ] ) ) ) {
689+ // Case: tool(name, paramsSchema, annotations, cb)
690+ // Or: tool(name, description, paramsSchema, annotations, cb)
691+ annotations = rest . shift ( ) as ToolAnnotations ;
692+ }
693+ } else if ( typeof firstArg === "object" && firstArg !== null ) {
694+ // Not a ZodRawShape, so must be annotations in this position
695+ // Case: tool(name, annotations, cb)
696+ // Or: tool(name, description, annotations, cb)
697+ annotations = rest . shift ( ) as ToolAnnotations ;
698+ }
639699 }
640700
641701 const cb = rest [ 0 ] as ToolCallback < ZodRawShape | undefined > ;
642702 const registeredTool : RegisteredTool = {
643703 description,
644704 inputSchema :
645705 paramsSchema === undefined ? undefined : z . object ( paramsSchema ) ,
706+ annotations,
646707 callback : cb ,
647708 enabled : true ,
648709 disable : ( ) => registeredTool . update ( { enabled : false } ) ,
@@ -656,6 +717,7 @@ export class McpServer {
656717 if ( typeof updates . description !== "undefined" ) registeredTool . description = updates . description
657718 if ( typeof updates . paramsSchema !== "undefined" ) registeredTool . inputSchema = z . object ( updates . paramsSchema )
658719 if ( typeof updates . callback !== "undefined" ) registeredTool . callback = updates . callback
720+ if ( typeof updates . annotations !== "undefined" ) registeredTool . annotations = updates . annotations
659721 if ( typeof updates . enabled !== "undefined" ) registeredTool . enabled = updates . enabled
660722 this . sendToolListChanged ( )
661723 } ,
@@ -853,11 +915,12 @@ export type ToolCallback<Args extends undefined | ZodRawShape = undefined> =
853915export type RegisteredTool = {
854916 description ?: string ;
855917 inputSchema ?: AnyZodObject ;
918+ annotations ?: ToolAnnotations ;
856919 callback : ToolCallback < undefined | ZodRawShape > ;
857920 enabled : boolean ;
858921 enable ( ) : void ;
859922 disable ( ) : void ;
860- update < Args extends ZodRawShape > ( updates : { name ?: string | null , description ?: string , paramsSchema ?: Args , callback ?: ToolCallback < Args > , enabled ?: boolean } ) : void
923+ update < Args extends ZodRawShape > ( updates : { name ?: string | null , description ?: string , paramsSchema ?: Args , callback ?: ToolCallback < Args > , annotations ?: ToolAnnotations , enabled ?: boolean } ) : void
861924 remove ( ) : void
862925} ;
863926
0 commit comments