Skip to main content
Glama
Tiberriver256

Azure DevOps MCP Server

list_pull_requests

Retrieve pull requests from Azure DevOps repositories with filters for status, creator, reviewer, branches, and pagination to manage code review workflows.

Instructions

List pull requests in a repository

Input Schema

TableJSON Schema
NameRequiredDescriptionDefault
projectIdNoThe ID or name of the project (Default: MyProject)
organizationIdNoThe ID or name of the organization (Default: mycompany)
repositoryIdYesThe ID or name of the repository
statusNoFilter by pull request status
creatorIdNoFilter by creator ID (must be a UUID string)
reviewerIdNoFilter by reviewer ID (must be a UUID string)
sourceRefNameNoFilter by source branch name
targetRefNameNoFilter by target branch name
topNoMaximum number of pull requests to return (default: 10)
skipNoNumber of pull requests to skip for pagination
pullRequestIdNoIf provided, return only the matching pull request ID

Implementation Reference

  • The core handler function that implements the logic to list pull requests using the Azure DevOps Git API, including filtering by status, creator, reviewer, branches, pagination with top/skip, and single PR lookup by ID.
    export async function listPullRequests(
      connection: WebApi,
      projectId: string,
      repositoryId: string,
      options: ListPullRequestsOptions,
    ): Promise<{
      count: number;
      value: PullRequest[];
      hasMoreResults: boolean;
      warning?: string;
    }> {
      try {
        const gitApi = await connection.getGitApi();
    
        if (options.pullRequestId !== undefined) {
          const pullRequest = await gitApi.getPullRequest(
            repositoryId,
            options.pullRequestId,
            projectId,
          );
    
          const value = pullRequest ? [pullRequest] : [];
          return {
            count: value.length,
            value,
            hasMoreResults: false,
            warning: undefined,
          };
        }
    
        // Create search criteria
        const searchCriteria: GitPullRequestSearchCriteria = {};
    
        // Add filters if provided
        if (options.status) {
          // Map our status enum to Azure DevOps PullRequestStatus
          switch (options.status) {
            case 'active':
              searchCriteria.status = PullRequestStatus.Active;
              break;
            case 'abandoned':
              searchCriteria.status = PullRequestStatus.Abandoned;
              break;
            case 'completed':
              searchCriteria.status = PullRequestStatus.Completed;
              break;
            case 'all':
              // Don't set status to get all
              break;
          }
        }
    
        if (options.creatorId) {
          searchCriteria.creatorId = options.creatorId;
        }
    
        if (options.reviewerId) {
          searchCriteria.reviewerId = options.reviewerId;
        }
    
        if (options.sourceRefName) {
          searchCriteria.sourceRefName = options.sourceRefName;
        }
    
        if (options.targetRefName) {
          searchCriteria.targetRefName = options.targetRefName;
        }
    
        // Set default values for pagination
        const top = options.top ?? 10;
        const skip = options.skip ?? 0;
    
        // List pull requests with search criteria
        const pullRequests = await gitApi.getPullRequests(
          repositoryId,
          searchCriteria,
          projectId,
          undefined, // maxCommentLength
          skip,
          top,
        );
    
        const results = pullRequests || [];
        const count = results.length;
    
        // Determine if there are likely more results
        // If we got exactly the number requested, there are probably more
        const hasMoreResults = count === top;
    
        // Add a warning message if results were truncated
        let warning: string | undefined;
        if (hasMoreResults) {
          warning = `Results limited to ${top} items. Use 'skip: ${skip + top}' to get the next page.`;
        }
    
        return {
          count,
          value: results,
          hasMoreResults,
          warning,
        };
      } catch (error) {
        if (error instanceof AzureDevOpsError) {
          throw error;
        }
        throw new Error(
          `Failed to list pull requests: ${error instanceof Error ? error.message : String(error)}`,
        );
      }
    }
  • Zod schema defining the input parameters for the list_pull_requests tool, including projectId, repositoryId, filters like status, creatorId, pagination options.
    export const ListPullRequestsSchema = z.object({
      projectId: z
        .string()
        .optional()
        .describe(`The ID or name of the project (Default: ${defaultProject})`),
      organizationId: z
        .string()
        .optional()
        .describe(`The ID or name of the organization (Default: ${defaultOrg})`),
      repositoryId: z.string().describe('The ID or name of the repository'),
      status: z
        .enum(['all', 'active', 'completed', 'abandoned'])
        .optional()
        .describe('Filter by pull request status'),
      creatorId: z
        .string()
        .optional()
        .describe('Filter by creator ID (must be a UUID string)'),
      reviewerId: z
        .string()
        .optional()
        .describe('Filter by reviewer ID (must be a UUID string)'),
      sourceRefName: z.string().optional().describe('Filter by source branch name'),
      targetRefName: z.string().optional().describe('Filter by target branch name'),
      top: z
        .number()
        .default(10)
        .describe('Maximum number of pull requests to return (default: 10)'),
      skip: z
        .number()
        .optional()
        .describe('Number of pull requests to skip for pagination'),
      pullRequestId: z
        .number()
        .optional()
        .describe('If provided, return only the matching pull request ID'),
    });
  • Tool definition registration in the pullRequestsTools array, specifying name, description, and input JSON schema for MCP tool discovery.
    {
      name: 'list_pull_requests',
      description: 'List pull requests in a repository',
      inputSchema: zodToJsonSchema(ListPullRequestsSchema),
    },
  • Request handler switch case that parses arguments with schema and invokes the listPullRequests handler function.
    case 'list_pull_requests': {
      const params = ListPullRequestsSchema.parse(request.params.arguments);
      const result = await listPullRequests(
        connection,
        params.projectId ?? defaultProject,
        params.repositoryId,
        {
          projectId: params.projectId ?? defaultProject,
          repositoryId: params.repositoryId,
          status: params.status,
          creatorId: params.creatorId,
          reviewerId: params.reviewerId,
          sourceRefName: params.sourceRefName,
          targetRefName: params.targetRefName,
          top: params.top,
          skip: params.skip,
          pullRequestId: params.pullRequestId,
        },
      );
      return {
        content: [{ type: 'text', text: JSON.stringify(result, null, 2) }],
      };
  • TypeScript interface defining the options parameter for the listPullRequests handler function.
    export interface ListPullRequestsOptions {
      projectId: string;
      repositoryId: string;
      status?: 'all' | 'active' | 'completed' | 'abandoned';
      creatorId?: string;
      reviewerId?: string;
      sourceRefName?: string;
      targetRefName?: string;
      top?: number;
      skip?: number;
      pullRequestId?: number;
    }
Behavior2/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

No annotations are provided, so the description carries full burden but adds minimal behavioral context. It doesn't disclose if this is a read-only operation, how pagination works (beyond the 'top' and 'skip' parameters), rate limits, authentication needs, or what the output format looks like (no output schema). The description is too basic for a tool with 11 parameters.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is a single, efficient sentence with zero waste. It's appropriately sized and front-loaded, stating the core purpose without unnecessary elaboration, earning its place as a concise definition.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness2/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

Given the tool's complexity (11 parameters, no annotations, no output schema), the description is incomplete. It doesn't address behavioral aspects like pagination, return format, or error handling, and fails to differentiate from sibling tools. For a list operation with rich filtering options, more context is needed to guide effective use.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 100%, so the schema fully documents all 11 parameters with descriptions, defaults, and enums. The description adds no additional meaning beyond the schema, such as explaining parameter interactions or usage examples. Baseline 3 is appropriate when the schema does all the work.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose3/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description 'List pull requests in a repository' clearly states the verb ('list') and resource ('pull requests'), but it's vague about scope and doesn't distinguish from siblings like 'get_pull_request_changes' or 'get_pull_request_comments'. It lacks specificity about what listing entails (e.g., returns metadata vs. full details).

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines2/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

No guidance is provided on when to use this tool versus alternatives. With many sibling tools like 'get_pull_request_changes' or 'search_code', the description doesn't indicate if this is for browsing all PRs, filtering, or pagination, leaving the agent to infer usage from parameters alone.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

Install Server

Other Tools

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