#
tokens: 15314/50000 1/281 files (page 8/8)
lines: on (toggle) GitHub
raw markdown copy reset
This is page 8 of 8. Use http://codebase.md/tiberriver256/azure-devops-mcp?lines=true&page={x} to view the full context.

# Directory Structure

```
├── .clinerules
├── .env.example
├── .eslintrc.json
├── .github
│   ├── FUNDING.yml
│   ├── release-please-config.json
│   ├── release-please-manifest.json
│   └── workflows
│       ├── main.yml
│       └── release-please.yml
├── .gitignore
├── .husky
│   ├── commit-msg
│   └── pre-commit
├── .kilocode
│   └── mcp.json
├── .prettierrc
├── .vscode
│   └── settings.json
├── CHANGELOG.md
├── commitlint.config.js
├── CONTRIBUTING.md
├── create_branch.sh
├── docs
│   ├── authentication.md
│   ├── azure-identity-authentication.md
│   ├── ci-setup.md
│   ├── examples
│   │   ├── azure-cli-authentication.env
│   │   ├── azure-identity-authentication.env
│   │   ├── pat-authentication.env
│   │   └── README.md
│   ├── testing
│   │   ├── README.md
│   │   └── setup.md
│   └── tools
│       ├── core-navigation.md
│       ├── organizations.md
│       ├── pipelines.md
│       ├── projects.md
│       ├── pull-requests.md
│       ├── README.md
│       ├── repositories.md
│       ├── resources.md
│       ├── search.md
│       ├── user-tools.md
│       ├── wiki.md
│       └── work-items.md
├── finish_task.sh
├── jest.e2e.config.js
├── jest.int.config.js
├── jest.unit.config.js
├── LICENSE
├── memory
│   └── tasks_memory_2025-05-26T16-18-03.json
├── package-lock.json
├── package.json
├── project-management
│   ├── planning
│   │   ├── architecture-guide.md
│   │   ├── azure-identity-authentication-design.md
│   │   ├── project-plan.md
│   │   ├── project-structure.md
│   │   ├── tech-stack.md
│   │   └── the-dream-team.md
│   ├── startup.xml
│   ├── tdd-cycle.xml
│   └── troubleshooter.xml
├── README.md
├── setup_env.sh
├── shrimp-rules.md
├── src
│   ├── clients
│   │   └── azure-devops.ts
│   ├── features
│   │   ├── organizations
│   │   │   ├── __test__
│   │   │   │   └── test-helpers.ts
│   │   │   ├── index.spec.unit.ts
│   │   │   ├── index.ts
│   │   │   ├── list-organizations
│   │   │   │   ├── feature.spec.int.ts
│   │   │   │   ├── feature.spec.unit.ts
│   │   │   │   ├── feature.ts
│   │   │   │   ├── index.ts
│   │   │   │   └── schema.ts
│   │   │   ├── schemas.ts
│   │   │   ├── tool-definitions.ts
│   │   │   └── types.ts
│   │   ├── pipelines
│   │   │   ├── get-pipeline
│   │   │   │   ├── feature.spec.int.ts
│   │   │   │   ├── feature.spec.unit.ts
│   │   │   │   ├── feature.ts
│   │   │   │   ├── index.ts
│   │   │   │   └── schema.ts
│   │   │   ├── index.spec.unit.ts
│   │   │   ├── index.ts
│   │   │   ├── list-pipelines
│   │   │   │   ├── feature.spec.int.ts
│   │   │   │   ├── feature.spec.unit.ts
│   │   │   │   ├── feature.ts
│   │   │   │   ├── index.ts
│   │   │   │   └── schema.ts
│   │   │   ├── tool-definitions.ts
│   │   │   ├── trigger-pipeline
│   │   │   │   ├── feature.spec.int.ts
│   │   │   │   ├── feature.spec.unit.ts
│   │   │   │   ├── feature.ts
│   │   │   │   ├── index.ts
│   │   │   │   └── schema.ts
│   │   │   └── types.ts
│   │   ├── projects
│   │   │   ├── __test__
│   │   │   │   └── test-helpers.ts
│   │   │   ├── get-project
│   │   │   │   ├── feature.spec.int.ts
│   │   │   │   ├── feature.spec.unit.ts
│   │   │   │   ├── feature.ts
│   │   │   │   ├── index.ts
│   │   │   │   └── schema.ts
│   │   │   ├── get-project-details
│   │   │   │   ├── feature.spec.int.ts
│   │   │   │   ├── feature.spec.unit.ts
│   │   │   │   ├── feature.ts
│   │   │   │   ├── index.ts
│   │   │   │   └── schema.ts
│   │   │   ├── index.spec.unit.ts
│   │   │   ├── index.ts
│   │   │   ├── list-projects
│   │   │   │   ├── feature.spec.int.ts
│   │   │   │   ├── feature.ts
│   │   │   │   ├── index.ts
│   │   │   │   └── schema.ts
│   │   │   ├── schemas.ts
│   │   │   ├── tool-definitions.ts
│   │   │   └── types.ts
│   │   ├── pull-requests
│   │   │   ├── add-pull-request-comment
│   │   │   │   ├── feature.spec.int.ts
│   │   │   │   ├── feature.spec.unit.ts
│   │   │   │   ├── feature.ts
│   │   │   │   └── index.ts
│   │   │   ├── create-pull-request
│   │   │   │   ├── feature.spec.int.ts
│   │   │   │   ├── feature.spec.unit.ts
│   │   │   │   ├── feature.ts
│   │   │   │   ├── index.ts
│   │   │   │   └── schema.ts
│   │   │   ├── get-pull-request-comments
│   │   │   │   ├── feature.spec.int.ts
│   │   │   │   ├── feature.spec.unit.ts
│   │   │   │   ├── feature.ts
│   │   │   │   └── index.ts
│   │   │   ├── index.spec.unit.ts
│   │   │   ├── index.ts
│   │   │   ├── list-pull-requests
│   │   │   │   ├── feature.spec.int.ts
│   │   │   │   ├── feature.spec.unit.ts
│   │   │   │   ├── feature.ts
│   │   │   │   ├── index.ts
│   │   │   │   └── schema.ts
│   │   │   ├── schemas.ts
│   │   │   ├── tool-definitions.ts
│   │   │   ├── types.ts
│   │   │   └── update-pull-request
│   │   │       ├── feature.spec.int.ts
│   │   │       ├── feature.spec.unit.ts
│   │   │       ├── feature.ts
│   │   │       └── index.ts
│   │   ├── repositories
│   │   │   ├── __test__
│   │   │   │   └── test-helpers.ts
│   │   │   ├── get-all-repositories-tree
│   │   │   │   ├── __snapshots__
│   │   │   │   │   └── feature.spec.unit.ts.snap
│   │   │   │   ├── feature.spec.int.ts
│   │   │   │   ├── feature.spec.unit.ts
│   │   │   │   ├── feature.ts
│   │   │   │   ├── index.ts
│   │   │   │   └── schema.ts
│   │   │   ├── get-file-content
│   │   │   │   ├── feature.spec.int.ts
│   │   │   │   ├── feature.spec.unit.ts
│   │   │   │   ├── feature.ts
│   │   │   │   ├── index.ts
│   │   │   │   └── schema.ts
│   │   │   ├── get-repository
│   │   │   │   ├── feature.spec.int.ts
│   │   │   │   ├── feature.spec.unit.ts
│   │   │   │   ├── feature.ts
│   │   │   │   ├── index.ts
│   │   │   │   └── schema.ts
│   │   │   ├── get-repository-details
│   │   │   │   ├── feature.spec.int.ts
│   │   │   │   ├── feature.spec.unit.ts
│   │   │   │   ├── feature.ts
│   │   │   │   ├── index.ts
│   │   │   │   └── schema.ts
│   │   │   ├── index.spec.unit.ts
│   │   │   ├── index.ts
│   │   │   ├── list-repositories
│   │   │   │   ├── feature.spec.int.ts
│   │   │   │   ├── feature.spec.unit.ts
│   │   │   │   ├── feature.ts
│   │   │   │   ├── index.ts
│   │   │   │   └── schema.ts
│   │   │   ├── schemas.ts
│   │   │   ├── tool-definitions.ts
│   │   │   └── types.ts
│   │   ├── search
│   │   │   ├── index.spec.unit.ts
│   │   │   ├── index.ts
│   │   │   ├── schemas.ts
│   │   │   ├── search-code
│   │   │   │   ├── feature.spec.int.ts
│   │   │   │   ├── feature.spec.unit.ts
│   │   │   │   ├── feature.ts
│   │   │   │   └── index.ts
│   │   │   ├── search-wiki
│   │   │   │   ├── feature.spec.int.ts
│   │   │   │   ├── feature.spec.unit.ts
│   │   │   │   ├── feature.ts
│   │   │   │   └── index.ts
│   │   │   ├── search-work-items
│   │   │   │   ├── feature.spec.int.ts
│   │   │   │   ├── feature.spec.unit.ts
│   │   │   │   ├── feature.ts
│   │   │   │   └── index.ts
│   │   │   ├── tool-definitions.ts
│   │   │   └── types.ts
│   │   ├── users
│   │   │   ├── get-me
│   │   │   │   ├── feature.spec.int.ts
│   │   │   │   ├── feature.spec.unit.ts
│   │   │   │   ├── feature.ts
│   │   │   │   ├── index.ts
│   │   │   │   └── schema.ts
│   │   │   ├── index.spec.unit.ts
│   │   │   ├── index.ts
│   │   │   ├── schemas.ts
│   │   │   ├── tool-definitions.ts
│   │   │   └── types.ts
│   │   ├── wikis
│   │   │   ├── create-wiki
│   │   │   │   ├── feature.spec.int.ts
│   │   │   │   ├── feature.spec.unit.ts
│   │   │   │   ├── feature.ts
│   │   │   │   ├── index.ts
│   │   │   │   └── schema.ts
│   │   │   ├── create-wiki-page
│   │   │   │   ├── feature.spec.int.ts
│   │   │   │   ├── feature.spec.unit.ts
│   │   │   │   ├── feature.ts
│   │   │   │   ├── index.ts
│   │   │   │   └── schema.ts
│   │   │   ├── get-wiki-page
│   │   │   │   ├── feature.spec.int.ts
│   │   │   │   ├── feature.spec.unit.ts
│   │   │   │   ├── feature.ts
│   │   │   │   ├── index.ts
│   │   │   │   └── schema.ts
│   │   │   ├── get-wikis
│   │   │   │   ├── feature.spec.int.ts
│   │   │   │   ├── feature.spec.unit.ts
│   │   │   │   ├── feature.ts
│   │   │   │   ├── index.ts
│   │   │   │   └── schema.ts
│   │   │   ├── index.spec.unit.ts
│   │   │   ├── index.ts
│   │   │   ├── list-wiki-pages
│   │   │   │   ├── feature.spec.int.ts
│   │   │   │   ├── feature.spec.unit.ts
│   │   │   │   ├── feature.ts
│   │   │   │   ├── index.ts
│   │   │   │   └── schema.ts
│   │   │   ├── tool-definitions.ts
│   │   │   └── update-wiki-page
│   │   │       ├── feature.spec.int.ts
│   │   │       ├── feature.ts
│   │   │       ├── index.ts
│   │   │       └── schema.ts
│   │   └── work-items
│   │       ├── __test__
│   │       │   ├── fixtures.ts
│   │       │   ├── test-helpers.ts
│   │       │   └── test-utils.ts
│   │       ├── create-work-item
│   │       │   ├── feature.spec.int.ts
│   │       │   ├── feature.spec.unit.ts
│   │       │   ├── feature.ts
│   │       │   ├── index.ts
│   │       │   └── schema.ts
│   │       ├── get-work-item
│   │       │   ├── feature.spec.int.ts
│   │       │   ├── feature.spec.unit.ts
│   │       │   ├── feature.ts
│   │       │   ├── index.ts
│   │       │   └── schema.ts
│   │       ├── index.spec.unit.ts
│   │       ├── index.ts
│   │       ├── list-work-items
│   │       │   ├── feature.spec.int.ts
│   │       │   ├── feature.spec.unit.ts
│   │       │   ├── feature.ts
│   │       │   ├── index.ts
│   │       │   └── schema.ts
│   │       ├── manage-work-item-link
│   │       │   ├── feature.spec.int.ts
│   │       │   ├── feature.spec.unit.ts
│   │       │   ├── feature.ts
│   │       │   ├── index.ts
│   │       │   └── schema.ts
│   │       ├── schemas.ts
│   │       ├── tool-definitions.ts
│   │       ├── types.ts
│   │       └── update-work-item
│   │           ├── feature.spec.int.ts
│   │           ├── feature.spec.unit.ts
│   │           ├── feature.ts
│   │           ├── index.ts
│   │           └── schema.ts
│   ├── index.spec.unit.ts
│   ├── index.ts
│   ├── server.spec.e2e.ts
│   ├── server.ts
│   ├── shared
│   │   ├── api
│   │   │   ├── client.ts
│   │   │   └── index.ts
│   │   ├── auth
│   │   │   ├── auth-factory.ts
│   │   │   ├── client-factory.ts
│   │   │   └── index.ts
│   │   ├── config
│   │   │   ├── index.ts
│   │   │   └── version.ts
│   │   ├── enums
│   │   │   ├── index.spec.unit.ts
│   │   │   └── index.ts
│   │   ├── errors
│   │   │   ├── azure-devops-errors.ts
│   │   │   ├── handle-request-error.ts
│   │   │   └── index.ts
│   │   ├── test
│   │   │   └── test-helpers.ts
│   │   └── types
│   │       ├── config.ts
│   │       ├── index.ts
│   │       ├── request-handler.ts
│   │       └── tool-definition.ts
│   └── utils
│       ├── environment.spec.unit.ts
│       └── environment.ts
├── tasks.json
├── tests
│   └── setup.ts
└── tsconfig.json
```

