@doist/todoist-mcp 12.3.0 → 12.3.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,6 +1,6 @@
1
1
  import { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';
2
2
  import { FEATURE_NAMES, Feature, FeatureName, Features } from './mcp-helpers.js';
3
- export declare const instructions = "\n## Todoist Task and Project Management Tools\n\nYou have access to comprehensive Todoist management tools for personal productivity and team collaboration. Use these tools to help users manage tasks, projects, sections, comments, and assignments effectively.\n\n### Core Capabilities:\n- Create, update, complete, and search tasks with rich metadata (priorities, due dates, durations, assignments)\n- Manage projects and sections with flexible organization\n- Handle comments and collaboration features\n- Bulk assignment operations for team workflows\n- Get overviews and insights about workload and progress\n\n### Tool Usage Guidelines:\n\n**Task Management:**\n- **add-tasks**: Create tasks (max 25 per call) with content, description, priority (`p1`, `p2`, `p3`, `p4` strings only; `p1` highest and `p4` lowest/default; integers are not accepted), dueString (natural language like \"tomorrow\", \"next Friday\", \"2024-12-25\"), deadlineDate (ISO 8601 format like \"2025-12-31\" for immovable constraints), duration (formats like \"2h\", \"90m\", \"2h30m\"), and assignments to project collaborators\n- **update-tasks**: Modify existing tasks - get task IDs from search results first, only include fields that need changes. Supports priority updates using `p1`/`p2`/`p3`/`p4` string values (`p1` highest, `p4` lowest/default; integers are not accepted), due date updates via dueString and due date removal via \"dueString: remove\", plus deadlineDate (ISO 8601 format like \"2025-12-31\") updates and removals via \"deadlineDate: remove\". **IMPORTANT: Do NOT use update-tasks to reschedule/move task dates \u2014 use reschedule-tasks instead.** update-tasks replaces the entire due string which destroys recurrence patterns on recurring tasks.\n- **reschedule-tasks**: **Always use this tool when moving/rescheduling task due dates to a different date.** This tool preserves recurring schedules and existing time-of-day. Accepts YYYY-MM-DD or YYYY-MM-DDTHH:MM:SS. Works for both recurring and non-recurring tasks. Do NOT use update-tasks for rescheduling.\n- **complete-tasks**: Mark tasks as done using task IDs\n- **uncomplete-tasks**: Reopen completed tasks using task IDs\n- **find-tasks**: Search by text, project/section/parent container, responsible user, labels, a raw Todoist `filter` string (e.g. \"today\", \"p1\", \"##Work\", \"(today | overdue) & p1\"), or a saved filter by ID or name (`filterIdOrName`). Requires at least one search parameter. `filter`/`filterIdOrName` cannot be combined with projectId/sectionId/parentId, and `filter` and `filterIdOrName` are mutually exclusive.\n- **find-tasks-by-date**: Get tasks by date range (startDate: YYYY-MM-DD or 'today' which includes overdue tasks) or specific day counts\n- **find-completed-tasks**: View completed tasks by completion date or original due date; if since/until are omitted, defaults to the last 7 days (returns all collaborators unless filtered)\n\n**Project & Organization:**\n- **add-projects/update-projects/find-projects**: Manage project lifecycle with names, descriptions (Markdown), favorites, view styles (list/board/calendar), and workspace assignment for new projects (by name or ID). find-projects returns active projects by default; pass archivedStatus ('archived' or 'all') to include archived projects. Every returned project includes an isArchived field\n- **project-management**: Archive or unarchive projects by ID\n- To delete a project (active or archived), use **delete-object** with type \"project\". Note: workspace projects must be archived first; personal projects can be deleted regardless\n- **project-move**: Move projects between personal and workspace contexts\n- **add-sections/update-sections/find-sections**: Organize tasks within projects using sections\n- **get-overview**: Get comprehensive Markdown overview of entire account or specific project with task hierarchies. Project data includes parentId (sub-projects), folderId (workspace folder membership), and childOrder (sibling ordering)\n- **list-workspaces**: Get all workspaces for the user with details like plan type, role, and settings\n\n**Reminders:**\n- **add-reminders**: Create reminders for tasks. Three types: \"relative\" (minutes before due), \"absolute\" (specific date/time), or \"location\" (geofence-triggered). Each reminder must specify a taskId.\n- **find-reminders**: Find reminders by task ID (returns both time-based and location reminders), or get a specific reminder by ID (use reminderId for time-based, locationReminderId for location-based).\n- **update-reminders**: Update existing reminders. Must specify the reminder type (\"relative\", \"absolute\", or \"location\") and ID.\n- Relative and absolute reminders support an **isUrgent** flag to mark a reminder as urgent.\n- Reminders can be deleted using **delete-object** with type \"reminder\" (time-based) or \"location_reminder\" (location-based).\n\n**Collaboration & Comments:**\n- **add-comments/update-comments/find-comments**: Manage task and project discussions\n- **view-attachment**: View file attachments from comments. Pass the fileUrl from a comment's fileAttachment. Returns images inline, text files as text, and binary files as embedded resources.\n- **find-project-collaborators**: Look up Todoist users (collaborators, teammates) by name or email to get their user ID \u2014 use for \"find/who is X\" questions or any time you need to resolve a person's name to an ID. By default searches collaborators of every shared project the authenticated user can access (plus the authenticated user themselves). An empty result means the person is not a collaborator on any shared project, not that they do not exist. Pass projectId to scope to a single project\n- **manage-assignments**: Bulk assign/unassign/reassign up to 50 tasks with atomic operations and dry-run validation\n\n**Filters:**\n- **find-filters**: List all personal filters or search by name; filters are saved task views using query syntax\n- **add-filters**: Create personal filters with name, query (e.g. \"today & p1\"), color, and favorite flag\n- **update-filters**: Modify existing filters' name, query, color, or favorite status\n\n**Activity & Audit:**\n- **find-activity**: Retrieve recent activity logs to monitor and audit changes. Shows events from all users by default; use initiatorId to filter by specific user. Filter by object type (task/project/comment), event type (added/updated/deleted/completed/uncompleted/archived/unarchived/shared/left), and specific objects (objectId, projectId, taskId). Useful for tracking who did what and when. Note: Date-based filtering is not supported.\n- **get-productivity-stats**: Get comprehensive productivity statistics including daily/weekly completion breakdowns, goal streaks (current, last, max), karma score and trends, and historical karma data. No parameters required.\n\n**Project Health & Insights:**\n- **get-project-health**: Get comprehensive health assessment for a project including completion progress (completed/active counts, percentage), health status (EXCELLENT/ON_TRACK/AT_RISK/CRITICAL), description, and task-level recommendations. Use includeContext=true for detailed metrics (overdue tasks, weekly activity, avg completion time) and full task data. Health data may be stale \u2014 check isStale flag.\n- **get-project-activity-stats**: Get daily and optional weekly activity statistics for a project over a configurable time window (1-12 weeks). Useful for identifying activity trends.\n- **analyze-project-health**: Trigger a new health analysis for a project. Use when health data is stale. The analysis may take time \u2014 use get-project-health afterward to see updated results.\n- **get-workspace-insights**: Get aggregated health and progress insights across all projects in a workspace. Accepts workspace name or ID, with optional project ID filtering.\n\n**General Operations:**\n- **delete-object**: Remove projects, sections, tasks, comments, labels, filters, reminders, or location reminders by type and ID. Deletes both active and archived projects (workspace projects must be archived first; use find-projects with archivedStatus to locate archived projects)\n- **fetch-object**: Fetch a single task, project, comment, or section by its ID. Pass includeChildren=true to also get its direct children (subtasks for a task, sub-projects for a project) with a childCount - use this to check whether a task hides subtasks rather than a speculative find-tasks call\n- **reorder-objects**: Reorder sibling projects or sections, and optionally move projects to a new parent. For projects: set order to reorder siblings, and/or set parentId to move under a new parent (use \"root\" for top level). For sections: set order to reorder within a project\n- **user-info**: Get user details including timezone, goals, and plan information\n\n### Best Practices:\n\n1. **Task Creation**: Write clear, actionable task titles. Use natural language for due dates (\"tomorrow\", \"next Monday\"). Set appropriate priorities and include detailed descriptions when needed.\n\n2. **Search Strategy**: Use specific search queries combining multiple filters for precise results. When searching for tasks, start with broader queries and narrow down as needed.\n\n3. **Assignments & user lookup**: Always validate project collaborators exist before assigning tasks. Use find-project-collaborators to verify user access. Also use find-project-collaborators (with just a searchTerm and no projectId) to resolve a user's ID whenever the user references a person by name or email \u2014 it searches collaborators of all shared projects you can access, plus yourself.\n\n4. **Bulk Operations**: When working with multiple items, prefer bulk tools (complete-tasks, manage-assignments) over individual operations for better performance.\n\n5. **Date Handling**: All dates respect user timezone settings. Use 'today' keyword for dynamic date filtering (includes overdue tasks). **When rescheduling/moving tasks to a different date, always use reschedule-tasks** \u2014 never update-tasks with dueString, as that destroys recurrence on recurring tasks.\n\n6. **Labels**: Use label filtering with AND/OR operators for advanced task organization. Most search tools support labels parameter. Use **find-labels** to discover personal and shared labels \u2014 use label **names** (not IDs) when filtering tasks, and use label **IDs** only with **delete-object** and **update-labels** (for personal label updates). Use **add-labels** to create new personal labels. Use **update-labels** to rename or recolor personal labels (by ID), or to rename shared labels (by name) \u2014 note that shared labels support renaming only, not color/order/favorite changes.\n\n7. **Pagination**: Large result sets use cursor-based pagination. Use limit parameter to control result size (default varies by tool).\n\n8. **Error Handling**: All tools provide detailed error messages and next-step suggestions. Pay attention to validation feedback for corrective actions. Batch tools (e.g. add-tasks, update-tasks) report per-item `failures` alongside successes \u2014 a single failed item does not undo the rest of the batch. When an item fails, **do not retry the whole batch**; inspect its failure reason and only re-send the items that are actually fixable.\n\n### Common Workflows:\n\n- **Daily Planning**: Use find-tasks-by-date with 'today' and get-overview for project status\n- **Team Assignment**: find-project-collaborators \u2192 add-tasks with responsibleUser \u2192 manage-assignments for bulk changes\n- **User Lookup**: find-project-collaborators with just a searchTerm (no projectId) to resolve a name or email to a Todoist user ID across all shared-project collaborators you can access\n- **Task Search**: find-tasks with multiple filters \u2192 update-tasks or complete-tasks based on results\n- **Project Organization**: add-projects \u2192 add-sections \u2192 add-tasks with projectId and sectionId\n- **Progress Reviews**: find-completed-tasks (defaults to last 7 days; optionally use explicit date ranges) \u2192 get-overview for project summaries\n- **Activity Auditing**: find-activity with event/object filters to track changes, monitor team activity, or investigate specific actions\n- **Productivity Analysis**: Use the productivity-analysis prompt for comprehensive analysis combining user-info, get-productivity-stats, and find-completed-tasks data into actionable insights\n- **Project Health Reviews**: get-project-health \u2192 analyze-project-health if stale \u2192 get-project-health with includeContext=true for detailed metrics \u2192 get-workspace-insights for cross-project overview\n\nAlways provide clear, actionable task titles and descriptions. Use the overview tools to give users context about their workload and project status.\n";
3
+ export declare const instructions = "\n## Todoist Task and Project Management Tools\n\nYou have access to comprehensive Todoist management tools for personal productivity and team collaboration. Use these tools to help users manage tasks, projects, sections, comments, and assignments effectively.\n\n### Core Capabilities:\n- Create, update, complete, and search tasks with rich metadata (priorities, due dates, durations, assignments)\n- Manage projects and sections with flexible organization\n- Handle comments and collaboration features\n- Bulk assignment operations for team workflows\n- Get overviews and insights about workload and progress\n\n### Tool Usage Guidelines:\n\n**Task Management:**\n- **add-tasks**: Create tasks (max 25 per call) with content, description, priority (`p1`, `p2`, `p3`, `p4` strings only; `p1` highest and `p4` lowest/default; integers are not accepted), dueString (natural language like \"tomorrow\", \"next Friday\", \"2024-12-25\"; also use natural language for recurrences and do not prefix them with `recurring`), deadlineDate (ISO 8601 format like \"2025-12-31\" for immovable constraints), duration (formats like \"2h\", \"90m\", \"2h30m\"), and assignments to project collaborators\n- **update-tasks**: Modify existing tasks - get task IDs from search results first, only include fields that need changes. Supports priority updates using `p1`/`p2`/`p3`/`p4` string values (`p1` highest, `p4` lowest/default; integers are not accepted), due date updates via dueString and due date removal via \"dueString: remove\", plus deadlineDate (ISO 8601 format like \"2025-12-31\") updates and removals via \"deadlineDate: remove\". **IMPORTANT: Do NOT use update-tasks to reschedule/move task dates \u2014 use reschedule-tasks instead.** update-tasks replaces the entire due string which destroys recurrence patterns on recurring tasks. Never echo back a task's existing projectId/sectionId/parentId \u2014 those fields are treated as a move.\n- **reschedule-tasks**: **Always use this tool when moving/rescheduling task due dates to a different date.** This tool preserves recurring schedules and existing time-of-day. Accepts YYYY-MM-DD or YYYY-MM-DDTHH:MM:SS. Works for both recurring and non-recurring tasks. Do NOT use update-tasks for rescheduling.\n- **complete-tasks**: Mark tasks as done using task IDs\n- **uncomplete-tasks**: Reopen completed tasks using task IDs\n- **find-tasks**: Search by text, project/section/parent container, responsible user, labels, a raw Todoist `filter` string (e.g. \"today\", \"p1\", \"##Work\", \"(today | overdue) & p1\"), or a saved filter by ID or name (`filterIdOrName`). Requires at least one search parameter. `filter`/`filterIdOrName` cannot be combined with projectId/sectionId/parentId, and `filter` and `filterIdOrName` are mutually exclusive.\n- **find-tasks-by-date**: Get tasks by date range (startDate: YYYY-MM-DD or 'today' which includes overdue tasks) or specific day counts\n- **find-completed-tasks**: View completed tasks by completion date or original due date; if since/until are omitted, defaults to the last 7 days (returns all collaborators unless filtered)\n\n**Project & Organization:**\n- **add-projects/update-projects/find-projects**: Manage project lifecycle with names, descriptions (Markdown), favorites, view styles (list/board/calendar), and workspace assignment for new projects (by name or ID). find-projects returns active projects by default; pass archivedStatus ('archived' or 'all') to include archived projects. Every returned project includes an isArchived field\n- **project-management**: Archive or unarchive projects by ID\n- To delete a project (active or archived), use **delete-object** with type \"project\". Note: workspace projects must be archived first; personal projects can be deleted regardless\n- **project-move**: Move projects between personal and workspace contexts\n- **add-sections/update-sections/find-sections**: Organize tasks within projects using sections\n- **get-overview**: Get comprehensive Markdown overview of entire account or specific project with task hierarchies. Project data includes parentId (sub-projects), folderId (workspace folder membership), and childOrder (sibling ordering)\n- **list-workspaces**: Get all workspaces for the user with details like plan type, role, and settings\n\n**Reminders:**\n- **add-reminders**: Create reminders for tasks. Three types: \"relative\" (minutes before due), \"absolute\" (specific date/time), or \"location\" (geofence-triggered). Each reminder must specify a taskId.\n- **find-reminders**: Find reminders by task ID (returns both time-based and location reminders), or get a specific reminder by ID (use reminderId for time-based, locationReminderId for location-based).\n- **update-reminders**: Update existing reminders. Must specify the reminder type (\"relative\", \"absolute\", or \"location\") and ID.\n- Relative and absolute reminders support an **isUrgent** flag to mark a reminder as urgent.\n- Reminders can be deleted using **delete-object** with type \"reminder\" (time-based) or \"location_reminder\" (location-based).\n\n**Collaboration & Comments:**\n- **add-comments/update-comments/find-comments**: Manage task and project discussions\n- **view-attachment**: View file attachments from comments. Pass the fileUrl from a comment's fileAttachment. Returns images inline, text files as text, and binary files as embedded resources.\n- **find-project-collaborators**: Look up Todoist users (collaborators, teammates) by name or email to get their user ID \u2014 use for \"find/who is X\" questions or any time you need to resolve a person's name to an ID. By default searches collaborators of every shared project the authenticated user can access (plus the authenticated user themselves). An empty result means the person is not a collaborator on any shared project, not that they do not exist. Pass projectId to scope to a single project\n- **manage-assignments**: Bulk assign/unassign/reassign up to 50 tasks with atomic operations and dry-run validation\n\n**Filters:**\n- **find-filters**: List all personal filters or search by name; filters are saved task views using query syntax\n- **add-filters**: Create personal filters with name, query (e.g. \"today & p1\"), color, and favorite flag\n- **update-filters**: Modify existing filters' name, query, color, or favorite status\n\n**Activity & Audit:**\n- **find-activity**: Retrieve recent activity logs to monitor and audit changes. Shows events from all users by default; use initiatorId to filter by specific user. Filter by object type (task/project/comment), event type (added/updated/deleted/completed/uncompleted/archived/unarchived/shared/left), and specific objects (objectId, projectId, taskId). Useful for tracking who did what and when. Note: Date-based filtering is not supported.\n- **get-productivity-stats**: Get comprehensive productivity statistics including daily/weekly completion breakdowns, goal streaks (current, last, max), karma score and trends, and historical karma data. No parameters required.\n\n**Project Health & Insights:**\n- **get-project-health**: Get comprehensive health assessment for a project including completion progress (completed/active counts, percentage), health status (EXCELLENT/ON_TRACK/AT_RISK/CRITICAL), description, and task-level recommendations. Use includeContext=true for detailed metrics (overdue tasks, weekly activity, avg completion time) and full task data. Health data may be stale \u2014 check isStale flag.\n- **get-project-activity-stats**: Get daily and optional weekly activity statistics for a project over a configurable time window (1-12 weeks). Useful for identifying activity trends.\n- **analyze-project-health**: Trigger a new health analysis for a project. Use when health data is stale. The analysis may take time \u2014 use get-project-health afterward to see updated results.\n- **get-workspace-insights**: Get aggregated health and progress insights across all projects in a workspace. Accepts workspace name or ID, with optional project ID filtering.\n\n**General Operations:**\n- **delete-object**: Remove projects, sections, tasks, comments, labels, filters, reminders, or location reminders by type and ID. Deletes both active and archived projects (workspace projects must be archived first; use find-projects with archivedStatus to locate archived projects)\n- **fetch-object**: Fetch a single task, project, comment, or section by its ID. Pass includeChildren=true to also get its direct children (subtasks for a task, sub-projects for a project) with a childCount - use this to check whether a task hides subtasks rather than a speculative find-tasks call\n- **reorder-objects**: Reorder sibling projects or sections, and optionally move projects to a new parent. For projects: set order to reorder siblings, and/or set parentId to move under a new parent (use \"root\" for top level). For sections: set order to reorder within a project\n- **user-info**: Get user details including timezone, goals, and plan information\n\n### Best Practices:\n\n1. **Task Creation**: Write clear, actionable task titles. Use natural language for due dates (\"tomorrow\", \"next Monday\"). Set appropriate priorities and include detailed descriptions when needed.\n\n2. **Search Strategy**: Use specific search queries combining multiple filters for precise results. When searching for tasks, start with broader queries and narrow down as needed.\n\n3. **Assignments & user lookup**: Always validate project collaborators exist before assigning tasks. Use find-project-collaborators to verify user access. Also use find-project-collaborators (with just a searchTerm and no projectId) to resolve a user's ID whenever the user references a person by name or email \u2014 it searches collaborators of all shared projects you can access, plus yourself.\n\n4. **Bulk Operations**: When working with multiple items, prefer bulk tools (complete-tasks, manage-assignments) over individual operations for better performance.\n\n5. **Date Handling**: All dates respect user timezone settings. Use 'today' keyword for dynamic date filtering (includes overdue tasks). **When rescheduling/moving tasks to a different date, always use reschedule-tasks** \u2014 never update-tasks with dueString, as that destroys recurrence on recurring tasks.\n\n6. **Labels**: Use label filtering with AND/OR operators for advanced task organization. Most search tools support labels parameter. Use **find-labels** to discover personal and shared labels \u2014 use label **names** (not IDs) when filtering tasks, and use label **IDs** only with **delete-object** and **update-labels** (for personal label updates). Use **add-labels** to create new personal labels. Use **update-labels** to rename or recolor personal labels (by ID), or to rename shared labels (by name) \u2014 note that shared labels support renaming only, not color/order/favorite changes.\n\n7. **Pagination**: Large result sets use cursor-based pagination. Use limit parameter to control result size (default varies by tool).\n\n8. **Error Handling**: All tools provide detailed error messages and next-step suggestions. Pay attention to validation feedback for corrective actions. Batch tools (e.g. add-tasks, update-tasks) report per-item `failures` alongside successes \u2014 a single failed item does not undo the rest of the batch. When an item fails, **do not retry the whole batch**; inspect its failure reason and only re-send the items that are actually fixable.\n\n### Common Workflows:\n\n- **Daily Planning**: Use find-tasks-by-date with 'today' and get-overview for project status\n- **Team Assignment**: find-project-collaborators \u2192 add-tasks with responsibleUser \u2192 manage-assignments for bulk changes\n- **User Lookup**: find-project-collaborators with just a searchTerm (no projectId) to resolve a name or email to a Todoist user ID across all shared-project collaborators you can access\n- **Task Search**: find-tasks with multiple filters \u2192 update-tasks or complete-tasks based on results\n- **Project Organization**: add-projects \u2192 add-sections \u2192 add-tasks with projectId and sectionId\n- **Progress Reviews**: find-completed-tasks (defaults to last 7 days; optionally use explicit date ranges) \u2192 get-overview for project summaries\n- **Activity Auditing**: find-activity with event/object filters to track changes, monitor team activity, or investigate specific actions\n- **Productivity Analysis**: Use the productivity-analysis prompt for comprehensive analysis combining user-info, get-productivity-stats, and find-completed-tasks data into actionable insights\n- **Project Health Reviews**: get-project-health \u2192 analyze-project-health if stale \u2192 get-project-health with includeContext=true for detailed metrics \u2192 get-workspace-insights for cross-project overview\n\nAlways provide clear, actionable task titles and descriptions. Use the overview tools to give users context about their workload and project status.\n";
4
4
  /**
5
5
  * Create the MCP server.
6
6
  * @param todoistApiKey - The API key for the todoist account.
@@ -1 +1 @@
1
- {"version":3,"file":"mcp-server.d.ts","sourceRoot":"","sources":["../src/mcp-server.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAA;AAGnE,OAAO,EACH,aAAa,EACb,KAAK,OAAO,EACZ,KAAK,WAAW,EAChB,KAAK,QAAQ,EAEhB,MAAM,kBAAkB,CAAA;AAiDzB,eAAO,MAAM,YAAY,mjZAkGxB,CAAA;AAED;;;;;;GAMG;AACH,iBAAS,YAAY,CAAC,EAClB,aAAa,EACb,OAAO,EACP,QAAa,GAChB,EAAE;IACC,aAAa,EAAE,MAAM,CAAA;IACrB,OAAO,CAAC,EAAE,MAAM,CAAA;IAChB,QAAQ,CAAC,EAAE,QAAQ,CAAA;CACtB,aAwHA;AAED,OAAO,EAAE,aAAa,EAAE,KAAK,OAAO,EAAE,KAAK,WAAW,EAAE,KAAK,QAAQ,EAAE,YAAY,EAAE,CAAA"}
1
+ {"version":3,"file":"mcp-server.d.ts","sourceRoot":"","sources":["../src/mcp-server.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAA;AAGnE,OAAO,EACH,aAAa,EACb,KAAK,OAAO,EACZ,KAAK,WAAW,EAChB,KAAK,QAAQ,EAEhB,MAAM,kBAAkB,CAAA;AAiDzB,eAAO,MAAM,YAAY,gvZAkGxB,CAAA;AAED;;;;;;GAMG;AACH,iBAAS,YAAY,CAAC,EAClB,aAAa,EACb,OAAO,EACP,QAAa,GAChB,EAAE;IACC,aAAa,EAAE,MAAM,CAAA;IACrB,OAAO,CAAC,EAAE,MAAM,CAAA;IAChB,QAAQ,CAAC,EAAE,QAAQ,CAAA;CACtB,aAwHA;AAED,OAAO,EAAE,aAAa,EAAE,KAAK,OAAO,EAAE,KAAK,WAAW,EAAE,KAAK,QAAQ,EAAE,YAAY,EAAE,CAAA"}
@@ -1,4 +1,4 @@
1
- import { P as A, Q as v, R as T } from "./mcp-server-BOvuwJio.js";
1
+ import { P as A, Q as v, R as T } from "./mcp-server-CNSVzmhm.js";
2
2
  const y = /* @__PURE__ */ new Set([401, 403]);
3
3
  function C(e) {
4
4
  const t = T(e);
@@ -1,3 +1,9 @@
1
+ export declare class DueStringParseError extends Error {
2
+ constructor(message: string);
3
+ }
4
+ export declare class BatchDueStringParseError extends Error {
5
+ constructor(message: string);
6
+ }
1
7
  /**
2
8
  * Compact single-line variant of {@link formatToolExecutionError} for batch
3
9
  * tools that report per-item failures. Unlike `error.message` (which for SDK
@@ -6,6 +12,17 @@
6
12
  * recognizable after aggregation.
7
13
  */
8
14
  export declare function formatBatchItemError(error: unknown): string;
15
+ /**
16
+ * Return task-specific recovery guidance only when Todoist rejected a supplied
17
+ * natural-language due string. The REST API currently returns the generic
18
+ * text "Invalid date format" without a stable field/tag, so callers must pass
19
+ * the known field context before we use that fallback.
20
+ */
21
+ export declare function formatDueStringParseError(error: unknown, { taskContent, dueString, deadlineDate, }: {
22
+ taskContent: string;
23
+ dueString: string | undefined;
24
+ deadlineDate?: string;
25
+ }): string | undefined;
9
26
  /**
10
27
  * Format tool execution errors in a consistent, actionable format.
11
28
  */
@@ -1 +1 @@
1
- {"version":3,"file":"tool-execution-error.d.ts","sourceRoot":"","sources":["../src/tool-execution-error.ts"],"names":[],"mappings":"AA4fA;;;;;;GAMG;AACH,wBAAgB,oBAAoB,CAAC,KAAK,EAAE,OAAO,GAAG,MAAM,CAc3D;AAED;;GAEG;AACH,wBAAgB,wBAAwB,CAAC,KAAK,EAAE,OAAO,GAAG,MAAM,CAW/D"}
1
+ {"version":3,"file":"tool-execution-error.d.ts","sourceRoot":"","sources":["../src/tool-execution-error.ts"],"names":[],"mappings":"AA4fA,qBAAa,mBAAoB,SAAQ,KAAK;gBAC9B,OAAO,EAAE,MAAM;CAI9B;AAED,qBAAa,wBAAyB,SAAQ,KAAK;gBACnC,OAAO,EAAE,MAAM;CAI9B;AAED;;;;;;GAMG;AACH,wBAAgB,oBAAoB,CAAC,KAAK,EAAE,OAAO,GAAG,MAAM,CAkB3D;AAED;;;;;GAKG;AACH,wBAAgB,yBAAyB,CACrC,KAAK,EAAE,OAAO,EACd,EACI,WAAW,EACX,SAAS,EACT,YAAY,GACf,EAAE;IAAE,WAAW,EAAE,MAAM,CAAC;IAAC,SAAS,EAAE,MAAM,GAAG,SAAS,CAAC;IAAC,YAAY,CAAC,EAAE,MAAM,CAAA;CAAE,GACjF,MAAM,GAAG,SAAS,CA+BpB;AAED;;GAEG;AACH,wBAAgB,wBAAwB,CAAC,KAAK,EAAE,OAAO,GAAG,MAAM,CAe/D"}
@@ -1 +1 @@
1
- {"version":3,"file":"add-tasks.d.ts","sourceRoot":"","sources":["../../src/tools/add-tasks.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAqB,UAAU,EAAE,MAAM,oBAAoB,CAAA;AACvE,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAA;AAkBvB,QAAA,MAAM,uBAAuB,IAAkC,CAAA;AA0D/D,QAAA,MAAM,QAAQ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;sBAmDwB,MAAM;uBAAS,MAAM;;;;;;;CA0CI,CAAA;AAkL/D,OAAO,EAAE,QAAQ,EAAE,uBAAuB,EAAE,CAAA"}
1
+ {"version":3,"file":"add-tasks.d.ts","sourceRoot":"","sources":["../../src/tools/add-tasks.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAqB,UAAU,EAAE,MAAM,oBAAoB,CAAA;AACvE,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAA;AAuBvB,QAAA,MAAM,uBAAuB,IAAkC,CAAA;AA4D/D,QAAA,MAAM,QAAQ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;sBAmDwB,MAAM;uBAAS,MAAM;;;;;;;CAgDI,CAAA;AA8L/D,OAAO,EAAE,QAAQ,EAAE,uBAAuB,EAAE,CAAA"}
@@ -63,6 +63,7 @@ declare const updateTasks: {
63
63
  updateCount: z.ZodNumber;
64
64
  skippedCount: z.ZodNumber;
65
65
  failureCount: z.ZodNumber;
66
+ redundantMovesSkipped: z.ZodNumber;
66
67
  }, z.core.$strip>;
67
68
  };
68
69
  annotations: {
@@ -120,6 +121,7 @@ declare const updateTasks: {
120
121
  updateCount: number;
121
122
  skippedCount: number;
122
123
  failureCount: number;
124
+ redundantMovesSkipped: number;
123
125
  };
124
126
  };
125
127
  }>;
@@ -1 +1 @@
1
- {"version":3,"file":"update-tasks.d.ts","sourceRoot":"","sources":["../../src/tools/update-tasks.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAQ,UAAU,EAAkB,MAAM,oBAAoB,CAAA;AAC1E,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAA;AAqIvB,QAAA,MAAM,WAAW;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;sBAsBqB,MAAM;uBAAS,MAAM;uBAAS,MAAM;;;;;;;;;CAsDX,CAAA;AAsN/D,OAAO,EAAE,WAAW,EAAE,CAAA"}
1
+ {"version":3,"file":"update-tasks.d.ts","sourceRoot":"","sources":["../../src/tools/update-tasks.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAIR,UAAU,EAEb,MAAM,oBAAoB,CAAA;AAC3B,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAA;AA2LvB,QAAA,MAAM,WAAW;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;sBAoMW,MAAM;uBAAS,MAAM;uBAAS,MAAM;;;;;;;;;;CARD,CAAA;AA+d/D,OAAO,EAAE,WAAW,EAAE,CAAA"}
@@ -1 +1 @@
1
- {"version":3,"file":"concurrency.d.ts","sourceRoot":"","sources":["../../src/utils/concurrency.ts"],"names":[],"mappings":"AAGA;;GAEG;AACH,KAAK,OAAO,GAAG,CAAC,CAAC,EAAE,EAAE,EAAE,MAAM,OAAO,CAAC,CAAC,CAAC,KAAK,OAAO,CAAC,CAAC,CAAC,CAAA;AAetD;;;;;;;;;;;;;GAaG;AACH,iBAAS,aAAa,CAClB,aAAa,EAAE,MAAM,EACrB,EAAE,cAAgD,EAAE,GAAE;IAAE,cAAc,CAAC,EAAE,MAAM,CAAA;CAAO,GACvF,OAAO,CA8DT;AAsCD;;;GAGG;AACH,iBAAS,sBAAsB,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,IAAI,CAQpE;AAMD,iBAAS,cAAc,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAE/C;AAED,iBAAS,eAAe,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAEhD;AAED,kFAAkF;AAClF,iBAAS,uBAAuB,IAAI,IAAI,CAGvC;AAED,OAAO,EACH,aAAa,EACb,cAAc,EACd,eAAe,EACf,KAAK,OAAO,EACZ,sBAAsB,EACtB,uBAAuB,GAC1B,CAAA"}
1
+ {"version":3,"file":"concurrency.d.ts","sourceRoot":"","sources":["../../src/utils/concurrency.ts"],"names":[],"mappings":"AAGA;;GAEG;AACH,KAAK,OAAO,GAAG,CAAC,CAAC,EAAE,EAAE,EAAE,MAAM,OAAO,CAAC,CAAC,CAAC,KAAK,OAAO,CAAC,CAAC,CAAC,CAAA;AAetD;;;;;;;;;;;;;GAaG;AACH,iBAAS,aAAa,CAClB,aAAa,EAAE,MAAM,EACrB,EAAE,cAAgD,EAAE,GAAE;IAAE,cAAc,CAAC,EAAE,MAAM,CAAA;CAAO,GACvF,OAAO,CA8DT;AAyCD;;;GAGG;AACH,iBAAS,sBAAsB,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,IAAI,CAQpE;AAMD,iBAAS,cAAc,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAE/C;AAED,iBAAS,eAAe,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAEhD;AAED,kFAAkF;AAClF,iBAAS,uBAAuB,IAAI,IAAI,CAGvC;AAED,OAAO,EACH,aAAa,EACb,cAAc,EACd,eAAe,EACf,KAAK,OAAO,EACZ,sBAAsB,EACtB,uBAAuB,GAC1B,CAAA"}
@@ -52,16 +52,17 @@ export declare const BatchLimits: {
52
52
  };
53
53
  export declare const ConcurrencyLimits: {
54
54
  /**
55
- * In-flight task-move requests per account.
55
+ * In-flight task-move requests per account, per process.
56
56
  *
57
57
  * Kept at 1 because the API locks the whole task tree for a move, and a tree
58
58
  * spans a task's source as well as its destination — two moves of sibling
59
59
  * subtasks contend even when they target different projects, and the loser
60
60
  * fails. Batching same-destination moves into a single request means
61
- * serialising costs little in practice.
61
+ * serialising costs little in practice. One per process is the smallest
62
+ * contribution a process can make; see the note above for the global picture.
62
63
  */
63
64
  readonly TASK_MOVES: 1;
64
- /** In-flight non-move write requests per account. */
65
+ /** In-flight non-move write requests per account, per process. */
65
66
  readonly WRITES: 4;
66
67
  /**
67
68
  * How long a request may wait for a slot before it is abandoned unsent.
@@ -1 +1 @@
1
- {"version":3,"file":"constants.d.ts","sourceRoot":"","sources":["../../src/utils/constants.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAGH,eAAO,MAAM,SAAS;IAClB,sCAAsC;;IAEtC,wDAAwD;;IAExD,wCAAwC;;IAExC,wCAAwC;;IAExC,yCAAyC;;IAEzC,yCAAyC;;IAEzC,yCAAyC;;IAEzC,qDAAqD;;IAErD,iGAAiG;;IAEjG,yCAAyC;;IAEzC,2DAA2D;;IAE3D,8CAA8C;;IAE9C,gEAAgE;;IAEhE,uCAAuC;;IAEvC,uCAAuC;;IAEvC,0CAA0C;;IAE1C,mDAAmD;;CAE7C,CAAA;AAGV,eAAO,MAAM,aAAa;IACtB,oEAAoE;;IAEpE,gDAAgD;;CAE1C,CAAA;AAGV,eAAO,MAAM,WAAW;IACpB,oEAAoE;;CAE9D,CAAA;AAGV,eAAO,MAAM,iBAAiB;IAC1B;;;;;;;;OAQG;;IAEH,qDAAqD;;IAErD;;;;;;;OAOG;;CAEG,CAAA;AAGV,eAAO,MAAM,cAAc;IACvB,oDAAoD;;IAEpD,mCAAmC;;CAE7B,CAAA"}
1
+ {"version":3,"file":"constants.d.ts","sourceRoot":"","sources":["../../src/utils/constants.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAGH,eAAO,MAAM,SAAS;IAClB,sCAAsC;;IAEtC,wDAAwD;;IAExD,wCAAwC;;IAExC,wCAAwC;;IAExC,yCAAyC;;IAEzC,yCAAyC;;IAEzC,yCAAyC;;IAEzC,qDAAqD;;IAErD,iGAAiG;;IAEjG,yCAAyC;;IAEzC,2DAA2D;;IAE3D,8CAA8C;;IAE9C,gEAAgE;;IAEhE,uCAAuC;;IAEvC,uCAAuC;;IAEvC,0CAA0C;;IAE1C,mDAAmD;;CAE7C,CAAA;AAGV,eAAO,MAAM,aAAa;IACtB,oEAAoE;;IAEpE,gDAAgD;;CAE1C,CAAA;AAGV,eAAO,MAAM,WAAW;IACpB,oEAAoE;;CAE9D,CAAA;AAYV,eAAO,MAAM,iBAAiB;IAC1B;;;;;;;;;OASG;;IAEH,kEAAkE;;IAElE;;;;;;;OAOG;;CAEG,CAAA;AAGV,eAAO,MAAM,cAAc;IACvB,oDAAoD;;IAEpD,mCAAmC;;CAE7B,CAAA"}
@@ -49,6 +49,16 @@ export declare const TEST_ERRORS: {
49
49
  readonly INVALID_CURSOR: "Invalid cursor format";
50
50
  readonly INVALID_FILTER: "Invalid filter query";
51
51
  };
52
+ /**
53
+ * Creates an error shaped like a rejected Todoist API call, so tests exercise the
54
+ * signals `formatBatchItemError` reads (status, `error`, `error_tag`) rather than a
55
+ * bare `Error` whose message collapses to "HTTP 403".
56
+ */
57
+ export declare function createApiError({ status, error, tag, }: {
58
+ status: number;
59
+ error: string;
60
+ tag?: string;
61
+ }): Error;
52
62
  /**
53
63
  * Creates multiple test cases for parameterized testing.
54
64
  */
@@ -1 +1 @@
1
- {"version":3,"file":"test-helpers.d.ts","sourceRoot":"","sources":["../../src/utils/test-helpers.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACR,WAAW,EACX,KAAK,EACL,eAAe,EACf,OAAO,EACP,IAAI,EACJ,gBAAgB,EACnB,MAAM,oBAAoB,CAAA;AAC3B,OAAO,EAAE,KAAK,UAAU,EAAE,MAAM,iBAAiB,CAAA;AACjD,OAAO,EAA2B,KAAK,QAAQ,EAAE,MAAM,cAAc,CAAA;AAErE,KAAK,0BAA0B,GAAG,IAAI,CAAC,IAAI,EAAE,UAAU,CAAC,GAAG;IACvD,QAAQ,EAAE,QAAQ,CAAA;CACrB,CAAA;AAED;;;GAGG;AACH,wBAAgB,cAAc,CAAC,EAC3B,QAAe,EACf,GAAG,SAAS,EACf,GAAE,OAAO,CAAC,0BAA0B,CAAM,GAAG,IAAI,CA6BjD;AAED;;;GAGG;AACH,wBAAgB,iBAAiB,CAAC,SAAS,GAAE,OAAO,CAAC,OAAO,CAAM,GAAG,OAAO,CAiB3E;AAED;;;GAGG;AACH,wBAAgB,iBAAiB,CAAC,SAAS,GAAE,OAAO,CAAC,eAAe,CAAM,GAAG,eAAe,CAuB3F;AAED;;;GAGG;AACH,wBAAgB,0BAA0B,CACtC,SAAS,GAAE,OAAO,CAAC,gBAAgB,CAAM,GAC1C,gBAAgB,CA4BlB;AAED;;;GAGG;AACH,wBAAgB,eAAe,CAAC,SAAS,GAAE,OAAO,CAAC,KAAK,CAAM,GAAG,KAAK,CASrE;AAED;;GAEG;AACH,wBAAgB,qBAAqB,CAAC,CAAC,EACnC,OAAO,EAAE,CAAC,EAAE,EACZ,UAAU,GAAE,MAAM,GAAG,IAAW,GACjC;IACC,OAAO,EAAE,CAAC,EAAE,CAAA;IACZ,UAAU,EAAE,MAAM,GAAG,IAAI,CAAA;CAC5B,CAKA;AAED;;GAEG;AACH,wBAAgB,gBAAgB,CAAC,SAAS,GAAE,OAAO,CAAC,UAAU,CAAM,GAAG,UAAU,CAqBhF;AAED;;GAEG;AACH,eAAO,MAAM,WAAW;;;;;CAKd,CAAA;AAEV;;GAEG;AACH,wBAAgB,eAAe,CAAC,CAAC,EAAE,CAAC,GAAG,OAAO,EAC1C,KAAK,EAAE,KAAK,CAAC;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,CAAC,CAAC;IAAC,QAAQ,CAAC,EAAE,CAAC,CAAA;CAAE,CAAC;UAAjC,MAAM;WAAS,CAAC;eAAa,CAAC;IAGtD;AAED;;GAEG;AACH,eAAO,MAAM,QAAQ;;;;;;;;;;;;CAYX,CAAA;AAEV;;;GAGG;AACH,eAAO,MAAM,KAAK,EAAG,YAAqB,CAAA;AAE1C;;;GAGG;AACH,wBAAgB,cAAc,CAAC,SAAS,GAAE,OAAO,CAAC,WAAW,CAAM,GAAG,WAAW,CAoChF"}
1
+ {"version":3,"file":"test-helpers.d.ts","sourceRoot":"","sources":["../../src/utils/test-helpers.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACR,WAAW,EACX,KAAK,EACL,eAAe,EACf,OAAO,EACP,IAAI,EACJ,gBAAgB,EACnB,MAAM,oBAAoB,CAAA;AAC3B,OAAO,EAAE,KAAK,UAAU,EAAE,MAAM,iBAAiB,CAAA;AACjD,OAAO,EAA2B,KAAK,QAAQ,EAAE,MAAM,cAAc,CAAA;AAErE,KAAK,0BAA0B,GAAG,IAAI,CAAC,IAAI,EAAE,UAAU,CAAC,GAAG;IACvD,QAAQ,EAAE,QAAQ,CAAA;CACrB,CAAA;AAED;;;GAGG;AACH,wBAAgB,cAAc,CAAC,EAC3B,QAAe,EACf,GAAG,SAAS,EACf,GAAE,OAAO,CAAC,0BAA0B,CAAM,GAAG,IAAI,CA6BjD;AAED;;;GAGG;AACH,wBAAgB,iBAAiB,CAAC,SAAS,GAAE,OAAO,CAAC,OAAO,CAAM,GAAG,OAAO,CAiB3E;AAED;;;GAGG;AACH,wBAAgB,iBAAiB,CAAC,SAAS,GAAE,OAAO,CAAC,eAAe,CAAM,GAAG,eAAe,CAuB3F;AAED;;;GAGG;AACH,wBAAgB,0BAA0B,CACtC,SAAS,GAAE,OAAO,CAAC,gBAAgB,CAAM,GAC1C,gBAAgB,CA4BlB;AAED;;;GAGG;AACH,wBAAgB,eAAe,CAAC,SAAS,GAAE,OAAO,CAAC,KAAK,CAAM,GAAG,KAAK,CASrE;AAED;;GAEG;AACH,wBAAgB,qBAAqB,CAAC,CAAC,EACnC,OAAO,EAAE,CAAC,EAAE,EACZ,UAAU,GAAE,MAAM,GAAG,IAAW,GACjC;IACC,OAAO,EAAE,CAAC,EAAE,CAAA;IACZ,UAAU,EAAE,MAAM,GAAG,IAAI,CAAA;CAC5B,CAKA;AAED;;GAEG;AACH,wBAAgB,gBAAgB,CAAC,SAAS,GAAE,OAAO,CAAC,UAAU,CAAM,GAAG,UAAU,CAqBhF;AAED;;GAEG;AACH,eAAO,MAAM,WAAW;;;;;CAKd,CAAA;AAEV;;;;GAIG;AACH,wBAAgB,cAAc,CAAC,EAC3B,MAAM,EACN,KAAK,EACL,GAAG,GACN,EAAE;IACC,MAAM,EAAE,MAAM,CAAA;IACd,KAAK,EAAE,MAAM,CAAA;IACb,GAAG,CAAC,EAAE,MAAM,CAAA;CACf,GAAG,KAAK,CASR;AAED;;GAEG;AACH,wBAAgB,eAAe,CAAC,CAAC,EAAE,CAAC,GAAG,OAAO,EAC1C,KAAK,EAAE,KAAK,CAAC;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,CAAC,CAAC;IAAC,QAAQ,CAAC,EAAE,CAAC,CAAA;CAAE,CAAC;UAAjC,MAAM;WAAS,CAAC;eAAa,CAAC;IAGtD;AAED;;GAEG;AACH,eAAO,MAAM,QAAQ;;;;;;;;;;;;CAYX,CAAA;AAEV;;;GAGG;AACH,eAAO,MAAM,KAAK,EAAG,YAAqB,CAAA;AAE1C;;;GAGG;AACH,wBAAgB,cAAc,CAAC,SAAS,GAAE,OAAO,CAAC,WAAW,CAAM,GAAG,WAAW,CAoChF"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@doist/todoist-mcp",
3
- "version": "12.3.0",
3
+ "version": "12.3.2",
4
4
  "type": "module",
5
5
  "main": "./dist/index.js",
6
6
  "types": "./dist/index.d.ts",