22// Licensed under the MIT License.
33
44import { McpToolProperty , McpToolTriggerOptions , McpToolTriggerOptionsToRpc } from '../../types' ;
5+ import { normalizeToolProperties } from '../utils/toolProperties' ;
56
67// Copyright (c) .NET Foundation. All rights reserved.
78// Licensed under the MIT License.
@@ -21,129 +22,33 @@ export function converToMcpToolTriggerOptionsToRpc(
2122 description : mcpToolTriggerOptions . description ,
2223 } ;
2324
24- // Check for null or undefined toolProperties
25- if ( ! mcpToolTriggerOptions ?. toolProperties ) {
26- return {
27- ...baseResult ,
28- toolProperties : JSON . stringify ( [ ] ) , // Default to an empty array
29- } ;
30- }
31-
32- // Check if toolProperties is an array of McpToolProperty objects
33- if ( Array . isArray ( mcpToolTriggerOptions . toolProperties ) ) {
34- const isValid = mcpToolTriggerOptions . toolProperties . every ( isMcpToolProperty ) ;
35- if ( isValid ) {
36- return {
37- ...baseResult ,
38- toolProperties : JSON . stringify ( mcpToolTriggerOptions . toolProperties ) ,
39- } ;
40- } else {
41- throw new Error (
42- 'Invalid toolProperties: Array contains invalid McpToolProperty, please validate the parameters.'
43- ) ;
25+ // Try to normalize tool properties first (handles both array and fluent formats)
26+ let normalizedProperties : McpToolProperty [ ] | undefined ;
27+ try {
28+ // eslint-disable-next-line @typescript-eslint/no-unsafe-argument
29+ normalizedProperties = normalizeToolProperties ( mcpToolTriggerOptions . toolProperties ) ;
30+ } catch ( error ) {
31+ // Re-throw validation errors from normalizeToolProperties
32+ if (
33+ error instanceof Error &&
34+ ( error . message . includes ( 'Property type is required' ) ||
35+ error . message . includes ( 'Property type must be specified' ) )
36+ ) {
37+ throw error ;
4438 }
39+ normalizedProperties = undefined ;
4540 }
4641
47- // Handle cases where toolProperties is an object (e.g., Zod schema)
48- if ( typeof mcpToolTriggerOptions . toolProperties === 'object' ) {
49- // Define the type of the ZodObject shape and ZodPropertyDef
50- type ZodPropertyDef = {
51- description ?: string ;
52- typeName : string ;
53- } ;
54- type ZodObjectShape = Record < string , { _def : ZodPropertyDef } > ;
55-
56- // Define the type of the toolProperties object
57- type ToolProperties =
58- | {
59- _def ?: {
60- typeName ?: string ;
61- } ;
62- shape ?: ZodObjectShape ;
63- }
64- | Record < string , unknown > ;
65-
66- let isZodObject = false ;
67-
68- const toolProperties = mcpToolTriggerOptions . toolProperties as ToolProperties ;
69-
70- // Check if the object is a ZodObject
71- if ( ( toolProperties ?. _def as { typeName ?: string } ) ?. typeName === 'ZodObject' ) {
72- isZodObject = true ;
73- }
74-
75- // Check if shape is a valid ZodObject shape
76- const shape : ZodObjectShape | Record < string , unknown > = isZodObject
77- ? ( toolProperties as { shape : ZodObjectShape } ) . shape
78- : toolProperties ;
79-
80- // Extract properties from the ZodObject shape
81- const result = Object . keys ( shape ) . map ( ( propertyName ) => {
82- const property = shape [ propertyName ] as { _def : ZodPropertyDef } ;
83- const description = property ?. _def ?. description || '' ;
84- const propertyType = getPropertyType ( property ?. _def ?. typeName ?. toLowerCase ( ) || 'unknown' ) ; // Extract type name or default to "unknown"
85-
86- return {
87- propertyName,
88- propertyType,
89- description,
90- } ;
91- } ) ;
92-
42+ // If we successfully normalized the properties, use them
43+ if ( normalizedProperties !== undefined ) {
9344 return {
9445 ...baseResult ,
95- toolProperties : JSON . stringify ( result ) ,
46+ toolProperties : JSON . stringify ( normalizedProperties ) ,
9647 } ;
9748 }
98- // Handle cases where toolProperties is not an array
99- throw new Error ( 'Invalid toolProperties: Expected an array of McpToolProperty objects or zod objects.' ) ;
100- }
101-
102- // Helper function to infer property type from zod schema
103- function getPropertyType ( zodType : string ) : string {
104- switch ( zodType ) {
105- case 'zodnumber' :
106- return 'number' ;
107- case 'zodstring' :
108- return 'string' ;
109- case 'zodboolean' :
110- return 'boolean' ;
111- case 'zodarray' :
112- return 'array' ;
113- case 'zodobject' :
114- return 'object' ;
115- case 'zodbigint' :
116- return 'long' ;
117- case 'zoddate' :
118- return 'DateTime' ;
119- case 'zodtuple' :
120- return 'Tuple' ;
121- default :
122- console . warn ( `Unknown zod type: ${ zodType } ` ) ;
123- return 'unknown' ;
124- }
125- }
12649
127- /**
128- * Type guard to check if a given object is of type McpToolProperty.
129- *
130- * @param property - The object to check.
131- * @returns True if the object is of type McpToolProperty, otherwise false.
132- *
133- * This function ensures that the object:
134- * - Is not null and is of type 'object'.
135- * - Contains the required properties: 'propertyName', 'propertyValue', and 'description'.
136- * - Each of these properties is of the correct type (string).
137- */
138- function isMcpToolProperty ( property : unknown ) : property is McpToolProperty {
139- return (
140- typeof property === 'object' &&
141- property !== null &&
142- 'propertyName' in property &&
143- 'propertyType' in property &&
144- 'description' in property &&
145- typeof ( property as McpToolProperty ) . propertyName === 'string' &&
146- typeof ( property as McpToolProperty ) . propertyType === 'string' &&
147- typeof ( property as McpToolProperty ) . description === 'string'
50+ // Handle cases where toolProperties is not an array
51+ throw new Error (
52+ `Invalid toolProperties for tool '${ mcpToolTriggerOptions . toolName } ': Expected an array of McpToolProperty or ToolProps objects or ToolProps need a type defined.`
14853 ) ;
14954}
0 commit comments