Skip to main content
Glama

roadmap_view

View project roadmaps to track work status, identify pending or blocked tasks, and monitor progress across organizations and projects.

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

TableJSON Schema
NameRequiredDescriptionDefault
org_idNoFilter by organization ID (optional) case-insensitive
project_idNoFilter by project ID (optional) - recommended to reduce output size
active_onlyNoOnly show non-done tickets (default: true)

Implementation Reference

  • Handler logic for roadmap_view tool: fetches roadmap from DB, applies filters, formats as markdown summary.
    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)
  • Tool registration in list_tools(), including name, description, and inputSchema.
            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,
                        },
                    },
                },
            ),
  • Pydantic model RoadmapView used as return type for get_roadmap and processed in handler.
    class RoadmapView(BaseModel):
        """Full roadmap at a glance."""
    
        orgs: list[OrgView] = Field(default_factory=list)
        stats: dict = Field(default_factory=dict)
  • Database method get_roadmap that constructs the RoadmapView by aggregating orgs, projects, tickets, tasks and computes stats.
    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,
            },
        )

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/urjitbhatia/tpm-mcp'

If you have feedback or need assistance with the MCP directory API, please join our Discord server