task_list
List and filter project tasks with status, priority, assignee, and tag options. View subtask counts and dependencies across epics or specific projects.
Instructions
List tasks with optional filters. If no epic_id given, lists across ALL epics. Includes subtask counts and dependency info.
Input Schema
TableJSON Schema
| Name | Required | Description | Default |
|---|---|---|---|
| epic_id | No | Filter by epic (omit for all tasks) | |
| status | No | ||
| priority | No | ||
| assigned_to | No | Filter by assignee | |
| tag | No | Filter by tag | |
| sort_by | No | Sort order: priority (critical first), created (newest first), due_date (earliest first), status (actionable first) | priority |
| limit | No | Max results |
Implementation Reference
- src/tools/tasks.ts:227-281 (handler)The 'handleTaskList' function, which executes the logic for listing tasks, including optional filtering by epic, status, priority, assignee, tag, sorting, and limit.
function handleTaskList(args: Record<string, unknown>) { const db = getDb(); const epicId = args.epic_id as number | undefined; const status = args.status as string | undefined; const priority = args.priority as string | undefined; const assignedTo = args.assigned_to as string | undefined; const tag = args.tag as string | undefined; const sortBy = (args.sort_by as string) ?? 'priority'; const limit = (args.limit as number) ?? 50; const whereClauses: string[] = []; const params: unknown[] = []; if (epicId !== undefined) { whereClauses.push('t.epic_id = ?'); params.push(epicId); } if (status) { whereClauses.push('t.status = ?'); params.push(status); } if (priority) { whereClauses.push('t.priority = ?'); params.push(priority); } if (assignedTo) { whereClauses.push('t.assigned_to = ?'); params.push(assignedTo); } if (tag) { addTagFilter(whereClauses, params, tag, 't'); } const whereStr = whereClauses.length > 0 ? `WHERE ${whereClauses.join(' AND ')}` : ''; const sql = ` SELECT t.*, e.name as epic_name, COUNT(DISTINCT s.id) as subtask_count, SUM(CASE WHEN s.status = 'done' THEN 1 ELSE 0 END) as subtask_done_count, (SELECT COUNT(*) FROM task_dependencies d JOIN tasks dt ON dt.id = d.depends_on_task_id AND dt.status != 'done' WHERE d.task_id = t.id) as blocked_by_count FROM tasks t JOIN epics e ON e.id = t.epic_id LEFT JOIN subtasks s ON s.task_id = t.id ${whereStr} GROUP BY t.id ORDER BY ${getTaskOrderClause(sortBy)} LIMIT ? `; params.push(limit); return db.prepare(sql).all(...params); } - src/tools/tasks.ts:50-72 (schema)The tool definition for 'task_list', specifying its input schema, description, and annotations.
{ name: 'task_list', description: 'List tasks with optional filters. If no epic_id given, lists across ALL epics. Includes subtask counts and dependency info.', annotations: { title: 'List Tasks', readOnlyHint: true, destructiveHint: false, idempotentHint: true, openWorldHint: false }, inputSchema: { type: 'object', properties: { epic_id: { type: 'integer', description: 'Filter by epic (omit for all tasks)' }, status: { type: 'string', enum: ['todo', 'in_progress', 'review', 'done', 'blocked'] }, priority: { type: 'string', enum: ['low', 'medium', 'high', 'critical'] }, assigned_to: { type: 'string', description: 'Filter by assignee' }, tag: { type: 'string', description: 'Filter by tag' }, sort_by: { type: 'string', enum: ['priority', 'created', 'due_date', 'status'], default: 'priority', description: 'Sort order: priority (critical first), created (newest first), due_date (earliest first), status (actionable first)', }, limit: { type: 'integer', default: 50, description: 'Max results' }, }, }, }, - src/tools/tasks.ts:406-406 (registration)The mapping of the 'task_list' tool name to its handler function 'handleTaskList' in the 'handlers' registry object.
task_list: handleTaskList,