Skip to main content
Glama

Azure DevOps MCP Server

A production-grade Model Context Protocol server for Azure DevOps. Exposes Azure DevOps operations as MCP tools (plus, in later phases, resources and prompts) over stdio (local) and Streamable HTTP (hosted/multi-user).

  • TypeScript (ESM, Node 20+)

  • ADO access via the official azure-devops-node-api SDK, with an axios REST fallback for endpoints the SDK doesn't cover (search, analytics, etc.)

  • Three auth modes: PAT, Azure CLI (az login), On-Behalf-Of + Entra JWT (hosted)

  • Per-tool RBAC, destructive-op guard, secret redaction, structured logging, retry with backoff

Status: All 6 phases complete — 113 tools across 13 domains, plus 4 MCP resources and 4 MCP prompts:

  • core (7) · repos (15) · pullrequests (12) · workitems (16) · boards (10)

  • pipelines (13) · releases (8) · testplans (10) · wiki (7) · search (3) · artifacts (5)

  • security (5) · analytics (2)

  • Resources: ado://projects, ado://project/{project}/repos, ado://project/{project}/workitem/{id}, ado://project/{project}/repo/{repo}/pullrequest/{prId}

  • Prompts: pr-review, release-readiness, sprint-planning, bug-triage

Hardening: per-host circuit breaker, retry w/ backoff + Retry-After, secret redaction, per-tool RBAC + destructive guard, audit logging, ESLint, a Vitest suite (unit + live MCP-protocol test), and an Azure Pipelines CI (azure-pipelines.yml).


1. Prerequisites

  • Node.js ≥ 20 and npm

  • An Azure DevOps organization you can access

  • One of:

    • a Personal Access Token (PAT), or

    • the Azure CLI installed and az login completed, or

    • (hosted) an Entra app registration with the ADO delegated permission, for OBO

Related MCP server: Azure DevOps MCP Server (Python)

2. Install

cd "E:\MCP Servers\ado-mcp-server"
npm install

3. Configure

cp .env.example .env      # PowerShell: Copy-Item .env.example .env

Edit .env. Minimum for a quick local start with the Azure CLI:

ADO_ORG=YourOrgName
ADO_DEFAULT_PROJECT=YourProject
AUTH_MODE=azcli

Auth modes

AUTH_MODE

Needs

Notes

azcli

az login done locally

Easiest for dev. No secrets stored.

pat

ADO_PAT

PAT scopes must cover the tools you call (e.g. Work Items: Read & Write, Code: Read & Write).

obo

AZURE_TENANT_ID, AZURE_CLIENT_ID, AZURE_CLIENT_SECRET

HTTP transport only. Validates the caller's Entra JWT, then exchanges it for an ADO token preserving the user's identity.

A PAT is created in Azure DevOps → User settings → Personal access tokens.

4. Build & run

npm run build      # compile to dist/
npm start          # stdio transport (default)

Development with auto-reload:

npm run dev        # stdio
npm run dev:http   # Streamable HTTP on PORT (default 3000)

Force a transport regardless of TRANSPORT:

node dist/index.js --transport http
node dist/index.js --transport stdio

5. Connect a client

Claude Desktop / VS Code / Claude Code (stdio)

Add to your MCP client config (e.g. Claude Desktop claude_desktop_config.json).

Published package via npx (recommended distribution — no clone, no build):

{
  "mcpServers": {
    "azure-devops": {
      "command": "npx",
      "args": ["-y", "ado-mcp-server"],
      "env": {
        "ADO_ORG": "YourOrgName",
        "ADO_DEFAULT_PROJECT": "YourProject",
        "AUTH_MODE": "pat",
        "ADO_PAT": "<your-pat>"
      }
    }
  }
}

Local build via node (for development on a clone):

