A Model Context Protocol (MCP) server that provides enhanced file operation capabilities with streaming, patching, and change tracking support.
- Basic File Operations: Copy, read, write, move, and delete files
- Directory Operations: Create, remove, and copy directories
- File Watching: Monitor files and directories for changes
- Change Tracking: Track and query file operation history
- Streaming Support: Handle large files efficiently with streaming
- HTTP Interface: Streamable HTTP interface with Server-Sent Events (SSE)
- Resource Support: Access files and directories through MCP resources
- Progress Reporting: Real-time progress updates for long operations
- Rate Limiting: Protection against excessive requests
- Enhanced Security: Path validation and input sanitization
- Robust Error Handling: Comprehensive error handling and reporting
- Type Safety: Full TypeScript support with strict type checking
- Docker Support: Containerized deployment with volume mounting
To install File Operations Server for Claude Desktop automatically via Smithery:
npx -y @smithery/cli install @bsmi021/mcp-file-operations-server --client claudenpm installSee DOCKER.md for comprehensive Docker setup instructions including local drive mounting for Windows and Linux.
Quick Docker Start:
# Stdio transport (for MCP clients)
docker run -it --rm -v "$(pwd):/workspace" ghcr.io/bsmi021/mcp-file-operations-server
# HTTP transport (for web/remote access)
docker run -it --rm -p 3001:3001 -v "$(pwd):/workspace" -e MCP_TRANSPORT=http ghcr.io/bsmi021/mcp-file-operations-serverThe server supports two transport modes:
For direct integration with MCP clients like Claude Desktop:
npm startFor remote connections and web applications:
npm run start:httpThe HTTP server provides:
- SSE Endpoint:
GET http://localhost:3001/sse- Establishes streaming connection - Messages Endpoint:
POST http://localhost:3001/messages- Receives client messages - Health Check:
GET http://localhost:3001/health- Server status - Sessions:
GET http://localhost:3001/sessions- Active connection info
# Stdio transport with auto-reload
npm run dev
# HTTP transport with auto-reload
npm run dev:http# Stdio transport
npm start
# HTTP transport
npm run start:http
# Custom port for HTTP
npm run start:http -- --port 8080copy_file: Copy a file to a new locationread_file: Read content from a filewrite_file: Write content to a filemove_file: Move/rename a filedelete_file: Delete a fileappend_file: Append content to a file
make_directory: Create a directoryremove_directory: Remove a directorycopy_directory: Copy a directory recursively (with progress reporting)
watch_directory: Start watching a directory for changesunwatch_directory: Stop watching a directory
get_changes: Get the list of recorded changesclear_changes: Clear all recorded changes
file:///recent-changes: List of recent file system changes
file://{path}: Access file contentsmetadata://{path}: Access file metadatadirectory://{path}: List directory contents
// Copy a file
await fileOperations.copyFile({
source: 'source.txt',
destination: 'destination.txt',
overwrite: false
});
// Watch a directory
await fileOperations.watchDirectory({
path: './watched-dir',
recursive: true
});
// Access file contents through resource
const resource = await mcp.readResource('file:///path/to/file.txt');
console.log(resource.contents[0].text);
// Copy directory with progress tracking
const result = await fileOperations.copyDirectory({
source: './source-dir',
destination: './dest-dir',
overwrite: false
});
// Progress token in result can be used to track progress
console.log(result.progressToken);Connecting via JavaScript:
// Establish SSE connection
const eventSource = new EventSource('http://localhost:3001/sse');
let sessionId = null;
eventSource.onopen = function() {
console.log('Connected to MCP server');
};
eventSource.onmessage = function(event) {
const message = JSON.parse(event.data);
// Extract session ID from first message
if (!sessionId && message.sessionId) {
sessionId = message.sessionId;
}
console.log('Received:', message);
};
// Send a message to the server
async function sendMessage(method, params) {
const message = {
jsonrpc: '2.0',
id: Date.now(),
method: method,
params: params
};
const response = await fetch('http://localhost:3001/messages', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'X-Session-ID': sessionId
},
body: JSON.stringify(message)
});
return response.json();
}
// Example: List tools
sendMessage('tools/list', {});
// Example: Read a file
sendMessage('tools/call', {
name: 'read_file',
arguments: { path: '/workspace/example.txt' }
});Using curl for testing:
# Start SSE connection in background
curl -N http://localhost:3001/sse &
# Check server health
curl http://localhost:3001/health
# List active sessions
curl http://localhost:3001/sessionsInteractive Web Client:
A complete interactive example is available at examples/http-client.html. Open this file in a web browser to test the HTTP interface with a user-friendly GUI.
- Streamable HTTP Interface: New HTTP transport with Server-Sent Events (SSE)
- Enhanced API: Upgraded to MCP SDK v1.5 with improved zod-based schemas
- Multiple Connections: Support for simultaneous HTTP connections with session management
- Better Type Safety: Improved TypeScript integration and error handling
- Large File Support: Efficient streaming for large file operations
- Real-time Progress: Progress updates via SSE for long-running operations
- Session Management: Multiple client connections with isolated sessions
- HTTP API: RESTful endpoints alongside traditional MCP protocol
# Build the image
docker build -t mcp-file-operations-server .
# Run with stdio (for MCP clients)
docker run -it --rm -v "$(pwd):/workspace" mcp-file-operations-server
# Run with HTTP interface
docker run -it --rm -p 3001:3001 -v "$(pwd):/workspace" -e MCP_TRANSPORT=http mcp-file-operations-serverWindows:
docker run -it --rm -v "C:\MyProject:/workspace" -p 3001:3001 -e MCP_TRANSPORT=http mcp-file-operations-serverLinux/macOS:
docker run -it --rm -v "/home/user/project:/workspace" -p 3001:3001 -e MCP_TRANSPORT=http mcp-file-operations-serverFor comprehensive Docker setup instructions including local drive mounting for Windows and Linux, see DOCKER.md.
The server implements rate limiting to prevent abuse:
- Tools: 100 requests per minute
- Resources: 200 requests per minute
- Watch Operations: 20 operations per minute
Rate limit errors include a retry-after period in the error message.
All file paths are validated to prevent directory traversal attacks:
- No parent directory references (
../) - Proper path normalization
- Input sanitization
- Rate limiting on all operations
- Proper error handling and logging
- Input validation on all parameters
- Safe resource cleanup
Long-running operations like directory copying provide progress updates:
interface ProgressUpdate {
token: string | number;
message: string;
percentage: number;
}Progress can be tracked through the progress token returned in the operation result.
npm run buildnpm run lintnpm run formatnpm test| Variable | Default | Description |
|---|---|---|
MCP_TRANSPORT |
stdio |
Transport mode: stdio or http |
MCP_HTTP_PORT |
3001 |
Port for HTTP transport |
- Stdio: Best for MCP clients like Claude Desktop, direct integration
- HTTP: Best for web applications, remote access, development/testing
The server can be configured through various settings:
- Rate Limiting: Configure request limits and windows
- Progress Reporting: Control update frequency and detail level
- Resource Access: Configure resource permissions and limits
- Security Settings: Configure path validation rules
- Change Tracking: Set retention periods and storage options
- Watch Settings: Configure debounce times and recursive watching
The server provides detailed error information through the FileOperationError class and MCP error codes:
InvalidRequest: Invalid parameters or request formatMethodNotFound: Unknown tool or resource requestedInvalidParams: Invalid parameters (e.g., path validation failure)InternalError: Server-side errors
- File operation failures
- Rate limit exceeded
- Path validation errors
- Resource access errors
Each error includes:
- Specific error code
- Detailed error message
- Relevant metadata (file paths, limits, etc.)
- Stack traces in development mode
- Fork the repository
- Create your feature branch (
git checkout -b feature/amazing-feature) - Commit your changes (
git commit -m 'Add amazing feature') - Push to the branch (
git push origin feature/amazing-feature) - Open a Pull Request
This project is licensed under the MIT License - see the LICENSE file for details.