todoist_get_tasks
Retrieve filtered Todoist tasks by project ID, priority, natural language filters, or task limits to organize and manage your to-do list effectively.
Instructions
Get a list of tasks from Todoist with various filters
Args: project_id: Filter tasks by project ID (optional) filter: Natural language filter like 'today', 'tomorrow', 'next week', 'priority 1', 'overdue' (optional) priority: Filter by priority level (1-4) (optional) limit: Maximum number of tasks to return (optional)
Input Schema
TableJSON Schema
| Name | Required | Description | Default |
|---|---|---|---|
| filter | No | ||
| limit | No | ||
| priority | No | ||
| project_id | No |
Implementation Reference
- src/tasks.py:121-240 (handler)Main handler function implementing the todoist_get_tasks tool. Fetches tasks from Todoist API supporting filters by project, section, parent, label, or IDs, with pagination handling up to nmax tasks.def todoist_get_tasks( ctx: Context, project_id: Optional[str] = None, section_id: Optional[str] = None, parent_id: Optional[str] = None, label: Optional[str] = None, ids: Optional[list[str]] = None, nmax: Optional[int] = 100, limit: int = 200 ) -> str: """Get a list of tasks from Todoist with basic filters This is a wrapper around the Todoist API's get_tasks method that handles pagination automatically. By default, it will fetch up to 100 matching tasks. Set nmax=None to fetch ALL matching tasks across multiple API calls. For natural language filtering (like 'today', 'overdue'), use todoist_filter_tasks instead. Examples: # Get up to 100 tasks (default) todoist_get_tasks(ctx) # Get all tasks in a project (up to 100 by default) todoist_get_tasks(ctx, project_id="12345") # Get first 500 tasks total todoist_get_tasks(ctx, nmax=500) # Get ALL tasks (unlimited) todoist_get_tasks(ctx, nmax=None) # Get specific tasks by ID todoist_get_tasks(ctx, ids=["task1", "task2", "task3"]) Args: project_id: Filter tasks by project ID (optional) section_id: Filter tasks by section ID (optional) parent_id: Filter tasks by parent task ID (optional) label: Filter tasks by label name (optional) ids: A list of the IDs of the tasks to retrieve (optional) nmax: Maximum total number of tasks to return. Set to None for ALL matching tasks (default: 100) limit: Number of tasks to fetch per API request (default: 200, max: 200) """ todoist_client = ctx.request_context.lifespan_context.todoist_client try: logger.info(f"Getting tasks with project_id: {project_id}, section_id: {section_id}, parent_id: {parent_id}, label: {label}, nmax: {nmax}, limit: {limit}") # Early exit for zero requests to avoid unnecessary API calls if nmax is not None: if nmax == 0: logger.info("nmax=0 specified, returning empty result") return [] elif nmax < 0: logger.warning(f"Invalid nmax {nmax}, using default of 100") nmax = 100 if limit > 200: logger.warning(f"Limit {limit} exceeds API maximum of 200, using 200 instead") limit = 200 elif limit <= 0: logger.warning(f"Invalid limit {limit}, using default of 200") limit = 200 # Key optimization: match page size to actual need to reduce API payload effective_limit = limit if nmax is not None and nmax < limit: effective_limit = nmax logger.info(f"Optimized limit from {limit} to {effective_limit} to match nmax") params = {} if project_id: params["project_id"] = project_id if section_id: params["section_id"] = section_id if parent_id: params["parent_id"] = parent_id if label: params["label"] = label if ids: params["ids"] = ids params["limit"] = effective_limit tasks_iterator = todoist_client.get_tasks(**params) all_tasks = [] pages_fetched = 0 for task_batch in tasks_iterator: pages_fetched += 1 all_tasks.extend(task_batch) logger.info(f"Fetched page {pages_fetched} with {len(task_batch)} tasks (total: {len(all_tasks)})") if nmax is not None and len(all_tasks) >= nmax: # Trim excess - rare due to effective_limit optimization, but handles edge cases all_tasks = all_tasks[:nmax] logger.info(f"Reached nmax of {nmax} tasks, stopping pagination") break # Todoist API signals end of results by returning fewer items than requested if len(task_batch) < effective_limit: logger.info(f"Received {len(task_batch)} tasks (less than limit {effective_limit}), reached end of results") break if not all_tasks: logger.info("No tasks found matching the criteria") return "No tasks found matching the criteria" logger.info(f"Retrieved {len(all_tasks)} tasks total across {pages_fetched} pages") if nmax is None: logger.info("Fetched ALL matching tasks (nmax=None specified)") elif len(all_tasks) == nmax: logger.info(f"Retrieved exactly the requested {nmax} tasks") return json.dumps([task.to_dict() for task in all_tasks], indent=2, default=str) except Exception as error: logger.error(f"Error getting tasks: {error}") return f"Error getting tasks: {str(error)}"
- src/main.py:85-85 (registration)Registers the todoist_get_tasks handler as an MCP tool using FastMCP's decorator.mcp.tool()(todoist_get_tasks)
- src/main.py:26-36 (registration)Imports the todoist_get_tasks function from tasks module for registration.from .tasks import ( todoist_get_task, todoist_get_tasks, todoist_filter_tasks, todoist_add_task, todoist_update_task, todoist_complete_task, todoist_uncomplete_task, todoist_move_task, todoist_delete_task, )