{
  "mcpServers": {
    "azure-devops": {
      "command": "node",
      "args": ["E:\\MCP Servers\\ado-mcp-server\\dist\\index.js"],
      "env": {
        "ADO_ORG": "YourOrgName",
        "ADO_DEFAULT_PROJECT": "YourProject",
        "AUTH_MODE": "azcli"
      }
    }
  }
}

The org is never hardcoded — it comes from ADO_ORG in the client's env block, so the same published package serves any org.

Remote / hosted (Streamable HTTP)

node dist/index.js --transport http

Endpoint: POST http://localhost:3000/mcp · health: GET /health. In obo mode every request must carry Authorization: Bearer <Entra access token>.

6. Verify it works

# Health (HTTP mode)
curl http://localhost:3000/health

# From an MCP client, call the connectivity probe tool:
#   ado_get_me      → confirms auth + org connection
#   ado_list_projects

A scripted stdio smoke test (lists tools without calling ADO):

printf '%s\n' \
 '{"jsonrpc":"2.0","id":1,"method":"initialize","params":{"protocolVersion":"2024-11-05","capabilities":{},"clientInfo":{"name":"smoke","version":"1.0"}}}' \
 '{"jsonrpc":"2.0","method":"notifications/initialized"}' \
 '{"jsonrpc":"2.0","id":2,"method":"tools/list","params":{}}' \
 | ADO_ORG=x AUTH_MODE=pat ADO_PAT=dummy node dist/index.js

7. Publishing (npx distribution)

This server is distributed as an npm package so anyone can run it with npx ado-mcp-server — no clone or build on their side.

npm run build          # compile (also runs automatically via prepublishOnly)
npm version patch      # bump version
npm publish            # publishes; only dist/, README.md, .env.example ship (see "files")

After publishing, the npx client config in §5 works as-is. To test the package contents before publishing:

npm pack --dry-run     # lists exactly what will be uploaded
npm pack               # builds the .tgz locally; install it to smoke-test

Auth for distributed use: prefer AUTH_MODE=pat — each user supplies their own ADO_PAT (and ADO_ORG) in their MCP client's env. azcli only works where the user has the Azure CLI installed and az login completed.

8. Scripts

Script

Purpose

npm run build

Compile TypeScript → dist/

npm start

Run compiled server (stdio)

npm run start:http

Run compiled server (HTTP)

npm run dev / dev:http

Watch-mode dev (tsx)

npm run typecheck

tsc --noEmit

npm run lint

ESLint

npm test

Vitest

9. Configuration reference

See .env.example. Key vars: ADO_ORG, ADO_DEFAULT_PROJECT, ADO_API_VERSION, AUTH_MODE, ADO_PAT, AZURE_TENANT_ID/CLIENT_ID/CLIENT_SECRET, TRANSPORT, PORT, LOCAL_ROLE, LOG_LEVEL, ALLOW_DESTRUCTIVE.

  • ALLOW_DESTRUCTIVE — destructive tools (delete_*, complete PR, deploy release, …) are blocked unless this is true.

  • LOCAL_ROLE — effective RBAC role in pat/azcli modes (admin/editor/viewer). In obo mode roles come from Entra App Roles on the caller's token.

10. Architecture (short)

transport (stdio | http)
  → server (McpServer + registry)
    → dispatch (RBAC · destructive guard · audit · error envelope)
      → domain tools (Zod schemas)
        → domain services
          → AdoClient (azure-devops-node-api SDK | REST fallback + retry)
            → auth (PAT | AzCli | OBO credential)

Each ADO area is a self-contained module under src/domains/<area>/ exporting a DomainModule. To add an area, create the module and append it to domains in src/server.ts — nothing else changes.

Full walkthrough: see docs/END_TO_END_FLOW.md for how a request travels through every layer (startup, a tool call step by step, auth flows, resources/prompts, reliability, and a worked example).

Available Tools

113 tools
ado_abandon_pull_requestA
Destructive

Abandon (close without merging) a pull request. Destructive.

Inputs: prId (required), repoId (required), project.

