rm
Remove files or directories permanently from the filesystem. Specify a path to delete items, with options for recursive deletion of folders and ignoring missing files.
Instructions
Permanently delete a file or directory. This action is irreversible.
Input Schema
TableJSON Schema
| Name | Required | Description | Default |
|---|---|---|---|
| path | Yes | Absolute path to file or directory. | |
| recursive | No | Delete non-empty directories | |
| ignoreIfNotExists | No | No error if missing |
Implementation Reference
- src/tools/delete-file.ts:40-88 (handler)The `handleDeleteFile` function contains the actual logic for deleting files or directories, including handling recursive options and checking for existence.
async function handleDeleteFile( args: z.infer<typeof DeleteFileInputSchema>, signal?: AbortSignal ): Promise<ToolResponse<z.infer<typeof DeleteFileOutputSchema>>> { const validPath = await validatePathForWrite(args.path, signal); if (isAllowedDirectoryRoot(validPath)) { throw new McpError( ErrorCode.E_ACCESS_DENIED, `Deleting a workspace root directory is not allowed: ${args.path}` ); } let stats: Awaited<ReturnType<typeof fs.lstat>> | undefined; try { stats = await withAbort(fs.lstat(validPath), signal); } catch (error) { if ( isNodeError(error) && error.code === 'ENOENT' && args.ignoreIfNotExists ) { return buildToolResponse(`Successfully deleted: ${args.path}`, { ok: true, path: validPath, }); } throw error; } if (stats.isDirectory() && !args.recursive) { // Use rmdir for non-recursive directory deletes so non-empty directories // consistently return ENOTEMPTY-style errors with actionable guidance. await withAbort(fs.rmdir(validPath), signal); } else { await withAbort( fs.rm(validPath, { recursive: args.recursive, force: args.ignoreIfNotExists, }), signal ); } return buildToolResponse(`Successfully deleted: ${args.path}`, { ok: true, path: validPath, }); } - src/tools/delete-file.ts:90-184 (registration)The `registerDeleteFileTool` function registers the 'rm' tool with the MCP server, including the handler, schemas, and icons.
export function registerDeleteFileTool( server: McpServer, options: ToolRegistrationOptions = {} ): void { const handler = ( args: z.infer<typeof DeleteFileInputSchema>, extra: ToolExtra ): Promise<ToolResult<z.infer<typeof DeleteFileOutputSchema>>> => executeToolWithDiagnostics({ toolName: 'rm', extra, outputSchema: DeleteFileOutputSchema, timedSignal: {}, context: { path: args.path }, run: (signal) => handleDeleteFile(args, signal), onError: (error) => { if (isNodeError(error)) { if (error.code === 'ENOENT') { return buildToolErrorResponse( error, ErrorCode.E_NOT_FOUND, args.path ); } if (error.code === 'ENOTEMPTY') { return buildToolErrorResponse( new Error( `Directory is not empty: ${args.path}. Use recursive: true to delete non-empty directories.` ), ErrorCode.E_INVALID_INPUT, args.path ); } if (error.code === 'EISDIR') { return buildToolErrorResponse( new Error( `Path is a directory: ${args.path}. Use recursive: true to delete directories.` ), ErrorCode.E_INVALID_INPUT, args.path ); } if (error.code === 'EEXIST') { return buildToolErrorResponse( new Error( `Directory is not empty: ${args.path}. Use recursive: true to delete non-empty directories.` ), ErrorCode.E_INVALID_INPUT, args.path ); } if (error.code === 'EPERM' || error.code === 'EACCES') { return buildToolErrorResponse( error, ErrorCode.E_PERMISSION_DENIED, args.path ); } } return buildToolErrorResponse(error, ErrorCode.E_UNKNOWN, args.path); }, }); const wrappedHandler = wrapToolHandler(handler, { guard: options.isInitialized, progressMessage: (args) => `🛠 rm: ${path.basename(args.path)}`, completionMessage: (args, result) => { const name = path.basename(args.path); if (result.isError) return `🛠 rm: ${name} • failed`; return `🛠 rm: ${name}`; }, }); const validatedHandler = withValidatedArgs( DeleteFileInputSchema, wrappedHandler ); if ( registerToolTaskIfAvailable( server, 'rm', DELETE_FILE_TOOL, validatedHandler, options.iconInfo, options.isInitialized ) ) return; server.registerTool( 'rm', withDefaultIcons({ ...DELETE_FILE_TOOL }, options.iconInfo), validatedHandler ); } - src/tools/delete-file.ts:28-38 (schema)The `DELETE_FILE_TOOL` object defines the metadata for the 'rm' tool, including its name, description, and schema references.
export const DELETE_FILE_TOOL: ToolContract = { name: 'rm', title: 'Delete File', description: 'Permanently delete a file or directory. This action is irreversible.', inputSchema: DeleteFileInputSchema, outputSchema: DeleteFileOutputSchema, annotations: DESTRUCTIVE_WRITE_TOOL_ANNOTATIONS, gotchas: ['Non-empty directories require `recursive=true`.'], taskSupport: 'forbidden', } as const;