@@ -7,12 +7,12 @@ import (
77 "fmt"
88 "log"
99 "mime"
10- "net/http"
1110 "os"
1211 "path/filepath"
1312 "strings"
1413 "time"
1514
15+ "github.com/gabriel-vasile/mimetype"
1616 "github.com/mark3labs/mcp-go/mcp"
1717 "github.com/mark3labs/mcp-go/server"
1818)
@@ -392,47 +392,77 @@ func (s *FilesystemServer) searchFiles(
392392
393393// detectMimeType tries to determine the MIME type of a file
394394func detectMimeType (path string ) string {
395- // First try by extension
396- ext := filepath .Ext (path )
397- if ext != "" {
398- mimeType := mime .TypeByExtension (ext )
399- if mimeType != "" {
400- return mimeType
401- }
402- }
403-
404- // If that fails, try to read a bit of the file
405- file , err := os .Open (path )
406- if err != nil {
407- return "application/octet-stream" // Default
408- }
409- defer file .Close ()
410-
411- // Read first 512 bytes to detect content type
412- buffer := make ([]byte , 512 )
413- n , err := file .Read (buffer )
395+ // Use mimetype library for more accurate detection
396+ mtype , err := mimetype .DetectFile (path )
414397 if err != nil {
398+ // Fallback to extension-based detection if file can't be read
399+ ext := filepath .Ext (path )
400+ if ext != "" {
401+ mimeType := mime .TypeByExtension (ext )
402+ if mimeType != "" {
403+ return mimeType
404+ }
405+ }
415406 return "application/octet-stream" // Default
416407 }
417-
418- // Use http.DetectContentType
419- return http .DetectContentType (buffer [:n ])
408+
409+ return mtype .String ()
420410}
421411
422412// isTextFile determines if a file is likely a text file based on MIME type
423413func isTextFile (mimeType string ) bool {
424- return strings .HasPrefix (mimeType , "text/" ) ||
425- mimeType == "application/json" ||
426- mimeType == "application/xml" ||
427- mimeType == "application/javascript" ||
428- mimeType == "application/x-javascript" ||
429- strings .Contains (mimeType , "+xml" ) ||
430- strings .Contains (mimeType , "+json" )
414+ // Check for common text MIME types
415+ if strings .HasPrefix (mimeType , "text/" ) {
416+ return true
417+ }
418+
419+ // Common application types that are text-based
420+ textApplicationTypes := []string {
421+ "application/json" ,
422+ "application/xml" ,
423+ "application/javascript" ,
424+ "application/x-javascript" ,
425+ "application/typescript" ,
426+ "application/x-typescript" ,
427+ "application/x-yaml" ,
428+ "application/yaml" ,
429+ "application/toml" ,
430+ "application/x-sh" ,
431+ "application/x-shellscript" ,
432+ }
433+
434+ for _ , textType := range textApplicationTypes {
435+ if mimeType == textType {
436+ return true
437+ }
438+ }
439+
440+ // Check for +format types
441+ if strings .Contains (mimeType , "+xml" ) ||
442+ strings .Contains (mimeType , "+json" ) ||
443+ strings .Contains (mimeType , "+yaml" ) {
444+ return true
445+ }
446+
447+ // Common code file types that might be misidentified
448+ if strings .HasPrefix (mimeType , "text/x-" ) {
449+ return true
450+ }
451+
452+ if strings .HasPrefix (mimeType , "application/x-" ) &&
453+ (strings .Contains (mimeType , "script" ) ||
454+ strings .Contains (mimeType , "source" ) ||
455+ strings .Contains (mimeType , "code" )) {
456+ return true
457+ }
458+
459+ return false
431460}
432461
433462// isImageFile determines if a file is an image based on MIME type
434463func isImageFile (mimeType string ) bool {
435- return strings .HasPrefix (mimeType , "image/" )
464+ return strings .HasPrefix (mimeType , "image/" ) ||
465+ (mimeType == "application/xml" && strings .HasSuffix (strings .ToLower (mimeType ), ".svg" ))
436466}
437467
438468// pathToResourceURI converts a file path to a resource URI
@@ -674,7 +704,7 @@ func (s *FilesystemServer) handleReadFile(
674704 }, nil
675705 }
676706
677- // Handle based on content type
707+ // Check if it's a text file
678708 if isTextFile (mimeType ) {
679709 // It's a text file, return as text
680710 return & mcp.CallToolResult {
0 commit comments