Skip to content
aimcpazure-devopsclaude-codecoding-agentsdelivery

Running Claude Code Against Azure DevOps: Why We Built an Opinionated MCP Server

Matt Hammond 7 min read
Kanban delivery board on a dark wall with sticky notes moving through in progress, testing, and complete columns

Coding agents do their most useful work in the codebase, but our delivery record lives in the tracker. We connect Claude Code to Azure DevOps through an opinionated Model Context Protocol (MCP) server that we built for our own delivery. Its tools use delivery language (work items, sprints, test plans and runs, delivery summaries, dependency graphs) rather than mirroring the REST API. We find agents use tools well when the tool vocabulary matches the task and the server enforces the conventions, and badly when every call is a raw API decision.

  • Expose the delivery process as tools: an agent gets ‘create a test run’ right far more often than ‘PATCH this JSON document’.
  • Make writes specific and typed, and keep destructive operations scarce and separate.
  • The benefit is closed loops: bug reports with evidence, accurate work item state, and delivery questions answered from live data.

Our MCP patterns for production agents guide sets out the wider patterns.

Most of what is written about coding agents stops at the pull request. Our delivery record does not live in the repository, though. It lives in the tracker, in work items, sprints, test plans, and the running answer to ‘where are we?’. If an agent cannot reach the tracker, someone on the team spends the day copying information between the two.

Azure DevOps is where that record lives for us and for many of the UK .NET teams we work with, so we built a Model Context Protocol (MCP) server for it. This post explains why we shaped it the way we did, which we think is more useful to other teams than the fact that it exists.

Why we built an opinionated server rather than a generic wrapper

The obvious way to connect an agent to Azure DevOps is a thin wrapper over the REST API, and in our view it is also the approach that works worst. A raw API surface hands the agent every decision: which endpoint, which JSON shape, which state values, and which conventions this team uses for linking and estimation. Each decision is a chance to be wrong, and the agent’s mistakes end up in your delivery data.

Our server instead encodes Talk Think Do’s delivery process as the tool surface. Rather than building a PATCH document, the agent works with tools that mirror how our delivery runs:

  • Work items: create and update items of known types, link related items, add comments and attachments, schedule items into sprints.
  • Sprints: create, update, and list iterations.
  • Test management: create test plans, suites, and cases; create test runs and publish results; query coverage by work item; surface failing and flaky tests.
  • Delivery intelligence: fetch a delivery summary or a dependency graph for planning conversations.
  • Housekeeping: register client projects and track AI usage against delivery, because attribution is part of our operating model (see AI code attribution for enterprise procurement).

With a generic wrapper, the conventions live in the prompt, and in our experience they degrade as the context fills up. With an opinionated server, the conventions live in the tool, so the agent states its intent and the server applies the process. We use the same principle in the codebase, where written guidance shapes the agent’s first attempt and deterministic checks enforce the rules. The framework is in harness engineering for coding agents.

How we scope the server to keep it safe

The MCP patterns guide sets out the production disciplines in general terms. On a work tracker, we apply them like this:

Reads are widely available, and writes go through typed tools. Anything that answers a question (list work items, get the test run summary, fetch the dependency graph) is cheap and safe to expose widely. Writes go through specific, typed tools with validated inputs, rather than a generic update endpoint that could rewrite anything.

Destructive operations are few and separate. The surface has very few delete verbs. Where one exists, it is its own tool rather than a flag on a general one, so an agent has no way to bulk-delete anything.

Every call is attributable. Tracker writes made in an agent session are logged and visible. That is what makes the arrangement comfortable for us, because a wrong comment or a mis-set field is corrected in the open, with a record of how it happened.

The server is part of the governed agent surface. We version and review it like any other dependency the agents hold, as described in governing the AI agent supply chain.

What our agents use the connection for

In our delivery, four uses account for most of the value.

Bug reports with evidence. An agent that can read the codebase and write to the tracker files a more useful kind of ticket. It records the symptom, a root-cause analysis, the affected code paths, and a suggested fix, structured into the work item type our process expects. We wrote up the skill side of this in building a Claude skill for codebase-aware bug reports.

Accurate work item state. Agentic sessions move fast, and that is when trackers drift furthest from reality. When an agent comments on progress and updates state as part of finishing a task, the delivery record stays in step with the code, and nobody has to transcribe between them.

Test management from generated suites. AI-augmented QA produces test cases and runs faster than anyone could administer them by hand. Publishing plans, cases, and results through tools turns that volume into tracked delivery data we can query. The QA workflow it supports is described in how to generate test cases from acceptance criteria with AI.

Delivery questions answered from data. Questions such as ‘what is blocked, what is failing, what is flaky, and where are we against the sprint?’ become tool calls against live state. The answers no longer depend on what people remember at stand-up. Flaky-test queries become more useful over time, because flakiness is a signal people stop noticing once they are used to it.

How this fits with the wider Azure tooling

The wider ecosystem is moving the same way. Microsoft publishes an Azure Skills plugin for Claude Code, and marketplace tasks exist for running Claude Code inside Azure DevOps pipelines. Basic connectivity is becoming a commodity, so each team still has to shape its own tool surface around its delivery process, scope it to its risk appetite, and version it with its code.

If your team runs on Azure DevOps and is adopting coding agents, we think the tracker connection deserves the same design care as the rest of your setup. Our Claude Code for .NET developers guide covers the project configuration it sits alongside, including CLAUDE.md and pre-approved commands. Book a consultation if you want help shaping it.

Frequently asked questions

Why connect a coding agent to Azure DevOps at all?
Delivery work involves more than code. Agents that can read and update work items, comment with findings, publish test results, and answer delivery questions close the loop between the codebase and the plan. Without that connection, someone copies information between the agent and the tracker all day, which is the kind of toil agents should remove.
Why not just use a generic Azure DevOps MCP wrapper?
Generic wrappers expose the raw API surface, which pushes every decision onto the agent: which endpoint, which fields, which conventions. An opinionated server exposes your delivery process as tools (create a work item of a known type, publish a test run, fetch the delivery summary). The agent states its intent and the server enforces the conventions. In our experience, agents make fewer mistakes when the tool vocabulary matches the task.
Is it safe to let an agent write to the work tracker?
With the right scoping, yes. Reads are broad and cheap, while writes go through specific, typed tools rather than a generic update endpoint. Destructive operations are either absent or kept as separate tools, and every call is attributable. A wrong comment or field update is also visible and easy to correct in the open, which is not true of a code change that nobody notices.
What do agents use the connection for day to day?
The most valuable uses are structured bug reports with codebase evidence, keeping work item state accurate during agentic sessions, and publishing test plans and results from generated test suites. Agents also answer delivery questions (progress, dependencies, failing and flaky tests) from live data instead of stand-up recollection.

Ready to transform your software?

Let's talk about your project. Contact us for a free consultation and see how we can deliver a business-critical solution at startup speed.