ado_add_pr_reviewersB

Add reviewers (by identity ID) to a pull request.

Inputs: prId (required), repoId (required), reviewerIds (required), project.

ado_add_test_casesC

Add existing test case work items to a suite.

Inputs: planId (required), suiteId (required), workItemIds (required), project.

ado_add_work_item_attachmentC

Upload a text attachment and link it to a work item.

Inputs: id (required), content (required), fileName (required), comment, +1 more.

ado_add_work_item_commentB

Add a comment to a work item.

Inputs: id (required), text (required), project.

ado_approve_releaseA
Destructive

Approve or reject a pending release approval. Destructive — gates a deployment.

Inputs: decision (required), approvalId (required), project, comments.

ado_bulk_create_work_itemsB

Create multiple work items in one call.

Inputs: items (required), project.

ado_bulk_export_work_itemsA
Read-only

Export work items selected by a WIQL query (batched for large result sets).

Inputs: query (required), fields, project.

ado_cancel_buildB

Cancel an in-progress build.

Inputs: buildId (required), project.

ado_complete_pull_requestA
Destructive

Complete (merge) a pull request. Destructive — merges code and optionally deletes the source branch.

Inputs: prId (required), repoId (required), project, bypassPolicy, +3 more.

ado_create_branchA

Create a new branch from the tip of an existing source branch.

Inputs: repoId (required), newBranch (required), sourceBranch (required), project.

ado_create_classification_nodeA

Create an area or iteration path node (admin). For iterations, pass start/finish dates in attributes.

Inputs: name (required), structureGroup (required), project, attributes, +1 more.

ado_create_projectA

Create a new project (async operation; returns an OperationReference). Resolves the process template by name when an explicit ID is not given.

Inputs: name (required), visibility, description, sourceControl, +2 more.

ado_create_pr_threadA

Start a new comment thread on a pull request (optionally anchored to a file).

Inputs: prId (required), repoId (required), content (required), project, +1 more.

ado_create_pull_requestB

Create a pull request from a source branch into a target branch.

Inputs: title (required), repoId (required), sourceBranch (required), targetBranch (required), +4 more.

ado_create_pushB

Commit and push one or more file add/edit/delete changes to a branch in a single push.

Inputs: branch (required), repoId (required), changes (required), comment (required), +1 more.

ado_create_releaseC

Create a release from a release definition.

Inputs: definitionId (required), isDraft, project, artifacts, +1 more.

ado_create_repoB

Create a new Git repository in a project.

Inputs: name (required), project.

ado_create_tagB

Create an annotated tag pointing at a commit.

Inputs: name (required), repoId (required), message (required), objectId (required), +1 more.

ado_create_test_planC

Create a test plan.

Inputs: name (required), project, areaPath, iteration, +1 more.

ado_create_test_runB

Create a test run for a plan (optionally over specific test points).

Inputs: name (required), planId (required), project, pointIds, +1 more.

ado_create_test_suiteA

Create a test suite under a parent suite in a plan (static/requirement/query).

Inputs: name (required), planId (required), parentSuiteId (required), project, +3 more.

ado_create_wikiB

Create a project wiki.

Inputs: name (required), project.

ado_create_wiki_pageB

Create a wiki page at a path with markdown content.

Inputs: path (required), wikiId (required), content (required), project.

ado_create_work_itemB

Create a work item (Bug, Task, User Story, Epic, …). Pass fields as a map; optionally set a parent.

Inputs: type (required), fields (required), project, parentId.

ado_delete_repoA
Destructive

Permanently delete a Git repository. Destructive.

Inputs: repoId (required), project.

ado_delete_wiki_pageB
Destructive

Delete a wiki page by path. Destructive.

Inputs: path (required), wikiId (required), project.

ado_delete_work_itemA
Destructive

Delete a work item (recycle bin by default; destroy=true is permanent). Destructive.

Inputs: id (required), destroy, project.

