List Todos
list_todosRetrieve and organize tasks with filtering by status, priority, tags, due dates, search queries, sorting, and pagination controls.
Instructions
List todos with filtering, search, sorting, and pagination
Input Schema
| Name | Required | Description | Default |
|---|---|---|---|
| completed | No | Filter by completion status (deprecated; use status) | |
| status | No | Filter by status | |
| query | No | Search text in title, description, or tags | |
| priority | No | Filter by priority level | |
| tag | No | Filter by tag (must contain) | |
| dueBefore | No | Filter todos due before this date (ISO format) | |
| dueAfter | No | Filter todos due after this date (ISO format) | |
| sortBy | No | Sort results by field | |
| order | No | Sort order (default: asc) | |
| limit | No | Max number of results to return (default: 50) | |
| offset | No | Number of results to skip |
Output Schema
| Name | Required | Description | Default |
|---|---|---|---|
| ok | Yes | ||
| error | No | ||
| result | No |
Implementation Reference
- src/tools/list_todos.ts:206-226 (handler)Core handler function that normalizes filters, fetches todos from storage, computes counts, sorts and paginates them, and builds the response.
async function handleListTodos( filters: ListTodosFilters ): Promise<CallToolResult> { const normalized = normalizeFilters(filters); const allTodos = await getTodos({ completed: normalized.completed, priority: normalized.priority, tag: normalized.tag, dueBefore: normalized.dueBefore, dueAfter: normalized.dueAfter, query: normalized.query, }); const todayIso = getTodayIso(); const counts = computeCounts(allTodos, todayIso); const sorted = canReuseOrder(normalized.sortBy, normalized.order, counts) ? allTodos : sortTodos(allTodos, normalized.sortBy, normalized.order); const paged = paginateTodos(sorted, normalized.offset, normalized.limit); return buildListResponse(paged, counts, normalized); } - src/schemas/inputs.ts:228-269 (schema)Input schema using Zod for validating filters like status, query, priority, pagination for the list_todos tool.
export const ListTodosFilterSchema: ZodType<ListTodosFilterInput> = z.strictObject({ completed: z .boolean() .optional() .describe('Filter by completion status (deprecated; use status)'), status: z .enum(['pending', 'completed', 'all']) .optional() .describe('Filter by status'), query: z .string() .min(1) .max(200) .optional() .describe('Search text in title, description, or tags'), priority: z .enum(['low', 'normal', 'high']) .optional() .describe('Filter by priority level'), tag: TagSchema.optional().describe('Filter by tag (must contain)'), dueBefore: IsoDateSchema.optional().describe( 'Filter todos due before this date (ISO format)' ), dueAfter: IsoDateSchema.optional().describe( 'Filter todos due after this date (ISO format)' ), sortBy: SortBySchema.optional().describe('Sort results by field'), order: SortOrderSchema.optional().describe('Sort order (default: asc)'), limit: z .int() .min(1) .max(200) .optional() .describe('Max number of results to return (default: 50)'), offset: z .int() .min(0) .max(10000) .optional() .describe('Number of results to skip'), }); - src/tools/list_todos.ts:228-249 (registration)Registers the 'list_todos' tool with the MCP server, specifying title, description, schemas, and the handler function.
export function registerListTodos(server: McpServer): void { server.registerTool( 'list_todos', { title: 'List Todos', description: 'List todos with filtering, search, sorting, and pagination', inputSchema: ListTodosFilterSchema, outputSchema: DefaultOutputSchema, annotations: { readOnlyHint: true, idempotentHint: true, }, }, async (filters) => { try { return await handleListTodos(filters); } catch (err) { return createErrorResponse('E_LIST_TODOS', getErrorMessage(err)); } } ); } - src/tools/index.ts:11-19 (registration)Top-level registration function that calls registerListTodos among others to set up all tools on the server.
export function registerAllTools(server: McpServer): void { registerAddTodo(server); registerAddTodos(server); registerListTodos(server); registerUpdateTodo(server); registerCompleteTodo(server); registerDeleteTodo(server); registerDeleteTodos(server); }