get_anytime
Retrieve tasks from the Anytime list to access unscheduled to-dos in your Things 3 task manager.
Instructions
Get todos from Anytime list
Input Schema
| Name | Required | Description | Default |
|---|---|---|---|
No arguments | |||
Output Schema
| Name | Required | Description | Default |
|---|---|---|---|
| result | Yes |
Implementation Reference
- src/things_mcp/server.py:114-124 (handler)The get_anytime handler function: fetches todos from Things' Anytime list via things.anytime(), filters out tasks belonging to Someday projects (matching Things UI behavior), formats each todo using format_todo(), and joins them with separators. Returns 'No items found' if list is empty or entirely filtered.
async def get_anytime() -> str: """Get todos from Anytime list""" todos = things.anytime(include_items=True) if not todos: return "No items found" # Filter out tasks from Someday projects todos = filter_someday_project_tasks(todos) if not todos: return "No items found" formatted_todos = [format_todo(todo) for todo in todos] return "\n\n---\n\n".join(formatted_todos) - src/things_mcp/server.py:113-114 (registration)The @mcp.tool decorator registers get_anytime as an MCP tool on the FastMCP server instance.
@mcp.tool async def get_anytime() -> str: - src/things_mcp/server.py:58-74 (helper)filter_someday_project_tasks helper: filters out tasks belonging to Someday projects. Called by get_anytime (line 120) to exclude tasks from Someday projects, matching Things UI behavior.
def filter_someday_project_tasks(todos): """Filter out tasks that belong to Someday projects. This matches Things UI behavior where tasks from Someday projects don't appear in Today, Upcoming, or Anytime views. Handles both direct project membership and tasks under headings in Someday projects. Args: todos: List of todo dictionaries Returns: Filtered list excluding tasks from Someday projects """ someday_project_ids, heading_to_project = _get_someday_context() if not someday_project_ids: return todos return [todo for todo in todos if not _is_in_someday_project(todo, someday_project_ids, heading_to_project)] - src/things_mcp/formatters.py:40-144 (helper)format_todo helper: formats a single todo dictionary into a readable multi-line string with title, UUID, type, status, dates, notes, project, heading, area, tags, and checklist. Called by get_anytime (line 123) to format each todo.
def format_todo(todo: dict) -> str: """Helper function to format a single todo into a readable string.""" logger.debug(f"Formatting todo: {todo}") todo_text = f"Title: {todo['title']}" # Add UUID for reference todo_text += f"\nUUID: {todo['uuid']}" # Add type todo_text += f"\nType: {todo['type']}" # Add status if present if todo.get('status'): todo_text += f"\nStatus: {todo['status']}" # Look up parent project once (used for both List status and Project display) # For heading-level tasks without a project field, resolve heading -> project parent_project = None if todo.get('project'): try: parent_project = things.get(todo['project']) except Exception: pass elif todo.get('heading'): try: heading_obj = things.get(todo['heading']) if heading_obj and heading_obj.get('project'): parent_project = things.get(heading_obj['project']) except Exception: pass # Add start/list location with Someday inheritance if todo.get('start'): effective_start = todo['start'] if effective_start != 'Someday' and parent_project and parent_project.get('start') == 'Someday': effective_start = 'Someday' todo_text += f"\nList: {effective_start} (inherited from project)" else: todo_text += f"\nList: {effective_start}" # Add dates if todo.get('start_date'): todo_text += f"\nStart Date: {todo['start_date']}" if todo.get('deadline'): todo_text += f"\nDeadline: {todo['deadline']}" if todo.get('stop_date'): # Completion date todo_text += f"\nCompleted: {todo['stop_date']}" # Add creation and modification dates if todo.get('created'): todo_text += f"\nCreated: {todo['created']}" # Calculate age since creation try: age_text = _calculate_age(todo['created']) todo_text += f"\nAge: {age_text}" except (ValueError, TypeError): pass if todo.get('modified'): todo_text += f"\nModified: {todo['modified']}" # Calculate time since last modification try: modified_age = _calculate_age(todo['modified']) todo_text += f"\nLast modified: {modified_age}" except (ValueError, TypeError): pass # Add notes if present if todo.get('notes'): todo_text += f"\nNotes: {todo['notes']}" # Add project info if present if parent_project: todo_text += f"\nProject: {parent_project['title']}" # Add heading info if present if todo.get('heading'): try: heading = things.get(todo['heading']) if heading: todo_text += f"\nHeading: {heading['title']}" except Exception: pass # Add area info if present if todo.get('area'): try: area = things.get(todo['area']) if area: todo_text += f"\nArea: {area['title']}" except Exception: pass # Add tags if present if todo.get('tags'): todo_text += f"\nTags: {', '.join(todo['tags'])}" # Add checklist if present and contains items if isinstance(todo.get('checklist'), list): todo_text += "\nChecklist:" for item in todo['checklist']: checkbox = "✓" if item.get('status') == 'completed' else "☐" todo_text += f"\n {checkbox} {item['title']}" return todo_text