Skip to main content
Glama

Filesystem MCP Server

by mark3labs
package handler import ( "context" "fmt" "io" "os" "path/filepath" "github.com/mark3labs/mcp-go/mcp" ) func (fs *FilesystemHandler) HandleCopyFile( ctx context.Context, request mcp.CallToolRequest, ) (*mcp.CallToolResult, error) { source, err := request.RequireString("source") if err != nil { return nil, err } destination, err := request.RequireString("destination") if err != nil { return nil, err } // Handle empty or relative paths for source if source == "." || source == "./" { 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 } source = cwd } if destination == "." || destination == "./" { 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 } destination = cwd } validSource, err := fs.validatePath(source) if err != nil { return &mcp.CallToolResult{ Content: []mcp.Content{ mcp.TextContent{ Type: "text", Text: fmt.Sprintf("Error with source path: %v", err), }, }, IsError: true, }, nil } // Check if source exists srcInfo, err := os.Stat(validSource) if os.IsNotExist(err) { return &mcp.CallToolResult{ Content: []mcp.Content{ mcp.TextContent{ Type: "text", Text: fmt.Sprintf("Error: Source does not exist: %s", source), }, }, IsError: true, }, nil } else if err != nil { return &mcp.CallToolResult{ Content: []mcp.Content{ mcp.TextContent{ Type: "text", Text: fmt.Sprintf("Error accessing source: %v", err), }, }, IsError: true, }, nil } validDest, err := fs.validatePath(destination) if err != nil { return &mcp.CallToolResult{ Content: []mcp.Content{ mcp.TextContent{ Type: "text", Text: fmt.Sprintf("Error with destination path: %v", err), }, }, IsError: true, }, nil } // Create parent directory for destination if it doesn't exist destDir := filepath.Dir(validDest) if err := os.MkdirAll(destDir, 0755); err != nil { return &mcp.CallToolResult{ Content: []mcp.Content{ mcp.TextContent{ Type: "text", Text: fmt.Sprintf("Error creating destination directory: %v", err), }, }, IsError: true, }, nil } // Perform the copy operation based on whether source is a file or directory if srcInfo.IsDir() { // It's a directory, copy recursively if err := copyDir(validSource, validDest); err != nil { return &mcp.CallToolResult{ Content: []mcp.Content{ mcp.TextContent{ Type: "text", Text: fmt.Sprintf("Error copying directory: %v", err), }, }, IsError: true, }, nil } } else { // It's a file, copy directly if err := copyFile(validSource, validDest); err != nil { return &mcp.CallToolResult{ Content: []mcp.Content{ mcp.TextContent{ Type: "text", Text: fmt.Sprintf("Error copying file: %v", err), }, }, IsError: true, }, nil } } resourceURI := pathToResourceURI(validDest) return &mcp.CallToolResult{ Content: []mcp.Content{ mcp.TextContent{ Type: "text", Text: fmt.Sprintf( "Successfully copied %s to %s", source, destination, ), }, mcp.EmbeddedResource{ Type: "resource", Resource: mcp.TextResourceContents{ URI: resourceURI, MIMEType: "text/plain", Text: fmt.Sprintf("Copied file: %s", validDest), }, }, }, }, nil } // copyFile copies a single file from src to dst func copyFile(src, dst string) error { // Open the source file sourceFile, err := os.Open(src) if err != nil { return err } defer sourceFile.Close() // Create the destination file destFile, err := os.Create(dst) if err != nil { return err } defer destFile.Close() // Copy the contents if _, err := io.Copy(destFile, sourceFile); err != nil { return err } // Get source file mode sourceInfo, err := os.Stat(src) if err != nil { return err } // Set the same file mode on destination return os.Chmod(dst, sourceInfo.Mode()) } // copyDir recursively copies a directory tree from src to dst func copyDir(src, dst string) error { // Get properties of source dir srcInfo, err := os.Stat(src) if err != nil { return err } // Create the destination directory with the same permissions if err = os.MkdirAll(dst, srcInfo.Mode()); err != nil { return err } // Read directory entries entries, err := os.ReadDir(src) if err != nil { return err } for _, entry := range entries { srcPath := filepath.Join(src, entry.Name()) dstPath := filepath.Join(dst, entry.Name()) // Handle symlinks if entry.Type()&os.ModeSymlink != 0 { // For simplicity, we'll skip symlinks in this implementation continue } // Recursively copy subdirectories or copy files if entry.IsDir() { if err = copyDir(srcPath, dstPath); err != nil { return err } } else { if err = copyFile(srcPath, dstPath); err != nil { return err } } } return 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