remove_todo_task
Eliminate irrelevant or duplicate tasks from a TODO list by permanently removing a specific task. The tool updates task numbering, preserves other tasks, and ensures clean task management. Use it to streamline and maintain organized project workflows.
Instructions
Remove a task from a TODO list.
When to use this tool:
Task is no longer relevant
Removing duplicate tasks
Task was added by mistake
Consolidating similar tasks
Cleaning up TODO list
Key features:
Permanent task removal
Preserves other tasks
Updates task numbering
You should:
Verify task exists first
Consider if task is truly unnecessary
Check task number is correct
Understand removal is permanent
Document why removing if significant
DO NOT use when:
Task should be completed instead
Task might be needed later
Unsure about removal impact
Returns: {success: bool, message: str, error?: str}
Input Schema
| Name | Required | Description | Default |
|---|---|---|---|
| project_id | Yes | The project identifier | |
| task_number | Yes | The task number to remove | |
| todo_number | Yes | The TODO list number |
Implementation Reference
- Asynchronous implementation of the remove_todo_task tool. Locates the project TODO directory, finds the specific task markdown file by number, deletes it, commits the change to git, and returns confirmation.async removeTodoTaskAsync(params: { project_id: z.infer<typeof secureProjectIdSchema>; todo_number: z.infer<typeof secureTodoNumberSchema>; task_number: z.infer<typeof secureTodoNumberSchema>; }): Promise<string> { const context = this.createContext('remove_todo_task', params); try { const { project_id, todo_number, task_number } = params; const projectInfo = await getProjectDirectoryAsync(this.storagePath, project_id); if (!projectInfo) { throw new MCPError(MCPErrorCode.PROJECT_NOT_FOUND, `Project ${project_id} not found`, { project_id, traceId: context.traceId, }); } const [, projectPath] = projectInfo; const todoDir = join(projectPath, 'TODO', todo_number.toString()); // Check if TODO exists try { await access(todoDir); } catch { throw new MCPError(MCPErrorCode.TODO_NOT_FOUND, `TODO #${todo_number} not found`, { project_id, todo_number, traceId: context.traceId, }); } // Find task file const taskFile = await this.findTaskFileAsync(todoDir, task_number); if (!taskFile) { throw new MCPError( MCPErrorCode.TASK_NOT_FOUND, `Task #${task_number} not found in TODO #${todo_number}`, { project_id, todo_number, task_number, traceId: context.traceId } ); } // Delete the task file await unlink(join(todoDir, taskFile)); // Auto-commit await autoCommitAsync( this.storagePath, `Remove task #${task_number} from TODO #${todo_number}` ); this.logSuccess('remove_todo_task', params, context); return this.formatSuccessResponse({ message: `Removed task #${task_number} from TODO #${todo_number}`, }); } catch (error) { this.logError('remove_todo_task', params, error as MCPError, context); return this.formatErrorResponse(error, context); } }
- src/knowledge-mcp/server.ts:687-709 (registration)Registers the 'remove_todo_task' tool with MCP server, defining its title, description, input schema, and handler that delegates to TodoToolHandler.removeTodoTaskAsync.server.registerTool( 'remove_todo_task', { title: 'Remove TODO Task', description: TOOL_DESCRIPTIONS.remove_todo_task, inputSchema: { project_id: secureProjectIdSchema.describe('The project identifier'), todo_number: secureTodoNumberSchema.describe('The TODO list number'), task_number: secureTodoNumberSchema.describe('The task number to remove'), }, }, async ({ project_id, todo_number, task_number }) => { const result = await todoHandler.removeTodoTaskAsync({ project_id, todo_number, task_number }); return { content: [ { type: 'text', text: result, }, ], }; } );
- Zod schema for validating secure project_id input parameter used across all tools including remove_todo_task.export const secureProjectIdSchema = z .string() .min(1, 'Project ID cannot be empty') .max(100, 'Project ID too long') .refine( (val) => !val.includes('..') && !val.startsWith('.') && !val.endsWith('.'), 'Project ID cannot contain path traversal patterns' ) .refine( (val) => !/[/\\:*?"<>|\0]/.test(val), 'Project ID cannot contain filesystem reserved characters or null bytes' ) .refine((val) => val.trim() === val, 'Project ID cannot have leading/trailing spaces');
- Zod schema for validating todo_number and task_number input parameters for the remove_todo_task tool.export const secureTodoNumberSchema = z .number() .int('TODO number must be an integer') .positive('TODO number must be positive') .max(99999, 'TODO number too large');
- Helper method used by the handler to locate the specific task markdown file by extracting the task number from filenames like TASK-001-slug.md.private async findTaskFileAsync(todoDir: string, taskNumber: number): Promise<string | null> { const taskFiles = await this.getTaskFilesAsync(todoDir); for (const file of taskFiles) { const fileTaskNumber = this.extractTaskNumber(file); if (fileTaskNumber === taskNumber) { return file; } } return null; }