roadmap_view
View project roadmap to check work status, track progress on pending/blocked/completed tasks, and identify current project state.
Instructions
PROJECT MANAGEMENT (TPM): Get project roadmap showing work status.
USE THIS TOOL WHEN:
User asks "what's in progress?" or "what are we working on?"
User asks "TPM status", ":TPM:" prefix, or "show me the roadmap"
User asks about pending/blocked/completed work
Starting a work session to see current state
User completes work and you need to find related tasks to mark done
Returns summary of organizations, projects, and tickets. Use project_id filter to reduce output.
Input Schema
| Name | Required | Description | Default |
|---|---|---|---|
| org_id | No | Filter by organization ID (optional) case-insensitive | |
| project_id | No | Filter by project ID (optional) - recommended to reduce output size | |
| active_only | No | Only show non-done tickets (default: true) |
Implementation Reference
- src/tpm_mcp/server.py:741-800 (handler)The main handler for the roadmap_view tool. Processes input arguments (org_id, project_id, active_only), retrieves roadmap data from database, and formats a hierarchical Markdown summary of organizations, projects, tickets, and tasks with status icons and stats.if name == "roadmap_view": roadmap = db.get_roadmap(args.get("org_id")) project_filter = args.get("project_id", "").lower() if args.get("project_id") else None active_only = args.get("active_only", True) # Summary format (always use summary now - json was too large) lines = ["# Roadmap Summary\n"] lines.append( f"**Stats**: {roadmap.stats['tickets_done']}/{roadmap.stats['total_tickets']} tickets, " f"{roadmap.stats['tasks_done']}/{roadmap.stats['total_tasks']} tasks " f"({roadmap.stats['completion_pct']}% complete)\n" ) for org in roadmap.orgs: lines.append(f"## {org.name}") for proj in org.projects: # Filter by project if specified if project_filter and proj.id.lower() != project_filter: continue lines.append(f"\n### {proj.name}") if proj.description: lines.append(f"_{proj.description}_\n") lines.append(f"Tickets: {proj.tickets_done}/{proj.ticket_count} done\n") # Filter tickets tickets = proj.tickets if active_only: tickets = [t for t in tickets if t.status.value != "done"] for ticket in tickets[:20]: # Limit to 20 tickets per project status_icon = { "backlog": "[ ]", "planned": "[P]", "in-progress": "[~]", "done": "[x]", "blocked": "[!]", }.get(ticket.status.value, "[ ]") prio = ( f"({ticket.priority.value})" if ticket.priority.value in ["critical", "high"] else "" ) lines.append(f"- {status_icon} **{ticket.id}**: {ticket.title} {prio}") lines.append(f" Tasks: {ticket.tasks_done}/{ticket.task_count}") # Show incomplete tasks (max 3) incomplete = [t for t in ticket.tasks if t.status.value != "done"] for task in incomplete[:3]: t_icon = {"pending": "[ ]", "in-progress": "[~]", "blocked": "[!]"}.get( task.status.value, "[ ]" ) lines.append(f" - {t_icon} {task.id}: {task.title}") if len(incomplete) > 3: lines.append(f" - ... and {len(incomplete) - 3} more") if len(tickets) > 20: lines.append(f"\n_... and {len(tickets) - 20} more tickets_") return "\n".join(lines)
- src/tpm_mcp/server.py:43-73 (registration)Registers the 'roadmap_view' tool with the MCP server via @server.list_tools(), providing name, detailed usage instructions in description, and input schema for filtering parameters.Tool( name="roadmap_view", description="""PROJECT MANAGEMENT (TPM): Get project roadmap showing work status. USE THIS TOOL WHEN: - User asks "what's in progress?" or "what are we working on?" - User asks "TPM status", ":TPM:" prefix, or "show me the roadmap" - User asks about pending/blocked/completed work - Starting a work session to see current state - User completes work and you need to find related tasks to mark done Returns summary of organizations, projects, and tickets. Use project_id filter to reduce output.""", inputSchema={ "type": "object", "properties": { "org_id": { "type": "string", "description": "Filter by organization ID (optional) case-insensitive", }, "project_id": { "type": "string", "description": "Filter by project ID (optional) - recommended to reduce output size", }, "active_only": { "type": "boolean", "description": "Only show non-done tickets (default: true)", "default": True, }, }, }, ),
- src/tpm_mcp/models.py:200-205 (schema)Pydantic model for the RoadmapView return type, containing nested organizations, projects, tickets, tasks views, and overall completion statistics. Used internally by db.get_roadmap().class RoadmapView(BaseModel): """Full roadmap at a glance.""" orgs: list[OrgView] = Field(default_factory=list) stats: dict = Field(default_factory=dict)
- src/tpm_mcp/db.py:804-887 (helper)Database helper method TrackerDB.get_roadmap() that constructs the full RoadmapView by querying and aggregating all organizations, projects, tickets, and tasks, computing counts and completion percentages.def get_roadmap(self, org_id: str | None = None) -> RoadmapView: """Get full roadmap view with stats.""" orgs = self.list_orgs() if org_id: org_id = self._normalize_id(org_id) orgs = [o for o in orgs if o.id.lower() == org_id] org_views = [] total_tickets = 0 tickets_done = 0 total_tasks = 0 tasks_done = 0 for org in orgs: projects = self.list_projects(org.id) project_views = [] for proj in projects: tickets = self.list_tickets(proj.id) ticket_views = [] proj_tickets_done = 0 for ticket in tickets: tasks = self.list_tasks(ticket.id) task_views = [ TaskView( id=t.id, title=t.title, status=t.status, priority=t.priority, complexity=t.complexity, ) for t in tasks ] ticket_tasks_done = sum( 1 for t in tasks if t.status in (TaskStatus.DONE, TaskStatus.COMPLETED) ) ticket_views.append( TicketView( id=ticket.id, title=ticket.title, status=ticket.status, priority=ticket.priority, tags=ticket.tags, task_count=len(tasks), tasks_done=ticket_tasks_done, tasks=task_views, ) ) total_tasks += len(tasks) tasks_done += ticket_tasks_done if ticket.status in (TicketStatus.DONE, TicketStatus.COMPLETED): proj_tickets_done += 1 project_views.append( ProjectView( id=proj.id, name=proj.name, description=proj.description, ticket_count=len(tickets), tickets_done=proj_tickets_done, tickets=ticket_views, ) ) total_tickets += len(tickets) tickets_done += proj_tickets_done org_views.append(OrgView(id=org.id, name=org.name, projects=project_views)) return RoadmapView( orgs=org_views, stats={ "total_tickets": total_tickets, "tickets_done": tickets_done, "total_tasks": total_tasks, "tasks_done": tasks_done, "completion_pct": round(tasks_done / total_tasks * 100, 1) if total_tasks > 0 else 0, }, )