# Files

--------------------------------------------------------------------------------
/docs/tools/pull-requests.md:
--------------------------------------------------------------------------------

```markdown
  1 | # Azure DevOps Pull Requests Tools
  2 | 
  3 | This document describes the tools available for working with Azure DevOps Pull Requests.
  4 | 
  5 | ## create_pull_request
  6 | 
  7 | Creates a new pull request in a specific Git repository.
  8 | 
  9 | ### Description
 10 | 
 11 | The `create_pull_request` tool creates a new pull request in a specified Azure DevOps Git repository. It allows you to propose changes from a source branch to a target branch, add a title, description, reviewers, and link to work items. Pull requests are a key part of code review and collaboration workflows in Azure DevOps.
 12 | 
 13 | ### Parameters
 14 | 
 15 | ```json
 16 | {
 17 |   "projectId": "MyProject", // Required: The ID or name of the project
 18 |   "repositoryId": "MyRepo", // Required: The ID or name of the repository
 19 |   "title": "Update feature X", // Required: The title of the pull request
 20 |   "sourceRefName": "refs/heads/feature-branch", // Required: The source branch name
 21 |   "targetRefName": "refs/heads/main", // Required: The target branch name
 22 |   "description": "This PR implements feature X", // Optional: The description of the pull request
 23 |   "reviewers": ["[email protected]"], // Optional: List of reviewer email addresses or IDs
 24 |   "isDraft": true, // Optional: Whether the pull request should be created as a draft
 25 |   "workItemRefs": [123, 456] // Optional: List of work item IDs to link to the pull request
 26 | }
 27 | ```
 28 | 
 29 | | Parameter       | Type     | Required | Description                                                    |
 30 | | --------------- | -------- | -------- | -------------------------------------------------------------- |
 31 | | `projectId`     | string   | Yes      | The ID or name of the project containing the repository        |
 32 | | `repositoryId`  | string   | Yes      | The ID or name of the repository to create the pull request in |
 33 | | `title`         | string   | Yes      | The title of the pull request                                  |
 34 | | `sourceRefName` | string   | Yes      | The source branch name (e.g., "refs/heads/feature-branch")     |
 35 | | `targetRefName` | string   | Yes      | The target branch name (e.g., "refs/heads/main")               |
 36 | | `description`   | string   | No       | The description of the pull request                            |
 37 | | `reviewers`     | string[] | No       | List of reviewer email addresses or IDs                        |
 38 | | `isDraft`       | boolean  | No       | Whether the pull request should be created as a draft          |
 39 | | `workItemRefs`  | number[] | No       | List of work item IDs to link to the pull request              |
 40 | 
 41 | ### Response
 42 | 
 43 | The tool returns a `PullRequest` object containing:
 44 | 
 45 | - `pullRequestId`: The unique identifier of the created pull request
 46 | - `status`: The status of the pull request (active, abandoned, completed)
 47 | - `createdBy`: Information about the user who created the pull request
 48 | - `creationDate`: The date and time when the pull request was created
 49 | - `title`: The title of the pull request
 50 | - `description`: The description of the pull request
 51 | - `sourceRefName`: The source branch name
 52 | - `targetRefName`: The target branch name
 53 | - `mergeStatus`: The merge status of the pull request
 54 | - And various other fields and references
 55 | 
 56 | Example response:
 57 | 
 58 | ```json
 59 | {
 60 |   "repository": {
 61 |     "id": "repo-guid",
 62 |     "name": "MyRepo",
 63 |     "url": "https://dev.azure.com/organization/MyProject/_apis/git/repositories/MyRepo",
 64 |     "project": {
 65 |       "id": "project-guid",
 66 |       "name": "MyProject"
 67 |     }
 68 |   },
 69 |   "pullRequestId": 42,
 70 |   "codeReviewId": 42,
 71 |   "status": 1,
 72 |   "createdBy": {
 73 |     "displayName": "John Doe",
 74 |     "id": "user-guid",
 75 |     "uniqueName": "[email protected]"
 76 |   },
 77 |   "creationDate": "2023-01-01T12:00:00Z",
 78 |   "title": "Update feature X",
 79 |   "description": "This PR implements feature X",
 80 |   "sourceRefName": "refs/heads/feature-branch",
 81 |   "targetRefName": "refs/heads/main",
 82 |   "mergeStatus": 1,
 83 |   "isDraft": true,
 84 |   "reviewers": [
 85 |     {
 86 |       "displayName": "Jane Smith",
 87 |       "id": "reviewer-guid",
 88 |       "uniqueName": "[email protected]",
 89 |       "voteResult": 0
 90 |     }
 91 |   ],
 92 |   "url": "https://dev.azure.com/organization/MyProject/_apis/git/repositories/MyRepo/pullRequests/42"
 93 | }
 94 | ```
 95 | 
 96 | ### Error Handling
 97 | 
 98 | The tool may throw the following errors:
 99 | 
100 | - ValidationError: If required parameters are missing or invalid
101 | - AuthenticationError: If authentication fails
102 | - PermissionError: If the user doesn't have permission to create a pull request
103 | - ResourceNotFoundError: If the project, repository, or specified branches don't exist
104 | - GitError: For Git-related errors (e.g., conflicts, branch issues)
105 | - GeneralError: For other unexpected errors
106 | 
107 | Error messages will include details about what went wrong and suggestions for resolution.
108 | 
109 | ### Example Usage
110 | 
111 | ```typescript
112 | // Basic example - create a PR from feature branch to main
113 | const pr = await mcpClient.callTool('create_pull_request', {
114 |   projectId: 'MyProject',
115 |   repositoryId: 'MyRepo',
116 |   title: 'Add new feature',
117 |   sourceRefName: 'refs/heads/feature-branch',
118 |   targetRefName: 'refs/heads/main',
119 | });
120 | console.log(`Created PR #${pr.pullRequestId}: ${pr.url}`);
121 | 
122 | // Create a draft PR with description and reviewers
123 | const draftPr = await mcpClient.callTool('create_pull_request', {
124 |   projectId: 'MyProject',
125 |   repositoryId: 'MyRepo',
126 |   title: 'WIP: Refactor authentication code',
127 |   description:
128 |     '# Work in Progress\n\nRefactoring authentication code to use the new identity service.',
129 |   sourceRefName: 'refs/heads/auth-refactor',
130 |   targetRefName: 'refs/heads/develop',
131 |   isDraft: true,
132 |   reviewers: ['[email protected]', '[email protected]'],
133 | });
134 | console.log(`Created draft PR #${draftPr.pullRequestId}`);
135 | 
136 | // Create a PR linked to work items
137 | const linkedPr = await mcpClient.callTool('create_pull_request', {
138 |   projectId: 'MyProject',
139 |   repositoryId: 'MyRepo',
140 |   title: 'Fix bugs in payment processor',
141 |   sourceRefName: 'refs/heads/bugfix/payment',
142 |   targetRefName: 'refs/heads/main',
143 |   workItemRefs: [1234, 1235, 1236],
144 | });
145 | console.log(`Created PR #${linkedPr.pullRequestId} linked to work items`);
146 | ```
147 | 
148 | ## list_pull_requests
149 | 
150 | Lists pull requests in a specific Git repository with optional filtering.
151 | 
152 | ### Description
153 | 
154 | The `list_pull_requests` tool retrieves pull requests from a specified Azure DevOps Git repository. It supports filtering by status (active, completed, abandoned), creator, reviewer, and source/target branches. This tool is useful for monitoring code review progress, identifying pending PRs, and automating PR-related workflows.
155 | 
156 | ### Parameters
157 | 
158 | ```json
159 | {
160 |   "projectId": "MyProject", // Required: The ID or name of the project
161 |   "repositoryId": "MyRepo", // Required: The ID or name of the repository
162 |   "status": "active", // Optional: The status of pull requests to return (active, completed, abandoned, all)
163 |   "creatorId": "a8a8a8a8-a8a8-a8a8-a8a8-a8a8a8a8a8a8", // Optional: Filter by creator ID (must be a UUID)
164 |   "reviewerId": "b9b9b9b9-b9b9-b9b9-b9b9-b9b9b9b9b9b9", // Optional: Filter by reviewer ID (must be a UUID)
165 |   "sourceRefName": "refs/heads/feature-branch", // Optional: Filter by source branch name
166 |   "targetRefName": "refs/heads/main", // Optional: Filter by target branch name
167 |   "top": 10, // Optional: Maximum number of pull requests to return (default: 10)
168 |   "skip": 0 // Optional: Number of pull requests to skip for pagination
169 | }
170 | ```
171 | 
172 | | Parameter       | Type   | Required | Description                                                                         |
173 | | --------------- | ------ | -------- | ----------------------------------------------------------------------------------- |
174 | | `projectId`     | string | Yes      | The ID or name of the project containing the repository                             |
175 | | `repositoryId`  | string | Yes      | The ID or name of the repository to list pull requests from                         |
176 | | `status`        | string | No       | The status of pull requests to return: "active", "completed", "abandoned", or "all" |
177 | | `creatorId`     | string | No       | Filter pull requests by creator ID (must be a UUID)                                 |
178 | | `reviewerId`    | string | No       | Filter pull requests by reviewer ID (must be a UUID)                                |
179 | | `sourceRefName` | string | No       | Filter pull requests by source branch name                                          |
180 | | `targetRefName` | string | No       | Filter pull requests by target branch name                                          |
181 | | `top`           | number | No       | Maximum number of pull requests to return                                           |
182 | 
183 | ### Response
184 | 
185 | The tool returns an object containing:
186 | 
187 | - `count`: The number of pull requests returned
188 | - `value`: An array of `PullRequest` objects
189 | - `hasMoreResults`: A boolean indicating if there are more results available
190 | - `warning`: A message with pagination guidance (only present when hasMoreResults is true)
191 | 
192 | Each pull request in the `value` array contains:
193 | 
194 | - `pullRequestId`: The unique identifier of the pull request
195 | - `title`: The title of the pull request
196 | - `status`: The status of the pull request (active, abandoned, completed)
197 | - `createdBy`: Information about the user who created the pull request
198 | - `creationDate`: The date and time when the pull request was created
199 | - `sourceRefName`: The source branch name
200 | - `targetRefName`: The target branch name
201 | - And various other fields and references
202 | 
203 | Example response:
204 | 
205 | ```json
206 | {
207 |   "count": 2,
208 |   "value": [
209 |     {
210 |       "repository": {
211 |         "id": "repo-guid",
212 |         "name": "MyRepo",
213 |         "project": {
214 |           "id": "project-guid",
215 |           "name": "MyProject"
216 |         }
217 |       },
218 |       "pullRequestId": 42,
219 |       "codeReviewId": 42,
220 |       "status": 1,
221 |       "createdBy": {
222 |         "displayName": "John Doe",
223 |         "uniqueName": "[email protected]"
224 |       },
225 |       "creationDate": "2023-01-01T12:00:00Z",
226 |       "title": "Update feature X",
227 |       "description": "This PR implements feature X",
228 |       "sourceRefName": "refs/heads/feature-branch",
229 |       "targetRefName": "refs/heads/main",
230 |       "mergeStatus": 3,
231 |       "isDraft": false,
232 |       "url": "https://dev.azure.com/organization/MyProject/_apis/git/repositories/MyRepo/pullRequests/42"
233 |     },
234 |     {
235 |       "repository": {
236 |         "id": "repo-guid",
237 |         "name": "MyRepo",
238 |         "project": {
239 |           "id": "project-guid",
240 |           "name": "MyProject"
241 |         }
242 |       },
243 |       "pullRequestId": 43,
244 |       "codeReviewId": 43,
245 |       "status": 1,
246 |       "createdBy": {
247 |         "displayName": "Jane Smith",
248 |         "uniqueName": "[email protected]"
249 |       },
250 |       "creationDate": "2023-01-02T14:30:00Z",
251 |       "title": "Fix bug in login flow",
252 |       "description": "This PR fixes a critical bug in the login flow",
253 |       "sourceRefName": "refs/heads/bugfix/login",
254 |       "targetRefName": "refs/heads/main",
255 |       "mergeStatus": 3,
256 |       "isDraft": false,
257 |       "url": "https://dev.azure.com/organization/MyProject/_apis/git/repositories/MyRepo/pullRequests/43"
258 |     }
259 |   ],
260 |   "hasMoreResults": false
261 | }
262 | ```
263 | 
264 | ### Error Handling
265 | 
266 | The tool may throw the following errors:
267 | 
268 | - ValidationError: If required parameters are missing or invalid
269 | - AuthenticationError: If authentication fails
270 | - PermissionError: If the user doesn't have permission to list pull requests
271 | - ResourceNotFoundError: If the project or repository doesn't exist
272 | - GeneralError: For other unexpected errors
273 | 
274 | Error messages will include details about what went wrong and suggestions for resolution.
275 | 
276 | ### Example Usage
277 | 
278 | ```typescript
279 | // List all active pull requests in a repository
280 | const activePRs = await mcpClient.callTool('list_pull_requests', {
281 |   projectId: 'MyProject',
282 |   repositoryId: 'MyRepo',
283 |   status: 'active',
284 | });
285 | console.log(`Found ${activePRs.count} active pull requests`);
286 | 
287 | // List pull requests created by a specific user (using their UUID)
288 | const userPRs = await mcpClient.callTool('list_pull_requests', {
289 |   projectId: 'MyProject',
290 |   repositoryId: 'MyRepo',
291 |   creatorId: 'a8a8a8a8-a8a8-a8a8-a8a8-a8a8a8a8a8a8',
292 | });
293 | console.log(`Found ${userPRs.count} pull requests created by this user`);
294 | 
295 | // List pull requests targeting a specific branch
296 | const mainPRs = await mcpClient.callTool('list_pull_requests', {
297 |   projectId: 'MyProject',
298 |   repositoryId: 'MyRepo',
299 |   targetRefName: 'refs/heads/main',
300 | });
301 | console.log(`Found ${mainPRs.count} pull requests targeting main branch`);
302 | 
303 | // Paginate through pull requests
304 | const page1 = await mcpClient.callTool('list_pull_requests', {
305 |   projectId: 'MyProject',
306 |   repositoryId: 'MyRepo',
307 |   top: 10,
308 |   skip: 0,
309 | });
310 | 
311 | // Check if there are more results and get the next page
312 | let page2 = { count: 0, value: [] };
313 | if (page1.hasMoreResults) {
314 |   page2 = await mcpClient.callTool('list_pull_requests', {
315 |     projectId: 'MyProject',
316 |     repositoryId: 'MyRepo',
317 |     top: 10,
318 |     skip: 10,
319 |   });
320 | }
321 | 
322 | console.log(`Retrieved ${page1.count + page2.count} pull requests in 2 pages`);
323 | ```
324 | 
325 | ### Pagination
326 | 
327 | The `list_pull_requests` tool supports pagination to handle large result sets. By default, results are limited to 10 pull requests per request to prevent performance issues.
328 | 
329 | #### Pagination Parameters
330 | 
331 | - `top`: Maximum number of pull requests to return (default: 10)
332 | - `skip`: Number of pull requests to skip for pagination
333 | 
334 | #### Example: Paginating through all pull requests
335 | 
336 | ```typescript
337 | // Get first page (10 items)
338 | const firstPage = await mcpClient.callTool('list_pull_requests', {
339 |   projectId: 'MyProject',
340 |   repositoryId: 'MyRepo',
341 | });
342 | 
343 | // Check if there are more results
344 | if (firstPage.hasMoreResults) {
345 |   // Get second page
346 |   const secondPage = await mcpClient.callTool('list_pull_requests', {
347 |     projectId: 'MyProject',
348 |     repositoryId: 'MyRepo',
349 |     skip: 10,
350 |   });
351 | 
352 |   // Continue until no more results
353 |   if (secondPage.hasMoreResults) {
354 |     const thirdPage = await mcpClient.callTool('list_pull_requests', {
355 |       projectId: 'MyProject',
356 |       repositoryId: 'MyRepo',
357 |       skip: 20,
358 |     });
359 |   }
360 | }
361 | ```
362 | 
363 | #### Handling Large Repositories
364 | 
365 | When working with repositories that have many pull requests, it's recommended to use pagination to avoid performance issues. The `list_pull_requests` tool now limits results to 10 by default to prevent issues with very large responses.
366 | 
367 | If you need to process all pull requests, use the pagination pattern shown above to iterate through the results in manageable chunks.
368 | 
369 | ### Implementation Details
370 | 
371 | The `list_pull_requests` tool:
372 | 
373 | 1. Establishes a connection to Azure DevOps using the provided credentials
374 | 2. Retrieves the Git API client
375 | 3. Constructs a search criteria object based on the provided filters
376 | 4. Maps status strings to Azure DevOps PullRequestStatus enum values
377 | 5. Makes the API call to retrieve the pull requests with pagination parameters
378 | 6. Determines if there are more results available
379 | 7. Returns an enhanced response object with count, value, hasMoreResults, and warning
380 | 8. Handles errors and provides meaningful error messages
381 | 
382 | This implementation provides a robust and flexible way to retrieve pull requests from Azure DevOps repositories while preventing infinite loop issues.
383 | 
384 | ## get_pull_request_comments
385 | 
386 | Gets comments and comment threads from a specific pull request.
387 | 
388 | ### Description
389 | 
390 | The `get_pull_request_comments` tool retrieves comment threads and their associated comments from a specific pull request in an Azure DevOps Git repository. It allows you to get all comments or filter for a specific thread, and supports options for including deleted comments and limiting the number of results. This tool is useful for reviewing feedback on code changes, monitoring discussions, and integrating pull request comments into external workflows.
391 | 
392 | ### Parameters
393 | 
394 | ```json
395 | {
396 |   "projectId": "MyProject", // Required: The ID or name of the project
397 |   "repositoryId": "MyRepo", // Required: The ID or name of the repository
398 |   "pullRequestId": 42, // Required: The ID of the pull request
399 |   "threadId": 123, // Optional: The ID of a specific thread to retrieve
400 |   "includeDeleted": false, // Optional: Whether to include deleted comments
401 |   "top": 50 // Optional: Maximum number of threads to return
402 | }
403 | ```
404 | 
405 | | Parameter        | Type    | Required | Description                                                                    |
406 | | ---------------- | ------- | -------- | ------------------------------------------------------------------------------ |
407 | | `projectId`      | string  | Yes      | The ID or name of the project containing the repository                        |
408 | | `repositoryId`   | string  | Yes      | The ID or name of the repository containing the pull request                   |
409 | | `pullRequestId`  | number  | Yes      | The ID of the pull request to get comments from                                |
410 | | `threadId`       | number  | No       | The ID of a specific thread to retrieve (if omitted, all threads are returned) |
411 | | `includeDeleted` | boolean | No       | Whether to include deleted comments in the results                             |
412 | | `top`            | number  | No       | Maximum number of comment threads to return                                    |
413 | 
414 | ### Response
415 | 
416 | The tool returns an array of `GitPullRequestCommentThread` objects, each containing:
417 | 
418 | - `id`: The unique identifier of the thread
419 | - `status`: The status of the thread (active, fixed, closed, etc.)
420 | - `threadContext`: Information about the location of the thread in the code (file path, line numbers)
421 | - `comments`: An array of comments within the thread
422 | - And various other fields and references
423 | 
424 | Each comment in the thread contains:
425 | 
426 | - `id`: The unique identifier of the comment
427 | - `content`: The text content of the comment
428 | - `commentType`: The type of comment (code change, general, etc.)
429 | - `author`: Information about the user who created the comment
430 | - `publishedDate`: The date and time when the comment was published
431 | - `filePath`: The path of the file the comment is associated with (if any)
432 | - `leftFileStart`: The start position in the left file (object with `line` and `offset`), or null
433 | - `leftFileEnd`: The end position in the left file (object with `line` and `offset`), or null
434 | - `rightFileStart`: The start position in the right file (object with `line` and `offset`), or null
435 | - `rightFileEnd`: The end position in the right file (object with `line` and `offset`), or null
436 | - And various other fields and references
437 | 
438 | Example response:
439 | 
440 | ```json
441 | [
442 |   {
443 |     "id": 123,
444 |     "status": 1,
445 |     "threadContext": {
446 |       "filePath": "/src/app.ts",
447 |       "rightFileStart": {
448 |         "line": 10,
449 |         "offset": 5
450 |       },
451 |       "rightFileEnd": {
452 |         "line": 10,
453 |         "offset": 15
454 |       }
455 |     },
456 |     "comments": [
457 |       {
458 |         "id": 456,
459 |         "content": "This variable name is not descriptive enough.",
460 |         "commentType": 1,
461 |         "author": {
462 |           "displayName": "Jane Smith",
463 |           "id": "user-guid",
464 |           "uniqueName": "[email protected]"
465 |         },
466 |         "publishedDate": "2023-04-15T14:30:00Z",
467 |         "filePath": "/src/app.ts",
468 |         "rightFileStart": { "line": 10, "offset": 5 },
469 |         "rightFileEnd": { "line": 10, "offset": 15 },
470 |         "leftFileStart": undefined,
471 |         "leftFileEnd": undefined
472 |       },
473 |       {
474 |         "id": 457,
475 |         "parentCommentId": 456,
476 |         "content": "Good point, I'll rename it to be more descriptive.",
477 |         "commentType": 1,
478 |         "author": {
479 |           "displayName": "John Doe",
480 |           "id": "user-guid-2",
481 |           "uniqueName": "[email protected]"
482 |         },
483 |         "publishedDate": "2023-04-15T14:35:00Z",
484 |         "filePath": "/src/app.ts",
485 |         "rightFileStart": { "line": 10, "offset": 5 },
486 |         "rightFileEnd": { "line": 10, "offset": 15 },
487 |         "leftFileStart": undefined,
488 |         "leftFileEnd": undefined
489 |       }
490 |     ],
491 |     "isDeleted": false
492 |   },
493 |   {
494 |     "id": 124,
495 |     "status": 2,
496 |     "comments": [
497 |       {
498 |         "id": 458,
499 |         "content": "Can you add more validation here?",
500 |         "commentType": 1,
501 |         "author": {
502 |           "displayName": "Jane Smith",
503 |           "id": "user-guid",
504 |           "uniqueName": "[email protected]"
505 |         },
506 |         "publishedDate": "2023-04-15T14:40:00Z",
507 |         "filePath": null,
508 |         "rightFileStart": undefined,
509 |         "rightFileEnd": undefined,
510 |         "leftFileStart": undefined,
511 |         "leftFileEnd": undefined
512 |       }
513 |     ],
514 |     "isDeleted": false
515 |   }
516 | ]
517 | ```
518 | 
519 | ### Error Handling
520 | 
521 | The tool may throw the following errors:
522 | 
523 | - ValidationError: If required parameters are missing or invalid
524 | - AuthenticationError: If authentication fails
525 | - PermissionError: If the user doesn't have permission to access the pull request comments
526 | - ResourceNotFoundError: If the project, repository, pull request, or thread doesn't exist
527 | - GeneralError: For other unexpected errors
528 | 
529 | Error messages will include details about what went wrong and suggestions for resolution.
530 | 
531 | ### Example Usage
532 | 
533 | ```typescript
534 | // Get all comments from a pull request
535 | const comments = await mcpClient.callTool('get_pull_request_comments', {
536 |   projectId: 'MyProject',
537 |   repositoryId: 'MyRepo',
538 |   pullRequestId: 42,
539 | });
540 | 
541 | // Get comments with file path and line number information
542 | comments.forEach(thread => {
543 |   thread.comments?.forEach(comment => {
544 |     if (comment.filePath && comment.rightFileStart && comment.rightFileEnd) {
545 |       console.log(`Comment on ${comment.filePath}:${comment.rightFileStart.line}-${comment.rightFileEnd.line}: ${comment.content}`);
546 |     } else {
547 |       console.log(`General comment: ${comment.content}`);
548 |     }
549 |   });
550 | });
551 | 
552 | // Get a specific thread by ID
553 | const thread = await mcpClient.callTool('get_pull_request_comments', {
554 |   projectId: 'MyProject',
555 |   repositoryId: 'MyRepo',
556 |   pullRequestId: 42,
557 |   threadId: 123,
558 | });
559 | 
560 | // Get comments with pagination
561 | const firstPage = await mcpClient.callTool('get_pull_request_comments', {
562 |   projectId: 'MyProject',
563 |   repositoryId: 'MyRepo',
564 |   pullRequestId: 42,
565 |   top: 10,
566 | });
567 | ```
568 | 
569 | ### Implementation Details
570 | 
571 | The `get_pull_request_comments` tool:
572 | 
573 | 1. Establishes a connection to Azure DevOps using the provided credentials
574 | 2. Retrieves the Git API client
575 | 3. Gets the comment threads from the pull request
576 | 4. For each thread:
577 |    - Extracts file path and line number information from the thread context
578 |    - Adds these fields to each comment in the thread
579 |    - Uses rightFileStart.line for line number if available, falls back to leftFileStart.line
580 | 5. Returns the transformed threads with enhanced comment information
581 | 6. Handles errors and provides meaningful error messages
582 | 
583 | This implementation provides a robust way to retrieve and analyze pull request comments from Azure DevOps repositories, with enhanced file and line number information for better code review integration.
584 | 
585 | ## add_pull_request_comment
586 | 
587 | Adds a comment to a pull request, either as a reply to an existing comment or as a new thread.
588 | 
589 | ### Description
590 | 
591 | The `add_pull_request_comment` tool allows you to create new comments in pull requests in Azure DevOps. You can either:
592 | 
593 | 1. Add a reply to an existing comment thread
594 | 2. Create a new thread with a comment in the general discussion
595 | 3. Create a new thread with a comment on a specific file at a specific line
596 | 
597 | This tool is useful for providing feedback on pull requests, engaging in code review discussions, and automating comment workflows.
598 | 
599 | ### Parameters
600 | 
601 | ```json
602 | {
603 |   "projectId": "MyProject", // Required: The ID or name of the project
604 |   "repositoryId": "MyRepo", // Required: The ID or name of the repository
605 |   "pullRequestId": 42, // Required: The ID of the pull request
606 |   "content": "This looks good, let's merge!", // Required: The content of the comment
607 |   "threadId": 123, // Optional: The ID of the thread to add the comment to (for replying)
608 |   "parentCommentId": 456, // Optional: The ID of the parent comment (for threaded replies)
609 |   "filePath": "/src/app.ts", // Optional: The path of the file to comment on (for file comments)
610 |   "lineNumber": 42, // Optional: The line number to comment on (for file comments)
611 |   "status": "active" // Optional: The status to set for a new thread (active, fixed, wontFix, closed, pending)
612 | }
613 | ```
614 | 
615 | | Parameter         | Type   | Required | Description                                                                                      |
616 | | ----------------- | ------ | -------- | ------------------------------------------------------------------------------------------------ |
617 | | `projectId`       | string | Yes      | The ID or name of the project containing the repository                                          |
618 | | `repositoryId`    | string | Yes      | The ID or name of the repository containing the pull request                                     |
619 | | `pullRequestId`   | number | Yes      | The ID of the pull request to comment on                                                         |
620 | | `content`         | string | Yes      | The text content of the comment                                                                  |
621 | | `threadId`        | number | No       | The ID of an existing thread to add the comment to. Required when replying to an existing thread |
622 | | `parentCommentId` | number | No       | ID of the parent comment when replying to a specific comment in a thread                         |
623 | | `filePath`        | string | No       | The path of the file to comment on (for creating a new thread on a file)                         |
624 | | `lineNumber`      | number | No       | The line number to comment on (for creating a new thread on a file)                              |
625 | | `status`          | string | No       | The status to set for a new thread: "active", "fixed", "wontFix", "closed", or "pending"         |
626 | 
627 | ### Response
628 | 
629 | When adding a comment to an existing thread, the tool returns an object containing:
630 | 
631 | - `comment`: The created comment object with details like ID, content, and author
632 | 
633 | When creating a new thread with a comment, the tool returns an object containing:
634 | 
635 | - `comment`: The created comment object
636 | - `thread`: The created thread object with details like ID, status, and context
637 | 
638 | Example response for replying to an existing thread:
639 | 
640 | ```json
641 | {
642 |   "comment": {
643 |     "id": 101,
644 |     "content": "I agree with the suggestion",
645 |     "commentType": 1,
646 |     "parentCommentId": 100,
647 |     "author": {
648 |       "displayName": "John Doe",
649 |       "id": "user-guid",
650 |       "uniqueName": "[email protected]"
651 |     },
652 |     "publishedDate": "2023-05-15T10:23:45Z"
653 |   }
654 | }
655 | ```
656 | 
657 | Example response for creating a new thread on a file:
658 | 
659 | ```json
660 | {
661 |   "comment": {
662 |     "id": 200,
663 |     "content": "This variable name should be more descriptive",
664 |     "commentType": 1,
665 |     "author": {
666 |       "displayName": "John Doe",
667 |       "id": "user-guid",
668 |       "uniqueName": "[email protected]"
669 |     },
670 |     "publishedDate": "2023-05-15T10:30:12Z"
671 |   },
672 |   "thread": {
673 |     "id": 50,
674 |     "status": 1,
675 |     "threadContext": {
676 |       "filePath": "/src/app.ts",
677 |       "rightFileStart": {
678 |         "line": 42,
679 |         "offset": 1
680 |       },
681 |       "rightFileEnd": {
682 |         "line": 42,
683 |         "offset": 1
684 |       }
685 |     },
686 |     "comments": [
687 |       {
688 |         "id": 200,
689 |         "content": "This variable name should be more descriptive",
690 |         "commentType": 1,
691 |         "author": {
692 |           "displayName": "John Doe",
693 |           "id": "user-guid",
694 |           "uniqueName": "[email protected]"
695 |         },
696 |         "publishedDate": "2023-05-15T10:30:12Z"
697 |       }
698 |     ]
699 |   }
700 | }
701 | ```
702 | 
703 | ### Error Handling
704 | 
705 | The tool may throw the following errors:
706 | 
707 | - ValidationError: If required parameters are missing or invalid
708 | - AuthenticationError: If authentication fails
709 | - PermissionError: If the user doesn't have permission to comment on the pull request
710 | - ResourceNotFoundError: If the project, repository, pull request, or thread doesn't exist
711 | - GeneralError: For other unexpected errors
712 | 
713 | Error messages will include details about what went wrong and suggestions for resolution.
714 | 
715 | ### Example Usage
716 | 
717 | ```typescript
718 | // Reply to an existing thread in a pull request
719 | const reply = await mcpClient.callTool('add_pull_request_comment', {
720 |   projectId: 'MyProject',
721 |   repositoryId: 'MyRepo',
722 |   pullRequestId: 42,
723 |   threadId: 123,
724 |   content: 'I agree with the suggestion, let me implement this change.',
725 | });
726 | console.log(`Created reply with ID ${reply.comment.id}`);
727 | 
728 | // Reply to a specific comment in a thread
729 | const threadedReply = await mcpClient.callTool('add_pull_request_comment', {
730 |   projectId: 'MyProject',
731 |   repositoryId: 'MyRepo',
732 |   pullRequestId: 42,
733 |   threadId: 123,
734 |   parentCommentId: 456,
735 |   content: 'Specifically addressing your point about error handling.',
736 | });
737 | console.log(`Created threaded reply with ID ${threadedReply.comment.id}`);
738 | 
739 | // Create a new general discussion thread in a pull request
740 | const newThread = await mcpClient.callTool('add_pull_request_comment', {
741 |   projectId: 'MyProject',
742 |   repositoryId: 'MyRepo',
743 |   pullRequestId: 42,
744 |   content:
745 |     "Overall this looks good, but let's discuss the error handling approach.",
746 | });
747 | console.log(`Created new thread with ID ${newThread.thread.id}`);
748 | 
749 | // Create a comment on a specific file and line
750 | const fileComment = await mcpClient.callTool('add_pull_request_comment', {
751 |   projectId: 'MyProject',
752 |   repositoryId: 'MyRepo',
753 |   pullRequestId: 42,
754 |   content: 'This variable name should be more descriptive.',
755 |   filePath: '/src/app.ts',
756 |   lineNumber: 42,
757 | });
758 | console.log(
759 |   `Created file comment with ID ${fileComment.comment.id} in thread ${fileComment.thread.id}`,
760 | );
761 | 
762 | // Create a comment with thread status
763 | const statusComment = await mcpClient.callTool('add_pull_request_comment', {
764 |   projectId: 'MyProject',
765 |   repositoryId: 'MyRepo',
766 |   pullRequestId: 42,
767 |   content: "There's an edge case not handled here.",
768 |   filePath: '/src/app.ts',
769 |   lineNumber: 87,
770 |   status: 'active',
771 | });
772 | console.log(`Created active thread with ID ${statusComment.thread.id}`);
773 | ```
774 | 
775 | ### Implementation Details
776 | 
777 | The `add_pull_request_comment` tool:
778 | 
779 | 1. Establishes a connection to Azure DevOps using the provided credentials
780 | 2. Retrieves the Git API client
781 | 3. Creates the comment object with the provided content
782 | 4. Determines whether to add a comment to an existing thread or create a new thread:
783 |    - For existing threads, it calls `createComment` to add a comment to the thread
784 |    - For new threads, it creates a thread object and calls `createThread` to create a new thread with the comment
785 | 5. For file comments, it adds file path and line information to the thread context
786 | 6. Maps status strings to the appropriate CommentThreadStatus enum values
787 | 7. Returns the created comment or thread information
788 | 8. Handles errors and provides meaningful error messages
789 | 
790 | This implementation provides a flexible way to add comments to pull requests, supporting both regular discussion comments and code review feedback.
791 | 
792 | ## update_pull_request
793 | 
794 | Updates an existing pull request with new properties, links work items, and manages reviewers.
795 | 
796 | ### Description
797 | 
798 | The `update_pull_request` tool allows you to update various aspects of an existing pull request in Azure DevOps. You can modify the title, description, status, draft state, add or remove linked work items, and add or remove reviewers. This tool is useful for automating pull request workflows, updating PR details based on new information, and managing the review process.
799 | 
800 | ### Parameters
801 | 
802 | ```json
803 | {
804 |   "projectId": "MyProject", // Required: The ID or name of the project
805 |   "repositoryId": "MyRepo", // Required: The ID or name of the repository
806 |   "pullRequestId": 42, // Required: The ID of the pull request to update
807 |   "title": "Updated PR Title", // Optional: The updated title of the pull request
808 |   "description": "Updated PR description", // Optional: The updated description
809 |   "status": "active", // Optional: The updated status (active, abandoned, completed)
810 |   "isDraft": false, // Optional: Whether to mark (true) or unmark (false) as draft
811 |   "addWorkItemIds": [123, 456], // Optional: Work item IDs to link to the PR
812 |   "removeWorkItemIds": [789], // Optional: Work item IDs to unlink from the PR
813 |   "addReviewers": ["[email protected]"], // Optional: Reviewers to add
814 |   "removeReviewers": ["[email protected]"], // Optional: Reviewers to remove
815 |   "additionalProperties": {} // Optional: Additional properties to update
816 | }
817 | ```
818 | 
819 | | Parameter              | Type     | Required | Description                                                  |
820 | | ---------------------- | -------- | -------- | ------------------------------------------------------------ |
821 | | `projectId`            | string   | Yes      | The ID or name of the project containing the repository      |
822 | | `repositoryId`         | string   | Yes      | The ID or name of the repository containing the pull request |
823 | | `pullRequestId`        | number   | Yes      | The ID of the pull request to update                         |
824 | | `title`                | string   | No       | The updated title of the pull request                        |
825 | | `description`          | string   | No       | The updated description of the pull request                  |
826 | | `status`               | string   | No       | The updated status: "active", "abandoned", or "completed"    |
827 | | `isDraft`              | boolean  | No       | Whether to mark (true) or unmark (false) the PR as a draft   |
828 | | `addWorkItemIds`       | number[] | No       | Array of work item IDs to link to the pull request           |
829 | | `removeWorkItemIds`    | number[] | No       | Array of work item IDs to unlink from the pull request       |
830 | | `addReviewers`         | string[] | No       | Array of reviewer email addresses or IDs to add              |
831 | | `removeReviewers`      | string[] | No       | Array of reviewer email addresses or IDs to remove           |
832 | | `additionalProperties` | object   | No       | Additional properties to update on the pull request          |
833 | 
834 | ### Response
835 | 
836 | The tool returns the updated `PullRequest` object containing:
837 | 
838 | - `pullRequestId`: The unique identifier of the updated pull request
839 | - `title`: The title of the pull request (updated if provided)
840 | - `description`: The description of the pull request (updated if provided)
841 | - `status`: The status of the pull request (active, abandoned, completed)
842 | - `isDraft`: Whether the pull request is a draft
843 | - And various other fields and references, including updated reviewers and work item references
844 | 
845 | Example response:
846 | 
847 | ```json
848 | {
849 |   "repository": {
850 |     "id": "repo-guid",
851 |     "name": "MyRepo",
852 |     "url": "https://dev.azure.com/organization/MyProject/_apis/git/repositories/MyRepo",
853 |     "project": {
854 |       "id": "project-guid",
855 |       "name": "MyProject"
856 |     }
857 |   },
858 |   "pullRequestId": 42,
859 |   "codeReviewId": 42,
860 |   "status": 1,
861 |   "createdBy": {
862 |     "displayName": "John Doe",
863 |     "id": "user-guid",
864 |     "uniqueName": "[email protected]"
865 |   },
866 |   "creationDate": "2023-01-01T12:00:00Z",
867 |   "title": "Updated PR Title",
868 |   "description": "Updated PR description",
869 |   "sourceRefName": "refs/heads/feature-branch",
870 |   "targetRefName": "refs/heads/main",
871 |   "mergeStatus": 3,
872 |   "isDraft": false,
873 |   "reviewers": [
874 |     {
875 |       "displayName": "Jane Smith",
876 |       "id": "reviewer-guid",
877 |       "uniqueName": "[email protected]",
878 |       "voteResult": 0
879 |     }
880 |   ],
881 |   "url": "https://dev.azure.com/organization/MyProject/_apis/git/repositories/MyRepo/pullRequests/42",
882 |   "workItemRefs": [
883 |     {
884 |       "id": "123",
885 |       "url": "https://dev.azure.com/organization/MyProject/_apis/wit/workItems/123"
886 |     },
887 |     {
888 |       "id": "456",
889 |       "url": "https://dev.azure.com/organization/MyProject/_apis/wit/workItems/456"
890 |     }
891 |   ]
892 | }
893 | ```
894 | 
895 | ### Error Handling
896 | 
897 | The tool may throw the following errors:
898 | 
899 | - ValidationError: If required parameters are missing or invalid
900 | - AuthenticationError: If authentication fails
901 | - PermissionError: If the user doesn't have permission to update the pull request
902 | - ResourceNotFoundError: If the project, repository, or pull request doesn't exist
903 | - GeneralError: For other unexpected errors
904 | 
905 | Error messages will include details about what went wrong and suggestions for resolution.
906 | 
907 | ### Example Usage
908 | 
909 | ```typescript
910 | // Update the title and description of a pull request
911 | const updatedPR = await mcpClient.callTool('update_pull_request', {
912 |   projectId: 'MyProject',
913 |   repositoryId: 'MyRepo',
914 |   pullRequestId: 42,
915 |   title: 'Updated PR Title',
916 |   description: 'This PR has been updated to add new features',
917 | });
918 | console.log(`Updated PR: ${updatedPR.title}`);
919 | 
920 | // Mark a pull request as completed
921 | const completedPR = await mcpClient.callTool('update_pull_request', {
922 |   projectId: 'MyProject',
923 |   repositoryId: 'MyRepo',
924 |   pullRequestId: 42,
925 |   status: 'completed',
926 | });
927 | console.log(
928 |   `PR status: ${completedPR.status === 3 ? 'Completed' : 'Not completed'}`,
929 | );
930 | 
931 | // Convert a draft PR to a normal PR
932 | const readyPR = await mcpClient.callTool('update_pull_request', {
933 |   projectId: 'MyProject',
934 |   repositoryId: 'MyRepo',
935 |   pullRequestId: 42,
936 |   isDraft: false,
937 | });
938 | console.log(`PR is draft: ${readyPR.isDraft ? 'Yes' : 'No'}`);
939 | 
940 | // Add and remove work items from a PR
941 | const workItemPR = await mcpClient.callTool('update_pull_request', {
942 |   projectId: 'MyProject',
943 |   repositoryId: 'MyRepo',
944 |   pullRequestId: 42,
945 |   addWorkItemIds: [123, 456],
946 |   removeWorkItemIds: [789],
947 | });
948 | console.log(
949 |   `PR now has ${workItemPR.workItemRefs?.length || 0} linked work items`,
950 | );
951 | 
952 | // Add and remove reviewers
953 | const reviewersPR = await mcpClient.callTool('update_pull_request', {
954 |   projectId: 'MyProject',
955 |   repositoryId: 'MyRepo',
956 |   pullRequestId: 42,
957 |   addReviewers: ['[email protected]', '[email protected]'],
958 |   removeReviewers: ['[email protected]'],
959 | });
960 | console.log(`PR now has ${reviewersPR.reviewers?.length || 0} reviewers`);
961 | ```
962 | 
963 | ### Implementation Details
964 | 
965 | The `update_pull_request` tool:
966 | 
967 | 1. Establishes a connection to Azure DevOps using the provided credentials
968 | 2. Retrieves the Git API client
969 | 3. Gets the current pull request to verify it exists
970 | 4. Creates an update object with only the properties that are being updated:
971 |    - Basic properties (title, description, isDraft)
972 |    - Status (active, abandoned, completed)
973 |    - Any additional properties provided
974 | 5. Updates the pull request with the provided changes
975 | 6. If specified, handles adding and removing work item associations:
976 |    - Adds work items by creating links between the PR and work items
977 |    - Removes work items by deleting links between the PR and work items
978 | 7. If specified, handles adding and removing reviewers:
979 |    - Adds reviewers by creating reviewer references
980 |    - Removes reviewers by deleting reviewer references
981 | 8. Gets the final updated pull request to return all changes
982 | 9. Handles errors and provides meaningful error messages
983 | 
984 | This implementation provides a comprehensive way to update pull requests in Azure DevOps repositories, supporting all common update scenarios.
985 | 
```
Page 8/8FirstPrevNextLast