Skip to main content
Glama

Filesystem MCP Server

by mark3labs
package handler import ( "fmt" "mime" "os" "path/filepath" "slices" "strings" "github.com/gabriel-vasile/mimetype" ) // isPathInAllowedDirs checks if a path is within any of the allowed directories func (fs *FilesystemHandler) isPathInAllowedDirs(path string) bool { // Ensure path is absolute and clean absPath, err := filepath.Abs(path) if err != nil { return false } // Add trailing separator to ensure we're checking a directory or a file within a directory // and not a prefix match (e.g., /tmp/foo should not match /tmp/foobar) if !strings.HasSuffix(absPath, string(filepath.Separator)) { // If it's a file, we need to check its directory if info, err := os.Stat(absPath); err == nil && !info.IsDir() { absPath = filepath.Dir(absPath) + string(filepath.Separator) } else { absPath = absPath + string(filepath.Separator) } } // Check if the path is within any of the allowed directories for _, dir := range fs.allowedDirs { if strings.HasPrefix(absPath, dir) { return true } } return false } func (fs *FilesystemHandler) validatePath(requestedPath string) (string, error) { // Always convert to absolute path first abs, err := filepath.Abs(requestedPath) if err != nil { return "", fmt.Errorf("invalid path: %w", err) } // Check if path is within allowed directories if !fs.isPathInAllowedDirs(abs) { return "", fmt.Errorf( "access denied - path outside allowed directories: %s", abs, ) } // Handle symlinks realPath, err := filepath.EvalSymlinks(abs) if err != nil { if !os.IsNotExist(err) { return "", err } // For new files, check parent directory parent := filepath.Dir(abs) realParent, err := filepath.EvalSymlinks(parent) if err != nil { return "", fmt.Errorf("parent directory does not exist: %s", parent) } if !fs.isPathInAllowedDirs(realParent) { return "", fmt.Errorf( "access denied - parent directory outside allowed directories", ) } return abs, nil } // Check if the real path (after resolving symlinks) is still within allowed directories if !fs.isPathInAllowedDirs(realPath) { return "", fmt.Errorf( "access denied - symlink target outside allowed directories", ) } return realPath, nil } // detectMimeType tries to determine the MIME type of a file func detectMimeType(path string) string { // Use mimetype library for more accurate detection mtype, err := mimetype.DetectFile(path) if err != nil { // Fallback to extension-based detection if file can't be read ext := filepath.Ext(path) if ext != "" { mimeType := mime.TypeByExtension(ext) if mimeType != "" { return mimeType } } return "application/octet-stream" // Default } return mtype.String() } // isTextFile determines if a file is likely a text file based on MIME type func isTextFile(mimeType string) bool { // Check for common text MIME types if strings.HasPrefix(mimeType, "text/") { return true } // Common application types that are text-based textApplicationTypes := []string{ "application/json", "application/xml", "application/javascript", "application/x-javascript", "application/typescript", "application/x-typescript", "application/x-yaml", "application/yaml", "application/toml", "application/x-sh", "application/x-shellscript", } if slices.Contains(textApplicationTypes, mimeType) { return true } // Check for +format types if strings.Contains(mimeType, "+xml") || strings.Contains(mimeType, "+json") || strings.Contains(mimeType, "+yaml") { return true } // Common code file types that might be misidentified if strings.HasPrefix(mimeType, "text/x-") { return true } if strings.HasPrefix(mimeType, "application/x-") && (strings.Contains(mimeType, "script") || strings.Contains(mimeType, "source") || strings.Contains(mimeType, "code")) { return true } return false } // isImageFile determines if a file is an image based on MIME type func isImageFile(mimeType string) bool { return strings.HasPrefix(mimeType, "image/") || (mimeType == "application/xml" && strings.HasSuffix(strings.ToLower(mimeType), ".svg")) }

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/mark3labs/mcp-filesystem-server'

If you have feedback or need assistance with the MCP directory API, please join our Discord server