Skip to main content
Glama
AbdelrhmanSror

Azure DevOps MCP Server

Azure DevOps MCP Server

A Model Context Protocol (MCP) server that provides AI-powered tools for interacting with Azure DevOps repositories, pull requests, and work items. Built with FastMCP for seamless integration with Claude and other MCP-compatible AI assistants.

Features

  • Project Discovery - List all accessible Azure DevOps projects

  • Repository Management - Resolve repository IDs, list branches

  • Pull Request Operations - List, create, inspect, and comment on PRs

  • Work Item Management - Create PBIs, Bugs, and custom work items

  • Diff Analysis - Fetch complete unified diffs with original and modified content

  • Code Review - Built-in review policy and automated review capabilities

  • PR-Work Item Linking - Link pull requests to work items

  • Auto-Discovery - Automatic tool and resource registration

  • Extensible Architecture - Simple pattern for adding new functionality

Project Structure

AzureDevopsMcp/ ├── src/ │ ├── config.py # Global MCP instance & configuration │ ├── client.py # HTTP client for Azure DevOps API │ ├── server.py # Server entry point │ ├── utils/ │ │ └── helpers.py # Helper functions (repo resolution, blob fetching) │ ├── tools/ │ │ ├── __init__.py # Auto-import tool modules │ │ ├── repository.py # Repository & project tools │ │ ├── pull_requests.py # Pull request tools │ │ └── work_items.py # Work item tools (PBI, Bug, etc.) │ └── policies/ │ ├── __init__.py # Auto-import policy modules │ └── review_policy.py # Code review policy resource ├── main.py # Application entry point ├── requirements.txt # Python dependencies ├── .env # Environment configuration └── README.md

Setup

1. Clone and Install

git clone <repository-url> cd AzureDevopsMcp pip install -r requirements.txt

2. Configure Environment

Create a .env file in the project root:

ADO_ORG_URL=https://dev.azure.com/YourOrganization ADO_PROJECT=YourDefaultProject ADO_PAT=your_personal_access_token_here

Getting a Personal Access Token (PAT):

  1. Go to Azure DevOps → User Settings → Personal Access Tokens

  2. Create new token with permissions:

    • Code (Read & Write) - for repository and PR operations

    • Pull Request Threads (Read & Write) - for PR comments

    • Work Items (Read & Write) - for creating/updating work items

  3. Copy the token to your .env file

3. Run the Server

python main.py

The server will run in stdio mode, ready to accept MCP protocol requests.

Available Tools

Project & Repository Tools

list_projects() -> List[Dict]

Lists all Azure DevOps projects you have access to.

Returns: List of projects with name, id, description, and state.

Usage: Call this before creating work items to discover available projects.


resolve_repo_id(repo_key: str, project: str = None) -> str

Converts a repository name to its GUID identifier.

Parameters:

  • repo_key - Repository name (e.g., "my-api") or GUID

Returns: Repository GUID


list_branches(repo_id: str, filter_name: str = None, top: int = 100) -> List[Dict]

Lists branches in a repository.

Parameters:

  • repo_id - Repository GUID from resolve_repo_id

  • filter_name - Optional filter by name prefix (e.g., "feature/")

  • top - Maximum number of branches to return

Returns: List of branches with name, fullName, isDefault, creator, objectId


Pull Request Tools

list_pull_requests(repo_id: str, status: str = "active", top: int = 10) -> List[Dict]

Lists pull requests for a repository.

Parameters:

  • repo_id - Repository GUID

  • status - Filter: "active", "completed", "abandoned"

  • top - Maximum number of PRs


get_pull_request(repo_id: str, pr_id: int) -> str

Retrieves detailed information about a specific pull request.


create_pull_request(repo_id: str, source_branch: str, target_branch: str, title: str, description: str = None, work_item_ids: List[int] = None) -> Dict

Creates a new pull request.

Parameters:

  • repo_id - Repository GUID

  • source_branch - Full ref name (e.g., "refs/heads/feature/my-feature")

  • target_branch - Full ref name (e.g., "refs/heads/main")

  • title - PR title

  • description - Optional PR description

  • work_item_ids - Optional list of work item IDs to link

