@@ -116,12 +116,16 @@ async function validatePath(requestedPath: string): Promise<string> {
116116}
117117
118118// Schema definitions
119- const ReadFileArgsSchema = z . object ( {
119+ const ReadTextFileArgsSchema = z . object ( {
120120 path : z . string ( ) ,
121121 tail : z . number ( ) . optional ( ) . describe ( 'If provided, returns only the last N lines of the file' ) ,
122122 head : z . number ( ) . optional ( ) . describe ( 'If provided, returns only the first N lines of the file' )
123123} ) ;
124124
125+ const ReadMediaFileArgsSchema = z . object ( {
126+ path : z . string ( )
127+ } ) ;
128+
125129const ReadMultipleFilesArgsSchema = z . object ( {
126130 paths : z . array ( z . string ( ) ) ,
127131} ) ;
@@ -476,15 +480,23 @@ server.setRequestHandler(ListToolsRequestSchema, async () => {
476480 return {
477481 tools : [
478482 {
479- name : "read_file " ,
483+ name : "read_text_file " ,
480484 description :
481- "Read the complete contents of a file from the file system. " +
485+ "Read the complete contents of a file from the file system as text . " +
482486 "Handles various text encodings and provides detailed error messages " +
483487 "if the file cannot be read. Use this tool when you need to examine " +
484488 "the contents of a single file. Use the 'head' parameter to read only " +
485489 "the first N lines of a file, or the 'tail' parameter to read only " +
486- "the last N lines of a file. Only works within allowed directories." ,
487- inputSchema : zodToJsonSchema ( ReadFileArgsSchema ) as ToolInput ,
490+ "the last N lines of a file. Operates on the file as text regardless of extension. " +
491+ "Only works within allowed directories." ,
492+ inputSchema : zodToJsonSchema ( ReadTextFileArgsSchema ) as ToolInput ,
493+ } ,
494+ {
495+ name : "read_media_file" ,
496+ description :
497+ "Read an image or audio file. Returns the base64 encoded data and MIME type. " +
498+ "Only works within allowed directories." ,
499+ inputSchema : zodToJsonSchema ( ReadMediaFileArgsSchema ) as ToolInput ,
488500 } ,
489501 {
490502 name : "read_multiple_files" ,
@@ -597,10 +609,10 @@ server.setRequestHandler(CallToolRequestSchema, async (request) => {
597609 const { name, arguments : args } = request . params ;
598610
599611 switch ( name ) {
600- case "read_file " : {
601- const parsed = ReadFileArgsSchema . safeParse ( args ) ;
612+ case "read_text_file " : {
613+ const parsed = ReadTextFileArgsSchema . safeParse ( args ) ;
602614 if ( ! parsed . success ) {
603- throw new Error ( `Invalid arguments for read_file : ${ parsed . error } ` ) ;
615+ throw new Error ( `Invalid arguments for read_text_file : ${ parsed . error } ` ) ;
604616 }
605617 const validPath = await validatePath ( parsed . data . path ) ;
606618
@@ -630,6 +642,38 @@ server.setRequestHandler(CallToolRequestSchema, async (request) => {
630642 } ;
631643 }
632644
645+ case "read_media_file" : {
646+ const parsed = ReadMediaFileArgsSchema . safeParse ( args ) ;
647+ if ( ! parsed . success ) {
648+ throw new Error ( `Invalid arguments for read_media_file: ${ parsed . error } ` ) ;
649+ }
650+ const validPath = await validatePath ( parsed . data . path ) ;
651+ const extension = path . extname ( validPath ) . toLowerCase ( ) ;
652+ const mimeTypes : Record < string , string > = {
653+ ".png" : "image/png" ,
654+ ".jpg" : "image/jpeg" ,
655+ ".jpeg" : "image/jpeg" ,
656+ ".gif" : "image/gif" ,
657+ ".webp" : "image/webp" ,
658+ ".bmp" : "image/bmp" ,
659+ ".svg" : "image/svg+xml" ,
660+ ".mp3" : "audio/mpeg" ,
661+ ".wav" : "audio/wav" ,
662+ ".ogg" : "audio/ogg" ,
663+ ".flac" : "audio/flac" ,
664+ } ;
665+ const mimeType = mimeTypes [ extension ] || "application/octet-stream" ;
666+ const data = ( await fs . readFile ( validPath ) ) . toString ( "base64" ) ;
667+ const type = mimeType . startsWith ( "image/" )
668+ ? "image"
669+ : mimeType . startsWith ( "audio/" )
670+ ? "audio"
671+ : "blob" ;
672+ return {
673+ content : [ { type, data, mimeType } as any ] ,
674+ } ;
675+ }
676+
633677 case "read_multiple_files" : {
634678 const parsed = ReadMultipleFilesArgsSchema . safeParse ( args ) ;
635679 if ( ! parsed . success ) {
0 commit comments