Skip to main content
Glama
Tiberriver256

Azure DevOps MCP Server

download_pipeline_artifact

Retrieve text content from Azure DevOps pipeline artifacts by specifying the run ID and file path within the artifact.

Instructions

Download a file from a pipeline run artifact and return its textual content

Input Schema

TableJSON Schema
NameRequiredDescriptionDefault
projectIdNoThe ID or name of the project (Default: MyProject)
runIdYesPipeline run identifier
artifactPathYesPath to the desired file inside the artifact (format: <artifactName>/<path/to/file>)
pipelineIdNoOptional guard; validates the run belongs to this pipeline

Implementation Reference

  • Core handler function that orchestrates downloading a specific file from a pipeline run's artifact using Azure DevOps Build and Pipelines APIs, handling both container and zip-based artifacts.
    export async function downloadPipelineArtifact(
      connection: WebApi,
      options: DownloadPipelineArtifactOptions,
    ): Promise<PipelineArtifactContent> {
      try {
        const projectId = options.projectId ?? defaultProject;
        const runId = options.runId;
        const { artifactName, relativePath } = normalizeArtifactPath(
          options.artifactPath,
        );
    
        const buildApi = await connection.getBuildApi();
    
        let artifacts: BuildArtifact[];
        try {
          artifacts = await buildApi.getArtifacts(projectId, runId);
        } catch (error) {
          throw new AzureDevOpsResourceNotFoundError(
            `Pipeline run ${runId} not found in project ${projectId}: ${String(error)}`,
          );
        }
    
        const artifact = artifacts.find((item) => item.name === artifactName);
        if (!artifact) {
          throw new AzureDevOpsResourceNotFoundError(
            `Artifact ${artifactName} not found for run ${runId} in project ${projectId}.`,
          );
        }
    
        const containerResult = await downloadFromContainer(
          connection,
          projectId,
          artifactName,
          artifact,
          relativePath,
        );
    
        if (containerResult) {
          return containerResult;
        }
    
        return await downloadFromPipelineArtifact(
          connection,
          projectId,
          runId,
          artifactName,
          artifact,
          relativePath,
          options.pipelineId,
        );
      } 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 artifact or project not found: ${error.message}`,
            );
          }
        }
    
        throw new AzureDevOpsError(
          `Failed to download pipeline artifact: ${
            error instanceof Error ? error.message : String(error)
          }`,
        );
      }
    }
  • Zod schema defining the input parameters for the download_pipeline_artifact tool.
    export const DownloadPipelineArtifactSchema = 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'),
      artifactPath: z
        .string()
        .min(1)
        .describe(
          'Path to the desired file inside the artifact (format: <artifactName>/<path/to/file>)',
        ),
      pipelineId: z
        .number()
        .int()
        .min(1)
        .optional()
        .describe('Optional guard; validates the run belongs to this pipeline'),
    });
  • Tool definition registration including name, description, and input schema.
    {
      name: 'download_pipeline_artifact',
      description:
        'Download a file from a pipeline run artifact and return its textual content',
      inputSchema: zodToJsonSchema(DownloadPipelineArtifactSchema),
      mcp_enabled: true,
    },
  • Request handler switch case that parses arguments with the schema and invokes the downloadPipelineArtifact handler.
    case 'download_pipeline_artifact': {
      const args = DownloadPipelineArtifactSchema.parse(
        request.params.arguments,
      );
      const result = await downloadPipelineArtifact(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