list_organizations
Retrieve a list of all Azure DevOps organizations you have access to, enabling quick identification and selection for further management actions.
Instructions
List all Azure DevOps organizations accessible to the current authentication
Input Schema
| Name | Required | Description | Default |
|---|---|---|---|
No arguments | |||
Implementation Reference
- The main handler function `listOrganizations` that executes the tool logic. It authenticates (PAT or Azure Identity), fetches user profile, retrieves organizations via the Azure DevOps REST API, and returns transformed Organization objects.
export async function listOrganizations( config: AzureDevOpsConfig, ): Promise<Organization[]> { try { if (!isAzureDevOpsServicesUrl(config.organizationUrl)) { throw new AzureDevOpsValidationError( 'The list_organizations endpoint is only available for Azure DevOps Services', ); } // Determine auth method and create appropriate authorization header let authHeader: string; if (config.authMethod === AuthenticationMethod.PersonalAccessToken) { // PAT authentication if (!config.personalAccessToken) { throw new AzureDevOpsAuthenticationError( 'Personal Access Token (PAT) is required when using PAT authentication', ); } authHeader = createBasicAuthHeader(config.personalAccessToken); } else { // Azure Identity authentication (DefaultAzureCredential or AzureCliCredential) const credential = config.authMethod === AuthenticationMethod.AzureCli ? new AzureCliCredential() : new DefaultAzureCredential(); const token = await credential.getToken( `${AZURE_DEVOPS_RESOURCE_ID}/.default`, ); if (!token || !token.token) { throw new AzureDevOpsAuthenticationError( 'Failed to acquire Azure Identity token', ); } authHeader = `Bearer ${token.token}`; } // Step 1: Get the user profile to get the publicAlias const profileResponse = await axios.get( 'https://app.vssps.visualstudio.com/_apis/profile/profiles/me?api-version=6.0', { headers: { Authorization: authHeader, 'Content-Type': 'application/json', }, }, ); // Extract the publicAlias const publicAlias = profileResponse.data.publicAlias; if (!publicAlias) { throw new AzureDevOpsAuthenticationError( 'Unable to get user publicAlias from profile', ); } // Step 2: Get organizations using the publicAlias const orgsResponse = await axios.get( `https://app.vssps.visualstudio.com/_apis/accounts?memberId=${publicAlias}&api-version=6.0`, { headers: { Authorization: authHeader, 'Content-Type': 'application/json', }, }, ); // Define the shape of the API response interface AzureDevOpsOrganization { accountId: string; accountName: string; accountUri: string; } // Transform the response return orgsResponse.data.value.map((org: AzureDevOpsOrganization) => ({ id: org.accountId, name: org.accountName, url: org.accountUri, })); } catch (error) { // Handle profile API errors as authentication errors if (axios.isAxiosError(error) && error.config?.url?.includes('profile')) { throw new AzureDevOpsAuthenticationError( `Authentication failed: ${error.toJSON()}`, ); } else if ( error instanceof Error && (error.message.includes('profile') || error.message.includes('Unauthorized') || error.message.includes('Authentication')) ) { throw new AzureDevOpsAuthenticationError( `Authentication failed: ${error.message}`, ); } if (error instanceof AzureDevOpsError) { throw error; } throw new AzureDevOpsAuthenticationError( `Failed to list organizations: ${error instanceof Error ? error.message : String(error)}`, ); } } - Zod schema `ListOrganizationsSchema` - an empty object schema since list_organizations requires no input parameters.
import { z } from 'zod'; /** * Schema for the list organizations request * Note: This is an empty schema because the operation doesn't require any parameters */ export const ListOrganizationsSchema = z.object({}); - src/features/organizations/tool-definitions.ts:8-15 (registration)Tool definition registration for `list_organizations` with name, description, and JSON Schema input schema.
export const organizationsTools: ToolDefinition[] = [ { name: 'list_organizations', description: 'List all Azure DevOps organizations accessible to the current authentication', inputSchema: zodToJsonSchema(ListOrganizationsSchema), }, ]; - src/features/organizations/index.ts:24-62 (registration)Request routing: `isOrganizationsRequest` checks if the tool name matches 'list_organizations', and `handleOrganizationsRequest` dispatches to the handler, building the config from environment variables.
export const isOrganizationsRequest: RequestIdentifier = ( request: CallToolRequest, ): boolean => { const toolName = request.params.name; return ['list_organizations'].includes(toolName); }; /** * Handles organizations feature requests */ export const handleOrganizationsRequest: RequestHandler = async ( connection: WebApi, request: CallToolRequest, ): Promise<{ content: Array<{ type: string; text: string }> }> => { switch (request.params.name) { case 'list_organizations': { // Use environment variables for authentication method and PAT // This matches how other features handle authentication const config: AzureDevOpsConfig = { authMethod: process.env.AZURE_DEVOPS_AUTH_METHOD?.toLowerCase() === 'pat' ? AuthenticationMethod.PersonalAccessToken : process.env.AZURE_DEVOPS_AUTH_METHOD?.toLowerCase() === 'azure-cli' ? AuthenticationMethod.AzureCli : AuthenticationMethod.AzureIdentity, personalAccessToken: process.env.AZURE_DEVOPS_PAT, organizationUrl: connection.serverUrl || '', }; const result = await listOrganizations(config); return { content: [{ type: 'text', text: JSON.stringify(result, null, 2) }], }; } default: throw new Error(`Unknown organizations tool: ${request.params.name}`); } }; - Helper function `createBasicAuthHeader` that creates a Basic Auth header from a PAT.
function createBasicAuthHeader(pat: string): string { const token = Buffer.from(`:${pat}`).toString('base64'); return `Basic ${token}`; }