Skip to main content
Glama

Azure DevOps MCP Server

feature.ts4.5 kB
import { WebApi } from 'azure-devops-node-api'; import axios from 'axios'; import { DefaultAzureCredential, AzureCliCredential } from '@azure/identity'; import { AzureDevOpsError, AzureDevOpsAuthenticationError, AzureDevOpsValidationError, } from '../../../shared/errors'; import { UserProfile } from '../types'; /** * Get details of the currently authenticated user * * This function returns basic profile information about the authenticated user. * * @param connection The Azure DevOps WebApi connection * @returns User profile information including id, displayName, and email * @throws {AzureDevOpsError} If retrieval of user information fails */ export async function getMe(connection: WebApi): Promise<UserProfile> { try { // Extract organization from the connection URL const { organization } = extractOrgFromUrl(connection.serverUrl); // Get the authorization header const authHeader = await getAuthorizationHeader(); // Make direct call to the Profile API endpoint // Note: This API is in the vssps.dev.azure.com domain, not dev.azure.com const response = await axios.get( `https://vssps.dev.azure.com/${organization}/_apis/profile/profiles/me?api-version=7.1`, { headers: { Authorization: authHeader, 'Content-Type': 'application/json', }, }, ); const profile = response.data; // Return the user profile with required fields return { id: profile.id, displayName: profile.displayName || '', email: profile.emailAddress || '', }; } catch (error) { // Handle authentication errors if ( axios.isAxiosError(error) && (error.response?.status === 401 || error.response?.status === 403) ) { throw new AzureDevOpsAuthenticationError( `Authentication failed: ${error.message}`, ); } // If it's already an AzureDevOpsError, rethrow it if (error instanceof AzureDevOpsError) { throw error; } // Otherwise, wrap it in a generic error throw new AzureDevOpsError( `Failed to get user information: ${error instanceof Error ? error.message : String(error)}`, ); } } /** * Extract organization from the Azure DevOps URL * * @param url The Azure DevOps URL * @returns The organization */ function extractOrgFromUrl(url: string): { organization: string } { // First try modern dev.azure.com format let match = url.match(/https?:\/\/dev\.azure\.com\/([^/]+)/); // If not found, try legacy visualstudio.com format if (!match) { match = url.match(/https?:\/\/([^.]+)\.visualstudio\.com/); } // Fallback: capture the first path segment for any URL if (!match) { match = url.match(/https?:\/\/[^/]+\/([^/]+)/); } const organization = match ? match[1] : ''; if (!organization) { throw new AzureDevOpsValidationError( 'Could not extract organization from URL', ); } return { organization, }; } /** * Get the authorization header for API requests * * @returns The authorization header */ async function getAuthorizationHeader(): Promise<string> { try { // For PAT authentication, we can construct the header directly if ( process.env.AZURE_DEVOPS_AUTH_METHOD?.toLowerCase() === 'pat' && process.env.AZURE_DEVOPS_PAT ) { // For PAT auth, we can construct the Basic auth header directly const token = process.env.AZURE_DEVOPS_PAT; const base64Token = Buffer.from(`:${token}`).toString('base64'); return `Basic ${base64Token}`; } // For Azure Identity / Azure CLI auth, we need to get a token // using the Azure DevOps resource ID // Choose the appropriate credential based on auth method const credential = process.env.AZURE_DEVOPS_AUTH_METHOD?.toLowerCase() === 'azure-cli' ? new AzureCliCredential() : new DefaultAzureCredential(); // Azure DevOps resource ID for token acquisition const AZURE_DEVOPS_RESOURCE_ID = '499b84ac-1321-427f-aa17-267ca6975798'; // Get token for Azure DevOps const token = await credential.getToken( `${AZURE_DEVOPS_RESOURCE_ID}/.default`, ); if (!token || !token.token) { throw new Error('Failed to acquire token for Azure DevOps'); } return `Bearer ${token.token}`; } catch (error) { throw new AzureDevOpsAuthenticationError( `Failed to get authorization header: ${error instanceof Error ? error.message : String(error)}`, ); } }

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/Tiberriver256/mcp-server-azure-devops'

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