@@ -265,4 +265,183 @@ describe("normalizeToolSchema", () => {
265265 expect ( props . line_ranges . items ) . toBeDefined ( )
266266 expect ( props . line_ranges . description ) . toBe ( "Optional line ranges" )
267267 } )
268+
269+ describe ( "format field handling" , ( ) => {
270+ it ( "should preserve supported format values (date-time)" , ( ) => {
271+ const input = {
272+ type : "string" ,
273+ format : "date-time" ,
274+ description : "Timestamp" ,
275+ }
276+
277+ const result = normalizeToolSchema ( input )
278+
279+ expect ( result ) . toEqual ( {
280+ type : "string" ,
281+ format : "date-time" ,
282+ description : "Timestamp" ,
283+ additionalProperties : false ,
284+ } )
285+ } )
286+
287+ it ( "should preserve supported format values (email)" , ( ) => {
288+ const input = {
289+ type : "string" ,
290+ format : "email" ,
291+ }
292+
293+ const result = normalizeToolSchema ( input )
294+
295+ expect ( result . format ) . toBe ( "email" )
296+ } )
297+
298+ it ( "should preserve supported format values (uuid)" , ( ) => {
299+ const input = {
300+ type : "string" ,
301+ format : "uuid" ,
302+ }
303+
304+ const result = normalizeToolSchema ( input )
305+
306+ expect ( result . format ) . toBe ( "uuid" )
307+ } )
308+
309+ it ( "should preserve all supported format values" , ( ) => {
310+ const supportedFormats = [
311+ "date-time" ,
312+ "time" ,
313+ "date" ,
314+ "duration" ,
315+ "email" ,
316+ "hostname" ,
317+ "ipv4" ,
318+ "ipv6" ,
319+ "uuid" ,
320+ ]
321+
322+ for ( const format of supportedFormats ) {
323+ const input = { type : "string" , format }
324+ const result = normalizeToolSchema ( input )
325+ expect ( result . format ) . toBe ( format )
326+ }
327+ } )
328+
329+ it ( "should strip unsupported format value (uri)" , ( ) => {
330+ const input = {
331+ type : "string" ,
332+ format : "uri" ,
333+ description : "URL field" ,
334+ }
335+
336+ const result = normalizeToolSchema ( input )
337+
338+ expect ( result ) . toEqual ( {
339+ type : "string" ,
340+ description : "URL field" ,
341+ additionalProperties : false ,
342+ } )
343+ expect ( result . format ) . toBeUndefined ( )
344+ } )
345+
346+ it ( "should strip unsupported format value (uri-reference)" , ( ) => {
347+ const input = {
348+ type : "string" ,
349+ format : "uri-reference" ,
350+ }
351+
352+ const result = normalizeToolSchema ( input )
353+
354+ expect ( result . format ) . toBeUndefined ( )
355+ } )
356+
357+ it ( "should strip unsupported format values (various)" , ( ) => {
358+ const unsupportedFormats = [ "uri" , "uri-reference" , "iri" , "iri-reference" , "regex" , "json-pointer" ]
359+
360+ for ( const format of unsupportedFormats ) {
361+ const input = { type : "string" , format }
362+ const result = normalizeToolSchema ( input )
363+ expect ( result . format ) . toBeUndefined ( )
364+ }
365+ } )
366+
367+ it ( "should strip unsupported format in nested properties" , ( ) => {
368+ const input = {
369+ type : "object" ,
370+ properties : {
371+ url : {
372+ type : "string" ,
373+ format : "uri" ,
374+ description : "A URL" ,
375+ } ,
376+ email : {
377+ type : "string" ,
378+ format : "email" ,
379+ description : "An email" ,
380+ } ,
381+ } ,
382+ }
383+
384+ const result = normalizeToolSchema ( input )
385+
386+ const props = result . properties as Record < string , Record < string , unknown > >
387+ expect ( props . url . format ) . toBeUndefined ( )
388+ expect ( props . url . description ) . toBe ( "A URL" )
389+ expect ( props . email . format ) . toBe ( "email" )
390+ expect ( props . email . description ) . toBe ( "An email" )
391+ } )
392+
393+ it ( "should strip unsupported format in deeply nested structures" , ( ) => {
394+ const input = {
395+ type : "object" ,
396+ properties : {
397+ items : {
398+ type : "array" ,
399+ items : {
400+ type : "object" ,
401+ properties : {
402+ link : {
403+ type : "string" ,
404+ format : "uri" ,
405+ } ,
406+ timestamp : {
407+ type : "string" ,
408+ format : "date-time" ,
409+ } ,
410+ } ,
411+ } ,
412+ } ,
413+ } ,
414+ }
415+
416+ const result = normalizeToolSchema ( input )
417+
418+ const props = result . properties as Record < string , Record < string , unknown > >
419+ const itemsItems = props . items . items as Record < string , unknown >
420+ const nestedProps = itemsItems . properties as Record < string , Record < string , unknown > >
421+ expect ( nestedProps . link . format ) . toBeUndefined ( )
422+ expect ( nestedProps . timestamp . format ) . toBe ( "date-time" )
423+ } )
424+
425+ it ( "should handle MCP fetch server schema with uri format" , ( ) => {
426+ // This is similar to the actual fetch MCP server schema that caused the error
427+ const input = {
428+ type : "object" ,
429+ properties : {
430+ url : {
431+ type : "string" ,
432+ format : "uri" ,
433+ description : "URL to fetch" ,
434+ } ,
435+ } ,
436+ required : [ "url" ] ,
437+ }
438+
439+ const result = normalizeToolSchema ( input )
440+
441+ const props = result . properties as Record < string , Record < string , unknown > >
442+ expect ( props . url . format ) . toBeUndefined ( )
443+ expect ( props . url . type ) . toBe ( "string" )
444+ expect ( props . url . description ) . toBe ( "URL to fetch" )
445+ } )
446+ } )
268447} )
0 commit comments