update_pull_request
Modify an existing pull request to update its title, description, destination branch, or reviewers while preserving approval status. Works with Bitbucket repositories for streamlined PR lifecycle management.
Instructions
Update an existing pull request. When updating without specifying reviewers, existing reviewers and their approval status will be preserved.
Input Schema
TableJSON Schema
| Name | Required | Description | Default |
|---|---|---|---|
| description | No | New description (optional) | |
| destination_branch | No | New destination branch (optional) | |
| pull_request_id | Yes | Pull request ID | |
| repository | Yes | Repository slug (e.g., "my-repo") | |
| reviewers | No | New list of reviewer usernames/emails. If provided, replaces the reviewer list (preserving approval status for existing reviewers). If omitted, existing reviewers are preserved. (optional) | |
| title | No | New title (optional) | |
| workspace | Yes | Bitbucket workspace/project key (e.g., "PROJ") |
Implementation Reference
- Main handler function for update_pull_request tool. Validates input using isUpdatePullRequestArgs, constructs appropriate API request for Bitbucket Server or Cloud (preserving reviewer approvals on Server), performs PUT request to update PR, formats and returns the response.async handleUpdatePullRequest(args: any) { if (!isUpdatePullRequestArgs(args)) { throw new McpError( ErrorCode.InvalidParams, 'Invalid arguments for update_pull_request' ); } const { workspace, repository, pull_request_id, title, description, destination_branch, reviewers } = args; try { let apiPath: string; let requestBody: any = {}; if (this.apiClient.getIsServer()) { // Bitbucket Server API apiPath = `/rest/api/1.0/projects/${workspace}/repos/${repository}/pull-requests/${pull_request_id}`; // First get the current PR to get version number and existing data const currentPr = await this.apiClient.makeRequest<any>('get', apiPath); requestBody.version = currentPr.version; if (title !== undefined) requestBody.title = title; if (description !== undefined) requestBody.description = description; if (destination_branch !== undefined) { requestBody.toRef = { id: `refs/heads/${destination_branch}`, repository: { slug: repository, project: { key: workspace } } }; } // Handle reviewers: preserve existing ones if not explicitly updating if (reviewers !== undefined) { // User wants to update reviewers // Create a map of existing reviewers for preservation of approval status const existingReviewersMap = new Map( currentPr.reviewers.map((r: any) => [r.user.name, r]) ); requestBody.reviewers = reviewers.map(username => { const existing = existingReviewersMap.get(username); if (existing) { // Preserve existing reviewer's full data including approval status return existing; } else { // Add new reviewer (without approval status) return { user: { name: username } }; } }); } else { // No reviewers provided - preserve existing reviewers with their full data requestBody.reviewers = currentPr.reviewers; } } else { // Bitbucket Cloud API apiPath = `/repositories/${workspace}/${repository}/pullrequests/${pull_request_id}`; if (title !== undefined) requestBody.title = title; if (description !== undefined) requestBody.description = description; if (destination_branch !== undefined) { requestBody.destination = { branch: { name: destination_branch } }; } if (reviewers !== undefined) { requestBody.reviewers = reviewers.map(r => ({ username: r })); } } const pr = await this.apiClient.makeRequest<any>('put', apiPath, requestBody); const formattedResponse = this.apiClient.getIsServer() ? formatServerResponse(pr as BitbucketServerPullRequest, undefined, this.baseUrl) : formatCloudResponse(pr as BitbucketCloudPullRequest); return { content: [ { type: 'text', text: JSON.stringify({ message: 'Pull request updated successfully', pull_request: formattedResponse }, null, 2), }, ], }; } catch (error) { return this.apiClient.handleApiError(error, `updating pull request ${pull_request_id} in ${workspace}/${repository}`); } }
- src/tools/definitions.ts:102-139 (schema)MCP tool definition including name, description, and inputSchema JSON Schema for validating tool parameters.{ name: 'update_pull_request', description: 'Update an existing pull request. When updating without specifying reviewers, existing reviewers and their approval status will be preserved.', inputSchema: { type: 'object', properties: { workspace: { type: 'string', description: 'Bitbucket workspace/project key (e.g., "PROJ")', }, repository: { type: 'string', description: 'Repository slug (e.g., "my-repo")', }, pull_request_id: { type: 'number', description: 'Pull request ID', }, title: { type: 'string', description: 'New title (optional)', }, description: { type: 'string', description: 'New description (optional)', }, destination_branch: { type: 'string', description: 'New destination branch (optional)', }, reviewers: { type: 'array', items: { type: 'string' }, description: 'New list of reviewer usernames/emails. If provided, replaces the reviewer list (preserving approval status for existing reviewers). If omitted, existing reviewers are preserved. (optional)', }, }, required: ['workspace', 'repository', 'pull_request_id'], },
- src/types/guards.ts:53-72 (schema)Type guard function for validating and typing update_pull_request arguments at runtime.export const isUpdatePullRequestArgs = ( args: any ): args is { workspace: string; repository: string; pull_request_id: number; title?: string; description?: string; destination_branch?: string; reviewers?: string[]; } => typeof args === 'object' && args !== null && typeof args.workspace === 'string' && typeof args.repository === 'string' && typeof args.pull_request_id === 'number' && (args.title === undefined || typeof args.title === 'string') && (args.description === undefined || typeof args.description === 'string') && (args.destination_branch === undefined || typeof args.destination_branch === 'string') && (args.reviewers === undefined || Array.isArray(args.reviewers));
- src/index.ts:102-103 (registration)Tool dispatch registration in main server switch statement, routing 'update_pull_request' calls to the PullRequestHandlers.handleUpdatePullRequest method.case 'update_pull_request': return this.pullRequestHandlers.handleUpdatePullRequest(request.params.arguments);
- src/tools/definitions.ts:102-140 (registration)Tool registration in the exported toolDefinitions array used by listTools endpoint.{ name: 'update_pull_request', description: 'Update an existing pull request. When updating without specifying reviewers, existing reviewers and their approval status will be preserved.', inputSchema: { type: 'object', properties: { workspace: { type: 'string', description: 'Bitbucket workspace/project key (e.g., "PROJ")', }, repository: { type: 'string', description: 'Repository slug (e.g., "my-repo")', }, pull_request_id: { type: 'number', description: 'Pull request ID', }, title: { type: 'string', description: 'New title (optional)', }, description: { type: 'string', description: 'New description (optional)', }, destination_branch: { type: 'string', description: 'New destination branch (optional)', }, reviewers: { type: 'array', items: { type: 'string' }, description: 'New list of reviewer usernames/emails. If provided, replaces the reviewer list (preserving approval status for existing reviewers). If omitted, existing reviewers are preserved. (optional)', }, }, required: ['workspace', 'repository', 'pull_request_id'], }, },