@@ -176,22 +176,18 @@ const readTextFileHandler = async (args: z.infer<typeof ReadTextFileArgsSchema>)
176176 throw new Error ( "Cannot specify both head and tail parameters simultaneously" ) ;
177177 }
178178
179+ let content : string ;
179180 if ( args . tail ) {
180- const tailContent = await tailFile ( validPath , args . tail ) ;
181- return {
182- content : [ { type : "text" as const , text : tailContent } ] ,
183- } ;
181+ content = await tailFile ( validPath , args . tail ) ;
182+ } else if ( args . head ) {
183+ content = await headFile ( validPath , args . head ) ;
184+ } else {
185+ content = await readFileContent ( validPath ) ;
184186 }
185187
186- if ( args . head ) {
187- const headContent = await headFile ( validPath , args . head ) ;
188- return {
189- content : [ { type : "text" as const , text : headContent } ] ,
190- } ;
191- }
192- const content = await readFileContent ( validPath ) ;
193188 return {
194189 content : [ { type : "text" as const , text : content } ] ,
190+ structuredContent : { content }
195191 } ;
196192} ;
197193
@@ -201,12 +197,7 @@ server.registerTool(
201197 title : "Read File (Deprecated)" ,
202198 description : "Read the complete contents of a file as text. DEPRECATED: Use read_text_file instead." ,
203199 inputSchema : ReadTextFileArgsSchema . shape ,
204- outputSchema : {
205- content : z . array ( z . object ( {
206- type : z . literal ( "text" ) ,
207- text : z . string ( )
208- } ) )
209- }
200+ outputSchema : { content : z . string ( ) }
210201 } ,
211202 readTextFileHandler
212203) ;
@@ -228,12 +219,7 @@ server.registerTool(
228219 tail : z . number ( ) . optional ( ) . describe ( "If provided, returns only the last N lines of the file" ) ,
229220 head : z . number ( ) . optional ( ) . describe ( "If provided, returns only the first N lines of the file" )
230221 } ,
231- outputSchema : {
232- content : z . array ( z . object ( {
233- type : z . literal ( "text" ) ,
234- text : z . string ( )
235- } ) )
236- }
222+ outputSchema : { content : z . string ( ) }
237223 } ,
238224 readTextFileHandler
239225) ;
@@ -281,8 +267,10 @@ server.registerTool(
281267 ? "audio"
282268 // Fallback for other binary types, not officially supported by the spec but has been used for some time
283269 : "blob" ;
270+ const contentItem = { type : type as 'image' | 'audio' | 'blob' , data, mimeType } ;
284271 return {
285- content : [ { type, data, mimeType } ] ,
272+ content : [ contentItem ] ,
273+ structuredContent : { content : [ contentItem ] }
286274 } as unknown as CallToolResult ;
287275 }
288276) ;
@@ -302,12 +290,7 @@ server.registerTool(
302290 . min ( 1 )
303291 . describe ( "Array of file paths to read. Each path must be a string pointing to a valid file within allowed directories." )
304292 } ,
305- outputSchema : {
306- content : z . array ( z . object ( {
307- type : z . literal ( "text" ) ,
308- text : z . string ( )
309- } ) )
310- }
293+ outputSchema : { content : z . string ( ) }
311294 } ,
312295 async ( args : z . infer < typeof ReadMultipleFilesArgsSchema > ) => {
313296 const results = await Promise . all (
@@ -322,8 +305,10 @@ server.registerTool(
322305 }
323306 } ) ,
324307 ) ;
308+ const text = results . join ( "\n---\n" ) ;
325309 return {
326- content : [ { type : "text" as const , text : results . join ( "\n---\n" ) } ] ,
310+ content : [ { type : "text" as const , text } ] ,
311+ structuredContent : { content : text }
327312 } ;
328313 }
329314) ;
@@ -340,18 +325,15 @@ server.registerTool(
340325 path : z . string ( ) ,
341326 content : z . string ( )
342327 } ,
343- outputSchema : {
344- content : z . array ( z . object ( {
345- type : z . literal ( "text" ) ,
346- text : z . string ( )
347- } ) )
348- }
328+ outputSchema : { content : z . string ( ) }
349329 } ,
350330 async ( args : z . infer < typeof WriteFileArgsSchema > ) => {
351331 const validPath = await validatePath ( args . path ) ;
352332 await writeFileContent ( validPath , args . content ) ;
333+ const text = `Successfully wrote to ${ args . path } ` ;
353334 return {
354- content : [ { type : "text" as const , text : `Successfully wrote to ${ args . path } ` } ] ,
335+ content : [ { type : "text" as const , text } ] ,
336+ structuredContent : { content : text }
355337 } ;
356338 }
357339) ;
@@ -372,18 +354,14 @@ server.registerTool(
372354 } ) ) ,
373355 dryRun : z . boolean ( ) . default ( false ) . describe ( "Preview changes using git-style diff format" )
374356 } ,
375- outputSchema : {
376- content : z . array ( z . object ( {
377- type : z . literal ( "text" ) ,
378- text : z . string ( )
379- } ) )
380- }
357+ outputSchema : { content : z . string ( ) }
381358 } ,
382359 async ( args : z . infer < typeof EditFileArgsSchema > ) => {
383360 const validPath = await validatePath ( args . path ) ;
384361 const result = await applyFileEdits ( validPath , args . edits , args . dryRun ) ;
385362 return {
386363 content : [ { type : "text" as const , text : result } ] ,
364+ structuredContent : { content : result }
387365 } ;
388366 }
389367) ;
@@ -400,18 +378,15 @@ server.registerTool(
400378 inputSchema : {
401379 path : z . string ( )
402380 } ,
403- outputSchema : {
404- content : z . array ( z . object ( {
405- type : z . literal ( "text" ) ,
406- text : z . string ( )
407- } ) )
408- }
381+ outputSchema : { content : z . string ( ) }
409382 } ,
410383 async ( args : z . infer < typeof CreateDirectoryArgsSchema > ) => {
411384 const validPath = await validatePath ( args . path ) ;
412385 await fs . mkdir ( validPath , { recursive : true } ) ;
386+ const text = `Successfully created directory ${ args . path } ` ;
413387 return {
414- content : [ { type : "text" as const , text : `Successfully created directory ${ args . path } ` } ] ,
388+ content : [ { type : "text" as const , text } ] ,
389+ structuredContent : { content : text }
415390 } ;
416391 }
417392) ;
@@ -428,12 +403,7 @@ server.registerTool(
428403 inputSchema : {
429404 path : z . string ( )
430405 } ,
431- outputSchema : {
432- content : z . array ( z . object ( {
433- type : z . literal ( "text" ) ,
434- text : z . string ( )
435- } ) )
436- }
406+ outputSchema : { content : z . string ( ) }
437407 } ,
438408 async ( args : z . infer < typeof ListDirectoryArgsSchema > ) => {
439409 const validPath = await validatePath ( args . path ) ;
@@ -443,6 +413,7 @@ server.registerTool(
443413 . join ( "\n" ) ;
444414 return {
445415 content : [ { type : "text" as const , text : formatted } ] ,
416+ structuredContent : { content : formatted }
446417 } ;
447418 }
448419) ;
@@ -460,12 +431,7 @@ server.registerTool(
460431 path : z . string ( ) ,
461432 sortBy : z . enum ( [ "name" , "size" ] ) . optional ( ) . default ( "name" ) . describe ( "Sort entries by name or size" )
462433 } ,
463- outputSchema : {
464- content : z . array ( z . object ( {
465- type : z . literal ( "text" ) ,
466- text : z . string ( )
467- } ) )
468- }
434+ outputSchema : { content : z . string ( ) }
469435 } ,
470436 async ( args : z . infer < typeof ListDirectoryWithSizesArgsSchema > ) => {
471437 const validPath = await validatePath ( args . path ) ;
@@ -521,11 +487,11 @@ server.registerTool(
521487 `Combined size: ${ formatSize ( totalSize ) } `
522488 ] ;
523489
490+ const text = [ ...formattedEntries , ...summary ] . join ( "\n" ) ;
491+ const contentBlock = { type : "text" as const , text } ;
524492 return {
525- content : [ {
526- type : "text" as const ,
527- text : [ ...formattedEntries , ...summary ] . join ( "\n" )
528- } ] ,
493+ content : [ contentBlock ] ,
494+ structuredContent : { content : [ contentBlock ] }
529495 } ;
530496 }
531497) ;
@@ -543,12 +509,7 @@ server.registerTool(
543509 path : z . string ( ) ,
544510 excludePatterns : z . array ( z . string ( ) ) . optional ( ) . default ( [ ] )
545511 } ,
546- outputSchema : {
547- content : z . array ( z . object ( {
548- type : z . literal ( "text" ) ,
549- text : z . string ( )
550- } ) )
551- }
512+ outputSchema : { content : z . string ( ) }
552513 } ,
553514 async ( args : z . infer < typeof DirectoryTreeArgsSchema > ) => {
554515 interface TreeEntry {
@@ -595,11 +556,11 @@ server.registerTool(
595556 }
596557
597558 const treeData = await buildTree ( rootPath , args . excludePatterns ) ;
559+ const text = JSON . stringify ( treeData , null , 2 ) ;
560+ const contentBlock = { type : "text " as const , text } ;
598561 return {
599- content : [ {
600- type : "text" as const ,
601- text : JSON . stringify ( treeData , null , 2 )
602- } ] ,
562+ content : [ contentBlock ] ,
563+ structuredContent : { content : [ contentBlock ] }
603564 } ;
604565 }
605566) ;
@@ -617,19 +578,17 @@ server.registerTool(
617578 source : z . string ( ) ,
618579 destination : z . string ( )
619580 } ,
620- outputSchema : {
621- content : z . array ( z . object ( {
622- type : z . literal ( "text" ) ,
623- text : z . string ( )
624- } ) )
625- }
581+ outputSchema : { content : z . string ( ) }
626582 } ,
627583 async ( args : z . infer < typeof MoveFileArgsSchema > ) => {
628584 const validSourcePath = await validatePath ( args . source ) ;
629585 const validDestPath = await validatePath ( args . destination ) ;
630586 await fs . rename ( validSourcePath , validDestPath ) ;
587+ const text = `Successfully moved ${ args . source } to ${ args . destination } ` ;
588+ const contentBlock = { type : "text" as const , text } ;
631589 return {
632- content : [ { type : "text" as const , text : `Successfully moved ${ args . source } to ${ args . destination } ` } ] ,
590+ content : [ contentBlock ] ,
591+ structuredContent : { content : [ contentBlock ] }
633592 } ;
634593 }
635594) ;
@@ -649,18 +608,15 @@ server.registerTool(
649608 pattern : z . string ( ) ,
650609 excludePatterns : z . array ( z . string ( ) ) . optional ( ) . default ( [ ] )
651610 } ,
652- outputSchema : {
653- content : z . array ( z . object ( {
654- type : z . literal ( "text" ) ,
655- text : z . string ( )
656- } ) )
657- }
611+ outputSchema : { content : z . string ( ) }
658612 } ,
659613 async ( args : z . infer < typeof SearchFilesArgsSchema > ) => {
660614 const validPath = await validatePath ( args . path ) ;
661615 const results = await searchFilesWithValidation ( validPath , args . pattern , allowedDirectories , { excludePatterns : args . excludePatterns } ) ;
616+ const text = results . length > 0 ? results . join ( "\n" ) : "No matches found" ;
662617 return {
663- content : [ { type : "text" as const , text : results . length > 0 ? results . join ( "\n" ) : "No matches found" } ] ,
618+ content : [ { type : "text" as const , text } ] ,
619+ structuredContent : { content : text }
664620 } ;
665621 }
666622) ;
@@ -677,20 +633,17 @@ server.registerTool(
677633 inputSchema : {
678634 path : z . string ( )
679635 } ,
680- outputSchema : {
681- content : z . array ( z . object ( {
682- type : z . literal ( "text" ) ,
683- text : z . string ( )
684- } ) )
685- }
636+ outputSchema : { content : z . string ( ) }
686637 } ,
687638 async ( args : z . infer < typeof GetFileInfoArgsSchema > ) => {
688639 const validPath = await validatePath ( args . path ) ;
689640 const info = await getFileStats ( validPath ) ;
641+ const text = Object . entries ( info )
642+ . map ( ( [ key , value ] ) => `${ key } : ${ value } ` )
643+ . join ( "\n" ) ;
690644 return {
691- content : [ { type : "text" as const , text : Object . entries ( info )
692- . map ( ( [ key , value ] ) => `${ key } : ${ value } ` )
693- . join ( "\n" ) } ] ,
645+ content : [ { type : "text" as const , text } ] ,
646+ structuredContent : { content : text }
694647 } ;
695648 }
696649) ;
@@ -705,19 +658,13 @@ server.registerTool(
705658 "Use this to understand which directories and their nested paths are available " +
706659 "before trying to access files." ,
707660 inputSchema : { } ,
708- outputSchema : {
709- content : z . array ( z . object ( {
710- type : z . literal ( "text" ) ,
711- text : z . string ( )
712- } ) )
713- }
661+ outputSchema : { content : z . string ( ) }
714662 } ,
715663 async ( ) => {
664+ const text = `Allowed directories:\n${ allowedDirectories . join ( '\n' ) } ` ;
716665 return {
717- content : [ {
718- type : "text" as const ,
719- text : `Allowed directories:\n${ allowedDirectories . join ( '\n' ) } `
720- } ] ,
666+ content : [ { type : "text" as const , text } ] ,
667+ structuredContent : { content : text }
721668 } ;
722669 }
723670) ;
0 commit comments