Skip to main content
Glama
Tiberriver256

Azure DevOps MCP Server

get_pipeline_run

Retrieve detailed information about a specific Azure DevOps pipeline run, including its status, configuration, and execution results.

Instructions

Get details for a specific pipeline run

Input Schema

TableJSON Schema
NameRequiredDescriptionDefault
projectIdNoThe ID or name of the project (Default: MyProject)
runIdYesPipeline run identifier
pipelineIdNoOptional guard; validates the run belongs to this pipeline

Implementation Reference

  • The core handler function that implements the logic for retrieving pipeline run details, including API calls, artifact fetching, and error handling.
    export async function getPipelineRun(
      connection: WebApi,
      options: GetPipelineRunOptions,
    ): Promise<PipelineRunDetails> {
      try {
        const pipelinesApi = await connection.getPipelinesApi();
        const projectId = options.projectId ?? defaultProject;
        const runId = options.runId;
        const resolvedPipelineId = await resolvePipelineId(
          connection,
          projectId,
          runId,
          options.pipelineId,
        );
    
        const baseUrl = connection.serverUrl.replace(/\/+$/, '');
        const encodedProject = encodeURIComponent(projectId);
    
        const requestOptions = pipelinesApi.createRequestOptions(
          'application/json',
          API_VERSION,
        );
    
        const buildRunUrl = (pipelineId?: number) => {
          const route =
            typeof pipelineId === 'number'
              ? `${encodedProject}/_apis/pipelines/${pipelineId}/runs/${runId}`
              : `${encodedProject}/_apis/pipelines/runs/${runId}`;
          const url = new URL(`${route}`, `${baseUrl}/`);
          url.searchParams.set('api-version', API_VERSION);
          return url;
        };
    
        const urlsToTry: URL[] = [];
        if (typeof resolvedPipelineId === 'number') {
          urlsToTry.push(buildRunUrl(resolvedPipelineId));
        }
        urlsToTry.push(buildRunUrl());
    
        let response: {
          statusCode: number;
          result: PipelineRunDetails | null;
        } | null = null;
    
        for (const url of urlsToTry) {
          const attempt = await pipelinesApi.rest.get<PipelineRunDetails | null>(
            url.toString(),
            requestOptions,
          );
    
          if (attempt.statusCode !== 404 && attempt.result) {
            response = attempt;
            break;
          }
        }
    
        if (!response || !response.result) {
          throw new AzureDevOpsResourceNotFoundError(
            `Pipeline run ${runId} not found in project ${projectId}`,
          );
        }
    
        const run = pipelinesApi.formatResponse(
          response.result,
          TypeInfo.Run,
          false,
        ) as PipelineRunDetails;
    
        if (!run) {
          throw new AzureDevOpsResourceNotFoundError(
            `Pipeline run ${runId} not found in project ${projectId}`,
          );
        }
    
        const artifacts = await fetchRunArtifacts(
          connection,
          projectId,
          runId,
          resolvedPipelineId,
        );
    
        if (typeof options.pipelineId === 'number') {
          const runPipelineId = coercePipelineId(run.pipeline?.id);
          if (runPipelineId !== options.pipelineId) {
            throw new AzureDevOpsResourceNotFoundError(
              `Run ${runId} does not belong to pipeline ${options.pipelineId}`,
            );
          }
        }
    
        return artifacts.length > 0 ? { ...run, artifacts } : run;
      } catch (error) {
        if (error instanceof AzureDevOpsError) {
          throw error;
        }
    
        if (error instanceof Error) {
          const message = error.message.toLowerCase();
          if (
            message.includes('authentication') ||
            message.includes('unauthorized') ||
            message.includes('401')
          ) {
            throw new AzureDevOpsAuthenticationError(
              `Failed to authenticate: ${error.message}`,
            );
          }
    
          if (
            message.includes('not found') ||
            message.includes('does not exist') ||
            message.includes('404')
          ) {
            throw new AzureDevOpsResourceNotFoundError(
              `Pipeline run or project not found: ${error.message}`,
            );
          }
        }
    
        throw new AzureDevOpsError(
          `Failed to get pipeline run: ${
            error instanceof Error ? error.message : String(error)
          }`,
        );
      }
    }
  • Zod schema defining the input parameters for the get_pipeline_run tool.
    export const GetPipelineRunSchema = z.object({
      projectId: z
        .string()
        .optional()
        .describe(`The ID or name of the project (Default: ${defaultProject})`),
      runId: z.number().int().min(1).describe('Pipeline run identifier'),
      pipelineId: z
        .number()
        .int()
        .min(1)
        .optional()
        .describe('Optional guard; validates the run belongs to this pipeline'),
    });
  • Tool registration definition including name, description, and input schema conversion for MCP.
    {
      name: 'get_pipeline_run',
      description: 'Get details for a specific pipeline run',
      inputSchema: zodToJsonSchema(GetPipelineRunSchema),
      mcp_enabled: true,
    },
  • Request handler switch case that invokes the getPipelineRun handler after schema validation.
    case 'get_pipeline_run': {
      const args = GetPipelineRunSchema.parse(request.params.arguments);
      const result = await getPipelineRun(connection, {
        ...args,
        projectId: args.projectId ?? defaultProject,
      });
      return {
        content: [{ type: 'text', text: JSON.stringify(result, null, 2) }],
      };
    }

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

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