move
Relocate files between locations with safety validations and directory restrictions to prevent unintended overwrites.
Instructions
Move files with safety checks and current directory restrictions
Input Schema
| Name | Required | Description | Default |
|---|---|---|---|
| from | Yes | Source file path (required) | |
| to | Yes | Destination file path (required) | |
| overwrite | No | Allow overwriting existing files (default: false) |
Implementation Reference
- servers/file-mcp/tools/move.ts:39-103 (handler)Core handler function executing the move tool logic: validates input with Zod, performs security and boundary checks, ensures directories, handles overwrite logic, and executes file rename (with fallback copy+delete for cross-device).
async execute(args: any): Promise<any> { try { // Validate and parse input using Zod schema const validatedArgs = MoveToolInputSchema.parse(args); const { from: fromPath, to: toPath, overwrite } = validatedArgs; // Resolve absolute paths const fromResolved = resolve(fromPath); const toResolved = resolve(toPath); // Security checks this.validateCurrentDirectoryBounds(fromResolved, toResolved); if (PathSecurity.isDangerousFile(fromPath) || PathSecurity.isDangerousFile(toPath)) { throw new Error( `Security protection: Cannot operate on dangerous files (${fromPath} → ${toPath})` ); } if ( (await PathSecurity.isIgnoredByGit(fromResolved)) || (await PathSecurity.isIgnoredByGit(toResolved)) ) { throw new Error( `gitignore protection: Cannot operate on ignored files (${fromPath} → ${toPath})` ); } // Check if source exists try { await access(fromResolved); } catch { throw new Error(`Source file not found: ${fromPath}`); } // Check if destination exists const destinationExists = await this.checkDestinationExists(toResolved); // Smart dryRun control if (destinationExists && !overwrite) { const destStats = await stat(toResolved); const destSize = Math.round((destStats.size / 1024) * 100) / 100; throw new Error( `Destination already exists: ${toPath} (${destSize}KB, modified ${destStats.mtime.toISOString().split("T")[0]}). Move operation would overwrite this file. Use overwrite=true to force overwrite or choose a different destination path.` ); } // Ensure destination directory exists await this.ensureDestinationDirectory(toResolved); // Perform move operation await this.performMove(fromResolved, toResolved); const message = destinationExists ? `✅ Successfully moved (overwrote existing): ${fromPath} → ${toPath}` : `✅ Successfully moved: ${fromPath} → ${toPath}`; return ResultFormatter.createResponse(message); } catch (error: any) { // Handle Zod validation errors if (error instanceof Error && error.name === "ZodError") { throw ToolError.createValidationError("input", args, `Invalid input: ${error.message}`); } throw ToolError.wrapError("Move operation", error); } } - Zod schema defining input parameters for the move tool: from (source path), to (destination path), overwrite (boolean flag). Used in execute for validation.
// Move tool input schema export const MoveToolInputSchema = z.object({ from: FilePathSchema, to: FilePathSchema, overwrite: BooleanFlagSchema, }); - servers/file-mcp/tools/move.ts:13-37 (schema)Tool definition for MCP protocol, including the JSON inputSchema matching the Zod schema.
getDefinition(): Tool { return { name: "move", description: "Move files with safety checks and current directory restrictions", inputSchema: { type: "object", properties: { from: { type: "string", description: "Source file path (required)", }, to: { type: "string", description: "Destination file path (required)", }, overwrite: { type: "boolean", description: "Allow overwriting existing files (default: false)", default: false, }, }, required: ["from", "to"], }, }; } - servers/file-mcp/index.ts:90-100 (registration)Registration of the move tool's definition in the listTools response via getTools().
protected getTools(): Tool[] { return [ this.readTool.getDefinition(), this.findTool.getDefinition(), this.grepTool.getDefinition(), this.writeTool.getDefinition(), this.editTool.getDefinition(), this.moveTool.getDefinition(), this.copyTool.getDefinition(), ]; } - servers/file-mcp/index.ts:120-121 (registration)Tool dispatch in handleToolCall: routes 'move' calls to MoveTool.execute.
case "move": return await this.moveTool.execute(args);