@doist/todoist-ai 2.2.2 → 4.0.0

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.
Files changed (202) hide show
  1. package/README.md +6 -14
  2. package/dist/index.d.ts +619 -250
  3. package/dist/index.d.ts.map +1 -1
  4. package/dist/index.js +45 -29
  5. package/dist/main.js +2 -1
  6. package/dist/mcp-helpers.d.ts +25 -3
  7. package/dist/mcp-helpers.d.ts.map +1 -1
  8. package/dist/mcp-helpers.js +37 -19
  9. package/dist/mcp-server.d.ts.map +1 -1
  10. package/dist/mcp-server.js +44 -28
  11. package/dist/tools/__tests__/add-comments.test.d.ts +2 -0
  12. package/dist/tools/__tests__/add-comments.test.d.ts.map +1 -0
  13. package/dist/tools/__tests__/add-comments.test.js +241 -0
  14. package/dist/tools/__tests__/add-projects.test.d.ts +2 -0
  15. package/dist/tools/__tests__/add-projects.test.d.ts.map +1 -0
  16. package/dist/tools/__tests__/add-projects.test.js +152 -0
  17. package/dist/tools/__tests__/add-sections.test.d.ts +2 -0
  18. package/dist/tools/__tests__/add-sections.test.d.ts.map +1 -0
  19. package/dist/tools/__tests__/add-sections.test.js +181 -0
  20. package/dist/tools/__tests__/add-tasks.test.d.ts +2 -0
  21. package/dist/tools/__tests__/add-tasks.test.d.ts.map +1 -0
  22. package/dist/tools/__tests__/{tasks-add-multiple.test.js → add-tasks.test.js} +89 -79
  23. package/dist/tools/__tests__/complete-tasks.test.d.ts +2 -0
  24. package/dist/tools/__tests__/complete-tasks.test.d.ts.map +1 -0
  25. package/dist/tools/__tests__/complete-tasks.test.js +206 -0
  26. package/dist/tools/__tests__/delete-object.test.d.ts +2 -0
  27. package/dist/tools/__tests__/delete-object.test.d.ts.map +1 -0
  28. package/dist/tools/__tests__/{delete-one.test.js → delete-object.test.js} +42 -22
  29. package/dist/tools/__tests__/find-comments.test.d.ts +2 -0
  30. package/dist/tools/__tests__/find-comments.test.d.ts.map +1 -0
  31. package/dist/tools/__tests__/find-comments.test.js +242 -0
  32. package/dist/tools/__tests__/find-completed-tasks.test.d.ts +2 -0
  33. package/dist/tools/__tests__/find-completed-tasks.test.d.ts.map +1 -0
  34. package/dist/tools/__tests__/{tasks-list-completed.test.js → find-completed-tasks.test.js} +13 -36
  35. package/dist/tools/__tests__/find-projects.test.d.ts +2 -0
  36. package/dist/tools/__tests__/find-projects.test.d.ts.map +1 -0
  37. package/dist/tools/__tests__/{projects-list.test.js → find-projects.test.js} +55 -39
  38. package/dist/tools/__tests__/find-sections.test.d.ts +2 -0
  39. package/dist/tools/__tests__/find-sections.test.d.ts.map +1 -0
  40. package/dist/tools/__tests__/{sections-search.test.js → find-sections.test.js} +64 -50
  41. package/dist/tools/__tests__/find-tasks-by-date.test.d.ts +2 -0
  42. package/dist/tools/__tests__/find-tasks-by-date.test.d.ts.map +1 -0
  43. package/dist/tools/__tests__/{tasks-list-by-date.test.js → find-tasks-by-date.test.js} +96 -14
  44. package/dist/tools/__tests__/find-tasks.test.d.ts +2 -0
  45. package/dist/tools/__tests__/find-tasks.test.d.ts.map +1 -0
  46. package/dist/tools/__tests__/find-tasks.test.js +334 -0
  47. package/dist/tools/__tests__/get-overview.test.d.ts +2 -0
  48. package/dist/tools/__tests__/get-overview.test.d.ts.map +1 -0
  49. package/dist/tools/__tests__/{overview.test.js → get-overview.test.js} +77 -13
  50. package/dist/tools/__tests__/update-comments.test.d.ts +2 -0
  51. package/dist/tools/__tests__/update-comments.test.d.ts.map +1 -0
  52. package/dist/tools/__tests__/update-comments.test.js +296 -0
  53. package/dist/tools/__tests__/update-projects.test.d.ts +2 -0
  54. package/dist/tools/__tests__/update-projects.test.d.ts.map +1 -0
  55. package/dist/tools/__tests__/update-projects.test.js +205 -0
  56. package/dist/tools/__tests__/update-sections.test.d.ts +2 -0
  57. package/dist/tools/__tests__/update-sections.test.d.ts.map +1 -0
  58. package/dist/tools/__tests__/update-sections.test.js +156 -0
  59. package/dist/tools/__tests__/update-tasks.test.d.ts +2 -0
  60. package/dist/tools/__tests__/update-tasks.test.d.ts.map +1 -0
  61. package/dist/tools/__tests__/update-tasks.test.js +645 -0
  62. package/dist/tools/add-comments.d.ts +51 -0
  63. package/dist/tools/add-comments.d.ts.map +1 -0
  64. package/dist/tools/add-comments.js +79 -0
  65. package/dist/tools/add-projects.d.ts +50 -0
  66. package/dist/tools/add-projects.d.ts.map +1 -0
  67. package/dist/tools/add-projects.js +59 -0
  68. package/dist/tools/add-sections.d.ts +46 -0
  69. package/dist/tools/add-sections.d.ts.map +1 -0
  70. package/dist/tools/add-sections.js +61 -0
  71. package/dist/tools/add-tasks.d.ts +82 -0
  72. package/dist/tools/add-tasks.d.ts.map +1 -0
  73. package/dist/tools/add-tasks.js +96 -0
  74. package/dist/tools/complete-tasks.d.ts +40 -0
  75. package/dist/tools/complete-tasks.d.ts.map +1 -0
  76. package/dist/tools/complete-tasks.js +68 -0
  77. package/dist/tools/delete-object.d.ts +38 -0
  78. package/dist/tools/delete-object.d.ts.map +1 -0
  79. package/dist/tools/delete-object.js +79 -0
  80. package/dist/tools/find-comments.d.ts +46 -0
  81. package/dist/tools/find-comments.d.ts.map +1 -0
  82. package/dist/tools/find-comments.js +143 -0
  83. package/dist/tools/find-completed-tasks.d.ts +74 -0
  84. package/dist/tools/find-completed-tasks.d.ts.map +1 -0
  85. package/dist/tools/find-completed-tasks.js +112 -0
  86. package/dist/tools/find-projects.d.ts +53 -0
  87. package/dist/tools/find-projects.d.ts.map +1 -0
  88. package/dist/tools/find-projects.js +101 -0
  89. package/dist/tools/find-sections.d.ts +42 -0
  90. package/dist/tools/find-sections.d.ts.map +1 -0
  91. package/dist/tools/find-sections.js +96 -0
  92. package/dist/tools/find-tasks-by-date.d.ts +59 -0
  93. package/dist/tools/find-tasks-by-date.d.ts.map +1 -0
  94. package/dist/tools/find-tasks-by-date.js +121 -0
  95. package/dist/tools/find-tasks.d.ts +65 -0
  96. package/dist/tools/find-tasks.d.ts.map +1 -0
  97. package/dist/tools/find-tasks.js +182 -0
  98. package/dist/tools/get-overview.d.ts +67 -0
  99. package/dist/tools/get-overview.d.ts.map +1 -0
  100. package/dist/tools/{overview.js → get-overview.js} +66 -19
  101. package/dist/tools/update-comments.d.ts +50 -0
  102. package/dist/tools/update-comments.d.ts.map +1 -0
  103. package/dist/tools/update-comments.js +82 -0
  104. package/dist/tools/update-projects.d.ts +59 -0
  105. package/dist/tools/update-projects.d.ts.map +1 -0
  106. package/dist/tools/update-projects.js +84 -0
  107. package/dist/tools/update-sections.d.ts +47 -0
  108. package/dist/tools/update-sections.d.ts.map +1 -0
  109. package/dist/tools/update-sections.js +70 -0
  110. package/dist/tools/update-tasks.d.ts +94 -0
  111. package/dist/tools/update-tasks.d.ts.map +1 -0
  112. package/dist/tools/update-tasks.js +120 -0
  113. package/dist/utils/constants.d.ts +39 -0
  114. package/dist/utils/constants.d.ts.map +1 -0
  115. package/dist/utils/constants.js +41 -0
  116. package/dist/utils/response-builders.d.ts +88 -0
  117. package/dist/utils/response-builders.d.ts.map +1 -0
  118. package/dist/utils/response-builders.js +202 -0
  119. package/dist/{tools → utils}/test-helpers.d.ts +16 -0
  120. package/dist/utils/test-helpers.d.ts.map +1 -0
  121. package/dist/{tools → utils}/test-helpers.js +51 -0
  122. package/dist/utils/tool-names.d.ts +28 -0
  123. package/dist/utils/tool-names.d.ts.map +1 -0
  124. package/dist/utils/tool-names.js +31 -0
  125. package/package.json +1 -1
  126. package/dist/tools/__tests__/delete-one.test.d.ts +0 -2
  127. package/dist/tools/__tests__/delete-one.test.d.ts.map +0 -1
  128. package/dist/tools/__tests__/overview.test.d.ts +0 -2
  129. package/dist/tools/__tests__/overview.test.d.ts.map +0 -1
  130. package/dist/tools/__tests__/projects-list.test.d.ts +0 -2
  131. package/dist/tools/__tests__/projects-list.test.d.ts.map +0 -1
  132. package/dist/tools/__tests__/projects-manage.test.d.ts +0 -2
  133. package/dist/tools/__tests__/projects-manage.test.d.ts.map +0 -1
  134. package/dist/tools/__tests__/projects-manage.test.js +0 -106
  135. package/dist/tools/__tests__/sections-manage.test.d.ts +0 -2
  136. package/dist/tools/__tests__/sections-manage.test.d.ts.map +0 -1
  137. package/dist/tools/__tests__/sections-manage.test.js +0 -138
  138. package/dist/tools/__tests__/sections-search.test.d.ts +0 -2
  139. package/dist/tools/__tests__/sections-search.test.d.ts.map +0 -1
  140. package/dist/tools/__tests__/tasks-add-multiple.test.d.ts +0 -2
  141. package/dist/tools/__tests__/tasks-add-multiple.test.d.ts.map +0 -1
  142. package/dist/tools/__tests__/tasks-complete-multiple.test.d.ts +0 -2
  143. package/dist/tools/__tests__/tasks-complete-multiple.test.d.ts.map +0 -1
  144. package/dist/tools/__tests__/tasks-complete-multiple.test.js +0 -146
  145. package/dist/tools/__tests__/tasks-list-by-date.test.d.ts +0 -2
  146. package/dist/tools/__tests__/tasks-list-by-date.test.d.ts.map +0 -1
  147. package/dist/tools/__tests__/tasks-list-completed.test.d.ts +0 -2
  148. package/dist/tools/__tests__/tasks-list-completed.test.d.ts.map +0 -1
  149. package/dist/tools/__tests__/tasks-list-for-container.test.d.ts +0 -2
  150. package/dist/tools/__tests__/tasks-list-for-container.test.d.ts.map +0 -1
  151. package/dist/tools/__tests__/tasks-list-for-container.test.js +0 -232
  152. package/dist/tools/__tests__/tasks-organize-multiple.test.d.ts +0 -2
  153. package/dist/tools/__tests__/tasks-organize-multiple.test.d.ts.map +0 -1
  154. package/dist/tools/__tests__/tasks-organize-multiple.test.js +0 -245
  155. package/dist/tools/__tests__/tasks-search.test.d.ts +0 -2
  156. package/dist/tools/__tests__/tasks-search.test.d.ts.map +0 -1
  157. package/dist/tools/__tests__/tasks-search.test.js +0 -106
  158. package/dist/tools/__tests__/tasks-update-one.test.d.ts +0 -2
  159. package/dist/tools/__tests__/tasks-update-one.test.d.ts.map +0 -1
  160. package/dist/tools/__tests__/tasks-update-one.test.js +0 -251
  161. package/dist/tools/delete-one.d.ts +0 -17
  162. package/dist/tools/delete-one.d.ts.map +0 -1
  163. package/dist/tools/delete-one.js +0 -25
  164. package/dist/tools/overview.d.ts +0 -14
  165. package/dist/tools/overview.d.ts.map +0 -1
  166. package/dist/tools/projects-list.d.ts +0 -29
  167. package/dist/tools/projects-list.d.ts.map +0 -1
  168. package/dist/tools/projects-list.js +0 -39
  169. package/dist/tools/projects-manage.d.ts +0 -24
  170. package/dist/tools/projects-manage.d.ts.map +0 -1
  171. package/dist/tools/projects-manage.js +0 -26
  172. package/dist/tools/sections-manage.d.ts +0 -23
  173. package/dist/tools/sections-manage.d.ts.map +0 -1
  174. package/dist/tools/sections-manage.js +0 -37
  175. package/dist/tools/sections-search.d.ts +0 -18
  176. package/dist/tools/sections-search.d.ts.map +0 -1
  177. package/dist/tools/sections-search.js +0 -27
  178. package/dist/tools/tasks-add-multiple.d.ts +0 -55
  179. package/dist/tools/tasks-add-multiple.d.ts.map +0 -1
  180. package/dist/tools/tasks-add-multiple.js +0 -52
  181. package/dist/tools/tasks-complete-multiple.d.ts +0 -16
  182. package/dist/tools/tasks-complete-multiple.d.ts.map +0 -1
  183. package/dist/tools/tasks-complete-multiple.js +0 -23
  184. package/dist/tools/tasks-list-by-date.d.ts +0 -34
  185. package/dist/tools/tasks-list-by-date.d.ts.map +0 -1
  186. package/dist/tools/tasks-list-by-date.js +0 -53
  187. package/dist/tools/tasks-list-completed.d.ts +0 -44
  188. package/dist/tools/tasks-list-completed.d.ts.map +0 -1
  189. package/dist/tools/tasks-list-completed.js +0 -49
  190. package/dist/tools/tasks-list-for-container.d.ts +0 -34
  191. package/dist/tools/tasks-list-for-container.d.ts.map +0 -1
  192. package/dist/tools/tasks-list-for-container.js +0 -48
  193. package/dist/tools/tasks-organize-multiple.d.ts +0 -37
  194. package/dist/tools/tasks-organize-multiple.d.ts.map +0 -1
  195. package/dist/tools/tasks-organize-multiple.js +0 -34
  196. package/dist/tools/tasks-search.d.ts +0 -32
  197. package/dist/tools/tasks-search.d.ts.map +0 -1
  198. package/dist/tools/tasks-search.js +0 -30
  199. package/dist/tools/tasks-update-one.d.ts +0 -29
  200. package/dist/tools/tasks-update-one.d.ts.map +0 -1
  201. package/dist/tools/tasks-update-one.js +0 -63
  202. package/dist/tools/test-helpers.d.ts.map +0 -1
