使用说明
Azure DevOps MCP Server Deployment Guide
This comprehensive guide provides step-by-step instructions for deploying an Azure DevOps Model Context Protocol (MCP) Server. The deployment consists of a Node.js backend server and a Next.js frontend application.
Choose your deployment method:
- Part 1: Local Development Setup - Run the application on your local machine
- Part 2: Azure Web App Deployment - Deploy to Azure Web Apps with CI/CD
Part 1: Local Development Setup
This section covers running the Azure DevOps MCP Server locally for development and testing purposes.
Table of Contents - Local Setup
Local Prerequisites
Before starting local development, ensure you have:
- Node.js 18+ installed on your machine
- npm or yarn package manager
- Azure DevOps organization with a Personal Access Token (PAT) with read/write permissions
- (Optional) Azure OpenAI service for natural language processing
- Git for cloning the repository
Installation
Step 1: Clone the Repository
Clone the Azure DevOps MCP Server repository to your local machine:
git clone <repo-url>
cd azure-devops-mcp
Step 2: Install Root Dependencies
Install the root-level dependencies (includes concurrently for running both server and frontend):
npm install
Step 3: Install Server Dependencies
Navigate to the server directory and install dependencies:
cd server
npm install
cd ..
Step 4: Install Frontend Dependencies
Navigate to the frontend directory and install dependencies:
cd frontend
npm install
cd ..
Configuration
Step 5: Set Up Environment Variables
Create your environment configuration file:
-
Copy the example file:
cp .env.example .env -
Edit
.envwith your credentials:# Azure DevOps Configuration AZURE_DEVOPS_ORG_URL=https://dev.azure.com/<your-organization> AZURE_DEVOPS_PAT=<your-personal-access-token> AZURE_DEVOPS_PROJECT=<Your-Project-Name> # Server Configuration PORT=3001 MCP_SERVER_PORT=3002 NODE_ENV=development # Frontend Configuration NEXT_PUBLIC_API_URL=http://localhost:3001 # Azure OpenAI Configuration (Optional) AZURE_OPENAI_API_KEY=<your-openai-key> AZURE_OPENAI_ENDPOINT=https://<your-openai-endpoint>.openai.azure.com AZURE_OPENAI_API_VERSION=2025-01-01-preview AZURE_OPENAI_DEPLOYMENT_NAME=gpt-4
Configuration Guide:
| Variable | Description | Example |
|---|---|---|
AZURE_DEVOPS_ORG_URL |
Your Azure DevOps organization URL | https://dev.azure.com/mycompany |
AZURE_DEVOPS_PAT |
Personal Access Token from Azure DevOps | Get from Azure DevOps User Settings |
AZURE_DEVOPS_PROJECT |
Default project to work with | MyProject |
PORT |
Backend server port | 3001 |
NEXT_PUBLIC_API_URL |
Backend API URL for frontend | http://localhost:3001 |
AZURE_OPENAI_API_KEY |
Azure OpenAI API key (optional) | From Azure Portal |
AZURE_OPENAI_ENDPOINT |
OpenAI service endpoint | https://myopenai.openai.azure.com |
Getting Your Azure DevOps PAT:
- Go to Azure DevOps → User Settings → Personal Access Tokens
- Create new token with required permissions:
- Work Items (Read & Write)
- Code (Read)
- Build (Read)
- Release (Read)
- Copy the token and add to
.envfile
Running Locally
Option 1: Run Both Services Concurrently (Recommended)
From the root directory, run both server and frontend together:
npm run dev
What this does:
- Starts the MCP server on
http://localhost:3001 - Starts the frontend on
http://localhost:3000 - Runs both with hot-reload enabled
- Shows logs from both services in one terminal
Access the application:
- Frontend UI:
http://localhost:3000 - Backend API:
http://localhost:3001 - Health check:
http://localhost:3001/health
Option 2: Run Services Separately
If you prefer to run services in separate terminals for better log management:
Terminal 1 - Start the MCP Server:
cd server
npm run dev
Server will be available at http://localhost:3001
Terminal 2 - Start the Frontend:
cd frontend
npm run dev
Frontend will be available at http://localhost:3000
Local Development
Using the Frontend UI
- Open your browser and navigate to
http://localhost:3000 - The sidebar displays all 51 available Azure DevOps tools
- Natural Language Queries: Type queries like:
- "List all projects"
- "Create a bug titled 'Login issue'"
- "Show me recent builds"
- Manual Tool Selection: Click on a tool in the sidebar to execute it
- View results in the chat-style interface
Testing the API Directly
You can test the backend API using curl or tools like Postman:
Health Check:
curl http://localhost:3001/health
List Available Tools:
curl http://localhost:3001/api/tools
Execute a Tool:
curl -X POST http://localhost:3001/api/tools/list_projects \
-H "Content-Type: application/json" \
-d '{}'
Chat Completion:
curl -X POST http://localhost:3001/api/chat \
-H "Content-Type: application/json" \
-d '{"message": "List all projects"}'
Using as MCP Server (stdio mode)
For integration with Claude Desktop, Cursor, or other MCP clients:
-
Build the server:
cd server npm run build -
Configure your MCP client:
{ "mcpServers": { "azure-devops": { "command": "node", "args": ["/path/to/azure-devops-mcp/server/dist/index.js", "--stdio"], "env": { "AZURE_DEVOPS_ORG_URL": "https://dev.azure.com/your-org", "AZURE_DEVOPS_PAT": "your-pat-token", "AZURE_DEVOPS_PROJECT": "Your-Project" } } } }
Development Tips
Hot Reload:
- Both server and frontend support hot-reload during development
- Changes to TypeScript files in
/server/srcwill trigger automatic rebuild - Changes to React components in
/frontendwill refresh the browser
Debugging:
- Server logs appear in the terminal
- Frontend logs appear in browser console
- Check
http://localhost:3001/healthif backend isn't responding - Verify environment variables are loaded correctly
Common Local Development Issues:
| Issue | Solution |
|---|---|
| Port already in use | Kill process on port 3001/3000 or change PORT in .env |
| Frontend can't connect | Verify NEXT_PUBLIC_API_URL matches server port |
| Azure DevOps API errors | Check PAT permissions and expiration date |
| Build errors | Delete node_modules and run npm install again |
Part 2: Azure Web App Deployment
This section covers deploying the Azure DevOps MCP Server to Azure Web Apps for production use with automated CI/CD pipelines.
Table of Contents - Azure Deployment
- Azure Prerequisites
- Infrastructure Setup
- Backend Deployment
- Frontend Deployment
- CI/CD Pipeline Configuration
- Testing and Monitoring
Azure Prerequisites
Before starting Azure deployment, ensure you have:
- An active Azure subscription
- Azure CLI installed and configured
- Azure DevOps organization and project
- Personal Access Token (PAT) with required permissions
- Azure OpenAI service provisioned
- Source code repository with backend and frontend applications
Infrastructure Setup
Step 1: Authenticate with Azure
First, log in to your Azure account using the Azure CLI. This establishes an authenticated session for subsequent commands.
az login
What this does: Opens a browser window for interactive authentication. Once completed, you'll have access to your Azure subscriptions.
Step 2: Create a Resource Group
Create a dedicated resource group to organize all related Azure resources for the MCP server deployment.
az group create \
--name <RESOURCE_GROUP_NAME> \
--location <LOCATION>
Parameters explained:
--name: The name of the resource group (e.g.,rg-devops-mcp)--location: Azure region where resources will be deployed (e.g.,eastus,westus2,westeurope)
Why this matters: Resource groups provide a logical container for managing and organizing Azure resources. All resources for this project will be grouped together for easier management and billing.
Step 3: Create an App Service Plan
Provision an App Service Plan that defines the compute resources for hosting the web applications.
az appservice plan create \
--name <APP_SERVICE_PLAN_NAME> \
--resource-group <RESOURCE_GROUP_NAME> \
--sku B1 \
--is-linux
Parameters explained:
--name: Name of the App Service Plan--resource-group: The resource group created in Step 2--sku: Pricing tier (B1= Basic tier with 1 core, 1.75 GB RAM)--is-linux: Specifies Linux-based hosting environment
Cost consideration: The B1 SKU is cost-effective for development/testing. For production, consider upgrading to S1 or higher for better performance and SLA.
Step 4: Check Available Runtimes (Optional)
Verify the available Node.js runtime versions supported by Azure Web Apps on Linux.
az webapp list-runtimes --os-type linux
Why check this: Ensures you select a supported runtime version for your application. This helps avoid compatibility issues during deployment.
Backend Deployment
Step 5: Create the Backend Web App
Deploy a Web App instance for the Node.js backend server.
az webapp create \
--name <BACKEND_WEBAPP_NAME> \
--resource-group <RESOURCE_GROUP_NAME> \
--plan <APP_SERVICE_PLAN_NAME> \
--runtime "NODE|20-lts"
Parameters explained:
--name: Unique name for the web app (must be globally unique across Azure)--resource-group: Resource group containing the app--plan: App Service Plan created in Step 3--runtime: Node.js LTS version 20
Result: Creates a web app accessible at https://<BACKEND_WEBAPP_NAME>.azurewebsites.net
Step 6: Configure Backend Application Settings
Set environment variables required by the backend application. These settings configure Azure DevOps integration, OpenAI connectivity, and server configuration.
az webapp config appsettings set \
--name <BACKEND_WEBAPP_NAME> \
--resource-group <RESOURCE_GROUP_NAME> \
--settings \
AZURE_DEVOPS_ORG_URL="https://dev.azure.com/<YOUR_ORG_NAME>" \
AZURE_DEVOPS_PAT="<YOUR_DEVOPS_PAT_TOKEN>" \
AZURE_DEVOPS_PROJECT="<YOUR_PROJECT_NAME>" \
AZURE_OPENAI_API_KEY="<YOUR_OPENAI_API_KEY>" \
AZURE_OPENAI_ENDPOINT="https://<YOUR_OPENAI_RESOURCE_NAME>.openai.azure.com" \
AZURE_OPENAI_API_VERSION="2025-01-01-preview" \
AZURE_OPENAI_DEPLOYMENT_NAME="<YOUR_MODEL_DEPLOYMENT_NAME>" \
NODE_ENV="production" \
PORT=3001 \
MCP_SERVER_PORT=3002 \
ALLOWED_ORIGINS="https://<FRONTEND_WEBAPP_NAME>.azurewebsites.net"
Configuration variables explained:
| Variable | Purpose |
|---|---|
AZURE_DEVOPS_ORG_URL |
Your Azure DevOps organization URL |
AZURE_DEVOPS_PAT |
Personal Access Token for authenticating with Azure DevOps |
AZURE_DEVOPS_PROJECT |
Name of the Azure DevOps project to connect to |
AZURE_OPENAI_API_KEY |
API key for Azure OpenAI service |
AZURE_OPENAI_ENDPOINT |
Endpoint URL for Azure OpenAI resource |
AZURE_OPENAI_API_VERSION |
API version for OpenAI service calls |
AZURE_OPENAI_DEPLOYMENT_NAME |
Name of the deployed AI model |
NODE_ENV |
Node.js environment (production enables optimizations) |
PORT |
Main application port |
MCP_SERVER_PORT |
Port for MCP server functionality |
ALLOWED_ORIGINS |
CORS configuration for frontend access |
Security Note: Replace placeholder values with your actual credentials. Consider using Azure Key Vault for sensitive values in production.
Frontend Deployment
Step 7: Create the Frontend Web App
Deploy a separate Web App instance for the Next.js frontend application.
az webapp create \
--name <FRONTEND_WEBAPP_NAME> \
--resource-group <RESOURCE_GROUP_NAME> \
--plan <APP_SERVICE_PLAN_NAME> \
--runtime "NODE|20-lts"
Why separate apps:
- Enables independent scaling of frontend and backend
- Simplifies deployment and rollback procedures
- Allows different monitoring and logging configurations
- Better security isolation
Result: Creates a web app accessible at https://<FRONTEND_WEBAPP_NAME>.azurewebsites.net
Step 8: Configure Frontend Application Settings
Set environment variables for the Next.js frontend to communicate with the backend.
az webapp config appsettings set \
--name <FRONTEND_WEBAPP_NAME> \
--resource-group <RESOURCE_GROUP_NAME> \
--settings \
NEXT_PUBLIC_API_URL="https://<BACKEND_WEBAPP_NAME>.azurewebsites.net" \
SCM_DO_BUILD_DURING_DEPLOYMENT="true"
Configuration variables explained:
| Variable | Purpose |
|---|---|
NEXT_PUBLIC_API_URL |
Backend API endpoint for frontend to call |
SCM_DO_BUILD_DURING_DEPLOYMENT |
Enables Azure to run build commands during deployment (Kudu build) |
Next.js Note: Variables prefixed with NEXT_PUBLIC_ are exposed to the browser and embedded during build time.
CI/CD Pipeline Configuration
Step 9: Azure DevOps Pipeline Setup
Create an Azure DevOps pipeline to automate the build and deployment process. This pipeline consists of four stages: building the backend, building the frontend, deploying the backend, and deploying the frontend.
Pipeline Configuration File (azure-pipelines.yml)
trigger:
none
pool:
vmImage: 'ubuntu-latest'
variables:
- group: webappenv
Pipeline structure explained:
trigger: none: Manual trigger only (no automatic builds on code commits)pool: Specifies Ubuntu-based build agentvariables: References a variable group namedwebappenvcontaining shared configuration
Variable group setup: Create a variable group in Azure DevOps Library with these variables:
NODE_VERSION: e.g., "20.x"BACKEND_WEBAPP_NAME: Your backend web app name (e.g., "my-mcp-backend")FRONTEND_WEBAPP_NAME: Your frontend web app name (e.g., "my-mcp-frontend")azureSubscription: Your Azure service connection nameNEXT_PUBLIC_API_URL: Your backend URL (e.g., "https://my-mcp-backend.azurewebsites.net")
Stage 1: Build Backend
This stage compiles the Node.js backend application and prepares it for deployment.
stages:
- stage: BuildBackend
displayName: 'Build Backend'
jobs:
- job: BuildBackendJob
displayName: 'Build Backend Application'
steps:
- checkout: self
- task: NodeTool@0
displayName: 'Set up Node.js'
inputs:
versionSpec: '$(NODE_VERSION)'
- script: |
pwd
ls -la
echo ""
echo "Server Directory: $(System.DefaultWorkingDirectory)/server"
ls -la $(System.DefaultWorkingDirectory)/server
echo ""
echo "Frontend Directory: $(System.DefaultWorkingDirectory)/frontend"
ls -la $(System.DefaultWorkingDirectory)/frontend
echo ""
displayName: 'Get File Location'
- script: |
cd $(System.DefaultWorkingDirectory)/server
npm ci
npm run build
# Copy only what Azure needs
cp package.json dist/
cp package-lock.json dist/
# Install production dependencies WITHOUT deleting compiled files
npm install --omit=dev --prefix dist
displayName: 'Build backend'
Step breakdown:
- Checkout: Retrieves source code from repository
- NodeTool@0: Installs specified Node.js version
- Get File Location: Diagnostic step to verify directory structure
- Build backend:
npm ci: Clean install of dependencies (faster and more reliable thannpm install)npm run build: Compiles TypeScript to JavaScript indist/folder- Copies
package.jsonandpackage-lock.jsontodist/for Azure deployment - Installs only production dependencies in
dist/folder (excludes devDependencies)
- task: ArchiveFiles@2
inputs:
rootFolderOrFile: '$(System.DefaultWorkingDirectory)/server/dist'
includeRootFolder: false
archiveType: 'zip'
archiveFile: '$(Build.ArtifactStagingDirectory)/backend.zip'
- publish: $(Build.ArtifactStagingDirectory)/backend.zip
artifact: backend-drop
Artifact creation steps:
- ArchiveFiles@2: Creates a ZIP archive of the
dist/folderincludeRootFolder: false: Excludes thedist/folder name from archive (files at root)- Stores ZIP in build staging directory
- Publish: Makes the ZIP available as a pipeline artifact named
backend-dropfor deployment stage
Why this approach: Separating build and deployment stages enables redeployment without rebuilding, faster rollbacks, and better pipeline organization.
Stage 2: Build Frontend
This stage compiles the Next.js frontend application and packages it for deployment.
- stage: BuildFrontend
displayName: 'Build Frontend'
condition: succeeded()
jobs:
- job: BuildFrontendJob
displayName: 'Build Frontend Application'
steps:
- checkout: self
- script: |
pwd
ls -la
echo ""
echo "Server Directory: $(System.DefaultWorkingDirectory)/server"
ls -la $(System.DefaultWorkingDirectory)/server
echo ""
echo "Frontend Directory: $(System.DefaultWorkingDirectory)/frontend"
ls -la $(System.DefaultWorkingDirectory)/frontend
echo ""
displayName: 'Get File Location'
- task: NodeTool@0
displayName: 'Set up Node.js'
inputs:
versionSpec: '$(NODE_VERSION)'
- script: |
cd $(System.DefaultWorkingDirectory)/frontend
npm ci
npm run build
npm install --omit=dev
displayName: 'Build frontend'
env:
NEXT_PUBLIC_API_URL: $(NEXT_PUBLIC_API_URL)
- script: |
echo ""
echo "Listing files before archiving..."
ls -R $(System.DefaultWorkingDirectory)/frontend
echo ""
displayName: 'List Frontend Files Before Archiving'
- script: |
echo ""
echo "Listing frontend folder:"
ls -la $(System.DefaultWorkingDirectory)/frontend
echo ""
echo "Listing node_modules:"
ls -la $(System.DefaultWorkingDirectory)/frontend/node_modules
echo ""
echo "Listing node_modules/.bin:"
ls -la $(System.DefaultWorkingDirectory)/frontend/node_modules/.bin
echo ""
echo "Listing node_modules/next:"
ls -la $(System.DefaultWorkingDirectory)/frontend/node_modules/next
echo ""
displayName: 'Verify frontend build output'
- task: ArchiveFiles@2
inputs:
rootFolderOrFile: '$(System.DefaultWorkingDirectory)/frontend'
includeRootFolder: false
archiveType: 'zip'
archiveFile: '$(Pipeline.Workspace)/frontend-drop/frontend.zip'
replaceExistingArchive: true
- publish: $(Pipeline.Workspace)/frontend-drop/frontend.zip
artifact: frontend-drop
Frontend build steps explained:
- Build frontend:
npm ci: Clean install dependenciesnpm run build: Runs Next.js production build (creates.next/folder)npm install --omit=dev: Installs production-only dependencies- Environment variable
NEXT_PUBLIC_API_URLis injected during build
- Diagnostic scripts: Verify build output and critical dependencies (Next.js runtime)
- Archive and publish: Package entire frontend directory including
.next/,node_modules/, and config files
Next.js deployment note: The entire frontend folder is packaged because Next.js requires:
.next/folder (compiled app)node_modules/(runtime dependencies)package.jsonandnext.config.js
Stage 3: Deploy Backend
This stage deploys the built backend application to Azure Web App.
- stage: DeployBackend
displayName: 'Deploy Backend'
dependsOn: BuildBackend
condition: succeeded()
jobs:
- deployment: DeployBackendJob
environment: 'production'
strategy:
runOnce:
deploy:
steps:
- task: AzureWebApp@1
inputs:
azureSubscription: '$(azureSubscription)'
appType: 'webAppLinux'
appName: '$(BACKEND_WEBAPP_NAME)'
package: '$(Pipeline.Workspace)/backend-drop/backend.zip'
runtimeStack: 'NODE|20-lts'
startUpCommand: 'node index.js'
Deployment configuration explained:
dependsOn: BuildBackend: Ensures build completes before deploymentenvironment: 'production': Links deployment to Azure DevOps environment (enables approvals, deployment history)strategy: runOnce: Simple deployment strategy (alternatives: canary, rolling)- AzureWebApp@1 task:
azureSubscription: Service connection for Azure authenticationappType: Specifies Linux-based Web AppappName: Target Web App name from variablespackage: Path to the artifact from build stagestartUpCommand: Command executed to start the application (node index.js)
Security best practice: Configure the production environment in Azure DevOps with approval gates before allowing deployment.
Stage 4: Deploy Frontend
This stage deploys the built frontend application to Azure Web App.
- stage: DeployFrontend
displayName: 'Deploy Frontend'
dependsOn: [BuildFrontend, DeployBackend]
condition: succeeded()
jobs:
- deployment: DeployFrontendJob
environment: 'production'
strategy:
runOnce:
deploy:
steps:
- task: AzureWebApp@1
inputs:
azureSubscription: '$(azureSubscription)'
appType: 'webAppLinux'
appName: '$(FRONTEND_WEBAPP_NAME)'
package: '$(Pipeline.Workspace)/frontend-drop/frontend.zip'
runtimeStack: 'NODE|20-lts'
startUpCommand: 'next start'
Deployment dependencies explained:
dependsOn: [BuildFrontend, DeployBackend]: Waits for both frontend build AND backend deployment- Why wait for backend: Ensures backend API is available before frontend goes live
- Prevents frontend errors from missing backend endpoints
startUpCommand: 'next start': Starts Next.js production server
Deployment sequence: BuildBackend → BuildFrontend → DeployBackend → DeployFrontend
This order ensures minimal downtime and proper service availability during deployment.
Testing and Monitoring
Step 10: Configure Health Check Endpoints
Enable Azure's health monitoring feature to automatically detect application issues.
# Configure backend health check
az webapp config set \
--name <BACKEND_WEBAPP_NAME> \
--resource-group <RESOURCE_GROUP_NAME> \
--generic-configurations '{"healthCheckPath": "/health"}'
# Configure frontend health check
az webapp config set \
--name <FRONTEND_WEBAPP_NAME> \
--resource-group <RESOURCE_GROUP_NAME> \
--generic-configurations '{"healthCheckPath": "/health"}'
Health check benefits:
- Automatic monitoring: Azure pings the health endpoint every minute
- Auto-healing: Can automatically restart unhealthy instances
- Load balancing: Removes unhealthy instances from load balancer rotation
- Alerts: Integrates with Azure Monitor for notifications
Implementation requirement: Your application must expose a /health endpoint that returns HTTP 200 when healthy.
Step 11: Enable Application Logging
Configure logging to capture application output and diagnose issues.
# Enable application logging for backend
az webapp log config \
--name <BACKEND_WEBAPP_NAME> \
--resource-group <RESOURCE_GROUP_NAME> \
--application-logging filesystem \
--level information
# Enable application logging for frontend
az webapp log config \
--name <FRONTEND_WEBAPP_NAME> \
--resource-group <RESOURCE_GROUP_NAME> \
--application-logging filesystem \
--level information
Logging levels:
error: Only errorswarning: Errors and warningsinformation: Errors, warnings, and informational messages (recommended)verbose: All log messages including debug information
Log storage: Logs are stored in the App Service file system (/home/LogFiles/)
Step 12: Stream Live Logs
View real-time application logs to monitor deployments and troubleshoot issues.
# Stream backend logs
az webapp log tail \
--name <BACKEND_WEBAPP_NAME> \
--resource-group <RESOURCE_GROUP_NAME>
# Stream frontend logs (in another terminal)
az webapp log tail \
--name <FRONTEND_WEBAPP_NAME> \
--resource-group <RESOURCE_GROUP_NAME>
When to use log streaming:
- During and immediately after deployment
- When troubleshooting application errors
- To verify environment variables are loaded correctly
- To monitor API calls and performance
Alternative: View logs in Azure Portal under Monitoring → Log stream
Deployment Verification
After completing all steps, verify the deployment:
-
Test backend health endpoint:
curl https://<BACKEND_WEBAPP_NAME>.azurewebsites.net/healthExpected response:
{"status":"healthy"}or similar -
Test frontend application:
- Navigate to
https://<FRONTEND_WEBAPP_NAME>.azurewebsites.netin your browser - Verify the UI loads correctly
- Test authentication and API connectivity
- Navigate to
-
Check Azure Portal:
- Verify both Web Apps show as "Running"
- Review metrics for HTTP requests and response times
- Check for any errors in Application Insights (if configured)
Troubleshooting Tips
Common Issues
Build failures:
- Verify Node.js version matches between local and pipeline
- Check for missing dependencies in
package.json - Review build logs for TypeScript compilation errors
Deployment failures:
- Ensure service connection has proper permissions
- Verify Web App names match variables
- Check that startup command is correct for your application structure
Runtime errors:
- Verify all environment variables are set correctly
- Check CORS configuration (ALLOWED_ORIGINS)
- Review application logs for specific error messages
- Ensure backend is deployed before frontend
Networking issues:
- Verify NEXT_PUBLIC_API_URL points to correct backend URL
- Check Azure DevOps PAT has required permissions
- Ensure Azure OpenAI endpoint is accessible
Next Steps
Consider these enhancements for production:
-
Security:
- Migrate secrets to Azure Key Vault
- Enable managed identity for Azure service authentication
- Configure custom domain with SSL certificate
- Implement authentication (Azure AD, etc.)
-
Performance:
- Enable Application Insights for detailed telemetrics
- Configure autoscaling based on metrics
- Add CDN for frontend static assets
- Implement caching strategies
-
Reliability:
- Set up deployment slots for staging
- Configure automated backups
- Implement blue-green deployment strategy
- Add monitoring alerts and dashboards
-
DevOps:
- Add automated testing to pipeline
- Implement infrastructure as code (Bicep/Terraform)
- Set up continuous deployment on code commits
- Configure branch policies and code reviews
Summary
This guide covered deploying an Azure DevOps MCP Server consisting of:
- Infrastructure: Resource group, App Service Plan, and two Web Apps
- Backend: Node.js server with Azure DevOps and OpenAI integration
- Frontend: Next.js application consuming backend API
- CI/CD: Azure DevOps pipeline with build and deployment automation
- Monitoring: Health checks, logging, and log streaming
Your MCP server is now deployed and ready for use at:
- Backend:
https://<BACKEND_WEBAPP_NAME>.azurewebsites.net - Frontend:
https://<FRONTEND_WEBAPP_NAME>.azurewebsites.net
Additional Resources
About Azure DevOps MCP Server
An MCP (Model Context Protocol) server for querying Azure DevOps, with a frontend UI for chat completion. This project enables natural language interaction with Azure DevOps through a ChatGPT-style interface, powered by Azure OpenAI function calling.
Screenshots
🎥 Quick Demo
Watch a quick demo of the Azure DevOps MCP server in action, creating and updating work items using natural language.
✨ Features
- MCP Server: Implements the Model Context Protocol, exposing 51 Azure DevOps tools as MCP tools
- Frontend UI: A Next.js-based chat interface for interacting with the MCP server via natural language
- Azure DevOps Integration: Query work items, projects, builds, releases, repositories, pipelines, boards, and more using Azure DevOps REST API
- Environment Configuration: Store secrets and configuration in
.envfiles - OpenAI Function Calling: Uses Azure OpenAI to parse natural language queries and call the appropriate tools
- Real-time Data: All tools fetch live data from your Azure DevOps organization
- Modern UI: Responsive, ChatGPT-style interface with sidebar tool listing, conversation history, and markdown rendering
🏗️ Architecture Overview
Azure DevOps MCP Server
├── Server (Node.js + TypeScript)
│ ├── MCP Server (Model Context Protocol)
│ ├── HTTP API (Express)
│ ├── Azure DevOps Client (Axios)
│ └── OpenAI Integration (function calling)
├── Frontend (Next.js 14 + React + Tailwind CSS)
│ ├── Chat interface with message bubbles
│ ├── Sidebar with tool listing
│ ├── Real-time tool execution
│ └── Responsive design
└── Configuration
├── .env (secrets)
├── Azure DevOps PAT
└── Azure OpenAI credentials
📋 Available Tools (51 Total)
| Tool Name | Description | Required Parameters | Optional Parameters |
|---|---|---|---|
list_projects |
List all projects in the Azure DevOps organization | None | None |
list_project_teams |
Retrieve a list of teams for the specified Azure DevOps project. | project | None |
get_identity_ids |
Retrieve Azure DevOps identity IDs for a provided search filter. | searchFilter | None |
query_work_items |
Query work items using WIQL (Azure DevOps Query Language) | wiql | None |
get_work_items_by_ids |
Get work items by their IDs | ids | items |
get_builds |
Get recent builds for the project | None | definitionId |
get_releases |
Get recent releases for the project | None | top |
create_work_item |
Create a new work item in Azure DevOps (uses the default project configured in the environment). Provide work item type and title. The project is already set, so you do not need to specify it. | workItemType, title | None |
update_work_item |
Update fields of an existing work item in Azure DevOps. Provide the work item ID and a fields object with field names (e.g., System.Description) and new values. You can also add an optional comment. Common field mappings: "description" -> System.Description, "title" -> System.Title, "state" -> System.State, "assigned to" -> System.AssignedTo. | id, fields | None |
assign_work_item |
Assign a work item to a user. Provide the work item ID and the assignee (user display name or email). Optionally add a comment. | id, assignee | None |
list_repositories |
List repositories in a project (default project used if not specified) | None | project |
list_branches |
List branches in a repository | repositoryId | None |
list_pull_requests |
List pull requests in a repository or project | None | repositoryId |
get_pull_request |
Get details of a specific pull request | repositoryId, pullRequestId | None |
search_code |
Search for code across repositories | searchText | None |
search_work_items |
Search for work items using text search | searchText | None |
list_wikis |
List wikis in a project | None | project |
get_wiki_page |
Get content of a wiki page | wikiIdentifier | None |
list_team_iterations |
List iterations for a team | project, team | None |
list_test_plans |
List test plans in a project | project | None |
get_current_user |
Get the currently authenticated user details | None | None |
list_work_item_types |
List work item types available in a project | None | project |
list_iterations |
List iterations (sprints) for a project | None | project |
list_build_definitions |
List build definitions (pipelines) for a project | None | project |
list_release_definitions |
List release definitions for a project | None | project |
list_queries |
List saved work item queries in a project | None | project |
get_work_item_revisions |
Get revision history of a work item | id | None |
get_work_item_links |
Get links (relations) of a work item | id | None |
create_pull_request |
Create a new pull request | repositoryId, sourceBranch, targetBranch, title | None |
list_commits |
List commits in a repository | repositoryId | None |
get_file_content |
Get content of a file in a repository | repositoryId, path | None |
list_areas |
List areas (classification nodes) in a project | None | project |
list_iteration_capacities |
Get capacity for a team iteration | project, team, iterationId | None |
list_work_item_categories |
List work item categories in a project | None | project |
list_dashboards |
List dashboards in a project | None | project |
list_pipelines |
List pipelines (YAML pipelines) in a project | None | project |
list_test_suites |
List test suites in a test plan | project, planId | None |
list_variable_groups |
List variable groups for pipelines | None | project |
list_service_endpoints |
List service endpoints (service connections) | None | project |
list_tags |
List tags in a project | None | project |
list_team_members |
List members of a team | project, team | None |
list_boards |
List boards (work item boards) for a team | project, team | None |
list_board_columns |
List columns of a board | project, team, board | None |
list_board_rows |
List rows of a board | project, team, board | None |
list_work_item_states |
List states for a work item type | project, workItemType | None |
list_work_item_fields |
List work item fields (metadata) | None | project |
list_work_item_updates |
List updates (history) for a work item | id | None |
list_work_item_attachments |
List attachments for a work item | id | None |
list_work_item_comments |
List comments for a work item | id | None |
list_work_item_relations |
List relations (links) for a work item | id | None |
list_work_item_query_results |
Run a saved query and get results | project, queryId | None |
💬 Example Queries
Work Items
- "List all active bugs in the terraform-modules project"
- "Create a new task titled 'Update documentation'"
- "Assign work item 123 to John Doe"
- "Update the description of work item 456 to 'Fixed login bug'"
Projects & Teams
- "Show me all projects"
- "List teams in the terraform-modules project"
- "Who are the members of the terraform-modules team?"
Builds & Releases
- "Show recent builds"
- "List release definitions"
- "What's the status of the latest release?"
Repositories & Code
- "List repositories"
- "Search for 'TODO' in the code"
- "Show me the content of README.md in the main branch"
Boards & Sprints
- "List boards for the terraform-modules team"
- "What are the columns on the Sprint board?"
- "Show iterations for the team"
🔧 Development
Server Development
- The server is written in TypeScript and uses the
@modelcontextprotocol/sdkpackage. - To modify tools, edit
server/src/index.ts. - To change Azure DevOps API interactions, edit
server/src/azure-devops-client.ts. - Rebuild with
cd server && npm run build.
Frontend Development
- The frontend uses Next.js 14 with App Router and Tailwind CSS.
- Components are located in
frontend/components/. - The main chat interface is in
frontend/app/page.tsx. - Run frontend development server with
cd frontend && npm run dev.
Adding New Tools
- Add a new tool definition to the
toolsarray inserver/src/index.ts. - Implement the corresponding method in
server/src/azure-devops-client.ts. - Add a case in the MCP CallTool handler switch.
- Add a case in the HTTP API endpoint switch.
- Add a case in the chat completion endpoint switch.
- Test the tool via HTTP POST or the frontend.
🚢 Deployment
Server Deployment
Build the server for production:
cd server
npm run build
The output will be in server/dist/. You can run it with:
node dist/index.js
Set environment variables on your production server.
Frontend Deployment
Build the frontend:
cd frontend
npm run build
You can deploy the frontend/.next directory to Vercel, Netlify, or any static hosting.
Docker Deployment
A Dockerfile can be created to containerize both server and frontend.
🔒 Environment Variables
See .env.example for all available variables.
| Variable | Description | Required |
|---|---|---|
AZURE_DEVOPS_ORG_URL |
Your Azure DevOps organization URL (e.g., https://dev.azure.com/your-org) |
Yes |
AZURE_DEVOPS_PAT |
Personal Access Token with appropriate permissions | Yes |
AZURE_DEVOPS_PROJECT |
Default project name | Yes |
PORT |
HTTP server port (default 3001) |
No |
NEXT_PUBLIC_API_URL |
Frontend API URL (default http://localhost:3001) |
No |
AZURE_OPENAI_API_KEY |
Azure OpenAI API key | No (required for chat) |
AZURE_OPENAI_ENDPOINT |
Azure OpenAI endpoint | No |
AZURE_OPENAI_API_VERSION |
API version | No |
AZURE_OPENAI_DEPLOYMENT_NAME |
Deployment name (e.g., gpt-4) |
No |
🛠️ Troubleshooting
- Server fails to start: Check that
.envfile exists in the root directory with correct Azure DevOps credentials. - Frontend cannot connect to server: Ensure
NEXT_PUBLIC_API_URLmatches the server's port (defaulthttp://localhost:3001). - Azure DevOps API errors: Verify your PAT has sufficient permissions (read access to projects, work items, builds, releases, etc.).
- OpenAI function calling not working: Ensure Azure OpenAI credentials are set and the deployment is active.
- Tool returns empty results: The Azure DevOps API may have no data; check your project/team names.
☕ Support the Developers
If you find this project helpful and would like to support our work, consider buying me a coffee!
Your support helps me continue creating open-source tools and improving this project!
👨💻 About the Developers
Promise Uche Nwachukwu Microsoft MVP (AI & Azure) | DevOps/AI Engineer | Open Source Contributor
Damilola Onadeinde DevOps/AI Engineer | Cloud Infrastructure Specialist | Open Source Contributor
Connect with me:
- GitHub: @promiseuche
- LinkedIn: Promise Uche Nwachukwu
- YouTube: esimorphs
📝 License
MIT License - feel free to use for personal or commercial projects.
🆘 Support
For issues or questions:
- Check the troubleshooting section above.
- Review Azure DevOps REST API documentation.
- Verify Azure OpenAI service status.
- Check server logs for detailed error messages.
🎉 What's Next?
- Add support for Azure DevOps Analytics queries.
- Implement real-time notifications (webhooks).
- Add more tools (test runs, approvals, permissions).
- Enhanced UI with charts and dashboards.
- Multi‑organization support.
- Export functionality for query results.
Built with ❤️ Promise Uche Nwachukwu In Collaboration With Damilola Onadeinde | Support our work