move_items
Move or rename multiple files and directories efficiently by specifying source and destination paths in a structured array.
Instructions
Move or rename multiple specified files/directories.
Input Schema
TableJSON Schema
| Name | Required | Description | Default |
|---|---|---|---|
| operations | Yes | Array of {source, destination} objects. |
Implementation Reference
- src/handlers/move-items.ts:249-273 (handler)Core handler function implementing the logic for the 'move_items' tool: parses input, processes multiple move operations concurrently using Promise.allSettled, handles results, sorts them to maintain original order, and formats the JSON response.export const handleMoveItemsFuncCore = async ( args: unknown, dependencies: MoveItemsDependencies, ): Promise<McpToolResponse> => { const { operations } = parseAndValidateArgs(args); const movePromises = operations.map((op) => processSingleMoveOperation({ op }, dependencies), // Pass dependencies ); const settledResults = await Promise.allSettled(movePromises); const outputResults = processSettledResults(settledResults, operations); // Sort results based on the original order const originalIndexMap = new Map(operations.map((op, i) => [op.source.replaceAll('\\', '/'), i])); outputResults.sort((a, b) => { const indexA = originalIndexMap.get(a.source) ?? Infinity; const indexB = originalIndexMap.get(b.source) ?? Infinity; return indexA - indexB; }); return { content: [{ type: 'text', text: JSON.stringify(outputResults, undefined, 2) }], }; };
- src/handlers/move-items.ts:19-33 (schema)Zod schemas for move operation and the overall input arguments for the 'move_items' tool, enforcing structure and validation.export const MoveOperationSchema = z .object({ source: z.string().describe('Relative path of the source.'), destination: z.string().describe('Relative path of the destination.'), }) .strict(); export const MoveItemsArgsSchema = z .object({ operations: z .array(MoveOperationSchema) .min(1, { message: 'Operations array cannot be empty' }) .describe('Array of {source, destination} objects.'), }) .strict();
- src/handlers/move-items.ts:290-295 (registration)Definition object for the 'move_items' tool, including name, description, input schema, and reference to the handler function.export const moveItemsToolDefinition = { name: 'move_items', description: 'Move or rename multiple specified files/directories.', inputSchema: MoveItemsArgsSchema, handler: handleMoveItemsFunc, // Use the wrapper };
- src/handlers/index.ts:47-91 (registration)Central registration of all MCP tools in the 'allToolDefinitions' array, including the 'move_items' tool.// Use our more specific type to avoid naming conflicts export const allToolDefinitions: HandlerToolDefinition[] = [ listFilesToolDefinition, statItemsToolDefinition, readContentToolDefinition, writeContentToolDefinition, deleteItemsToolDefinition, createDirectoriesToolDefinition, chmodItemsToolDefinition, chownItemsToolDefinition, moveItemsToolDefinition, copyItemsToolDefinition, searchFilesToolDefinition, replaceContentToolDefinition, { name: 'apply_diff', description: 'Apply diffs to files', inputSchema: applyDiffInputSchema, handler: async (args: unknown): Promise<McpToolResponse> => { const validatedArgs = applyDiffInputSchema.parse(args); const result: ApplyDiffOutput = await handleApplyDiff(validatedArgs.changes, { readFile: async (path: string) => fs.promises.readFile(path, 'utf8'), writeFile: async (path: string, content: string) => fs.promises.writeFile(path, content, 'utf8'), path, projectRoot: process.cwd(), }); return { content: [ { type: 'text', text: JSON.stringify( { success: result.success, results: result.results, }, undefined, 2, ), }, ], }; }, }, ];
- src/handlers/move-items.ts:162-225 (helper)Helper function that processes a single move operation: validates, resolves paths, checks source, ensures destination directory, performs rename, and handles errors.async function processSingleMoveOperation( params: ProcessSingleMoveParams, dependencies: MoveItemsDependencies, // Inject dependencies ): Promise<MoveResult> { const { op } = params; // Validate operation parameters const validationResult = validateMoveOperation(op); if (validationResult) return validationResult; const sourceRelative = op.source; const destinationRelative = op.destination; const sourceOutput = sourceRelative.replaceAll('\\', '/'); const destOutput = destinationRelative.replaceAll('\\', '/'); try { // Safely resolve paths using injected dependency const sourceAbsolute = await dependencies.resolvePath(sourceRelative); const destinationAbsolute = await dependencies.resolvePath(destinationRelative); if (sourceAbsolute === dependencies.PROJECT_ROOT) { // Use injected dependency return { source: sourceOutput, destination: destOutput, success: false, error: 'Moving the project root is not allowed.', }; } // Check source existence using injected dependency const sourceCheckResult = await checkSourceExists( { sourceAbsolute, sourceRelative, sourceOutput, destOutput, }, dependencies, // Pass dependencies ); // Ensure we return immediately if source check fails (No change needed here, already correct) if (sourceCheckResult) return sourceCheckResult; // Perform the move using injected dependency return await performMoveOperation( { sourceAbsolute, destinationAbsolute, sourceOutput, destOutput, }, dependencies, // Pass dependencies ); } catch (error) { const specialErrorResult = handleSpecialMoveErrors(error, sourceOutput, destOutput); if (specialErrorResult) return specialErrorResult; return handleMoveError({ error, sourceRelative, destinationRelative, sourceOutput, destOutput, }); } }