@@ -0,0 +1,51 @@
1
+ import type { Comment } from '@doist/todoist-api-typescript';
2
+ import { z } from 'zod';
3
+ declare const addComments: {
4
+ name: "add-comments";
5
+ description: string;
6
+ parameters: {
7
+ comments: z.ZodArray<z.ZodObject<{
8
+ taskId: z.ZodOptional<z.ZodString>;
9
+ projectId: z.ZodOptional<z.ZodString>;
10
+ content: z.ZodString;
11
+ }, "strip", z.ZodTypeAny, {
12
+ content: string;
13
+ projectId?: string | undefined;
14
+ taskId?: string | undefined;
15
+ }, {
16
+ content: string;
17
+ projectId?: string | undefined;
18
+ taskId?: string | undefined;
19
+ }>, "many">;
20
+ };
21
+ execute(args: {
22
+ comments: {
23
+ content: string;
24
+ projectId?: string | undefined;
25
+ taskId?: string | undefined;
26
+ }[];
27
+ }, client: import("@doist/todoist-api-typescript").TodoistApi): Promise<{
28
+ content: {
29
+ type: "text";
30
+ text: string;
31
+ }[];
32
+ structuredContent: {
33
+ comments: Comment[];
34
+ totalCount: number;
35
+ addedCommentIds: string[];
36
+ };
37
+ } | {
38
+ content: ({
39
+ type: "text";
40
+ text: string;
41
+ mimeType?: undefined;
42
+ } | {
43
+ type: "text";
44
+ mimeType: string;
45
+ text: string;
46
+ })[];
47
+ structuredContent?: undefined;
48
+ }>;
49
+ };
50
+ export { addComments };
51
+ //# sourceMappingURL=add-comments.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"add-comments.d.ts","sourceRoot":"","sources":["../../src/tools/add-comments.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAkB,OAAO,EAAE,MAAM,+BAA+B,CAAA;AAC5E,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAA;AAkBvB,QAAA,MAAM,WAAW;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CA0CyB,CAAA;AA6C1C,OAAO,EAAE,WAAW,EAAE,CAAA"}
@@ -0,0 +1,79 @@
1
+ import { z } from 'zod';
2
+ import { getToolOutput } from '../mcp-helpers.js';
3
+ import { formatNextSteps } from '../utils/response-builders.js';
4
+ import { ToolNames } from '../utils/tool-names.js';
5
+ const { FIND_COMMENTS, UPDATE_COMMENTS, DELETE_OBJECT } = ToolNames;
6
+ const CommentSchema = z.object({
7
+ taskId: z.string().optional().describe('The ID of the task to comment on.'),
8
+ projectId: z.string().optional().describe('The ID of the project to comment on.'),
9
+ content: z.string().min(1).describe('The content of the comment.'),
10
+ });
11
+ const ArgsSchema = {
12
+ comments: z.array(CommentSchema).min(1).describe('The array of comments to add.'),
13
+ };
14
+ const addComments = {
15
+ name: ToolNames.ADD_COMMENTS,
16
+ description: 'Add multiple comments to tasks or projects. Each comment must specify either taskId or projectId.',
17
+ parameters: ArgsSchema,
18
+ async execute(args, client) {
19
+ const { comments } = args;
20
+ // Validate each comment
21
+ for (const [index, comment] of comments.entries()) {
22
+ if (!comment.taskId && !comment.projectId) {
23
+ throw new Error(`Comment ${index + 1}: Either taskId or projectId must be provided.`);
24
+ }
25
+ if (comment.taskId && comment.projectId) {
26
+ throw new Error(`Comment ${index + 1}: Cannot provide both taskId and projectId. Choose one.`);
27
+ }
28
+ }
29
+ const addCommentPromises = comments.map(async ({ content, taskId, projectId }) => await client.addComment({
30
+ content,
31
+ ...(taskId ? { taskId } : { projectId }),
32
+ }));
33
+ const newComments = await Promise.all(addCommentPromises);
34
+ const textContent = generateTextContent({ comments: newComments });
35
+ return getToolOutput({
36
+ textContent,
37
+ structuredContent: {
38
+ comments: newComments,
39
+ totalCount: newComments.length,
40
+ addedCommentIds: newComments.map((comment) => comment.id),
41
+ },
42
+ });
43
+ },
44
+ };
45
+ function generateTextContent({ comments, }) {
46
+ // Group comments by entity type and count
47
+ const taskComments = comments.filter((c) => c.taskId).length;
48
+ const projectComments = comments.filter((c) => c.projectId).length;
49
+ // Generate summary text
50
+ const parts = [];
51
+ if (taskComments > 0) {
52
+ const commentsLabel = taskComments > 1 ? 'comments' : 'comment';
53
+ parts.push(`${taskComments} task ${commentsLabel}`);
54
+ }
55
+ if (projectComments > 0) {
56
+ const commentsLabel = projectComments > 1 ? 'comments' : 'comment';
57
+ parts.push(`${projectComments} project ${commentsLabel}`);
58
+ }
59
+ const summary = parts.length > 0 ? `Added ${parts.join(' and ')}` : 'No comments added';
60
+ // Context-aware next steps
61
+ const nextSteps = [];
62
+ if (comments.length > 0) {
63
+ if (comments.length === 1 && comments[0]) {
64
+ const comment = comments[0];
65
+ const targetId = comment.taskId || comment.projectId || '';
66
+ const targetType = comment.taskId ? 'task' : 'project';
67
+ nextSteps.push(`Use ${FIND_COMMENTS} with ${targetType}Id=${targetId} to see all comments`);
68
+ nextSteps.push(`Use ${UPDATE_COMMENTS} with id=${comment.id} to edit content`);
69
+ }
70
+ else {
71
+ nextSteps.push(`Use ${FIND_COMMENTS} to view comments by task or project`);
72
+ nextSteps.push(`Use ${UPDATE_COMMENTS} to edit any comment content`);
73
+ }
74
+ nextSteps.push(`Use ${DELETE_OBJECT} with type=comment to remove comments`);
75
+ }
76
+ const next = formatNextSteps(nextSteps);
77
+ return `${summary}\n${next}`;
78
+ }
79
+ export { addComments };
@@ -0,0 +1,50 @@
1
+ import type { PersonalProject, WorkspaceProject } from '@doist/todoist-api-typescript';
2
+ import { z } from 'zod';
3
+ declare const addProjects: {
4
+ name: "add-projects";
5
+ description: string;
6
+ parameters: {
7
+ projects: z.ZodArray<z.ZodObject<{
8
+ name: z.ZodString;
9
+ isFavorite: z.ZodOptional<z.ZodBoolean>;
10
+ viewStyle: z.ZodOptional<z.ZodEnum<["list", "board", "calendar"]>>;
11
+ }, "strip", z.ZodTypeAny, {
12
+ name: string;
13
+ isFavorite?: boolean | undefined;
14
+ viewStyle?: "list" | "board" | "calendar" | undefined;
15
+ }, {
16
+ name: string;
17
+ isFavorite?: boolean | undefined;
18
+ viewStyle?: "list" | "board" | "calendar" | undefined;
19
+ }>, "many">;
20
+ };
21
+ execute({ projects }: {
22
+ projects: {
23
+ name: string;
24
+ isFavorite?: boolean | undefined;
25
+ viewStyle?: "list" | "board" | "calendar" | undefined;
26
+ }[];
27
+ }, client: import("@doist/todoist-api-typescript").TodoistApi): Promise<{
28
+ content: {
29
+ type: "text";
30
+ text: string;
31
+ }[];
32
+ structuredContent: {
33
+ projects: (PersonalProject | WorkspaceProject)[];
34
+ totalCount: number;
35
+ };
36
+ } | {
37
+ content: ({
38
+ type: "text";
39
+ text: string;
40
+ mimeType?: undefined;
41
+ } | {
42
+ type: "text";
43
+ mimeType: string;
44
+ text: string;
45
+ })[];
46
+ structuredContent?: undefined;
47
+ }>;
48
+ };
49
+ export { addProjects };
50
+ //# sourceMappingURL=add-projects.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"add-projects.d.ts","sourceRoot":"","sources":["../../src/tools/add-projects.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,eAAe,EAAE,gBAAgB,EAAE,MAAM,+BAA+B,CAAA;AACtF,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAA;AAwBvB,QAAA,MAAM,WAAW;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAgByB,CAAA;AAmC1C,OAAO,EAAE,WAAW,EAAE,CAAA"}
@@ -0,0 +1,59 @@
1
+ import { z } from 'zod';
2
+ import { getToolOutput } from '../mcp-helpers.js';
3
+ import { formatNextSteps } from '../utils/response-builders.js';
4
+ import { ToolNames } from '../utils/tool-names.js';
5
+ const { ADD_SECTIONS, ADD_TASKS, FIND_PROJECTS, GET_OVERVIEW } = ToolNames;
6
+ const ProjectSchema = z.object({
7
+ name: z.string().min(1).describe('The name of the project.'),
8
+ isFavorite: z
9
+ .boolean()
10
+ .optional()
11
+ .describe('Whether the project is a favorite. Defaults to false.'),
12
+ viewStyle: z
13
+ .enum(['list', 'board', 'calendar'])
14
+ .optional()
15
+ .describe('The project view style. Defaults to "list".'),
16
+ });
17
+ const ArgsSchema = {
18
+ projects: z.array(ProjectSchema).min(1).describe('The array of projects to add.'),
19
+ };
20
+ const addProjects = {
21
+ name: ToolNames.ADD_PROJECTS,
22
+ description: 'Add one or more new projects.',
23
+ parameters: ArgsSchema,
24
+ async execute({ projects }, client) {
25
+ const newProjects = await Promise.all(projects.map((project) => client.addProject(project)));
26
+ const textContent = generateTextContent({ projects: newProjects });
27
+ return getToolOutput({
28
+ textContent,
29
+ structuredContent: {
30
+ projects: newProjects,
31
+ totalCount: newProjects.length,
32
+ },
33
+ });
34
+ },
35
+ };
36
+ function generateTextContent({ projects, }) {
37
+ const count = projects.length;
38
+ const projectList = projects.map((project) => `• ${project.name} (id=${project.id})`).join('\n');
39
+ const summary = `Added ${count} project${count === 1 ? '' : 's'}:\n${projectList}`;
40
+ // Context-aware next steps for new projects
41
+ const nextSteps = [];
42
+ if (count === 1) {
43
+ const project = projects[0];
44
+ if (project) {
45
+ nextSteps.push(`Use ${ADD_SECTIONS} to organize new project with sections`);
46
+ nextSteps.push(`Use ${ADD_TASKS} to add your first tasks to this project`);
47
+ nextSteps.push(`Use ${GET_OVERVIEW} with projectId=${project.id} to see project structure`);
48
+ }
49
+ }
50
+ else {
51
+ nextSteps.push(`Use ${ADD_SECTIONS} to organize these projects with sections`);
52
+ nextSteps.push(`Use ${ADD_TASKS} to add tasks to these projects`);
53
+ nextSteps.push(`Use ${FIND_PROJECTS} to see all projects including the new ones`);
54
+ nextSteps.push(`Use ${GET_OVERVIEW} to see updated project hierarchy`);
55
+ }
56
+ const next = formatNextSteps(nextSteps);
57
+ return `${summary}\n${next}`;
58
+ }
59
+ export { addProjects };
@@ -0,0 +1,46 @@
1
+ import type { Section } from '@doist/todoist-api-typescript';
2
+ import { z } from 'zod';
3
+ declare const addSections: {
4
+ name: "add-sections";
5
+ description: string;
6
+ parameters: {
7
+ sections: z.ZodArray<z.ZodObject<{
8
+ name: z.ZodString;
9
+ projectId: z.ZodString;
10
+ }, "strip", z.ZodTypeAny, {
11
+ name: string;
12
+ projectId: string;
13
+ }, {
14
+ name: string;
15
+ projectId: string;
16
+ }>, "many">;
17
+ };
18
+ execute({ sections }: {
19
+ sections: {
20
+ name: string;
21
+ projectId: string;
22
+ }[];
23
+ }, client: import("@doist/todoist-api-typescript").TodoistApi): Promise<{
24
+ content: {
25
+ type: "text";
26
+ text: string;
27
+ }[];
28
+ structuredContent: {
29
+ sections: Section[];
30
+ totalCount: number;
31
+ };
32
+ } | {
33
+ content: ({
34
+ type: "text";
35
+ text: string;
36
+ mimeType?: undefined;
37
+ } | {
38
+ type: "text";
39
+ mimeType: string;
40
+ text: string;
41
+ })[];
42
+ structuredContent?: undefined;
43
+ }>;
44
+ };
45
+ export { addSections };
46
+ //# sourceMappingURL=add-sections.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"add-sections.d.ts","sourceRoot":"","sources":["../../src/tools/add-sections.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,+BAA+B,CAAA;AAC5D,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAA;AAiBvB,QAAA,MAAM,WAAW;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAgByB,CAAA;AAiD1C,OAAO,EAAE,WAAW,EAAE,CAAA"}
@@ -0,0 +1,61 @@
1
+ import { z } from 'zod';
2
+ import { getToolOutput } from '../mcp-helpers.js';
3
+ import { formatNextSteps } from '../utils/response-builders.js';
4
+ import { ToolNames } from '../utils/tool-names.js';
5
+ const { ADD_TASKS, FIND_TASKS, GET_OVERVIEW, FIND_SECTIONS } = ToolNames;
6
+ const SectionSchema = z.object({
7
+ name: z.string().min(1).describe('The name of the section.'),
8
+ projectId: z.string().min(1).describe('The ID of the project to add the section to.'),
9
+ });
10
+ const ArgsSchema = {
11
+ sections: z.array(SectionSchema).min(1).describe('The array of sections to add.'),
12
+ };
13
+ const addSections = {
14
+ name: ToolNames.ADD_SECTIONS,
15
+ description: 'Add one or more new sections to projects.',
16
+ parameters: ArgsSchema,
17
+ async execute({ sections }, client) {
18
+ const newSections = await Promise.all(sections.map((section) => client.addSection(section)));
19
+ const textContent = generateTextContent({ sections: newSections });
20
+ return getToolOutput({
21
+ textContent,
22
+ structuredContent: {
23
+ sections: newSections,
24
+ totalCount: newSections.length,
25
+ },
26
+ });
27
+ },
28
+ };
29
+ function generateTextContent({ sections, }) {
30
+ const count = sections.length;
31
+ const sectionList = sections
32
+ .map((section) => `• ${section.name} (id=${section.id}, projectId=${section.projectId})`)
33
+ .join('\n');
34
+ const summary = `Added ${count} section${count === 1 ? '' : 's'}:\n${sectionList}`;
35
+ // Context-aware next steps for new sections
36
+ const nextSteps = [];
37
+ if (count === 1) {
38
+ const section = sections[0];
39
+ if (section) {
40
+ nextSteps.push(`Use ${ADD_TASKS} with sectionId=${section.id} to add your first tasks`);
41
+ nextSteps.push(`Use ${FIND_TASKS} with sectionId=${section.id} to verify setup`);
42
+ nextSteps.push(`Use ${GET_OVERVIEW} with projectId=${section.projectId} to see project organization`);
43
+ }
44
+ }
45
+ else {
46
+ // Group sections by project for better guidance
47
+ const projectIds = [...new Set(sections.map((s) => s.projectId))];
48
+ nextSteps.push(`Use ${ADD_TASKS} to add tasks to these new sections`);
49
+ if (projectIds.length === 1) {
50
+ nextSteps.push(`Use ${GET_OVERVIEW} with projectId=${projectIds[0]} to see updated project structure`);
51
+ nextSteps.push(`Use ${FIND_SECTIONS} with projectId=${projectIds[0]} to see all sections`);
52
+ }
53
+ else {
54
+ nextSteps.push(`Use ${GET_OVERVIEW} to see updated project structures`);
55
+ nextSteps.push(`Use ${FIND_SECTIONS} to see sections in specific projects`);
56
+ }
57
+ }
58
+ const next = formatNextSteps(nextSteps);
59
+ return `${summary}\n${next}`;
60
+ }
61
+ export { addSections };
@@ -0,0 +1,82 @@
1
+ import type { TodoistApi } from '@doist/todoist-api-typescript';
2
+ import { z } from 'zod';
3
+ declare const addTasks: {
4
+ name: "add-tasks";
5
+ description: string;
6
+ parameters: {
7
+ tasks: z.ZodArray<z.ZodObject<{
8
+ content: z.ZodString;
9
+ description: z.ZodOptional<z.ZodString>;
10
+ priority: z.ZodOptional<z.ZodNumber>;
11
+ dueString: z.ZodOptional<z.ZodString>;
12
+ duration: z.ZodOptional<z.ZodString>;
13
+ projectId: z.ZodOptional<z.ZodString>;
14
+ sectionId: z.ZodOptional<z.ZodString>;
15
+ parentId: z.ZodOptional<z.ZodString>;
16
+ }, "strip", z.ZodTypeAny, {
17
+ content: string;
18
+ description?: string | undefined;
19
+ parentId?: string | undefined;
20
+ projectId?: string | undefined;
21
+ sectionId?: string | undefined;
22
+ priority?: number | undefined;
23
+ dueString?: string | undefined;
24
+ duration?: string | undefined;
25
+ }, {
26
+ content: string;
27
+ description?: string | undefined;
28
+ parentId?: string | undefined;
29
+ projectId?: string | undefined;
30
+ sectionId?: string | undefined;
31
+ priority?: number | undefined;
32
+ dueString?: string | undefined;
33
+ duration?: string | undefined;
34
+ }>, "many">;
35
+ };
36
+ execute({ tasks }: {
37
+ tasks: {
38
+ content: string;
39
+ description?: string | undefined;
40
+ parentId?: string | undefined;
41
+ projectId?: string | undefined;
42
+ sectionId?: string | undefined;
43
+ priority?: number | undefined;
44
+ dueString?: string | undefined;
45
+ duration?: string | undefined;
46
+ }[];
47
+ }, client: TodoistApi): Promise<{
48
+ content: {
49
+ type: "text";
50
+ text: string;
51
+ }[];
52
+ structuredContent: {
53
+ tasks: {
54
+ id: string;
55
+ content: string;
56
+ description: string;
57
+ dueDate: string | undefined;
58
+ recurring: string | boolean;
59
+ priority: number;
60
+ projectId: string;
61
+ sectionId: string | null;
62
+ parentId: string | null;
63
+ labels: string[];
64
+ duration: string | null;
65
+ }[];
66
+ totalCount: number;
67
+ };
68
+ } | {
69
+ content: ({
70
+ type: "text";
71
+ text: string;
72
+ mimeType?: undefined;
73
+ } | {
74
+ type: "text";
75
+ mimeType: string;
76
+ text: string;
77
+ })[];
78
+ structuredContent?: undefined;
79
+ }>;
80
+ };
81
+ export { addTasks };
82
+ //# sourceMappingURL=add-tasks.d.ts.map
@@ -0,0 +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,+BAA+B,CAAA;AAClF,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAA;AAgCvB,QAAA,MAAM,QAAQ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAsB4B,CAAA;AA8D1C,OAAO,EAAE,QAAQ,EAAE,CAAA"}
@@ -0,0 +1,96 @@
1
+ import { z } from 'zod';
2
+ import { getToolOutput } from '../mcp-helpers.js';
3
+ import { mapTask } from '../tool-helpers.js';
4
+ import { DurationParseError, parseDuration } from '../utils/duration-parser.js';
5
+ import { generateTaskNextSteps, getDateString, summarizeTaskOperation, } from '../utils/response-builders.js';
6
+ import { ToolNames } from '../utils/tool-names.js';
7
+ const TaskSchema = z.object({
8
+ content: z.string().min(1).describe('The content of the task to create.'),
9
+ description: z.string().optional().describe('The description of the task.'),
10
+ priority: z.number().int().min(1).max(4).optional().describe('The priority of the task (1-4).'),
11
+ dueString: z.string().optional().describe('The due date for the task, in natural language.'),
12
+ duration: z
13
+ .string()
14
+ .optional()
15
+ .describe('The duration of the task. Use format: "2h" (hours), "90m" (minutes), "2h30m" (combined), or "1.5h" (decimal hours). Max 24h.'),
16
+ projectId: z.string().optional().describe('The project ID to add this task to.'),
17
+ sectionId: z.string().optional().describe('The section ID to add this task to.'),
18
+ parentId: z.string().optional().describe('The parent task ID (for subtasks).'),
19
+ });
20
+ const ArgsSchema = {
21
+ tasks: z.array(TaskSchema).min(1).describe('The array of tasks to add.'),
22
+ };
23
+ const addTasks = {
24
+ name: ToolNames.ADD_TASKS,
25
+ description: 'Add one or more tasks to a project, section, or parent.',
26
+ parameters: ArgsSchema,
27
+ async execute({ tasks }, client) {
28
+ const addTaskPromises = tasks.map((task) => processTask(task, client));
29
+ const newTasks = await Promise.all(addTaskPromises);
30
+ const mappedTasks = newTasks.map(mapTask);
31
+ const textContent = generateTextContent({
32
+ tasks: mappedTasks,
33
+ args: { tasks },
34
+ });
35
+ return getToolOutput({
36
+ textContent,
37
+ structuredContent: {
38
+ tasks: mappedTasks,
39
+ totalCount: mappedTasks.length,
40
+ },
41
+ });
42
+ },
43
+ };
44
+ async function processTask(task, client) {
45
+ const { duration: durationStr, projectId, sectionId, parentId, ...otherTaskArgs } = task;
46
+ let taskArgs = { ...otherTaskArgs, projectId, sectionId, parentId };
47
+ // Parse duration if provided
48
+ if (durationStr) {
49
+ try {
50
+ const { minutes } = parseDuration(durationStr);
51
+ taskArgs = {
52
+ ...taskArgs,
53
+ duration: minutes,
54
+ durationUnit: 'minute',
55
+ };
56
+ }
57
+ catch (error) {
58
+ if (error instanceof DurationParseError) {
59
+ throw new Error(`Task "${task.content}": ${error.message}`);
60
+ }
61
+ throw error;
62
+ }
63
+ }
64
+ return await client.addTask(taskArgs);
65
+ }
66
+ function generateTextContent({ tasks, args, }) {
67
+ // Get context for smart next steps
68
+ const todayStr = getDateString();
69
+ const hasToday = tasks.some((task) => task.dueDate === todayStr);
70
+ // Generate context description for mixed contexts
71
+ const contextTypes = new Set();
72
+ for (const task of args.tasks) {
73
+ if (task.projectId)
74
+ contextTypes.add('projects');
75
+ else if (task.sectionId)
76
+ contextTypes.add('sections');
77
+ else if (task.parentId)
78
+ contextTypes.add('subtasks');
79
+ else
80
+ contextTypes.add('inbox');
81
+ }
82
+ let projectContext = '';
83
+ if (contextTypes.size === 1) {
84
+ const contextType = Array.from(contextTypes)[0];
85
+ projectContext = contextType === 'inbox' ? '' : `to ${contextType}`;
86
+ }
87
+ else if (contextTypes.size > 1) {
88
+ projectContext = 'to multiple contexts';
89
+ }
90
+ return summarizeTaskOperation('Added', tasks, {
91
+ context: projectContext,
92
+ nextSteps: generateTaskNextSteps('added', tasks, { hasToday }),
93
+ showDetails: true,
94
+ });
95
+ }
96
+ export { addTasks };
@@ -0,0 +1,40 @@
1
+ import { z } from 'zod';
2
+ declare const completeTasks: {
3
+ name: "complete-tasks";
4
+ description: string;
5
+ parameters: {
6
+ ids: z.ZodArray<z.ZodString, "many">;
7
+ };
8
+ execute(args: {
9
+ ids: string[];
10
+ }, client: import("@doist/todoist-api-typescript").TodoistApi): Promise<{
11
+ content: {
12
+ type: "text";
13
+ text: string;
14
+ }[];
15
+ structuredContent: {
16
+ completed: string[];
17
+ failures: {
18
+ item: string;
19
+ error: string;
20
+ code?: string;
21
+ }[];
22
+ totalRequested: number;
23
+ successCount: number;
24
+ failureCount: number;
25
+ };
26
+ } | {
27
+ content: ({
28
+ type: "text";
29
+ text: string;
30
+ mimeType?: undefined;
31
+ } | {
32
+ type: "text";
33
+ mimeType: string;
34
+ text: string;
35
+ })[];
36
+ structuredContent?: undefined;
37
+ }>;
38
+ };
39
+ export { completeTasks };
40
+ //# sourceMappingURL=complete-tasks.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"complete-tasks.d.ts","sourceRoot":"","sources":["../../src/tools/complete-tasks.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAA;AAUvB,QAAA,MAAM,aAAa;;;;;;;;;;;;;;;;sBAMmB,MAAM;uBAAS,MAAM;uBAAS,MAAM;;;;;;;;;;;;;;;;;;CAgChC,CAAA;AAsC1C,OAAO,EAAE,aAAa,EAAE,CAAA"}
@@ -0,0 +1,68 @@
1
+ import { z } from 'zod';
2
+ import { getToolOutput } from '../mcp-helpers.js';
3
+ import { summarizeBatch } from '../utils/response-builders.js';
4
+ import { ToolNames } from '../utils/tool-names.js';
5
+ const ArgsSchema = {
6
+ ids: z.array(z.string().min(1)).min(1).describe('The IDs of the tasks to complete.'),
7
+ };
8
+ const completeTasks = {
9
+ name: ToolNames.COMPLETE_TASKS,
10
+ description: 'Complete one or more tasks by their IDs.',
11
+ parameters: ArgsSchema,
12
+ async execute(args, client) {
13
+ const completed = [];
14
+ const failures = [];
15
+ for (const id of args.ids) {
16
+ try {
17
+ await client.closeTask(id);
18
+ completed.push(id);
19
+ }
20
+ catch (error) {
21
+ const errorMessage = error instanceof Error ? error.message : 'Unknown error';
22
+ failures.push({
23
+ item: id,
24
+ error: errorMessage,
25
+ });
26
+ }
27
+ }
28
+ const textContent = generateTextContent({
29
+ completed,
30
+ failures,
31
+ args,
32
+ });
33
+ return getToolOutput({
34
+ textContent,
35
+ structuredContent: {
36
+ completed,
37
+ failures,
38
+ totalRequested: args.ids.length,
39
+ successCount: completed.length,
40
+ failureCount: failures.length,
41
+ },
42
+ });
43
+ },
44
+ };
45
+ function generateNextSteps(completed, failures) {
46
+ if (completed > 0) {
47
+ const moveResult = failures === 0
48
+ ? "Use find-tasks-by-date('overdue') to tackle remaining overdue items."
49
+ : 'Review failed completions and retry if needed.';
50
+ return [moveResult];
51
+ }
52
+ if (failures > 0) {
53
+ return ['Check task IDs and permissions, then retry.'];
54
+ }
55
+ return ['No tasks were completed.'];
56
+ }
57
+ function generateTextContent({ completed, failures, args, }) {
58
+ const nextSteps = generateNextSteps(completed.length, failures.length);
59
+ return summarizeBatch({
60
+ action: 'Completed tasks',
61
+ success: completed.length,
62
+ total: args.ids.length,
63
+ successItems: completed,
64
+ failures,
65
+ nextSteps,
66
+ });
67
+ }
68
+ export { completeTasks };