Skip to main content
Glama

Filesystem MCP Server

by mark3labs
package handler import ( "context" "encoding/base64" "fmt" "os" "path/filepath" "strings" "github.com/mark3labs/mcp-go/mcp" ) // HandleReadResource handles the MCP resource reading functionality func (fs *FilesystemHandler) HandleReadResource( ctx context.Context, request mcp.ReadResourceRequest, ) ([]mcp.ResourceContents, error) { uri := request.Params.URI // Check if it's a file:// URI if !strings.HasPrefix(uri, "file://") { return nil, fmt.Errorf("unsupported URI scheme: %s", uri) } // Extract the path from the URI path := strings.TrimPrefix(uri, "file://") // Validate the path validPath, err := fs.validatePath(path) if err != nil { return nil, err } // Get file info fileInfo, err := os.Stat(validPath) if err != nil { return nil, err } // If it's a directory, return a listing if fileInfo.IsDir() { entries, err := os.ReadDir(validPath) if err != nil { return nil, err } var result strings.Builder result.WriteString(fmt.Sprintf("Directory listing for: %s\n\n", validPath)) for _, entry := range entries { entryPath := filepath.Join(validPath, entry.Name()) entryURI := pathToResourceURI(entryPath) if entry.IsDir() { result.WriteString(fmt.Sprintf("[DIR] %s (%s)\n", entry.Name(), entryURI)) } else { info, err := entry.Info() if err == nil { result.WriteString(fmt.Sprintf("[FILE] %s (%s) - %d bytes\n", entry.Name(), entryURI, info.Size())) } else { result.WriteString(fmt.Sprintf("[FILE] %s (%s)\n", entry.Name(), entryURI)) } } } return []mcp.ResourceContents{ mcp.TextResourceContents{ URI: uri, MIMEType: "text/plain", Text: result.String(), }, }, nil } // It's a file, determine how to handle it mimeType := detectMimeType(validPath) // Check file size if fileInfo.Size() > MAX_INLINE_SIZE { // File is too large to inline, return a reference instead return []mcp.ResourceContents{ mcp.TextResourceContents{ URI: uri, MIMEType: "text/plain", Text: fmt.Sprintf("File is too large to display inline (%d bytes). Use the read_file tool to access specific portions.", fileInfo.Size()), }, }, nil } // Read the file content content, err := os.ReadFile(validPath) if err != nil { return nil, err } // Handle based on content type if isTextFile(mimeType) { // It's a text file, return as text return []mcp.ResourceContents{ mcp.TextResourceContents{ URI: uri, MIMEType: mimeType, Text: string(content), }, }, nil } else { // It's a binary file if fileInfo.Size() <= MAX_BASE64_SIZE { // Small enough for base64 encoding return []mcp.ResourceContents{ mcp.BlobResourceContents{ URI: uri, MIMEType: mimeType, Blob: base64.StdEncoding.EncodeToString(content), }, }, nil } else { // Too large for base64, return a reference return []mcp.ResourceContents{ mcp.TextResourceContents{ URI: uri, MIMEType: "text/plain", Text: fmt.Sprintf("Binary file (%s, %d bytes). Use the read_file tool to access specific portions.", mimeType, fileInfo.Size()), }, }, nil } } }

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