Skip to main content
Glama

ticket_create

Create new tickets, epics, or issues to track project work items, breaking down features, bugs, and tasks into manageable, organized units for project management.

Instructions

PROJECT MANAGEMENT (TPM): Create a new ticket, epic, or issue to track.

USE THIS TOOL WHEN:

  • User says ":TPM: Add X feature to the roadmap"

  • User wants to add a new feature/ticket/issue

  • User says "add ticket for X" or "create feature for Y"

  • Breaking down work into trackable items

  • User asks to scope out or define new work

  • User discusses new work that should be tracked

Use roadmap_view first to get the project_id. Tickets are high-level work items (like Jira epics/stories).

ID AUTO-GENERATION: IDs are always auto-generated as {PREFIX}-{NNN} (e.g., FEAT-001, ISSUE-042). The number is automatically incremented based on existing tickets with that prefix.

OPTIONAL PREFIX PARAMETER: Provide a prefix to categorize the ticket type:

  • FEAT: New features or capabilities

  • ISSUE: Bugs, problems, or issues to fix

  • TASK: General tasks or chores

  • INFRA: Infrastructure or DevOps work

  • DOC: Documentation tasks

If no prefix is provided, uses the project ID as the prefix (e.g., FRONTEND-001, BACKEND-042).

Input Schema

TableJSON Schema
NameRequiredDescriptionDefault
project_idYesProject ID (use project_list to find) case-insensitive
prefixNoOptional prefix for ticket ID (e.g., FEAT, ISSUE, INFRA). Number is auto-generated. If omitted, uses project ID as prefix.
titleYesTicket title
descriptionNoDetailed description of the ticket
statusNoTicket status (default: backlog)
priorityNoPriority level (default: medium)
tagsNoTags for categorization
assigneesNoWho is working on this

