get_tasks
Retrieve tasks from TickTick, optionally filtered by project ID, to manage and organize task lists efficiently.
Instructions
Get all tasks or tasks from a specific project
Input Schema
TableJSON Schema
| Name | Required | Description | Default |
|---|---|---|---|
| projectId | No | Optional project ID to filter tasks |
Implementation Reference
- src/index.ts:225-234 (handler)MCP tool handler for 'get_tasks': calls TickTickClient.getTasks with optional projectId and returns JSON stringified tasks.case 'get_tasks': const tasks = await this.ticktickClient!.getTasks(args?.projectId as string); return { content: [ { type: 'text', text: JSON.stringify(tasks, null, 2), }, ], };
- src/index.ts:39-51 (registration)Tool registration in ListTools response, including name, description, and input schema allowing optional projectId.{ name: 'get_tasks', description: 'Get all tasks or tasks from a specific project', inputSchema: { type: 'object', properties: { projectId: { type: 'string', description: 'Optional project ID to filter tasks', }, }, }, },
- src/ticktick-client.ts:170-223 (helper)Main helper function implementing task retrieval: fetches from specific project or aggregates from all projects and inbox via TickTick API, enhances with priorityText.async getTasks(projectId?: string): Promise<TickTickTask[]> { await this.ensureAuthenticated(); try { if (projectId) { // Get tasks from a specific project using project data endpoint const response = await this.client.get(`/project/${projectId}/data`); const tasks = response.data?.tasks || []; return tasks.map((task: TickTickTask) => enhanceTaskForDisplay(task)); } else { // Get all tasks by getting all projects and their tasks const projects = await this.getProjects(); const allTasks: TickTickTask[] = []; for (const project of projects) { try { // Some special handling may be needed for inbox project const projectResponse = await this.client.get(`/project/${project.id}/data`); const projectTasks = projectResponse.data?.tasks || []; allTasks.push(...projectTasks); } catch (error) { // Skip projects that can't be accessed, but log more details console.warn(`Could not access tasks for project ${project.id} (${project.name}):`, error); } } // Also try to get inbox tasks specifically if inbox wasn't included try { const inboxResponse = await this.client.get('/project/inbox/data'); const inboxTasks = inboxResponse.data?.tasks || []; allTasks.push(...inboxTasks); } catch (error) { // Inbox might not be accessible this way, try alternative try { const inboxResponse = await this.client.get('/task?projectId=inbox'); const inboxTasks = inboxResponse.data || []; allTasks.push(...inboxTasks); } catch (inboxError) { console.warn('Could not access inbox tasks:', inboxError); } } return allTasks.map(task => enhanceTaskForDisplay(task)); } } catch (error) { // Log more detailed error information if (error instanceof Error && 'response' in error) { const axiosError = error as any; const errorData = axiosError.response?.data ? JSON.stringify(axiosError.response.data) : axiosError.message; throw new Error(`Failed to get tasks: ${axiosError.response?.status} ${axiosError.response?.statusText} - ${errorData}`); } throw new Error(`Failed to get tasks: ${error instanceof Error ? error.message : 'Unknown error'}`); } }
- src/ticktick-client.ts:5-33 (helper)Helper utility to enhance tasks with human-readable priorityText for better display.function enhanceTaskForDisplay(task: TickTickTask): any { const enhanced = { ...task }; // Add human-readable priority let priorityText = 'None'; switch (task.priority) { case 0: priorityText = 'None'; break; case 1: priorityText = 'Low'; break; case 3: priorityText = 'Medium'; break; case 5: priorityText = 'High'; break; default: priorityText = task.priority ? `Custom (${task.priority})` : 'None'; } return { ...enhanced, priorityText, // Keep original dates for display - they should show correctly dueDate: task.dueDate }; }
- src/types.ts:3-45 (schema)Zod schema defining the TickTickTask type used for return values.export const TickTickTaskSchema = z.object({ id: z.string(), title: z.string(), content: z.string().optional(), desc: z.string().optional(), allDay: z.boolean().optional(), startDate: z.string().optional(), dueDate: z.string().optional(), timeZone: z.string().optional(), isFloating: z.boolean().optional(), reminder: z.string().optional(), reminders: z.array(z.object({ id: z.string(), trigger: z.string() })).optional(), exDate: z.array(z.string()).optional(), completedTime: z.string().optional(), completedUserId: z.string().optional(), createdTime: z.string().optional(), creator: z.string().optional(), etag: z.string().optional(), modifiedTime: z.string().optional(), projectId: z.string(), sortOrder: z.number().optional(), status: z.number().optional(), tags: z.array(z.string()).optional(), priority: z.number().optional(), progress: z.number().optional(), assignee: z.string().optional(), isDirty: z.boolean().optional(), local: z.boolean().optional(), repeatFlag: z.string().optional(), items: z.array(z.object({ id: z.string(), title: z.string(), status: z.number().optional(), completedTime: z.string().optional(), isAllDay: z.boolean().optional(), sortOrder: z.number().optional(), startDate: z.string().optional(), timeZone: z.string().optional() })).optional() });