Azure DevOps MCP Server (Python)
Click on "Install Server".
Wait a few minutes for the server to deploy. Once ready, it will show a "Started" state.
In the chat, type
@followed by the MCP server name and your instructions, e.g., "@Azure DevOps MCP Server (Python)Get work item 42 from the default project."
That's it! The server will respond to your query, and you can continue using it as needed.
Here is a step-by-step guide with screenshots.
Azure DevOps MCP Server (Python)
Model Context Protocol (MCP) server for Azure DevOps integration, enabling AI assistants (Claude Desktop, OpenCode.ai) to interact with work items, test results, Git repositories, and analyze work item dependencies.
Supported Platforms:
✅ Claude Desktop - Anthropic's desktop application
✅ OpenCode.ai - Terminal-based AI coding agent
Features
Work Items: Get work items by ID, query with filters, execute WIQL queries
Saved Queries: Execute saved Azure DevOps queries by ID
Dependency Analysis: Analyze work item relationships and dependencies
Test Results: Access test runs and test results
Git Repositories: Browse repositories, commits, and pull requests
WIQL Support: Build and execute custom Work Item Query Language queries
Generic Deployment: Works with cloud and on-premise Azure DevOps (SSL verification disabled by default)
Multi-Project Support: Configure multiple Azure DevOps project base URLs and select per tool invocation
Project Enumeration:
list_projectstool returns configured shortnames and base URLsRequest Timeout: Optional
timeoutin AZDO_CONFIG (seconds) to bound network calls
Related MCP server: ado-workflows-mcp
Quick Start (Automated Installation)
Prerequisites
Python 3.8 or higher
Claude Desktop installed
Azure DevOps Personal Access Token (PAT) with permissions:
Work Items: Read
Code: Read
Test: Read
Install
Run the installation script with PowerShell:
./install.ps1You will be prompted to enter your Azure DevOps Personal Access Token. The script will:
Install Python dependencies
Backup your existing Claude Desktop configuration
Add the MCP server to your configuration
Create (or reuse) a unified JSON configuration file referenced by
AZDO_CONFIG
Parameters:
Parameter | Description | Example |
| Semicolon-separated |
|
| Personal Access Token (if omitted you will be prompted) |
|
| Python executable to use |
|
| Path for generated AZDO config file (optional) |
|
Custom Configuration Example:
./install.ps1 -Projects "default=https://dev.azure.com/Org/ProjectA;neo=https://dev.azure.com/Org/ProjectNeo" -Pat "your-pat-token" -PythonPath "python" -ConfigPath "C:\path\azure_devops_config.json"Uninstall
./uninstall.ps1Removes the server from Claude Desktop and creates a timestamped backup of the config. By default the AZDO_CONFIG file containing project definitions and PATs is retained.
Optional removal of AZDO_CONFIG:
./uninstall.ps1 -RemoveConfigWhen -RemoveConfig is supplied the script prompts for confirmation (must type YES) then attempts to delete the JSON file referenced by the server's AZDO_CONFIG environment entry (if it exists). Use this only if you no longer need the per-project PAT configuration.
Setup for OpenCode.ai
OpenCode is an AI coding agent for the terminal that supports MCP servers. You can add this Azure DevOps MCP server to OpenCode to interact with your Azure DevOps projects directly from your terminal.
1. Install Dependencies
pip install -r requirements.txt2. Configure Azure DevOps Connection
Create your Azure DevOps configuration file (see Configuration section below for details):
cp azure_devops_config.example.json azure_devops_config.json
# Edit azure_devops_config.json with your baseUrl and PAT3. Add to OpenCode Configuration
Copy the example OpenCode configuration:
cp opencode.example.jsonc opencode.jsoncThen edit opencode.jsonc and update the paths:
{
"$schema": "https://opencode.ai/config.json",
"mcp": {
"azure-devops": {
"type": "local",
"command": ["python", "/absolute/path/to/mcp_azure_devops/src/server.py"],
"enabled": true,
"environment": {
"AZDO_CONFIG": "/absolute/path/to/azure_devops_config.json",
"AZDO_LOG_LEVEL": "info"
},
"timeout": 10000
}
}
}Important: Replace /absolute/path/to/ with the actual absolute paths on your system.
4. Start OpenCode
Navigate to your project and start OpenCode:
cd /path/to/your/project
opencode5. Use Azure DevOps Tools
You can now use Azure DevOps tools in your prompts:
List all configured Azure DevOps projectsGet work item 123 from the default projectQuery by ID 02576c96-99fa-472b-8929-80b5f1760b02 and show the resultsFor better performance, you can configure OpenCode to only enable Azure DevOps tools for specific agents. See opencode.example.jsonc for examples.
Manual Setup (Claude Desktop)
1. Install Dependencies
pip install -r requirements.txt2. Configure Claude Desktop
Add the server configuration to your Claude Desktop config file:
Windows: %APPDATA%\Claude\claude_desktop_config.json
macOS: ~/Library/Application Support/Claude/claude_desktop_config.json
{
"mcpServers": {
"azure-devops": {
"command": "python",
"args": ["C:/path/to/mcp_azure_devops/src/server.py"],
"env": {
"AZDO_CONFIG": "C:/path/to/azure_devops_config.json"
}
}
}
}Sample azure_devops_config.json:
{
"projects": {
"iris": { "baseUrl": "https://dev.azure.com/Org/ProjectIris", "pat": "xxxxx" },
"neo": { "baseUrl": "https://dev.azure.com/Org/ProjectNeo", "pat": "yyyyy" }
},
"timeout": 15
}Important:
Update the path in
argsto match your installation directoryReplace placeholder PATs with valid tokens (do NOT commit real PATs)
Each
baseUrlincludes organization + project path (no trailing slash)Configuration is loaded exclusively from
AZDO_CONFIG; legacy env vars (AZURE_DEVOPS_BASE_URL,AZURE_DEVOPS_PAT, etc.) are deprecated and ignored by the current implementation.
Multi-Project Configuration (Per-Project PATs)
Multiple projects are defined exclusively via the AZDO_CONFIG JSON file (see above). Each project entry includes its own baseUrl and pat.
Key points:
baseUrlmust include the full organization + project path.patmust have scopes: Work Items Read, Code Read, Test Read.If
defaultshortname exists it is used whenprojectargument is omitted; else the first project is chosen.timeout(optional) applies uniformly to all requests.
To add a new project, edit azure_devops_config.json and restart Claude Desktop.
Claude tool call example (conceptual):
"Get work item 123 from project neo" (internally sets
{ "project": "neo", "id": 123 })If no
projectis specified, the server usesdefaultif present, else the first configured project.
3. Restart Claude Desktop
After adding the configuration, restart Claude Desktop to load the MCP server.
Available Tools
All tools accept an optional project parameter (string shortname) unless noted otherwise.
get_work_item
Get a work item by ID.
Parameters:
- project: (Optional) Project shortname
- id: Work item ID (number)
- fields: (Optional) Array of specific fields to retrievequery_by_id
Execute a saved query by its ID.
Parameters:
- project: (Optional) Project shortname
- queryId: Query ID (GUID format, e.g., "02576c96-99fa-472b-8929-80b5f1760b02")
- fields: (Optional) Specific fields to retrieve. If not provided, uses query's own columnsget_linked_work_items
Get work items from a query and analyze their dependencies/links.
Parameters:
- project: (Optional) Project shortname
- queryId: Query ID (GUID format)
- linkType: (Optional) Filter by link type: "Children", "Parent", "Related", "Tested By"
- fields: (Optional) Specific fields to retrieve
Example: Get all tasks (children) linked to bugs from a queryget_work_items_with_relations
Get work items with their relationship details (parent, children, related items, etc.).
Parameters:
- project: (Optional) Project shortname
- ids: Array of work item IDs
- fields: (Optional) Specific fields to retrievequery_work_items
Query work items using field filters.
Parameters:
- project: (Optional) Project shortname
- fields: Array of field names to return (e.g., ["System.Id", "System.Title"])
- filters: Object with filter conditions (e.g., {"System.State": "Active"})
- top: Maximum number of results (default: 50)execute_wiql
Execute a custom WIQL query.
Parameters:
- project: (Optional) Project shortname
- wiql: WIQL query string
Example: "SELECT [System.Id], [System.Title] FROM WorkItems WHERE [System.WorkItemType] = 'Bug'"get_test_runs
Get recent test runs.
Parameters:
- project: (Optional) Project shortname
- top: Maximum number of test runs to return (default: 10)get_test_results
Get test results for a specific test run.
Parameters:
- project: (Optional) Project shortname
- runId: Test run ID (number)get_repositories
Get all Git repositories in the project.
Parameters:
- project: (Optional) Project shortnameget_commits
Get commits from a Git repository.
Parameters:
- project: (Optional) Project shortname
- repositoryId: Repository ID or name
- top: Maximum number of commits (default: 20)get_pull_requests
Get pull requests from a Git repository.
Parameters:
- project: (Optional) Project shortname
- repositoryId: Repository ID or name
- status: PR status filter (active, completed, abandoned, all) (default: active)list_projects
List configured project shortnames and their base URLs.
Parameters:
(none)
Returns: Array of { shortname, baseUrl }
Example: "List configured Azure DevOps projects"ping
Health check summarizing server configuration.
Parameters:
(none)
Returns JSON object:
{
"serverVersion": "1.0.0",
"projects": [ { "shortname": "default", "baseUrl": "https://dev.azure.com/Org/ProjectA" }, ... ],
"timeout": 15,
"timestamp": "2025-11-03T12:34:56.789012Z"
}Example prompt: "Ping the Azure DevOps server" or "Health check"
Usage Examples
Once configured, you can use natural language to interact with Azure DevOps:
Work Items & Queries
"Query by ID 02576c96-99fa-472b-8929-80b5f1760b02 and create a table"
"Get work item 100"
"Show me all active bugs"
"Query work items where System.State is Active"
"In project iris get work item 200"
Dependency Analysis
"Give me all tasks linked to work items from query id a5ff7f63-ea7b-4b2e-9528-61513f744570"
"Show me all children of work items from query [query-id] in project neo"
"Analyze dependencies for work items 100, 200, 300"
Test Results
"Get the latest test runs"
"Show me test results for run 456 in project iris"
Git Operations
"List all Git repositories"
"Show recent commits in repository MyRepo"
"Get active pull requests in MyRepo for project neo"
Project Enumeration
"List configured Azure DevOps projects"
"Show projects"
OpenCode-Specific Examples
When using OpenCode, you can also add instructions to your AGENTS.md file to automatically use Azure DevOps tools:
AGENTS.md:
## Azure DevOps Integration
When working with work items, bugs, or tasks:
- Use Azure DevOps tools to query work items
- Use `list_projects` to see available projects
- Use `get_linked_work_items` for dependency analysis
When analyzing test failures:
- Use `get_test_runs` to see recent test executions
- Use `get_test_results` to investigate specific test failuresExample OpenCode Prompts:
"Show me all bugs assigned to me in the current sprint"
"Analyze the test failures from the last 5 test runs"
"Create a dependency graph for work item 456 showing all parent and child items"
"List all active pull requests in the MyRepo repository and summarize their status"
Configuration
JSON + Optional .env Overlay
Primary configuration remains the JSON file referenced by AZDO_CONFIG. Optionally you can supply or override project entries via environment variables or a .env file without editing the JSON (useful for keeping secrets out of tracked files).
Activation methods:
Set
AZDO_USE_ENV=1(process env) ORSet
AZDO_ENV_PATHto a custom dotenv file path (e.g.C:\secrets\azuredevops.env). If present this also activates overlay.Default dotenv path is
./.envif it exists.
Variable naming pattern (case sensitive):
AZDO_PROJECT_<SHORTNAME>_BASE_URL=https://dev.azure.com/Org/ProjectPath
AZDO_PROJECT_<SHORTNAME>_PAT=your_pat_token_here
AZDO_TIMEOUT=20 # optional timeout override in secondsExample .env:
# Azure DevOps MCP server secrets (DO NOT COMMIT)
AZDO_PROJECT_default_BASE_URL=https://dev.azure.com/Org/ProjectA
AZDO_PROJECT_default_PAT=pat_default_secret
AZDO_PROJECT_neo_BASE_URL=https://dev.azure.com/Org/ProjectNeo
AZDO_PROJECT_neo_PAT=pat_neo_secret
AZDO_TIMEOUT=25Behavior:
Overlay project entries override same shortnames from JSON.
Shortname discovery is based on matching both
BASE_URLandPATvariables; partial definitions are ignored.Trailing slashes are trimmed automatically.
Timeout override uses
AZDO_TIMEOUTif numeric.Final configuration must contain at least one valid project (baseUrl + pat) or startup exits.
Security:
Root
.envtemplate is committed (contains only placeholders) while other secret variants remain ignored.Never commit real PAT values; replace placeholders locally or use a non-tracked
.env.localfile or system environment.
Below is the original JSON-only description for reference (now extended for overlay-only mode):
The server loads configuration primarily from AZDO_CONFIG (path to JSON file). Legacy environment variables (AZURE_DEVOPS_BASE_URL, AZURE_DEVOPS_PAT, AZURE_DEVOPS_PROJECTS_FILE, AZURE_DEVOPS_PROJECTS, AZURE_DEVOPS_TIMEOUT) are deprecated and ignored.
Required file structure (JSON base):
{
"projects": {
"shortname": { "baseUrl": "https://dev.azure.com/Org/ProjectPath", "pat": "your-pat" }
},
"timeout": 15
}Overlay-only minimal example (all real data provided via environment / .env):
{
"projects": {},
"timeout": 15
}projectsmust be a non-empty object unless overlay is active (AZDO_USE_ENV=1 or AZDO_ENV_PATH set) and supplies valid project entries.Each project (from JSON or overlay) must include
baseUrlandpat.timeoutis optional (seconds).
SSL Configuration
The server supports both cloud and on-premise Azure DevOps instances. SSL verification is disabled by default (verify=False) to ensure compatibility across different environments. Users deploying in highly secure environments can implement certificate pinning separately if needed.
Structured Logging
The server supports optional structured JSON logging to stderr for debugging and monitoring. Logging is controlled by the AZDO_LOG_LEVEL environment variable.
Log Levels:
none(default): No logging outputinfo: Log tool invocations with timestamp, tool name, project, duration, and success/error statusdebug: Include all info-level data plus sanitized tool parameters
Configuration:
Add AZDO_LOG_LEVEL to the server environment in Claude Desktop config:
{
"mcpServers": {
"azure-devops": {
"command": "python",
"args": ["C:/path/to/mcp_azure_devops/src/server.py"],
"env": {
"AZDO_CONFIG": "C:/path/to/azure_devops_config.json",
"AZDO_LOG_LEVEL": "info"
}
}
}
}Log Format (JSON to stderr):
{
"timestamp": "2025-11-03T12:34:56.789012Z",
"level": "INFO",
"tool": "get_work_item",
"project": "default",
"duration_ms": 123.45,
"status": "success",
"error": null,
"params": {...}
}Viewing Logs:
On Windows, logs are written to:
%APPDATA%\Claude\logs\mcp-server-azure-devops.logOn macOS:
~/Library/Logs/Claude/mcp-server-azure-devops.logNotes:
Logging writes to stderr and does not interfere with MCP stdio protocol
Sensitive data (PAT) is never logged
Logging errors never crash the server
Use
infolevel for production monitoringUse
debuglevel for troubleshooting (includes request parameters)
Security Notes
⚠️ Important:
Your PAT (Personal Access Token) is stored in the Claude Desktop configuration file
Ensure this file has appropriate permissions and is not shared or committed to version control
The installation script creates automatic backups of your Claude Desktop configuration
Backups are stored in
%APPDATA%\Claude\with timestamps
Testing
Set the AZDO_CONFIG environment variable before running tests:
Windows (PowerShell):
$env:AZDO_CONFIG = "C:\path\azure_devops_config.json"
python tests/test_client.pymacOS/Linux (bash):
export AZDO_CONFIG=/path/azure_devops_config.json
python tests/test_client.pyRun All Tests
python tests/test_client.pyTest Dependency Analysis
python tests/test_dependencies.pyMulti-Project Integration Test
python tests/test_integration.pyManual Testing
Test specific queries:
python tests/test_dependencies.pyTroubleshooting
Server not showing in Claude Desktop
Check if Claude Desktop config is valid JSON
Verify the path to
src/server.pyis correctCheck Claude Desktop logs:
%APPDATA%\Claude\logs\mcp-server-azure-devops.logRestart Claude Desktop
401 Authentication Error
Verify your PAT is valid and not expired
Ensure PAT has required permissions (Work Items: Read, Code: Read, Test: Read)
Check if you can access the Azure DevOps URL in your browser
SSL Issues
Verify you can access the Azure DevOps URL directly in a browser
Check firewall/proxy settings if behind a corporate network
SSL verification is disabled by default; if you need certificate pinning, implement it separately
Query by ID not working
Verify the query ID is correct (GUID format)
Ensure you have access to the query in Azure DevOps
Check if the query exists in the specified project
ImportError or Module Not Found
Ensure all dependencies are installed:
pip install -r requirements.txtVerify Python version is 3.8 or higher:
python --version
OpenCode.ai Issues
MCP Server Not Loading
Check that paths in
opencode.jsoncare absolute pathsVerify
AZDO_CONFIGpath points to a valid configuration fileCheck OpenCode logs: Run
opencodewith increased verbosityEnsure Python is in your PATH:
which pythonorwhere python
Tools Not Available
Verify the MCP server is enabled:
"enabled": trueinopencode.jsoncCheck if tools are disabled globally in the
toolssectionRestart OpenCode after configuration changes
High Token Usage
Consider disabling Azure DevOps tools globally and enabling per-agent
Use the
/undocommand if a tool returns too much dataBe specific in your prompts to target specific work items or queries
Project Structure
mcp_azure_devops/
├── src/
│ ├── server.py # MCP server implementation
│ ├── config.py # Unified config loader (AZDO_CONFIG)
│ ├── logging_utils.py # Structured JSON logging
│ └── client.py # Azure DevOps REST API client
├── tests/
│ ├── test_client.py # Tool invocation tests
│ ├── test_dependencies.py # Dependency analysis tests
│ ├── test_integration.py # Multi-project integration tests
│ ├── test_logging.py # Logging functionality tests
│ ├── test_mock.py # Offline mock data tests
│ ├── test_ping.py # Health check tests
│ └── test_mock_client.py # Mock client for testing
├── reviews/
│ ├── README.md # Review process documentation
│ └── YYYYMMDD_HHMMSS_*.md # Timestamped review documents
├── azure_devops_config.example.json # Example Azure DevOps configuration
├── azure_devops_config.json # User configuration (gitignored)
├── opencode.example.jsonc # Example OpenCode.ai configuration
├── install.ps1 # Installation script (Claude Desktop)
├── uninstall.ps1 # Uninstallation script (Claude Desktop)
├── requirements.txt # Python dependencies
├── .env # Environment variable template
├── .gitignore
├── CONTEXT.md # Requirements documentation
└── README.md # This fileDevelopment
Based on proven Azure DevOps client code from the DvoiPad project, ensuring reliability and compatibility with enterprise Azure DevOps instances.
License
MIT
This server cannot be installed
Maintenance
Resources
Unclaimed servers have limited discoverability.
Looking for Admin?
If you are the server author, to access and configure the admin panel.
Latest Blog Posts
- Your AI Chatbot Just Exposed Your CEO's Salary to an InternBy Om-Shree-0709 on .Agent IdentityMCP SecurityOAuth Delegation
- Why MCP Servers Need Execution Sandboxing (And Why Your Current Stack Isn't Enough)By Om-Shree-0709 on .Agentic AiPrompt InjectionWebAssembly
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/trosinde/mcp_azure_devops'
If you have feedback or need assistance with the MCP directory API, please join our Discord server