Skip to main content
Glama

Delete Todos (Bulk)

delete_todos
Destructive

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
NameRequiredDescriptionDefault
statusNoFilter by status
priorityNoFilter by priority
tagNoFilter by tag
dueBeforeNoDelete todos due before this date (ISO format)
dueAfterNoDelete todos due after this date (ISO format)
queryNoSearch text filter
dryRunNoPreview deletion without removing data
limitNoMax items to delete (default: 10, safety limit)

Output Schema

TableJSON Schema
NameRequiredDescriptionDefault
okYes
errorNo
resultNo

Implementation Reference

  • 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);
    }
  • 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',
      });
  • 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));
          }
        }
      );
    }
  • 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);
    }
  • 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 };
      });
    }
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already indicate destructiveHint=true, readOnlyHint=false, and idempotentHint=false. The description adds valuable context beyond this: it specifies the safety limit (default limit=10) and the requirement for at least one filter, which are not covered by annotations. It does not contradict annotations, as 'Delete' aligns with destructiveHint=true.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is a single, efficient sentence that front-loads the core action and key constraints (filters, safety limit). Every word serves a purpose with no redundancy, making it highly concise and well-structured.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

Given the tool's complexity (destructive bulk operation with 8 parameters), annotations cover safety aspects, and an output schema exists, the description is mostly complete. It adds important behavioral context (filter requirement, safety limit) but could benefit from more explicit guidance on alternatives or error handling, though the output schema reduces the need for return value explanation.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 100%, so the schema fully documents all 8 parameters. The description adds minimal semantics by mentioning the safety limit and filter requirement, but does not provide additional meaning beyond what the schema already covers. Baseline is 3 due to high schema coverage.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description clearly states the action ('Delete multiple todos') and scope ('matching filters'), distinguishing it from the sibling 'delete_todo' which likely deletes a single todo. It specifies bulk deletion with filtering, making the purpose specific and differentiated.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description provides clear context for when to use it ('requires at least one filter') and mentions a safety default ('defaults to limit=10 for safety'), but does not explicitly state when to use this vs. alternatives like 'delete_todo' or other sibling tools. It implies usage through filtering but lacks explicit alternatives.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

Install Server

Other Tools

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/j0hanz/todokit-mcp-server'

If you have feedback or need assistance with the MCP directory API, please join our Discord server