get_projects
Retrieve all projects from Things 3. Optionally include tasks within each project.
Instructions
Get all projects from Things
Args: include_items: Include tasks within projects
Input Schema
| Name | Required | Description | Default |
|---|---|---|---|
| include_items | No |
Output Schema
| Name | Required | Description | Default |
|---|---|---|---|
| result | Yes |
Implementation Reference
- src/things_mcp/server.py:192-204 (handler)Handler function that retrieves all projects from Things via `things.projects()` and formats them using `format_project`. Registered as an MCP tool via the @mcp.tool decorator.
@mcp.tool async def get_projects(include_items: bool = False) -> str: """Get all projects from Things Args: include_items: Include tasks within projects """ projects = things.projects() if not projects: return "No projects found" formatted_projects = [format_project(project, include_items) for project in projects] return "\n\n---\n\n".join(formatted_projects) - src/things_mcp/server.py:192-193 (registration)Tool registration via @mcp.tool decorator on the FastMCP instance 'mcp'.
@mcp.tool async def get_projects(include_items: bool = False) -> str: - src/things_mcp/formatters.py:146-194 (helper)Helper function that formats a single project dict into a human-readable string, including title, UUID, area, notes, dates, headings, and optionally tasks.
def format_project(project: dict, include_items: bool = False) -> str: """Helper function to format a single project.""" project_text = f"Title: {project['title']}\nUUID: {project['uuid']}" if project.get('area'): try: area = things.get(project['area']) if area: project_text += f"\nArea: {area['title']}" except Exception: pass if project.get('notes'): project_text += f"\nNotes: {project['notes']}" # Add creation and modification dates if project.get('created'): project_text += f"\nCreated: {project['created']}" # Calculate age since creation try: age_text = _calculate_age(project['created']) project_text += f"\nAge: {age_text}" except (ValueError, TypeError): pass if project.get('modified'): project_text += f"\nModified: {project['modified']}" # Calculate time since last modification try: modified_age = _calculate_age(project['modified']) project_text += f"\nLast modified: {modified_age}" except (ValueError, TypeError): pass # Always show headings for projects headings = things.tasks(type='heading', project=project['uuid']) if headings: project_text += "\n\nHeadings:" for heading in headings: project_text += f"\n- {heading['title']}" if include_items: todos = things.todos(project=project['uuid']) if todos: project_text += "\n\nTasks:" for todo in todos: project_text += f"\n- {todo['title']}" return project_text