ado_deploy_releaseB
Destructive

Trigger deployment of a release to an environment/stage. Destructive — initiates a deployment.

Inputs: releaseId (required), environmentId (required), comment, project.

ado_get_aclsA
Read-only

Get access control lists for a security namespace, optionally scoped to a token.

Inputs: namespaceId (required), token, includeExtendedInfo.

ado_get_analytics_metadataA
Read-only

Fetch the Analytics OData $metadata (the entity model / available fields) as XML.

Inputs: project.

ado_get_backlog_work_itemsC
Read-only

Get the work items at a given backlog level for a team.

Inputs: backlogId (required), team, project.

ado_get_board_columnsB
Read-only

Get the columns configured on a board.

Inputs: board (required), team, project.

ado_get_branchA
Read-only

Get details (tip commit, stats) of a branch.

Inputs: name (required), repoId (required), project.

ado_get_buildA
Read-only

Get a single build by ID (status, result, timing).

Inputs: buildId (required), project.

ado_get_build_changesC
Read-only

List the source changes (commits/work items) associated with a build.

Inputs: buildId (required), top, project.

ado_get_build_logA
Read-only

Get the content (lines) of a specific build log.

Inputs: logId (required), buildId (required), project.

ado_get_build_logsA
Read-only

List the available logs for a build.

Inputs: buildId (required), project.

ado_get_commitA
Read-only

Get a single commit by SHA.

Inputs: repoId (required), commitId (required), project.

ado_get_diffsA
Read-only

Get the diff (changed files/commits) between two branches.

Inputs: repoId (required), baseBranch (required), targetBranch (required), top, +2 more.

ado_get_feedA
Read-only

Get a single feed by ID or name.

Inputs: feedId (required), project.

ado_get_fileA
Read-only

Read a file's content and metadata from a repository at an optional branch.

Inputs: path (required), repoId (required), branch, project.

ado_get_group_membersA
Read-only

List the members of a group by its subject descriptor.

Inputs: groupDescriptor (required).

ado_get_meA
Read-only

Return the authenticated identity and Azure DevOps organization connection data. Use this to verify connectivity and auth before other calls.

Inputs: no named parameters.

ado_get_packageB
Read-only

Get a package in a feed by ID.

Inputs: feedId (required), packageId (required), project.

ado_get_pipelineB
Read-only

Get a single pipeline by ID.

Inputs: pipelineId (required), project.

ado_get_pipeline_runB
Read-only

Get the status/result of a specific pipeline run.

Inputs: runId (required), pipelineId (required), project.

ado_get_projectA
Read-only

Get details for a single project, including process and version-control capabilities.

Inputs: project (required), includeCapabilities.

ado_get_pull_requestA
Read-only

Get a single pull request by ID.

Inputs: prId (required), repoId (required), project.

ado_get_queryA
Read-only

Get a saved query by GUID or folder path (includes its WIQL).

Inputs: queryIdOrPath (required), project.

ado_get_releaseA
Read-only

Get a single release (environments, status, artifacts).

Inputs: releaseId (required), project.

ado_get_release_definitionA
Read-only

Get a single release definition (stages, artifacts, triggers).

Inputs: definitionId (required), project.

ado_get_repoB
Read-only

Get a single Git repository by name or ID.

Inputs: repoId (required), project.

ado_get_sprint_work_itemsA
Read-only

Get the work items assigned to a sprint (iteration).

Inputs: iterationId (required), team, project.

ado_get_team_capacityB
Read-only

Get a team's capacity for a sprint (iteration).

Inputs: iterationId (required), team, project.

ado_get_test_planB
Read-only

Get a single test plan by ID.

Inputs: planId (required), project.

ado_get_test_resultsB
Read-only

Get the results of a test run.

Inputs: runId (required), project.

ado_get_test_runA
Read-only

Get a test run by ID (status, totals).

Inputs: runId (required), project.

ado_get_wikiA
Read-only

