fix(mcp): support custom issue types and statuses (#1023)
Change IssueType and IssueStatus from Literal to str to support custom types configured via: bd config set types.custom "agent,molecule,event" bd config set status.custom "awaiting_review,awaiting_testing" The CLI handles validation of these values against the configured options. The MCP layer is just a transport and shouldn't re-validate what the CLI already validates. This fixes Pydantic validation errors when listing issues that have custom types like 'event', 'molecule', or 'agent'. Built-in types: bug, feature, task, epic, chore Built-in statuses: open, in_progress, blocked, deferred, closed
This commit is contained in:
committed by
GitHub
parent
d04bffb9b6
commit
68da7c9f78
@@ -6,8 +6,17 @@ from typing import Literal, Any
|
|||||||
from pydantic import BaseModel, Field, field_validator
|
from pydantic import BaseModel, Field, field_validator
|
||||||
|
|
||||||
# Type aliases for issue statuses, types, and dependencies
|
# Type aliases for issue statuses, types, and dependencies
|
||||||
IssueStatus = Literal["open", "in_progress", "blocked", "deferred", "closed"]
|
#
|
||||||
IssueType = Literal["bug", "feature", "task", "epic", "chore"]
|
# IssueStatus and IssueType are strings (not Literals) to support custom
|
||||||
|
# statuses and types configured via:
|
||||||
|
# bd config set status.custom "awaiting_review,awaiting_testing"
|
||||||
|
# bd config set types.custom "agent,molecule,event"
|
||||||
|
#
|
||||||
|
# The CLI handles validation of these values against the configured options.
|
||||||
|
# Built-in statuses: open, in_progress, blocked, deferred, closed
|
||||||
|
# Built-in types: bug, feature, task, epic, chore
|
||||||
|
IssueStatus = str
|
||||||
|
IssueType = str
|
||||||
DependencyType = Literal["blocks", "related", "parent-child", "discovered-from"]
|
DependencyType = Literal["blocks", "related", "parent-child", "discovered-from"]
|
||||||
OperationAction = Literal["created", "updated", "closed", "reopened"]
|
OperationAction = Literal["created", "updated", "closed", "reopened"]
|
||||||
|
|
||||||
|
|||||||
@@ -383,9 +383,9 @@ async def get_tool_info(tool_name: str) -> dict[str, Any]:
|
|||||||
"name": "list",
|
"name": "list",
|
||||||
"description": "List all issues with optional filters",
|
"description": "List all issues with optional filters",
|
||||||
"parameters": {
|
"parameters": {
|
||||||
"status": "open|in_progress|blocked|deferred|closed (optional)",
|
"status": "open|in_progress|blocked|deferred|closed or custom (optional)",
|
||||||
"priority": "int 0-4 (optional)",
|
"priority": "int 0-4 (optional)",
|
||||||
"issue_type": "bug|feature|task|epic|chore (optional)",
|
"issue_type": "bug|feature|task|epic|chore or custom (optional)",
|
||||||
"assignee": "str (optional)",
|
"assignee": "str (optional)",
|
||||||
"labels": "list[str] (optional) - AND filter: must have ALL labels",
|
"labels": "list[str] (optional) - AND filter: must have ALL labels",
|
||||||
"labels_any": "list[str] (optional) - OR filter: must have at least one",
|
"labels_any": "list[str] (optional) - OR filter: must have at least one",
|
||||||
@@ -421,7 +421,7 @@ async def get_tool_info(tool_name: str) -> dict[str, Any]:
|
|||||||
"title": "str (required)",
|
"title": "str (required)",
|
||||||
"description": "str (default '')",
|
"description": "str (default '')",
|
||||||
"priority": "int 0-4 (default 2)",
|
"priority": "int 0-4 (default 2)",
|
||||||
"issue_type": "bug|feature|task|epic|chore (default task)",
|
"issue_type": "bug|feature|task|epic|chore or custom (default task)",
|
||||||
"assignee": "str (optional)",
|
"assignee": "str (optional)",
|
||||||
"labels": "list[str] (optional)",
|
"labels": "list[str] (optional)",
|
||||||
"deps": "list[str] (optional) - dependency IDs",
|
"deps": "list[str] (optional) - dependency IDs",
|
||||||
@@ -436,7 +436,7 @@ async def get_tool_info(tool_name: str) -> dict[str, Any]:
|
|||||||
"description": "Update an existing issue",
|
"description": "Update an existing issue",
|
||||||
"parameters": {
|
"parameters": {
|
||||||
"issue_id": "str (required)",
|
"issue_id": "str (required)",
|
||||||
"status": "open|in_progress|blocked|deferred|closed (optional)",
|
"status": "open|in_progress|blocked|deferred|closed or custom (optional)",
|
||||||
"priority": "int 0-4 (optional)",
|
"priority": "int 0-4 (optional)",
|
||||||
"assignee": "str (optional)",
|
"assignee": "str (optional)",
|
||||||
"title": "str (optional)",
|
"title": "str (optional)",
|
||||||
|
|||||||
@@ -392,9 +392,9 @@ async def beads_ready_work(
|
|||||||
|
|
||||||
|
|
||||||
async def beads_list_issues(
|
async def beads_list_issues(
|
||||||
status: Annotated[IssueStatus | None, "Filter by status (open, in_progress, blocked, deferred, closed)"] = None,
|
status: Annotated[IssueStatus | None, "Filter by status (open, in_progress, blocked, deferred, closed, or custom)"] = None,
|
||||||
priority: Annotated[int | None, "Filter by priority (0-4, 0=highest)"] = None,
|
priority: Annotated[int | None, "Filter by priority (0-4, 0=highest)"] = None,
|
||||||
issue_type: Annotated[IssueType | None, "Filter by type (bug, feature, task, epic, chore)"] = None,
|
issue_type: Annotated[IssueType | None, "Filter by type (bug, feature, task, epic, chore, or custom)"] = None,
|
||||||
assignee: Annotated[str | None, "Filter by assignee"] = None,
|
assignee: Annotated[str | None, "Filter by assignee"] = None,
|
||||||
labels: Annotated[list[str] | None, "Filter by labels (AND: must have ALL)"] = None,
|
labels: Annotated[list[str] | None, "Filter by labels (AND: must have ALL)"] = None,
|
||||||
labels_any: Annotated[list[str] | None, "Filter by labels (OR: must have at least one)"] = None,
|
labels_any: Annotated[list[str] | None, "Filter by labels (OR: must have at least one)"] = None,
|
||||||
@@ -438,7 +438,7 @@ async def beads_create_issue(
|
|||||||
acceptance: Annotated[str | None, "Acceptance criteria"] = None,
|
acceptance: Annotated[str | None, "Acceptance criteria"] = None,
|
||||||
external_ref: Annotated[str | None, "External reference (e.g., gh-9, jira-ABC)"] = None,
|
external_ref: Annotated[str | None, "External reference (e.g., gh-9, jira-ABC)"] = None,
|
||||||
priority: Annotated[int, "Priority (0-4, 0=highest)"] = 2,
|
priority: Annotated[int, "Priority (0-4, 0=highest)"] = 2,
|
||||||
issue_type: Annotated[IssueType, "Type: bug, feature, task, epic, or chore"] = DEFAULT_ISSUE_TYPE,
|
issue_type: Annotated[IssueType, "Type: bug, feature, task, epic, chore, or custom"] = DEFAULT_ISSUE_TYPE,
|
||||||
assignee: Annotated[str | None, "Assignee username"] = None,
|
assignee: Annotated[str | None, "Assignee username"] = None,
|
||||||
labels: Annotated[list[str] | None, "List of labels"] = None,
|
labels: Annotated[list[str] | None, "List of labels"] = None,
|
||||||
id: Annotated[str | None, "Explicit issue ID (e.g., bd-42)"] = None,
|
id: Annotated[str | None, "Explicit issue ID (e.g., bd-42)"] = None,
|
||||||
@@ -475,7 +475,7 @@ async def beads_create_issue(
|
|||||||
|
|
||||||
async def beads_update_issue(
|
async def beads_update_issue(
|
||||||
issue_id: Annotated[str, "Issue ID (e.g., bd-1)"],
|
issue_id: Annotated[str, "Issue ID (e.g., bd-1)"],
|
||||||
status: Annotated[IssueStatus | None, "New status (open, in_progress, blocked, deferred, closed)"] = None,
|
status: Annotated[IssueStatus | None, "New status (open, in_progress, blocked, deferred, closed, or custom)"] = None,
|
||||||
priority: Annotated[int | None, "New priority (0-4)"] = None,
|
priority: Annotated[int | None, "New priority (0-4)"] = None,
|
||||||
assignee: Annotated[str | None, "New assignee"] = None,
|
assignee: Annotated[str | None, "New assignee"] = None,
|
||||||
title: Annotated[str | None, "New title"] = None,
|
title: Annotated[str | None, "New title"] = None,
|
||||||
|
|||||||
2
integrations/beads-mcp/uv.lock
generated
2
integrations/beads-mcp/uv.lock
generated
@@ -76,7 +76,7 @@ wheels = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "beads-mcp"
|
name = "beads-mcp"
|
||||||
version = "0.34.0"
|
version = "0.47.0"
|
||||||
source = { editable = "." }
|
source = { editable = "." }
|
||||||
dependencies = [
|
dependencies = [
|
||||||
{ name = "fastmcp" },
|
{ name = "fastmcp" },
|
||||||
|
|||||||
Reference in New Issue
Block a user