export_tasks_ics
Export tasks from Microsoft To Do to iCalendar format for import into Google Calendar, Apple Calendar, Outlook, or Thunderbird. Converts recurrence to RRULE and reminders to VALARM.
Instructions
Export tasks to iCalendar format (text/calendar VTODO) for import into Google Calendar, Apple Calendar, Outlook, Thunderbird, etc. Recurrence converted to RRULE when possible. Reminder converted to VALARM.
Input Schema
| Name | Required | Description | Default |
|---|---|---|---|
| list_ids | No | ||
| include_completed | No | ||
| top_per_list | No |
Implementation Reference
- src/graph.ts:1028-1099 (handler)Core handler function that exports tasks to iCalendar format. Iterates over task lists, builds VTODO components with UID, summary, description, due date, status, priority, categories, RRULE for recurrence, and VALARM for reminders. Returns the full VCALENDAR string.
export async function exportTasksIcs( opts: { listIds?: string[]; includeCompleted?: boolean; topPerList?: number; } = {} ): Promise<string> { const allLists = await listTaskLists(); const lists = opts.listIds ? allLists.filter((l) => opts.listIds!.includes(l.id)) : allLists; const filterParts: string[] = []; if (!opts.includeCompleted) filterParts.push("status ne 'completed'"); const filter = filterParts.length > 0 ? filterParts.join(" and ") : undefined; const top = opts.topPerList ?? 100; const lines: string[] = [ "BEGIN:VCALENDAR", "VERSION:2.0", "PRODID:-//mag-cie//mcp-microsoft-todo//FR", "CALSCALE:GREGORIAN", ]; const now = formatIcsDate(new Date().toISOString()); for (const list of lists) { let tasks: TodoTask[] = []; try { tasks = await listTasks(list.id, { filter, top }); } catch { continue; } for (const task of tasks) { lines.push("BEGIN:VTODO"); lines.push(`UID:${task.id}@mcp-microsoft-todo`); lines.push(`DTSTAMP:${now}`); lines.push( `SUMMARY:${escapeIcsText(`[${list.displayName}] ${task.title}`)}` ); if (task.body?.content) lines.push(`DESCRIPTION:${escapeIcsText(task.body.content)}`); if (task.dueDateTime) lines.push(`DUE:${formatIcsDate(task.dueDateTime.dateTime)}`); if (task.status === "completed") lines.push("STATUS:COMPLETED"); else if (task.status === "inProgress") lines.push("STATUS:IN-PROCESS"); else lines.push("STATUS:NEEDS-ACTION"); if (task.importance === "high") lines.push("PRIORITY:1"); else if (task.importance === "low") lines.push("PRIORITY:9"); if (task.categories?.length) { lines.push( `CATEGORIES:${task.categories.map(escapeIcsText).join(",")}` ); } if (task.recurrence) { const rrule = recurrenceToRRule(task.recurrence); if (rrule) lines.push(`RRULE:${rrule}`); } if (task.isReminderOn && task.reminderDateTime) { lines.push("BEGIN:VALARM"); lines.push("ACTION:DISPLAY"); lines.push( `TRIGGER;VALUE=DATE-TIME:${formatIcsDate(task.reminderDateTime.dateTime)}` ); lines.push("DESCRIPTION:Reminder"); lines.push("END:VALARM"); } lines.push("END:VTODO"); } } lines.push("END:VCALENDAR"); return lines.join("\r\n"); } - src/index.ts:341-348 (schema)Zod schema for export_tasks_ics input validation: optional list_ids (array of strings), include_completed (boolean), and top_per_list (positive integer up to 500).
export_tasks_ics: z.object({ list_ids: z .array(z.string()) .optional() .describe("Restrict to the given list IDs. If omitted: all lists."), include_completed: z.boolean().optional(), top_per_list: z.number().int().positive().max(500).optional(), }), - src/index.ts:940-953 (registration)MCP tool registration: exports the tool metadata (name, description, inputSchema) alongside other tools. Annotations from ANNOTATIONS object are merged via map().
{ name: "export_tasks_ics", description: "Export tasks to iCalendar format (text/calendar VTODO) for import into Google Calendar, Apple Calendar, Outlook, Thunderbird, etc. Recurrence converted to RRULE when possible. Reminder converted to VALARM.", inputSchema: { type: "object", properties: { list_ids: { type: "array", items: { type: "string" } }, include_completed: { type: "boolean" }, top_per_list: { type: "number" }, }, }, }, ]).map((tool) => ({ ...tool, annotations: ANNOTATIONS[tool.name] })), - src/index.ts:1211-1219 (handler)CallTool request handler case for export_tasks_ics: parses args with Zod schema, calls exportTasksIcs from graph.ts, and returns the ICS string as text content.
case "export_tasks_ics": { const a = schemas.export_tasks_ics.strict().parse(args ?? {}); const ics = await exportTasksIcs({ listIds: a.list_ids, includeCompleted: a.include_completed, topPerList: a.top_per_list, }); return text(ics); } - src/index.ts:491-492 (registration)ANNOTATIONS entry for export_tasks_ics tool, inheriting READ annotation.
export_tasks_ics: { ...READ, title: "Export tasks as iCalendar (.ics)" }, };