motion_recurring_tasks
Manage recurring tasks in Motion by creating, listing, or deleting them with configurable frequency, assignees, and deadlines.
Instructions
Manage recurring tasks. Required params per operation: list: workspaceId or workspaceName. create: workspaceId/workspaceName + name + assigneeId + frequency (with frequency.type). delete: recurringTaskId.
Input Schema
TableJSON Schema
| Name | Required | Description | Default |
|---|---|---|---|
| operation | Yes | Operation to perform | |
| recurringTaskId | No | Recurring task ID. Required for: delete. | |
| workspaceId | No | Workspace ID. Required for: list, create. | |
| workspaceName | No | Workspace name (alternative to workspaceId). Required for: list, create. | |
| name | No | Task name. Required for: create. | |
| description | No | Task description. | |
| projectId | No | Project ID. | |
| assigneeId | No | User ID to assign the recurring task to. Required for: create. | |
| frequency | No | Frequency configuration (required for create) | |
| deadlineType | No | Deadline type (default: SOFT) | |
| duration | No | Task duration in minutes or REMINDER | |
| startingOn | No | Start date (ISO 8601 format) | |
| idealTime | No | Ideal time in HH:mm format | |
| schedule | No | Schedule name (default: Work Hours) | |
| priority | No | Task priority (default: MEDIUM) |
Implementation Reference
- Main handler class RecurringTaskHandler that implements the motion_recurring_tasks tool logic. Extends BaseHandler and handles three operations: list (get recurring tasks for a workspace), create (create a new recurring task with frequency configuration), and delete (delete a recurring task by ID). Uses workspace resolution and Motion service for API calls.import { BaseHandler } from './base/BaseHandler'; import { McpToolResponse } from '../types/mcp'; import { MotionRecurringTasksArgs } from '../types/mcp-tool-args'; import { CreateRecurringTaskData } from '../types/motion'; import { formatRecurringTaskList, formatRecurringTaskDetail, formatMcpSuccess } from '../utils'; export class RecurringTaskHandler extends BaseHandler { async handle(args: MotionRecurringTasksArgs): Promise<McpToolResponse> { try { const { operation } = args; switch(operation) { case 'list': return await this.handleList(args); case 'create': return await this.handleCreate(args); case 'delete': return await this.handleDelete(args); default: return this.handleUnknownOperation(operation); } } catch (error: unknown) { return this.handleError(error); } } private async handleList(args: MotionRecurringTasksArgs): Promise<McpToolResponse> { if (!args.workspaceId && !args.workspaceName) { return this.handleError(new Error('Workspace ID or workspace name is required for list operation')); } const workspace = await this.workspaceResolver.resolveWorkspace({ workspaceId: args.workspaceId, workspaceName: args.workspaceName }); const { items: recurringTasks, truncation } = await this.motionService.getRecurringTasks(workspace.id); return formatRecurringTaskList(recurringTasks, truncation); } private async handleCreate(args: MotionRecurringTasksArgs): Promise<McpToolResponse> { if (!args.name || (!args.workspaceId && !args.workspaceName) || !args.assigneeId || !args.frequency) { return this.handleError(new Error('Name, workspace ID/workspace name, assignee ID, and frequency are required for create operation')); } // Validate frequency if (!args.frequency.type || !['daily', 'weekly', 'biweekly', 'monthly', 'quarterly', 'yearly', 'custom'].includes(args.frequency.type)) { return this.handleError(new Error('Frequency type must be one of: daily, weekly, biweekly, monthly, quarterly, yearly, custom')); } const workspace = await this.workspaceResolver.resolveWorkspace({ workspaceId: args.workspaceId, workspaceName: args.workspaceName }); const taskData: CreateRecurringTaskData = { name: args.name, workspaceId: workspace.id, assigneeId: args.assigneeId, frequency: args.frequency, ...(args.description && { description: args.description }), ...(args.projectId && { projectId: args.projectId }), ...(args.deadlineType && { deadlineType: args.deadlineType }), ...(args.duration !== undefined && args.duration !== null && { duration: args.duration }), ...(args.startingOn && { startingOn: args.startingOn }), ...(args.idealTime && { idealTime: args.idealTime }), ...(args.schedule && { schedule: args.schedule }), ...(args.priority && { priority: args.priority }) }; const newTask = await this.motionService.createRecurringTask(taskData); return formatRecurringTaskDetail(newTask); } private async handleDelete(args: MotionRecurringTasksArgs): Promise<McpToolResponse> { if (!args.recurringTaskId) { return this.handleError(new Error('Recurring task ID is required for delete operation')); } await this.motionService.deleteRecurringTask(args.recurringTaskId); return formatMcpSuccess(`Recurring task ${args.recurringTaskId} deleted successfully`); } }
- src/tools/ToolDefinitions.ts:357-471 (registration)Tool definition for motion_recurring_tasks. Defines the input schema with operation types (list, create, delete), required parameters for each operation, and the frequency configuration object structure (type, daysOfWeek, dayOfMonth, weekOfMonth, monthOfQuarter, customPattern, etc.). Includes comprehensive parameter descriptions and constraints.export const recurringTasksToolDefinition: McpToolDefinition = { name: TOOL_NAMES.RECURRING_TASKS, description: "Manage recurring tasks. Required params per operation: list: workspaceId or workspaceName. create: workspaceId/workspaceName + name + assigneeId + frequency (with frequency.type). delete: recurringTaskId.", inputSchema: { type: "object", properties: { operation: { type: "string", enum: ["list", "create", "delete"], description: "Operation to perform" }, recurringTaskId: { type: "string", description: "Recurring task ID. Required for: delete." }, workspaceId: { type: "string", description: "Workspace ID. Required for: list, create." }, workspaceName: { type: "string", description: "Workspace name (alternative to workspaceId). Required for: list, create." }, name: { type: "string", description: "Task name. Required for: create." }, description: { type: "string", description: "Task description." }, projectId: { type: "string", description: "Project ID." }, assigneeId: { type: "string", description: "User ID to assign the recurring task to. Required for: create." }, frequency: { type: "object", properties: { type: { type: "string", enum: ["daily", "weekly", "biweekly", "monthly", "quarterly", "yearly", "custom"], description: "Frequency type - supports all Motion API patterns including biweekly and quarterly" }, daysOfWeek: { type: "array", items: { type: "number" }, description: "0-6 for Sunday-Saturday. Used with daily/weekly/biweekly for specific days, and with monthly/quarterly patterns (e.g., monthly_first_MO, quarterly_first_MO) for specifying days in those recurrence types" }, dayOfMonth: { type: "number", description: "1-31 for monthly recurrence on specific day of month" }, weekOfMonth: { type: "string", enum: ["first", "second", "third", "fourth", "last"], description: "Which week of month/quarter for monthly/quarterly patterns; daysOfWeek is optional (e.g., monthly_any_day_first_week or monthly_monday_first_week)" }, monthOfQuarter: { type: "number", enum: [1, 2, 3], description: "Which month of quarter (1-3) for quarterly patterns" }, interval: { type: "number", description: "Legacy support: weekly with interval:2 maps to biweekly patterns" }, customPattern: { type: "string", description: "Direct Motion API frequency pattern string (e.g., 'monthly_any_week_day_first_week')" }, endDate: { type: "string", description: "ISO 8601 format end date for the recurring task" } }, required: ["type"], description: "Frequency configuration (required for create)" }, deadlineType: { type: "string", enum: ["HARD", "SOFT"], description: "Deadline type (default: SOFT)" }, duration: { oneOf: [ { type: "number" }, { type: "string", enum: ["REMINDER"] } ], description: "Task duration in minutes or REMINDER" }, startingOn: { type: "string", description: "Start date (ISO 8601 format)" }, idealTime: { type: "string", description: "Ideal time in HH:mm format" }, schedule: { type: "string", description: "Schedule name (default: Work Hours)" }, priority: { type: "string", enum: ["ASAP", "HIGH", "MEDIUM", "LOW"], description: "Task priority (default: MEDIUM)" } }, required: ["operation"] } };
- src/handlers/HandlerFactory.ts:27-38 (registration)Handler registration that maps the motion_recurring_tasks tool name to the RecurringTaskHandler class. The registerHandlers() method sets up the mapping so when the tool is invoked, the factory creates an instance of RecurringTaskHandler.private registerHandlers(): void { this.handlers.set(TOOL_NAMES.TASKS, TaskHandler); this.handlers.set(TOOL_NAMES.PROJECTS, ProjectHandler); this.handlers.set(TOOL_NAMES.WORKSPACES, WorkspaceHandler); this.handlers.set(TOOL_NAMES.USERS, UserHandler); this.handlers.set(TOOL_NAMES.SEARCH, SearchHandler); this.handlers.set(TOOL_NAMES.COMMENTS, CommentHandler); this.handlers.set(TOOL_NAMES.CUSTOM_FIELDS, CustomFieldHandler); this.handlers.set(TOOL_NAMES.RECURRING_TASKS, RecurringTaskHandler); this.handlers.set(TOOL_NAMES.SCHEDULES, ScheduleHandler); this.handlers.set(TOOL_NAMES.STATUSES, StatusHandler); }
- src/schemas/motion.ts:172-225 (schema)Zod schema MotionRecurringTaskSchema for validating recurring task data from the Motion API. Includes fields for id, name, creator, assignee, project, workspace, status, priority, and labels. Also defines RecurringTasksResponseSchema that wraps recurring task data with pagination metadata.// Motion Recurring Task schema - Updated to match API structure (returns task instances) export const MotionRecurringTaskSchema = z.object({ id: z.string(), name: z.string(), creator: z.object({ id: z.string(), name: z.string(), email: z.string() }), assignee: z.object({ id: z.string(), name: z.string(), email: z.string() }), project: z.object({ id: z.string(), name: z.string(), description: z.string(), workspaceId: z.string(), status: z.object({ name: z.string(), isDefaultStatus: z.boolean(), isResolvedStatus: z.boolean() }), customFieldValues: z.record(z.string(), z.object({ type: z.string(), value: z.unknown() })).optional() }).optional(), workspace: z.object({ id: z.string(), name: z.string(), teamId: z.string().nullable(), type: z.string(), labels: z.array(z.union([ z.string(), z.object({ name: z.string() }) ])), statuses: z.array(z.object({ name: z.string(), isDefaultStatus: z.boolean(), isResolvedStatus: z.boolean() })).optional() }), status: z.object({ name: z.string(), isDefaultStatus: z.boolean(), isResolvedStatus: z.boolean() }), priority: z.enum(['ASAP', 'HIGH', 'MEDIUM', 'LOW']), labels: z.array(z.object({ name: z.string() })) });
- src/types/motion.ts:282-306 (schema)TypeScript type definitions for recurring tasks: FrequencyObject interface defines the frequency configuration (type, daysOfWeek, dayOfMonth, weekOfMonth, monthOfQuarter, customPattern, endDate), and CreateRecurringTaskData interface defines the data structure for creating new recurring tasks including all optional fields like description, deadlineType, duration, etc.export interface FrequencyObject { type: 'daily' | 'weekly' | 'biweekly' | 'monthly' | 'quarterly' | 'yearly' | 'custom'; daysOfWeek?: number[]; // [0-6] for Sunday-Saturday dayOfMonth?: number; // 1-31 for monthly patterns weekOfMonth?: 'first' | 'second' | 'third' | 'fourth' | 'last'; // For monthly/quarterly monthOfQuarter?: 1 | 2 | 3; // For quarterly patterns interval?: number; // Legacy support: weekly + interval:2 → biweekly customPattern?: string; // Direct Motion API pattern for complex cases endDate?: string; // ISO 8601 format end date } export interface CreateRecurringTaskData { name: string; workspaceId: string; projectId?: string; assigneeId: string; frequency: FrequencyObject; description?: string; deadlineType?: 'HARD' | 'SOFT'; duration?: number | 'REMINDER'; startingOn?: string; idealTime?: string; schedule?: string; priority?: 'ASAP' | 'HIGH' | 'MEDIUM' | 'LOW'; }