| name | ob-userstory |
| description | Parse Azure DevOps user story URL and create OpenSpec change. Use when user provides an Azure DevOps URL. |
| license | MIT |
| compatibility | Requires openspec CLI and Azure CLI. |
| metadata | {"author":"copilots","version":"3.1"} |
Browser MCP tools are FORBIDDEN for all Azure DevOps operations.
Azure CLI Setup (One-Time)
az config set extension.dynamic_install_allow_preview=true
az extension add --name azure-devops
az login
az devops login --organization https://dev.azure.com/{org}
az devops configure --defaults organization=https://dev.azure.com/{org} project={project}
The configure --defaults line is required: every command below relies on the default org/project instead of passing --organization.
PAT Token, go to https://dev.azure.com/{org}/_usersSettings/tokens
Create with scopes: Work Items (Read & Write) + Code (Read & Write)
Steps
-
Extract Work Item ID from URL
?workitem=193208 → ID: 193208
/workitems/edit/193208 → ID: 193208
-
Fetch Work Item
az boards work-item show --id 193208
Do NOT use --organization flag (uses default org).
-
Extract Key Fields from JSON response:
fields.System.Title → Title
fields.System.Description → Description (may be HTML, strip tags)
fields.System.WorkItemType → Type
fields.System.IterationPath → Sprint
fields.System.State → State
fields.System.AcceptanceCriteria → AC (if present)
-
Create OpenSpec Change
openspec new change "us-{id}-{slug}"
Full Azure DevOps CLI Reference
Use these for ALL DevOps operations, browser MCP is FORBIDDEN.
Work Items
az boards work-item show --id <id>
az boards work-item update --id <id> --state "Active"
PR Threads (Comments)
az devops invoke \
--area git --resource pullRequestThreads \
--route-parameters project={project} repositoryId=<repo> pullRequestId=<id> \
--http-method GET --api-version 7.1
az devops invoke \
--area git --resource pullRequestThreads \
--route-parameters project={project} repositoryId=<repo> pullRequestId=<id> \
--http-method POST --api-version 7.1 --in-file body.json
az devops invoke \
--area git --resource pullRequestThreadComments \
--route-parameters project={project} repositoryId=<repo> pullRequestId=<id> threadId=<tid> \
--http-method POST --api-version 7.1 --in-file reply.json
Comment Body JSON format
{
"comments": [
{
"parentCommentId": 0,
"content": "Your markdown comment here.",
"commentType": 1
}
],
"status": "active"
}
For replies, parentCommentId should be the ID of the first comment in the thread (usually 1).
Screenshot / Image Strategy
Never upload images as PR attachments. Save to openspec change folder and reference via raw URL.
Save location
openspec/changes/{change-name}/images/{screenshot}.png
Raw URL format (renders inline in PR comments)
https://dev.azure.com/{org}/{project}/_apis/git/repositories/{repo}/items?path=openspec/changes/{change}/images/{file}.png&versionType=branch&version={branch}&api-version=7.1
Do NOT use _git/ URLs, they return HTML, not raw binary.
URL Formats Reference
# Sprint board with work item
https://dev.azure.com/{org}/{project}/_sprints/backlog/{team}/{project}/Sprint%20110?workitem=193208
# Direct work item
https://dev.azure.com/{org}/{project}/_workitems/edit/193208
# PR
https://dev.azure.com/{org}/{project}/_git/{repo}/pullrequest/{pr-id}
Output Format
## User Story Parsed
**Work Item:** #{id}
**Title:** {title}
**Type:** User Story
**Iteration:** {sprint}
**State:** {state}
**Change Created:** us-{id}-{slug}
After outputting the above, the lead MUST load the ob-plan-propose skill (interactive mode) to generate the proposal, specs, and tasks. After it completes, STOP and ask the user: "Ready to implement? (yes/no)", do NOT load ob-plan-apply until confirmed.
Guardrails
- ✅ Parse Azure DevOps URL and create OpenSpec change
- ✅ Use
az CLI for all Azure DevOps operations
- ✅ Always load the
ob-plan-propose skill after parsing, never skip to implementation
- ✅ Always stop and confirm with user after propose, before loading
ob-plan-apply
- ❌ Browser MCP tools for Azure DevOps operations, FORBIDDEN
- ❌ Jump to implementation without user confirmation, FORBIDDEN