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

4jMuXuutDppO-fisUQ2_6YpN.jpg

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())