filesystem
Perform file system operations such as browsing directories, reading files, searching, retrieving file info, finding large files, and checking disk usage on Windows systems.
Instructions
Comprehensive file system operations including directory browsing, file reading, searching, and basic file operations
Input Schema
TableJSON Schema
| Name | Required | Description | Default |
|---|---|---|---|
| action | Yes | The file system action to perform | |
| max_depth | No | Maximum depth for recursive operations (default: 3) | |
| path | No | File or directory path (required for most actions) | |
| pattern | No | Search pattern for file searching (supports wildcards) | |
| recursive | No | Whether to search recursively (default: false) | |
| size_threshold | No | Size threshold in MB for finding large files (default: 100) |
Implementation Reference
- src/tools/filesystem.ts:46-80 (handler)The primary handler function for the 'filesystem' tool. It parses arguments, switches on the 'action' parameter, and delegates to specific helper methods for file system operations like listing directories, reading files, etc.async run(args: { action: string; path?: string; pattern?: string; recursive?: boolean; max_depth?: number; size_threshold?: number; }) { try { switch (args.action) { case "list_directory": return await this.listDirectory(args.path || "C:\\", args.recursive, args.max_depth); case "read_file": return await this.readFile(args.path!); case "search_files": return await this.searchFiles(args.pattern!, args.path, args.recursive); case "get_file_info": return await this.getFileInfo(args.path!); case "find_large_files": return await this.findLargeFiles(args.path || "C:\\", args.size_threshold!); case "get_disk_usage": return await this.getDiskUsage(); default: throw new Error(`Unknown action: ${args.action}`); } } catch (error: any) { return { content: [{ type: "text", text: `β File system operation failed: ${error.message}` }], isError: true }; } },
- src/tools/filesystem.ts:11-44 (schema)Input schema defining the parameters for the filesystem tool, including action types and optional parameters like path, pattern, etc.parameters: { type: "object", properties: { action: { type: "string", enum: ["list_directory", "read_file", "search_files", "get_file_info", "find_large_files", "get_disk_usage"], description: "The file system action to perform" }, path: { type: "string", description: "File or directory path (required for most actions)" }, pattern: { type: "string", description: "Search pattern for file searching (supports wildcards)" }, recursive: { type: "boolean", description: "Whether to search recursively (default: false)", default: false }, max_depth: { type: "number", description: "Maximum depth for recursive operations (default: 3)", default: 3 }, size_threshold: { type: "number", description: "Size threshold in MB for finding large files (default: 100)", default: 100 } }, required: ["action"] },
- src/index.ts:27-31 (registration)Registration of the 'filesystem' tool in the MCP ListToolsRequestSchema handler, exposing name, description, and input schema.{ name: fileSystemTool.name, description: fileSystemTool.description, inputSchema: fileSystemTool.parameters },
- src/index.ts:71-72 (registration)Dispatch logic in the MCP CallToolRequestSchema handler that routes calls to the 'filesystem' tool's run method.case "filesystem": return await fileSystemTool.run(args as any);
- src/tools/filesystem.ts:82-135 (helper)Helper method for listing directory contents, supporting recursive traversal up to a maximum depth, formatting directories and files with sizes and dates.async listDirectory(dirPath: string, recursive = false, maxDepth = 3) { try { const items = await fs.readdir(dirPath, { withFileTypes: true }); let result = `# Directory Listing: ${dirPath}\n\n`; const directories: string[] = []; const files: string[] = []; for (const item of items) { const fullPath = path.join(dirPath, item.name); try { const stats = await fs.stat(fullPath); const size = item.isFile() ? this.formatFileSize(stats.size) : ""; const modified = stats.mtime.toISOString().split('T')[0]; if (item.isDirectory()) { directories.push(`π ${item.name}/ (${modified})`); } else { files.push(`π ${item.name} (${size}, ${modified})`); } } catch { if (item.isDirectory()) { directories.push(`π ${item.name}/ (access denied)`); } else { files.push(`π ${item.name} (access denied)`); } } } result += "## Directories:\n" + directories.join("\n") + "\n\n"; result += "## Files:\n" + files.join("\n"); if (recursive && maxDepth > 0) { result += "\n\n## Subdirectories (recursive):\n"; for (const item of items) { if (item.isDirectory()) { try { const subPath = path.join(dirPath, item.name); const subResult = await this.listDirectory(subPath, true, maxDepth - 1); result += `\n### ${item.name}/\n${subResult.content[0].text}\n`; } catch { result += `\n### ${item.name}/ (access denied)\n`; } } } } return { content: [{ type: "text", text: result }] }; } catch (error: any) { throw new Error(`Cannot list directory ${dirPath}: ${error.message}`); } },