Azure DevOps MCP Server
An MCP server that exposes Azure DevOps work-item operations over Streamable HTTP. Runs as a single Cloudflare Worker.
If the code gets written in a Claude conversation, the work items should be reachable from the same conversation. This MCP server exposes Azure DevOps work-item operations — querying, creating, updating, state transitions — to any MCP client.
Like its Optimizely sibling it runs as a single stateless Cloudflare Worker speaking Streamable HTTP, which turns out to be a sweet spot for MCP servers: nothing to keep alive, and scale-to-zero when no agent is talking.
View the source on GitHub · Related: Visual.Workflow — the same problem from the editor side · Optimizely CMS MCP Server

Endpoint
POST https://<host>/<org>/<project>/mcp<org> is your Azure DevOps organization name (the bit in https://dev.azure.com/<org>/). <project> is the project inside that org. URL-encode if either contains spaces.
Authentication
Send an Azure DevOps Personal Access Token (PAT) as HTTP Basic auth — empty username, PAT in the password slot:
Authorization: Basic <base64(":<PAT>")>Required scopes:
Work Items (Read, Write & Manage) — required for everything
Project & Team (Read) — required for listiterations and listareas
Identity (Read) — optional; gives resolve_user access to the full org directory
Create a PAT at: https://dev.azure.com/<org>/_usersSettings/tokens
Tools
Read Operations
list_work_items — Filter by assignee / state / type / dates. Returns id, title, state, type, assignee, changedBy, changedDate, createdDate.
list_recently_updated — Convenience wrapper: items changed since a timestamp.
list_new_work_items — Items created since a timestamp.
get_work_item — Full detail for one item — description, repro steps, iteration, area, tags, parent id, recent comments.
list_mentions_since — Find @mentions of a user in comments created after a timestamp.
query_wiql — Run a raw WIQL SELECT. Returns matching ids plus hydrated summaries by default.
Write Operations
create_work_item — Create a new item with title, type, description, assignee, iteration, area, tags, parent in a single call.
update_work_item — Patch arbitrary fields (title, description, assignee, iteration, area, tags, state, parent)
update_state — Focused wrapper to change System.State. Allowed transitions depend on the process template.
add_link — Add a parent, child, related, predecessor, or successor link between two items.
add_comment — Append a comment. HTML supported.
Metadata
resolve_user — Look up users by display name or email.
list_iterations — Iteration nodes (sprints) as backslash-joined paths.
list_areas — Area nodes as backslash-joined paths.
Polling Pattern
listrecentlyupdated is designed to be the polling primitive — the orchestrator only needs to remember the last-poll timestamp.
Pseudocode for any scheduler with state:
schedule(every 15 min)
since ← state.get("azdo:<project>:last-poll", default="1970-01-01T00:00:00Z")
items ← MCP tool list_recently_updated since=${since}
if items not empty:
summary ← LLM summarize items
push summary
state.set("azdo:<project>:last-poll", now())