todoist_comment_create
Add comments to Todoist tasks by task ID or name to provide context, updates, or attachments for better task management.
Instructions
Add a comment to a task in Todoist by task ID or task name
Input Schema
TableJSON Schema
| Name | Required | Description | Default |
|---|---|---|---|
| task_id | No | ID of the task to comment on (provide this OR task_name) | |
| task_name | No | Name/content of the task to comment on (provide this OR task_id) | |
| content | Yes | Content of the comment | |
| attachment | No | Optional file attachment (optional) |
Implementation Reference
- src/handlers/comment-handlers.ts:24-81 (handler)The primary handler function implementing the todoist_comment_create tool. Resolves task by ID or name, validates/sanitizes content, handles optional attachments, calls Todoist API to add comment, clears cache, and returns formatted success message.export async function handleCreateComment( todoistClient: TodoistApi, args: CreateCommentArgs ): Promise<string> { return ErrorHandler.wrapAsync("create comment", async () => { // Validate and sanitize content const sanitizedContent = validateCommentContent(args.content); let taskId: string; // If task_id is provided, use it directly if (args.task_id) { taskId = args.task_id; } else if (args.task_name) { // Search for task by name const result = await todoistClient.getTasks(); const tasks = extractArrayFromResponse<TodoistTask>(result); const matchingTask = tasks.find((task: TodoistTask) => task.content.toLowerCase().includes(args.task_name!.toLowerCase()) ); if (!matchingTask) { ErrorHandler.handleTaskNotFound(args.task_name!); } taskId = matchingTask.id; } else { throw new Error("Either task_id or task_name must be provided"); } const commentData: CommentCreationData = { content: sanitizedContent, taskId: taskId, }; if (args.attachment) { commentData.attachment = { fileName: args.attachment.file_name, fileUrl: args.attachment.file_url, fileType: args.attachment.file_type, }; } const comment = await todoistClient.addComment(commentData); // Clear cache after creating comment commentCache.clear(); // Use defensive typing for comment response const commentResponse = comment as CommentResponse; return `Comment added to task:\nContent: ${commentResponse.content}${ commentResponse.attachment ? `\nAttachment: ${commentResponse.attachment.fileName} (${commentResponse.attachment.fileType})` : "" }\nPosted at: ${commentResponse.postedAt || new Date().toISOString()}`; }); }
- src/tools/comment-tools.ts:4-45 (schema)Tool definition including name, description, and detailed input schema for todoist_comment_create.export const CREATE_COMMENT_TOOL: Tool = { name: "todoist_comment_create", description: "Add a comment to a task in Todoist by task ID or task name", inputSchema: { type: "object", properties: { task_id: { type: "string", description: "ID of the task to comment on (provide this OR task_name)", }, task_name: { type: "string", description: "Name/content of the task to comment on (provide this OR task_id)", }, content: { type: "string", description: "Content of the comment", }, attachment: { type: "object", description: "Optional file attachment (optional)", properties: { file_name: { type: "string", description: "Name of the attached file", }, file_url: { type: "string", description: "URL of the attached file", }, file_type: { type: "string", description: "MIME type of the attached file", }, }, required: ["file_name", "file_url", "file_type"], }, }, required: ["content"], }, };
- src/tools/index.ts:62-69 (registration)Includes COMMENT_TOOLS (containing todoist_comment_create) in the ALL_TOOLS array provided to the MCP server for tool listing.export const ALL_TOOLS = [ ...TASK_TOOLS, ...PROJECT_TOOLS, ...COMMENT_TOOLS, ...LABEL_TOOLS, ...SUBTASK_TOOLS, ...TEST_TOOLS, ];
- src/index.ts:240-245 (registration)Switch case in central CallToolRequest handler that validates args and dispatches to the specific handleCreateComment implementation.case "todoist_comment_create": if (!isCreateCommentArgs(args)) { throw new Error("Invalid arguments for todoist_comment_create"); } result = await handleCreateComment(apiClient, args); break;
- src/type-guards.ts:199-210 (schema)Runtime type guard validating tool input arguments match CreateCommentArgs interface (used in dispatcher).export function isCreateCommentArgs(args: unknown): args is CreateCommentArgs { if (typeof args !== "object" || args === null) return false; const obj = args as Record<string, unknown>; return ( "content" in obj && typeof obj.content === "string" && (obj.task_id === undefined || typeof obj.task_id === "string") && (obj.task_name === undefined || typeof obj.task_name === "string") && (obj.task_id !== undefined || obj.task_name !== undefined) ); }