Skip to main content
Glama

Filesystem MCP Server

by mark3labs
package handler import ( "context" "fmt" "os" "path/filepath" "strings" "github.com/gobwas/glob" "github.com/mark3labs/mcp-go/mcp" ) func (fs *FilesystemHandler) HandleSearchFiles( ctx context.Context, request mcp.CallToolRequest, ) (*mcp.CallToolResult, error) { path, err := request.RequireString("path") if err != nil { return nil, err } pattern, err := request.RequireString("pattern") if err != nil { return nil, err } // Handle empty or relative paths like "." or "./" by converting to absolute path if path == "." || path == "./" { // Get current working directory cwd, err := os.Getwd() if err != nil { return &mcp.CallToolResult{ Content: []mcp.Content{ mcp.TextContent{ Type: "text", Text: fmt.Sprintf("Error resolving current directory: %v", err), }, }, IsError: true, }, nil } path = cwd } validPath, err := fs.validatePath(path) if err != nil { return &mcp.CallToolResult{ Content: []mcp.Content{ mcp.TextContent{ Type: "text", Text: fmt.Sprintf("Error: %v", err), }, }, IsError: true, }, nil } // Check if it's a directory info, err := os.Stat(validPath) if err != nil { return &mcp.CallToolResult{ Content: []mcp.Content{ mcp.TextContent{ Type: "text", Text: fmt.Sprintf("Error: %v", err), }, }, IsError: true, }, nil } if !info.IsDir() { return &mcp.CallToolResult{ Content: []mcp.Content{ mcp.TextContent{ Type: "text", Text: "Error: Search path must be a directory", }, }, IsError: true, }, nil } results, err := searchFiles(validPath, pattern, fs) if err != nil { return &mcp.CallToolResult{ Content: []mcp.Content{ mcp.TextContent{ Type: "text", Text: fmt.Sprintf("Error searching files: %v", err), }, }, IsError: true, }, nil } if len(results) == 0 { return &mcp.CallToolResult{ Content: []mcp.Content{ mcp.TextContent{ Type: "text", Text: fmt.Sprintf("No files found matching pattern '%s' in %s", pattern, path), }, }, }, nil } // Format results with resource URIs var formattedResults strings.Builder formattedResults.WriteString(fmt.Sprintf("Found %d results:\n\n", len(results))) for _, result := range results { resourceURI := pathToResourceURI(result) info, err := os.Stat(result) if err == nil { if info.IsDir() { formattedResults.WriteString(fmt.Sprintf("[DIR] %s (%s)\n", result, resourceURI)) } else { formattedResults.WriteString(fmt.Sprintf("[FILE] %s (%s) - %d bytes\n", result, resourceURI, info.Size())) } } else { formattedResults.WriteString(fmt.Sprintf("%s (%s)\n", result, resourceURI)) } } return &mcp.CallToolResult{ Content: []mcp.Content{ mcp.TextContent{ Type: "text", Text: formattedResults.String(), }, }, }, nil } func searchFiles(rootPath, pattern string, fs *FilesystemHandler) ([]string, error) { var results []string globPattern := glob.MustCompile(pattern) err := filepath.Walk( rootPath, func(path string, info os.FileInfo, err error) error { if err != nil { return nil // Skip errors and continue } // Try to validate path if _, err := fs.validatePath(path); err != nil { return nil // Skip invalid paths } if globPattern.Match(info.Name()) { results = append(results, path) } return nil }, ) if err != nil { return nil, err } return results, 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