Returns: Created PR details including id, url, title, status


set_pr_description(repo_id: str, pr_id: int, description: str) -> Dict

Updates the description of an existing pull request.

LLM Instructions: The description should include a structured format with:

  • Summary section with bullet points

  • Test plan section with checkboxes

  • Auto-detected checkboxes for tests and documentation based on diff analysis


get_pull_request_full_diff(repo_id: str, pr_id: int) -> Dict

Fetches complete diff and all review comments for a PR.


add_pull_request_comment(repo_id: str, pr_id: int, comment: str, file_path: str = None, line: int = None) -> str

Adds a comment to a pull request (top-level or inline).


Links a pull request to a work item.


Work Item Tools

list_work_item_types(project: str) -> List[Dict]

Lists all available work item types in a project.

Usage: Call this to discover what work item types are available (Bug, PBI, Task, etc.).


list_area_paths(project: str, depth: int = 3) -> List[Dict]

Lists all area paths in a project for organizing work items.


list_iteration_paths(project: str, depth: int = 3) -> List[Dict]

Lists all iteration paths (sprints) in a project.


create_product_backlog_item(project: str, title: str, assigned_to: str, ...) -> Dict

Creates a new Product Backlog Item (PBI).

Required Parameters:

  • project - Project name (use list_projects() first)

  • title - PBI title

  • assigned_to - Email or display name of assignee

Optional Parameters:

  • description - HTML description

  • acceptance_criteria - HTML acceptance criteria

  • area_path - Area path for organization

  • iteration_path - Sprint assignment

  • priority - Priority (1-4)

  • tags - Semicolon-separated tags


create_bug(project: str, title: str, assigned_to: str, description: str, steps_to_reproduce: str, expected_behavior: str, ...) -> Dict

Creates a new Bug work item (using custom "Bugs" type with required fields).

Required Parameters:

  • project - Project name

  • title - Bug title

  • assigned_to - Assignee

  • description - Bug description

  • steps_to_reproduce - Steps to reproduce the bug

  • expected_behavior - Expected app behavior

Optional Parameters:

  • environment - Environment (default: "Dev")

  • area_path, iteration_path, priority, tags


create_work_item(project: str, work_item_type: str, title: str, assigned_to: str, ...) -> Dict

Creates a work item of ANY type. Most flexible tool for custom work item types.

Parameters:

  • work_item_type - Exact type name from list_work_item_types()

  • custom_fields - Dict of custom field reference names to values

Example with custom fields:

create_work_item( project="MyProject", work_item_type="Bugs", title="Fix login error", assigned_to="john@company.com", custom_fields={ "Custom.Environment": "Dev", "Custom.Stepstoreproduce": "1. Go to login\n2. Click submit", "Custom.Expectedappbehavior": "User should be logged in" } )

Resources

policy://review - Code Review Policy

Official code review standards and expectations for PR reviews.

Usage: LLMs should load this resource before performing automated code reviews.

Extending the Server

Adding a New Tool

Step 1: Create your tool module in src/tools/

# src/tools/my_tools.py from ..config import mcp, ADO_ORG_URL from ..client import client @mcp.tool() def my_new_tool(param: str) -> dict: """Tool description for LLM.""" # Implementation pass

Step 2: Register in src/tools/__init__.py

from . import my_tools # noqa: F401

Adding a New Resource

Step 1: Create resource module in src/policies/

# src/policies/my_policy.py from ..config import mcp @mcp.resource(uri="policy://my-policy", name="My Policy", description="...") def get_my_policy() -> str: return "Policy content..."

Step 2: Register in src/policies/__init__.py

Architecture

  • Global MCP Instance (src/config.py) - Single FastMCP instance shared across all modules

  • Auto-Discovery - Modules self-register by importing in __init__.py

  • Separation of Concerns - Tools, resources, utilities, and configuration cleanly separated

  • Type Safety - Full type hints for better IDE support and error checking

Contributing

Contributions welcome! Please follow the existing code structure and patterns when adding new functionality.

-
security - not tested
F
license - not found
-
quality - not tested

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/AbdelrhmanSror/AzureDevopsMcp'

If you have feedback or need assistance with the MCP directory API, please join our Discord server