Implementation Reference

  • MCP tool handler for 'ticket_create': parses arguments, constructs TicketCreate model, calls db.create_ticket, returns confirmation.
    if name == "ticket_create":
        ticket = db.create_ticket(
            TicketCreate(
                project_id=args["project_id"],
                title=args["title"],
                prefix=args.get("prefix"),
                description=args.get("description"),
                status=TicketStatus(args.get("status", "backlog")),
                priority=Priority(args.get("priority", "medium")),
                tags=args.get("tags"),
                assignees=args.get("assignees"),
            )
        )
        # Return minimal confirmation to avoid context bleed
        return f"Created ticket: {ticket.id} - {ticket.title} [{ticket.status.value}]"
  • Registration of the 'ticket_create' tool in list_tools(), including name, description, and inputSchema.
            Tool(
                name="ticket_create",
                description="""PROJECT MANAGEMENT (TPM): Create a new ticket, epic, or issue to track.
    
    USE THIS TOOL WHEN:
    - User says ":TPM: Add X feature to the roadmap"
    - User wants to add a new feature/ticket/issue
    - User says "add ticket for X" or "create feature for Y"
    - Breaking down work into trackable items
    - User asks to scope out or define new work
    - User discusses new work that should be tracked
    
    Use roadmap_view first to get the project_id. Tickets are high-level work items (like Jira epics/stories).
    
    ID AUTO-GENERATION:
    IDs are always auto-generated as {PREFIX}-{NNN} (e.g., FEAT-001, ISSUE-042).
    The number is automatically incremented based on existing tickets with that prefix.
    
    OPTIONAL PREFIX PARAMETER:
    Provide a prefix to categorize the ticket type:
    - FEAT: New features or capabilities
    - ISSUE: Bugs, problems, or issues to fix
    - TASK: General tasks or chores
    - INFRA: Infrastructure or DevOps work
    - DOC: Documentation tasks
    
    If no prefix is provided, uses the project ID as the prefix (e.g., FRONTEND-001, BACKEND-042).""",
                inputSchema={
                    "type": "object",
                    "properties": {
                        "project_id": {
                            "type": "string",
                            "description": "Project ID (use project_list to find) case-insensitive",
                        },
                        "prefix": {
                            "type": "string",
                            "description": "Optional prefix for ticket ID (e.g., FEAT, ISSUE, INFRA). Number is auto-generated. If omitted, uses project ID as prefix.",
                        },
                        "title": {"type": "string", "description": "Ticket title"},
                        "description": {
                            "type": "string",
                            "description": "Detailed description of the ticket",
                        },
                        "status": {
                            "type": "string",
                            "enum": ["backlog", "planned", "in-progress", "done", "blocked"],
                            "description": "Ticket status (default: backlog)",
                        },
                        "priority": {
                            "type": "string",
                            "enum": ["critical", "high", "medium", "low"],
                            "description": "Priority level (default: medium)",
                        },
                        "tags": {
                            "type": "array",
                            "items": {"type": "string"},
                            "description": "Tags for categorization",
                        },
                        "assignees": {
                            "type": "array",
                            "items": {"type": "string"},
                            "description": "Who is working on this",
                        },
                    },
                    "required": ["project_id", "title"],
                },
            ),
  • Pydantic model TicketCreate defining the input structure for creating tickets, used by the handler and DB layer.
    class TicketCreate(BaseModel):
        project_id: str
        title: str
        prefix: str | None = None  # Optional prefix for auto-generated ID (e.g., FEAT, ISSUE, INFRA)
        description: str | None = None
        status: TicketStatus = TicketStatus.BACKLOG
        priority: Priority = Priority.MEDIUM
        assignees: list[str] | None = None
        tags: list[str] | None = None
        related_repos: list[str] | None = None
        acceptance_criteria: list[str] | None = None
        blockers: list[str] | None = None
        metadata: dict[str, Any] | None = None
  • Core database implementation: generates unique ticket ID with prefix and sequential number, inserts ticket record into SQLite.
    def create_ticket(self, data: TicketCreate) -> Ticket:
        normalized_project_id = self._normalize_id(data.project_id)
        # Check if a case-insensitive match already exists for project_id
        existing_project = self.conn.execute(
            "SELECT id FROM projects WHERE LOWER(id) = ?", (normalized_project_id,)
        ).fetchone()
        if existing_project:
            project_id = existing_project["id"]  # Use existing project ID
        else:
            project_id = normalized_project_id  # Use normalized project_id for new entries
        # Determine prefix for ID generation
        if data.prefix:
            # Use provided prefix (e.g., FEAT, ISSUE, INFRA)
            prefix = data.prefix.upper().replace(" ", "").replace("-", "").replace("_", "")
        else:
            # Auto-generate prefix from project ID
            project = self.get_project(project_id)
            if project:
                prefix = project.id.upper().replace(" ", "").replace("-", "").replace("_", "")
            else:
                prefix = "TICKET"
        next_num = self._get_next_ticket_number(prefix)
        id = f"{prefix}-{next_num:03d}"
        now = self._now()
        self.conn.execute(
            """INSERT INTO tickets (id, project_id, title, description, status, priority, created_at,
               assignees, tags, related_repos, acceptance_criteria, blockers, metadata)
               VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)""",
            (
                id,
                project_id,
                data.title,
                data.description,
                data.status.value,
                data.priority.value,
                now,
                _to_json(data.assignees),
                _to_json(data.tags),
                _to_json(data.related_repos),
                _to_json(data.acceptance_criteria),
                _to_json(data.blockers),
                _to_json(data.metadata),
            ),
        )
        self.conn.commit()
        return Ticket(
            id=id,
            project_id=project_id,
            title=data.title,
            description=data.description,
            status=data.status,
            priority=data.priority,
            created_at=datetime.fromisoformat(now),
            assignees=data.assignees,
            tags=data.tags,
            related_repos=data.related_repos,
            acceptance_criteria=data.acceptance_criteria,
            blockers=data.blockers,
            metadata=data.metadata,
        )

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