delete_todos
Remove multiple todo items from Todokit MCP Server by applying filters such as status, priority, tags, or due dates. Use dry run to preview deletions before removing data.
Instructions
Delete multiple todos matching filters (requires at least one filter, defaults to limit=10 for safety)
Input Schema
TableJSON Schema
| Name | Required | Description | Default |
|---|---|---|---|
| status | No | Filter by status | |
| priority | No | Filter by priority | |
| tag | No | Filter by tag | |
| dueBefore | No | Delete todos due before this date (ISO format) | |
| dueAfter | No | Delete todos due after this date (ISO format) | |
| query | No | Search text filter | |
| dryRun | No | Preview deletion without removing data | |
| limit | No | Max items to delete (default: 10, safety limit) |
Implementation Reference
- src/tools/delete_todos.ts:127-154 (handler)The main handler function executing the delete_todos tool: applies filters to find matching todos, handles dry-run preview, deletes via deleteTodosByIds, and constructs the response.async function handleDeleteTodos( input: DeleteTodosInput ): Promise<CallToolResult> { const limit = input.limit ?? DEFAULT_LIMIT; const dryRun = input.dryRun ?? false; const matches = await getTodos({ completed: resolveCompletedFilter(input.status), priority: input.priority, tag: input.tag, dueBefore: input.dueBefore, dueAfter: input.dueAfter, query: input.query, }); if (matches.length === 0) { return buildNoMatchResponse(); } const toDelete = matches.slice(0, limit); if (dryRun) { return buildDryRunResponse(toDelete, matches.length); } const deletedIds = await deleteTodosByIds(toDelete.map((t) => t.id)); return buildDeletedResponse(deletedIds, matches.length); }
- src/tools/delete_todos.ts:35-67 (schema)Zod schema defining the input for delete_todos tool, including filters for status, priority, tag, dates, query, with dryRun and limit options, requiring at least one filter.const DeleteTodosSchema = z .strictObject({ status: z .enum(['pending', 'completed', 'all']) .optional() .describe('Filter by status'), priority: z .enum(['low', 'normal', 'high']) .optional() .describe('Filter by priority'), tag: TagSchema.optional().describe('Filter by tag'), dueBefore: IsoDateSchema.optional().describe( 'Delete todos due before this date (ISO format)' ), dueAfter: IsoDateSchema.optional().describe( 'Delete todos due after this date (ISO format)' ), query: z.string().min(1).max(200).optional().describe('Search text filter'), dryRun: z .boolean() .optional() .describe('Preview deletion without removing data'), limit: z .number() .int() .min(1) .max(100) .optional() .describe('Max items to delete (default: 10, safety limit)'), }) .refine(hasAtLeastOneFilter, { error: 'At least one filter is required for bulk delete', });
- src/tools/delete_todos.ts:156-179 (registration)Registers the 'delete_todos' tool on the MCP server with schema, description, annotations, and handler wrapper.export function registerDeleteTodos(server: McpServer): void { server.registerTool( 'delete_todos', { title: 'Delete Todos (Bulk)', description: 'Delete multiple todos matching filters (requires at least one filter, defaults to limit=10 for safety)', inputSchema: DeleteTodosSchema, outputSchema: DefaultOutputSchema, annotations: { readOnlyHint: false, idempotentHint: false, destructiveHint: true, }, }, async (input) => { try { return await handleDeleteTodos(input); } catch (err) { return createErrorResponse('E_DELETE_TODOS', getErrorMessage(err)); } } ); }
- src/tools/index.ts:11-19 (registration)Central registration function that calls registerDeleteTodos among others to register all tools.export function registerAllTools(server: McpServer): void { registerAddTodo(server); registerAddTodos(server); registerListTodos(server); registerUpdateTodo(server); registerCompleteTodo(server); registerDeleteTodo(server); registerDeleteTodos(server); }
- src/lib/storage.ts:250-264 (helper)Helper function that deletes multiple todos by their IDs using atomic storage update, returns deleted IDs.export function deleteTodosByIds(ids: string[]): Promise<string[]> { const idsToDelete = new Set(ids); return withTodos((todos) => { const deletedIds: string[] = []; const remaining: Todo[] = []; for (const todo of todos) { if (idsToDelete.has(todo.id)) { deletedIds.push(todo.id); } else { remaining.push(todo); } } return { todos: remaining, result: deletedIds }; }); }