From story-coding-agent
Dispatches to the official Jira MCP server or Azure DevOps MCP server based on boardSource from resolved config. Validates ticket ID format before calling MCP. Maps ADO work item fields to the unified Jira-compatible raw object shape so ticket-normalizer and label-classifier require no changes. Receives storyBoardAvailable from resolved config — does not re-read .mcp.json.
How this skill is triggered — by the user, by Claude, or both
Slash command
/story-coding-agent:board-connectorThe summary Claude sees in its skill listing — used to decide when to auto-load this skill
Authenticates and fetches a single ticket from the configured board system (Jira or Azure DevOps Boards) via the appropriate official MCP server. Returns a unified raw issue object in the Jira-compatible shape that `ticket-normalizer` can process without modification.
Authenticates and fetches a single ticket from the configured board system (Jira or Azure DevOps Boards) via the appropriate official MCP server. Returns a unified raw issue object in the Jira-compatible shape that ticket-normalizer can process without modification.
| Input | Source | Description |
|---|---|---|
boardSource | Resolved config | "jira" or "ado" |
storyBoardAvailable | Resolved config | true if the MCP server entry was found in .mcp.json |
jira block | Resolved config | Present when boardSource: "jira" |
ado block | Resolved config | Present when boardSource: "ado" |
ticketId | User prompt argument | Jira issue key (e.g. PROJ-123) or ADO work item ID (e.g. 1234) |
Check storyBoardAvailable from resolved config.
If storyBoardAvailable: false:
ERROR: Board MCP server ({boardSource}) is not configured.
Add the MCP server entry to .mcp.json in the workspace root (or ~/.claude/mcp.json) and retry.
Halt immediately. Do not proceed.
Before making any MCP call, validate that the ticket ID format matches boardSource:
boardSource | Expected format | Regex | Example |
|---|---|---|---|
"jira" | Uppercase project key + number | ^[A-Z]+-[0-9]+$ | PROJ-123 |
"ado" | Integer only | ^[0-9]+$ | 1234 |
If format does not match:
ERROR: Ticket ID "{ticketId}" does not match the expected format for {boardSource}.
Jira format: PROJ-123 (uppercase project key, hyphen, number)
Azure DevOps format: 1234 (integer work item ID)
Check that boardSource in .story-agent.json matches your intended system.
Halt immediately.
boardSource: "jira")Uses the official Atlassian Jira MCP server.
Required env vars:
JIRA_EMAIL — Jira account emailJIRA_API_TOKEN — Jira API token (create at id.atlassian.com/manage-profile/security/api-tokens)Call:
mcp_jira_get_issue(issueKey: ticketId)
Note on tool names: MCP tool names follow the Claude Code convention
mcp__<server-name>__<tool-name>. The logical namemcp_jira_get_issueabove must be verified against the registered Atlassian Jira MCP server's tool manifest at integration time. Use the exact tool name as it appears in the server's tool list.
Returns the raw Jira issue object. This is already in the shape ticket-normalizer expects — no field mapping needed. Proceed to Step 3.
boardSource: "ado")Uses the official Azure DevOps MCP server.
Required env vars:
ADO_PAT — Azure DevOps Personal Access TokenCall:
mcp_azure_devops_get_work_item(id: ticketId, org: ado.orgUrl, project: ado.project)
Note on tool names: The logical name
mcp_azure_devops_get_work_itemabove must be verified against the registered Azure DevOps MCP server's tool manifest at integration time.
The response includes a fields object and a relations array. Map to the unified shape:
| ADO response field | Unified field | Transformation |
|---|---|---|
fields["System.Title"] | fields.summary | Direct copy |
fields["System.Description"] | fields.description | Strip HTML tags before mapping (ticket-normalizer processes ADF only; stripped plain text passes through its non-ADF fallback) |
fields["System.WorkItemType"] | fields.issuetype.name | Direct copy |
fields["System.Tags"] | fields.labels | Split on "; " (semicolon + space); trim each value |
fields["System.AreaPath"] | fields.components[].name | Use last segment after final \ |
fields["System.AssignedTo"].uniqueName | fields.assignee.emailAddress | null if unassigned |
fields["Microsoft.VSTS.Common.Priority"] | fields.priority.name | Map: 1→"Critical", 2→"High", 3→"Medium", 4→"Low" |
relations[] | fields.issuelinks | For each relation: { type: rel, targetId: <id extracted from url> }. Use the raw ADO rel string as-is (e.g. "System.LinkTypes.Related"); ticket-normalizer normalises unrecognised types to "relates to". |
Extracting work item ID from relation URL:
ADO relation URLs follow the pattern https://dev.azure.com/{org}/{project}/_apis/wit/workItems/{id}. Extract the final path segment as the targetId.
Constructed unified object:
{
"id": "1234",
"key": "1234",
"fields": {
"summary": "<System.Title>",
"description": "<System.Description>",
"issuetype": { "name": "<System.WorkItemType>" },
"labels": ["<tag1>", "<tag2>"],
"components": [{ "name": "<last-area-path-segment>" }],
"assignee": { "emailAddress": "<System.AssignedTo.uniqueName>" },
"priority": { "name": "<mapped-priority>" },
"issuelinks": [{ "type": "<rel>", "targetId": "<extracted-id>" }]
}
}
Return the raw issue object (Jira: as-is from MCP; ADO: mapped unified object) to ticket-fetch for processing by ticket-normalizer.
| Condition | Behaviour |
|---|---|
storyBoardAvailable: false | Halt (Step 0) |
| ID format mismatch | Halt (Step 1) |
| MCP call — ticket not found | Halt: "Ticket {ticketId} not found or not accessible in project {project}." |
| MCP call — auth failure | Halt: "Authentication failed. Verify JIRA_EMAIL + JIRA_API_TOKEN (Jira) or ADO_PAT (Azure DevOps)." |
| MCP call — access denied | Halt: "Access denied to ticket {ticketId}. Verify project permissions." |
| MCP call — service error | Halt: "Board MCP service error. Try again or check service status." |
npx claudepluginhub gagandeepp/software-agent-teams --plugin story-coding-agentGuides completion of development work by verifying tests, detecting environment, and presenting structured options for merge, PR, or cleanup.
Enforces test-driven development: write failing test first, then minimal code to pass. Use when implementing features or bugfixes.
Guides creation and editing of skills using test-driven development with pressure scenarios and subagents to verify agent compliance.