Skip to main content
Glama
jqlts1

OmniFocus MCP Enhanced

by jqlts1

batch_add_items

Add multiple tasks or projects to OmniFocus in one operation, specifying details like due dates, flags, tags, and project associations.

Instructions

Add multiple tasks or projects to OmniFocus in a single operation

Input Schema

TableJSON Schema
NameRequiredDescriptionDefault
itemsYesArray of items (tasks or projects) to add

Implementation Reference

  • The handler function for the batch_add_items tool. It calls the primitive batchAddItems function and formats the response with success/failure details.
    export async function handler(args: z.infer<typeof schema>, extra: RequestHandlerExtra) { try { // Call the batchAddItems function const result = await batchAddItems(args.items as BatchAddItemsParams[]); if (result.success) { const successCount = result.results.filter(r => r.success).length; const failureCount = result.results.filter(r => !r.success).length; let message = `✅ Successfully added ${successCount} items.`; if (failureCount > 0) { message += ` ⚠️ Failed to add ${failureCount} items.`; } // Include details about added items const details = result.results.map((item, index) => { if (item.success) { const itemType = args.items[index].type; const itemName = args.items[index].name; return `- ✅ ${itemType}: "${itemName}"`; } else { const itemType = args.items[index].type; const itemName = args.items[index].name; return `- ❌ ${itemType}: "${itemName}" - Error: ${item.error}`; } }).join('\n'); return { content: [{ type: "text" as const, text: `${message}\n\n${details}` }] }; } else { // Batch operation failed completely return { content: [{ type: "text" as const, text: `Failed to process batch operation: ${result.error}` }], isError: true }; } } catch (err: unknown) { const error = err as Error; console.error(`Tool execution error: ${error.message}`); return { content: [{ type: "text" as const, text: `Error processing batch operation: ${error.message}` }], isError: true }; } }
  • Zod schema defining the input parameters for the batch_add_items tool, matching the BatchAddItemsParams type.
    export const schema = z.object({ items: z.array(z.object({ type: z.enum(['task', 'project']).describe("Type of item to add ('task' or 'project')"), name: z.string().describe("The name of the item"), note: z.string().optional().describe("Additional notes for the item"), dueDate: z.string().optional().describe("The due date in ISO format (YYYY-MM-DD or full ISO date)"), deferDate: z.string().optional().describe("The defer date in ISO format (YYYY-MM-DD or full ISO date)"), flagged: z.boolean().optional().describe("Whether the item is flagged or not"), estimatedMinutes: z.number().optional().describe("Estimated time to complete the item, in minutes"), tags: z.array(z.string()).optional().describe("Tags to assign to the item"), // Task-specific properties projectName: z.string().optional().describe("For tasks: The name of the project to add the task to"), parentTaskId: z.string().optional().describe("For tasks: The ID of the parent task to create this task as a subtask"), parentTaskName: z.string().optional().describe("For tasks: The name of the parent task to create this task as a subtask"), // Project-specific properties folderName: z.string().optional().describe("For projects: The name of the folder to add the project to"), sequential: z.boolean().optional().describe("For projects: Whether tasks in the project should be sequential") })).describe("Array of items (tasks or projects) to add") });
  • src/server.ts:69-74 (registration)
    Registration of the batch_add_items tool on the MCP server using schema and handler from batchAddItemsTool.
    server.tool( "batch_add_items", "Add multiple tasks or projects to OmniFocus in a single operation", batchAddItemsTool.schema.shape, batchAddItemsTool.handler );
  • Core helper function that implements the batch addition logic by iterating over items and calling individual addOmniFocusTask or addProject functions.
    export async function batchAddItems(items: BatchAddItemsParams[]): Promise<BatchResult> { try { // Results array to track individual operation outcomes const results: ItemResult[] = []; // Process each item in sequence for (const item of items) { try { if (item.type === 'task') { // Extract task-specific params const taskParams: AddOmniFocusTaskParams = { name: item.name, note: item.note, dueDate: item.dueDate, deferDate: item.deferDate, flagged: item.flagged, estimatedMinutes: item.estimatedMinutes, tags: item.tags, projectName: item.projectName, parentTaskId: item.parentTaskId, parentTaskName: item.parentTaskName }; // Add task const taskResult = await addOmniFocusTask(taskParams); results.push({ success: taskResult.success, id: taskResult.taskId, error: taskResult.error }); } else if (item.type === 'project') { // Extract project-specific params const projectParams: AddProjectParams = { name: item.name, note: item.note, dueDate: item.dueDate, deferDate: item.deferDate, flagged: item.flagged, estimatedMinutes: item.estimatedMinutes, tags: item.tags, folderName: item.folderName, sequential: item.sequential }; // Add project const projectResult = await addProject(projectParams); results.push({ success: projectResult.success, id: projectResult.projectId, error: projectResult.error }); } else { // Invalid type results.push({ success: false, error: `Invalid item type: ${(item as any).type}` }); } } catch (itemError: any) { // Handle individual item errors results.push({ success: false, error: itemError.message || "Unknown error processing item" }); } } // Determine overall success (true if at least one item was added successfully) const overallSuccess = results.some(result => result.success); return { success: overallSuccess, results: results }; } catch (error: any) { console.error("Error in batchAddItems:", error); return { success: false, results: [], error: error.message || "Unknown error in batchAddItems" }; } }

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/jqlts1/omnifocus-mcp-enhanced'

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