Get a single wiki by ID or name.

Inputs: wikiId (required), project.

ado_get_wiki_pageA
Read-only

Read a wiki page's content (and ETag) by path.

Inputs: path (required), wikiId (required), project.

ado_get_work_itemA
Read-only

Get a single work item by ID (org-wide lookup; project optional). Optionally expand relations.

Inputs: id (required), fields, project, expandRelations.

ado_get_work_item_commentsA
Read-only

List the comments on a work item.

Inputs: id (required), project.

ado_get_work_itemsA
Read-only

Get multiple work items by their IDs.

Inputs: ids (required), fields, project.

ado_get_work_item_type_fieldsA
Read-only

List the fields defined for a given work item type.

Inputs: type (required), project.

ado_get_work_item_typesA
Read-only

List the work item types available in a project.

Inputs: project.

ado_list_area_pathsA
Read-only

List the area path classification tree for a project.

Inputs: depth, project.

ado_list_backlogsA
Read-only

List backlog levels (Epics, Features, Stories) for a team.

Inputs: team, project.

ado_list_boardsA
Read-only

List the boards available to a team.

Inputs: team, project.

ado_list_branchesC
Read-only

List branches (refs) in a repository.

Inputs: repoId (required), filter, project.

ado_list_build_definitionsA
Read-only

List build/pipeline definitions in a project.

Inputs: top, name, project.

ado_list_buildsB
Read-only

List builds, optionally filtered by definition and branch.

Inputs: top, branch, project, definitionIds.

ado_list_commitsC
Read-only

List commits in a repository, optionally filtered by branch.

Inputs: repoId (required), top, skip, branch, +1 more.

ado_list_feedsB
Read-only

List artifact feeds (org- or project-scoped).

Inputs: project.

ado_list_groupsA
Read-only

List groups in the organization (Graph API).

Inputs: no named parameters.

ado_list_itemsB
Read-only

List files and folders at a path in a repository.

Inputs: repoId (required), branch, project, recursive, +1 more.

ado_list_iteration_pathsB
Read-only

List the iteration path classification tree for a project.

Inputs: depth, project.

ado_list_packagesB
Read-only

List packages in a feed.

Inputs: feedId (required), top, query, project.

ado_list_package_versionsA
Read-only

List the versions of a package in a feed.

Inputs: feedId (required), packageId (required), project.

ado_list_pipeline_runsC
Read-only

List recent runs of a pipeline.

Inputs: pipelineId (required), project.

ado_list_pipelinesA
Read-only

List YAML pipelines in a project.

Inputs: top, project.

ado_list_pr_commitsA
Read-only

List the commits included in a pull request.

Inputs: prId (required), repoId (required), project.

ado_list_projectsA
Read-only

List all projects in the Azure DevOps organization, with optional state filter and paging.

Inputs: top, skip, stateFilter.

ado_list_pr_threadsB
Read-only

List comment threads on a pull request.

Inputs: prId (required), repoId (required), project.

ado_list_pull_requestsA
Read-only

List pull requests in a repository, filterable by status and source/target branch.

Inputs: repoId (required), top, skip, status, +3 more.

ado_list_queriesA
Read-only

List saved/shared queries in a project.

Inputs: depth, project.

ado_list_release_approvalsB
Read-only

List pending release approvals in a project.

Inputs: top, project.

ado_list_release_definitionsA
Read-only

List classic release definitions in a project.

Inputs: top, project, searchText.

ado_list_releasesC
Read-only

List releases, optionally filtered by definition.

Inputs: top, project, definitionId.

ado_list_reposB
Read-only

List Git repositories in a project.

Inputs: project.

ado_list_security_namespacesA
Read-only

List security namespaces (permission catalogs) in the organization.

Inputs: no named parameters.

ado_list_sprintsA
Read-only

List a team's sprints (iterations), optionally only the current one.

Inputs: team, project, timeframe.

ado_list_tagsB
Read-only

