Skip to main content
Glama

batch-operations

Update, delete, or mark tasks as complete in bulk based on priority, context, or project criteria to manage Todo.txt files efficiently.

Instructions

Perform batch operations (update, delete, mark-complete) on tasks matching criteria.

Input Schema

TableJSON Schema
NameRequiredDescriptionDefault
operationsYes

Implementation Reference

  • The handler function executes batch operations (delete, update, mark-complete) on tasks matching specified criteria. It loads tasks, applies each operation in sequence, saves changes, and returns success message.
    async ({ operations }) => { let tasks = await loadTasks(); for (const operation of operations) { if (operation.action === "delete") { tasks = tasks.filter(task => { if (!operation.criteria) return true; return !( (operation.criteria.priority && task.priority() === operation.criteria.priority) || (operation.criteria.context && task.contexts().includes(operation.criteria.context)) || (operation.criteria.project && task.projects().includes(operation.criteria.project)) ); }); } else if (operation.action === "update") { tasks.forEach(task => { if (operation.criteria) { if ( (operation.criteria.priority && task.priority() === operation.criteria.priority) || (operation.criteria.context && task.contexts().includes(operation.criteria.context)) || (operation.criteria.project && task.projects().includes(operation.criteria.project)) ) { if (operation.updates) { if (operation.updates.priority) { task.setPriority(operation.updates.priority); } if (operation.updates.addContexts) { operation.updates.addContexts.forEach((context: string) => task.addContext(context)); } if (operation.updates.removeContexts) { operation.updates.removeContexts.forEach((context: string) => task.removeContext(context)); } if (operation.updates.addProjects) { operation.updates.addProjects.forEach((project: string) => task.addProject(project)); } if (operation.updates.removeProjects) { operation.updates.removeProjects.forEach((project: string) => task.removeProject(project)); } if (operation.updates.extensions) { Object.entries(operation.updates.extensions).forEach(([key, value]) => task.setExtension(key as string, value as string)); } } } } }); } else if (operation.action === "mark-complete") { tasks.forEach(task => { if (operation.criteria) { if ( (operation.criteria.priority && task.priority() === operation.criteria.priority) || (operation.criteria.context && task.contexts().includes(operation.criteria.context)) || (operation.criteria.project && task.projects().includes(operation.criteria.project)) ) { task.setCompleted(new Date().toISOString().split("T")[0]); } } }); } } await saveTasks(tasks); return { content: [ { type: "text", text: "Batch operations completed successfully." }, ], }; }
  • Zod schema for the tool's input parameters, defining an array of operations each with action type, optional criteria for matching tasks, and optional updates for 'update' actions.
    { operations: z.array(z.object({ action: z.enum(["update", "delete", "mark-complete"]), criteria: z.object({ priority: z.string().optional(), context: z.string().optional(), project: z.string().optional(), }).optional(), updates: z.object({ priority: z.string().optional(), addContexts: z.array(z.string()).optional(), removeContexts: z.array(z.string()).optional(), addProjects: z.array(z.string()).optional(), removeProjects: z.array(z.string()).optional(), extensions: z.record(z.string(), z.string()).optional(), }).optional(), })), },
  • src/tools.ts:281-366 (registration)
    MCP server tool registration for 'batch-operations', including name, description, input schema, and handler function.
    server.tool( "batch-operations", "Perform batch operations (update, delete, mark-complete) on tasks matching criteria.", { operations: z.array(z.object({ action: z.enum(["update", "delete", "mark-complete"]), criteria: z.object({ priority: z.string().optional(), context: z.string().optional(), project: z.string().optional(), }).optional(), updates: z.object({ priority: z.string().optional(), addContexts: z.array(z.string()).optional(), removeContexts: z.array(z.string()).optional(), addProjects: z.array(z.string()).optional(), removeProjects: z.array(z.string()).optional(), extensions: z.record(z.string(), z.string()).optional(), }).optional(), })), }, async ({ operations }) => { let tasks = await loadTasks(); for (const operation of operations) { if (operation.action === "delete") { tasks = tasks.filter(task => { if (!operation.criteria) return true; return !( (operation.criteria.priority && task.priority() === operation.criteria.priority) || (operation.criteria.context && task.contexts().includes(operation.criteria.context)) || (operation.criteria.project && task.projects().includes(operation.criteria.project)) ); }); } else if (operation.action === "update") { tasks.forEach(task => { if (operation.criteria) { if ( (operation.criteria.priority && task.priority() === operation.criteria.priority) || (operation.criteria.context && task.contexts().includes(operation.criteria.context)) || (operation.criteria.project && task.projects().includes(operation.criteria.project)) ) { if (operation.updates) { if (operation.updates.priority) { task.setPriority(operation.updates.priority); } if (operation.updates.addContexts) { operation.updates.addContexts.forEach((context: string) => task.addContext(context)); } if (operation.updates.removeContexts) { operation.updates.removeContexts.forEach((context: string) => task.removeContext(context)); } if (operation.updates.addProjects) { operation.updates.addProjects.forEach((project: string) => task.addProject(project)); } if (operation.updates.removeProjects) { operation.updates.removeProjects.forEach((project: string) => task.removeProject(project)); } if (operation.updates.extensions) { Object.entries(operation.updates.extensions).forEach(([key, value]) => task.setExtension(key as string, value as string)); } } } } }); } else if (operation.action === "mark-complete") { tasks.forEach(task => { if (operation.criteria) { if ( (operation.criteria.priority && task.priority() === operation.criteria.priority) || (operation.criteria.context && task.contexts().includes(operation.criteria.context)) || (operation.criteria.project && task.projects().includes(operation.criteria.project)) ) { task.setCompleted(new Date().toISOString().split("T")[0]); } } }); } } await saveTasks(tasks); return { content: [ { type: "text", text: "Batch operations completed successfully." }, ], }; } );

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/guifelix/mcp-server-todotxt'

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