List tags in a repository.

Inputs: repoId (required), project.

ado_list_team_membersB
Read-only

List the members of a team within a project.

Inputs: team (required), project (required), top, skip.

ado_list_teamsB
Read-only

List teams in a project.

Inputs: project (required), top, mine, skip.

ado_list_test_casesB
Read-only

List the test cases in a suite.

Inputs: planId (required), suiteId (required), project.

ado_list_test_plansB
Read-only

List test plans in a project.

Inputs: project.

ado_list_test_suitesB
Read-only

List the test suites in a test plan.

Inputs: planId (required), project.

ado_list_usersA
Read-only

List users in the organization (Graph API).

Inputs: subjectTypes.

ado_list_wikisA
Read-only

List wikis in a project.

Inputs: project.

ado_query_analyticsA
Read-only

Query the Analytics OData feed for reporting. Common entity sets: WorkItems, WorkItemSnapshot, PipelineRuns, Builds. Supports $filter/$select/$orderby/$top/$apply (aggregation).

Inputs: entitySet (required), top, apply, filter, +3 more.

ado_query_work_itemsA
Read-only

Run a WIQL query and return matching work item references.

Inputs: query (required), project.

ado_queue_buildB

Queue a build from a build definition, optionally on a source branch.

Inputs: definitionId (required), branch, project.

ado_reply_pr_threadB

Reply to an existing comment thread on a pull request.

Inputs: prId (required), repoId (required), content (required), threadId (required), +1 more.

ado_run_pipelineA

Queue a run of a YAML pipeline, optionally on a branch and with variables/template parameters.

Inputs: pipelineId (required), branch, project, variables, +1 more.

ado_set_pr_voteB

Cast a vote on a pull request (approve, approve-with-suggestions, reset, wait-for-author, reject). Defaults to the caller.

Inputs: prId (required), vote (required), repoId (required), project, +1 more.

ado_update_projectA

Update a project's name, description, or visibility (async operation; returns an OperationReference).

Inputs: project (required), name, visibility, description.

ado_update_pull_requestA

Update a pull request: title, description, target branch, or draft state.

Inputs: prId (required), repoId (required), title, isDraft, +3 more.

ado_update_wiki_pageA

Update an existing wiki page's content (handles the required ETag automatically).

Inputs: path (required), wikiId (required), content (required), project.

ado_update_work_itemC

Update a work item's fields.

Inputs: id (required), fields (required), project.

Tool Schema Changelog

Recent tool additions, removals, and schema changes observed during successful MCP inspections.

Loading tool schema changelog…

    TDQS

    B3.3/5.0

    Scored across 113 tools

    Disambiguation4/5

    Most tools have clearly distinct purposes, especially with well-defined descriptions for different resource types. However, a few pairs like 'ado_list_pipelines' vs 'ado_list_build_definitions' (YAML vs classic builds) could cause minor confusion without careful reading.

    Naming Consistency5/5

    All tool names follow a strict 'ado_verb_noun' pattern in snake_case. Verbs are consistently imperative (list, get, create, update, delete) and nouns are descriptive (repo, branch, pr, work_item, pipeline, etc.). No naming convention deviations are present.

    Tool Count2/5

    With 113 tools, the server is extremely comprehensive but far exceeds the typical well-scoped range (3-15). The high number makes it difficult for agents to efficiently navigate and choose the correct tool, and it would benefit from being split into multiple focused servers per Azure DevOps domain.

    Completeness5/5

    The tool surface covers an impressively broad range of Azure DevOps features: source control, pull requests, work items (with queries, comments, attachments, links), boards, sprints, backlogs, pipelines (YAML and classic), releases, test management, wikis, search, feeds, security, and analytics. Only niche areas like service connections or variable groups are missing, but the core workflows are fully supported.

    Maintenance

    ActivityInactive
    ResponsivenessNo recent community issues

    Related MCP Connectors

    Related MCP Servers