update_merge_request
Modify an existing GitLab merge request by updating its title, description, target branch, assignees, labels, or state. Use this tool to change merge request properties, reassign reviewers, adjust merge settings, or close/reopen requests as needed.
Instructions
Update an existing merge request
Input Schema
TableJSON Schema
| Name | Required | Description | Default |
|---|---|---|---|
| allow_collaboration | No | Allow commits from members who can merge | |
| assignee_id | No | Assign a user to the merge request (use 0 to unassign) | |
| assignee_ids | No | Assign multiple users to the merge request | |
| description | No | Update merge request description (max 1,048,576 characters) | |
| labels | No | Update labels (comma-separated) | |
| merge_request_iid | Yes | Merge request internal ID | |
| merge_when_pipeline_succeeds | No | Set MR to merge when pipeline succeeds | |
| milestone_id | No | Assign a milestone (use 0 to remove) | |
| project_id | Yes | Project ID or path | |
| remove_source_branch | No | Flag to remove source branch after merging | |
| reviewer_ids | No | Set reviewers for the merge request | |
| squash | No | Toggle squash commits on merge | |
| state_event | No | Change the state (close or reopen the MR) | |
| target_branch | No | Change the target branch | |
| title | No | Update merge request title |
Implementation Reference
- src/handlers/merge-requests.ts:250-300 (handler)Core handler function implementing the update_merge_request tool. Resolves merge request IID from source_branch if not provided, conditionally builds update payload from arguments, performs PUT request to GitLab API, and returns the response.async updateMergeRequest(args: UpdateMergeRequestParams) { const mergeRequestIid = await this.resolveMergeRequestIid( args.project_id, args.merge_request_iid, args.source_branch ); const requestData: any = {}; // Only include provided parameters if (args.title !== undefined) requestData.title = args.title; if (args.description !== undefined) requestData.description = args.description; if (args.state_event !== undefined) requestData.state_event = args.state_event; if (args.target_branch !== undefined) requestData.target_branch = args.target_branch; if (args.assignee_id !== undefined) requestData.assignee_id = args.assignee_id; if (args.assignee_ids !== undefined) requestData.assignee_ids = args.assignee_ids; if (args.reviewer_ids !== undefined) requestData.reviewer_ids = args.reviewer_ids; if (args.milestone_id !== undefined) requestData.milestone_id = args.milestone_id; if (args.labels !== undefined) requestData.labels = args.labels; if (args.remove_source_branch !== undefined) requestData.remove_source_branch = args.remove_source_branch; if (args.squash !== undefined) requestData.squash = args.squash; if (args.allow_collaboration !== undefined) requestData.allow_collaboration = args.allow_collaboration; if (args.merge_when_pipeline_succeeds !== undefined) requestData.merge_when_pipeline_succeeds = args.merge_when_pipeline_succeeds; const data = await this.client.put( `/projects/${encodeURIComponent( args.project_id )}/merge_requests/${mergeRequestIid}`, requestData ); return { content: [ { type: "text", text: JSON.stringify(data, null, 2), }, ], }; }
- src/tools/merge-requests.ts:221-297 (schema)MCP tool definition including input schema for 'update_merge_request'. Defines the tool name, description, and detailed JSON schema for input parameters with types, descriptions, enums, and requirements.{ name: 'update_merge_request', description: 'Update an existing merge request. Either merge_request_iid or source_branch must be provided.', inputSchema: { type: 'object', properties: { project_id: { type: 'string', description: 'Project ID or path', }, merge_request_iid: { type: 'number', description: 'Merge request internal ID', }, source_branch: { type: 'string', description: 'Source branch name (alternative to merge_request_iid)', }, title: { type: 'string', description: 'Update merge request title', }, description: { type: 'string', description: 'Update merge request description (max 1,048,576 characters)', }, state_event: { type: 'string', enum: ['close', 'reopen'], description: 'Change the state (close or reopen the MR)', }, target_branch: { type: 'string', description: 'Change the target branch', }, assignee_id: { type: 'number', description: 'Assign a user to the merge request (use 0 to unassign)', }, assignee_ids: { type: 'array', items: { type: 'number' }, description: 'Assign multiple users to the merge request', }, reviewer_ids: { type: 'array', items: { type: 'number' }, description: 'Set reviewers for the merge request', }, milestone_id: { type: 'number', description: 'Assign a milestone (use 0 to remove)', }, labels: { type: 'string', description: 'Update labels (comma-separated)', }, remove_source_branch: { type: 'boolean', description: 'Flag to remove source branch after merging', }, squash: { type: 'boolean', description: 'Toggle squash commits on merge', }, allow_collaboration: { type: 'boolean', description: 'Allow commits from members who can merge', }, merge_when_pipeline_succeeds: { type: 'boolean', description: 'Set MR to merge when pipeline succeeds', }, }, required: ['project_id'], }, },
- src/types.ts:295-312 (schema)TypeScript interface definition for UpdateMergeRequestParams used in the handler for type safety and matching the MCP input schema.export interface UpdateMergeRequestParams { project_id: string; merge_request_iid?: number; source_branch?: string; title?: string; description?: string; state_event?: 'close' | 'reopen'; target_branch?: string; assignee_id?: number; assignee_ids?: number[]; reviewer_ids?: number[]; milestone_id?: number; labels?: string; remove_source_branch?: boolean; squash?: boolean; allow_collaboration?: boolean; merge_when_pipeline_succeeds?: boolean; }
- src/server.ts:189-192 (registration)Server dispatch/registration case in the tool call handler that routes 'update_merge_request' calls to the mergeRequestHandlers.updateMergeRequest method.case "update_merge_request": return await this.mergeRequestHandlers.updateMergeRequest( args as unknown as UpdateMergeRequestParams );
- src/tools/merge-requests.ts:3-692 (registration)The mergeRequestTools array exports the tool definitions, including 'update_merge_request', which are aggregated into allTools for server registration.export const mergeRequestTools: Tool[] = [ { name: 'list_merge_requests', description: 'List merge requests in a project', inputSchema: { type: 'object', properties: { project_id: { type: 'string', description: 'Project ID or path', }, state: { type: 'string', enum: ['opened', 'closed', 'merged', 'all'], description: 'Filter by merge request state', default: 'opened', }, target_branch: { type: 'string', description: 'Filter by target branch', }, source_branch: { type: 'string', description: 'Filter by source branch', }, assignee_id: { type: 'number', description: 'Filter by assignee user ID', }, author_id: { type: 'number', description: 'Filter by author user ID', }, reviewer_id: { type: 'number', description: 'Filter by reviewer user ID', }, reviewer_username: { type: 'string', description: 'Filter by reviewer username', }, search: { type: 'string', description: 'Search merge requests by title and description', }, scope: { type: 'string', enum: ['created_by_me', 'assigned_to_me', 'all'], description: 'Return merge requests with the given scope (optional)', }, per_page: { type: 'number', description: 'Number of results per page (max 100)', maximum: 100, default: 20, }, }, required: ['project_id'], }, }, { name: 'get_merge_request', description: 'Get details of a merge request. Either merge_request_iid or source_branch must be provided.', inputSchema: { type: 'object', properties: { project_id: { type: 'string', description: 'Project ID or path', }, merge_request_iid: { type: 'number', description: 'Merge request internal ID', }, source_branch: { type: 'string', description: 'Source branch name (alternative to merge_request_iid)', }, }, required: ['project_id'], }, }, { name: 'get_merge_request_diffs', description: 'Get the changes/diffs of a merge request. Either merge_request_iid or source_branch must be provided.', inputSchema: { type: 'object', properties: { project_id: { type: 'string', description: 'Project ID or path', }, merge_request_iid: { type: 'number', description: 'Merge request internal ID', }, source_branch: { type: 'string', description: 'Source branch name (alternative to merge_request_iid)', }, view: { type: 'string', enum: ['inline', 'parallel'], description: 'Diff view type', }, }, required: ['project_id'], }, }, { name: 'list_merge_request_diffs', description: 'List merge request diffs with pagination support. Either merge_request_iid or source_branch must be provided.', inputSchema: { type: 'object', properties: { project_id: { type: 'string', description: 'Project ID or path', }, merge_request_iid: { type: 'number', description: 'Merge request internal ID', }, source_branch: { type: 'string', description: 'Source branch name (alternative to merge_request_iid)', }, page: { type: 'number', description: 'Page number for pagination (default: 1)', }, per_page: { type: 'number', description: 'Number of items per page (max: 100, default: 20)', maximum: 100, }, unidiff: { type: 'boolean', description: 'Present diffs in unified diff format (GitLab 16.5+)', }, }, required: ['project_id'], }, }, { name: 'get_branch_diffs', description: 'Get the changes/diffs between two branches or commits in a GitLab project', inputSchema: { type: 'object', properties: { project_id: { type: 'string', description: 'Project ID or path', }, from: { type: 'string', description: 'The base branch or commit SHA to compare from', }, to: { type: 'string', description: 'The target branch or commit SHA to compare to', }, straight: { type: 'boolean', description: 'Comparison method: false for "..." (default), true for "--"', }, }, required: ['project_id', 'from', 'to'], }, }, { name: 'create_merge_request', description: 'Create a new merge request', inputSchema: { type: 'object', properties: { project_id: { type: 'string', description: 'Project ID or path', }, title: { type: 'string', description: 'Merge request title', }, source_branch: { type: 'string', description: 'Source branch name', }, target_branch: { type: 'string', description: 'Target branch name', }, description: { type: 'string', description: 'Merge request description', }, assignee_ids: { type: 'array', items: { type: 'number' }, description: 'Array of user IDs to assign', }, reviewer_ids: { type: 'array', items: { type: 'number' }, description: 'Array of user IDs to review', }, labels: { type: 'string', description: 'Comma-separated list of labels', }, milestone_id: { type: 'number', description: 'Milestone ID', }, }, required: ['project_id', 'title', 'source_branch', 'target_branch'], }, }, { name: 'update_merge_request', description: 'Update an existing merge request. Either merge_request_iid or source_branch must be provided.', inputSchema: { type: 'object', properties: { project_id: { type: 'string', description: 'Project ID or path', }, merge_request_iid: { type: 'number', description: 'Merge request internal ID', }, source_branch: { type: 'string', description: 'Source branch name (alternative to merge_request_iid)', }, title: { type: 'string', description: 'Update merge request title', }, description: { type: 'string', description: 'Update merge request description (max 1,048,576 characters)', }, state_event: { type: 'string', enum: ['close', 'reopen'], description: 'Change the state (close or reopen the MR)', }, target_branch: { type: 'string', description: 'Change the target branch', }, assignee_id: { type: 'number', description: 'Assign a user to the merge request (use 0 to unassign)', }, assignee_ids: { type: 'array', items: { type: 'number' }, description: 'Assign multiple users to the merge request', }, reviewer_ids: { type: 'array', items: { type: 'number' }, description: 'Set reviewers for the merge request', }, milestone_id: { type: 'number', description: 'Assign a milestone (use 0 to remove)', }, labels: { type: 'string', description: 'Update labels (comma-separated)', }, remove_source_branch: { type: 'boolean', description: 'Flag to remove source branch after merging', }, squash: { type: 'boolean', description: 'Toggle squash commits on merge', }, allow_collaboration: { type: 'boolean', description: 'Allow commits from members who can merge', }, merge_when_pipeline_succeeds: { type: 'boolean', description: 'Set MR to merge when pipeline succeeds', }, }, required: ['project_id'], }, }, { name: 'list_mr_notes', description: 'List all notes (comments) on a merge request', inputSchema: { type: 'object', properties: { project_id: { type: 'string', description: 'Project ID or path', }, merge_request_iid: { type: 'number', description: 'Merge request internal ID', }, sort: { type: 'string', enum: ['asc', 'desc'], description: 'Sort order (asc or desc)', default: 'desc', }, order_by: { type: 'string', enum: ['created_at', 'updated_at'], description: 'Field to order by', default: 'created_at', }, page: { type: 'number', description: 'Page number for pagination (default: 1)', minimum: 1, default: 1, }, per_page: { type: 'number', description: 'Number of results per page (max 100)', maximum: 100, default: 20, }, }, required: ['project_id', 'merge_request_iid'], }, }, { name: 'list_mr_discussions', description: 'List discussions (threaded comments including inline code comments) on a merge request. Use unresolved_only=true to fetch only unresolved discussions (saves tokens).', inputSchema: { type: 'object', properties: { project_id: { type: 'string', description: 'Project ID or path', }, merge_request_iid: { type: 'number', description: 'Merge request internal ID', }, unresolved_only: { type: 'boolean', description: 'If true, fetches all discussions and returns only unresolved ones. This reduces tokens sent to the LLM by filtering server-side.', default: false, }, page: { type: 'number', description: 'Page number for pagination (default: 1). Ignored when unresolved_only=true (fetches all pages).', minimum: 1, default: 1, }, per_page: { type: 'number', description: 'Number of results per page (max 100)', maximum: 100, default: 20, }, }, required: ['project_id', 'merge_request_iid'], }, }, { name: 'create_mr_note', description: 'Add a new top-level comment to a merge request', inputSchema: { type: 'object', properties: { project_id: { type: 'string', description: 'Project ID or path', }, merge_request_iid: { type: 'number', description: 'Merge request internal ID', }, body: { type: 'string', description: 'The content of the comment (supports Markdown)', }, }, required: ['project_id', 'merge_request_iid', 'body'], }, }, { name: 'create_mr_discussion', description: 'Create a new discussion on a merge request. Can be a general discussion or an inline comment on the diff', inputSchema: { type: 'object', properties: { project_id: { type: 'string', description: 'Project ID or path', }, merge_request_iid: { type: 'number', description: 'Merge request internal ID', }, body: { type: 'string', description: 'The content of the discussion (supports Markdown)', }, position: { type: 'object', description: 'Position for inline/diff comments. Required fields: base_sha, start_sha, head_sha, old_path, new_path. Use new_line for additions, old_line for deletions, both for context lines.', properties: { base_sha: { type: 'string', description: 'Base commit SHA (merge request target branch HEAD)', }, start_sha: { type: 'string', description: 'SHA of the commit when the MR was created (typically same as base_sha)', }, head_sha: { type: 'string', description: 'HEAD commit SHA of the merge request source branch', }, old_path: { type: 'string', description: 'File path before the change (use same as new_path for new files)', }, new_path: { type: 'string', description: 'File path after the change', }, position_type: { type: 'string', enum: ['text'], description: 'Type of position (text for code comments)', default: 'text', }, old_line: { type: 'number', description: 'Line number in old version (for deleted lines or context)', }, new_line: { type: 'number', description: 'Line number in new version (for added lines or context)', }, }, required: ['base_sha', 'start_sha', 'head_sha', 'old_path', 'new_path'], }, }, required: ['project_id', 'merge_request_iid', 'body'], }, }, { name: 'reply_to_mr_discussion', description: 'Reply to an existing discussion thread on a merge request', inputSchema: { type: 'object', properties: { project_id: { type: 'string', description: 'Project ID or path', }, merge_request_iid: { type: 'number', description: 'Merge request internal ID', }, discussion_id: { type: 'string', description: 'The ID of the discussion to reply to', }, body: { type: 'string', description: 'The content of the reply (supports Markdown)', }, }, required: ['project_id', 'merge_request_iid', 'discussion_id', 'body'], }, }, { name: 'resolve_mr_discussion', description: 'Mark a discussion on a merge request as resolved', inputSchema: { type: 'object', properties: { project_id: { type: 'string', description: 'Project ID or path', }, merge_request_iid: { type: 'number', description: 'Merge request internal ID', }, discussion_id: { type: 'string', description: 'The ID of the discussion to resolve', }, }, required: ['project_id', 'merge_request_iid', 'discussion_id'], }, }, { name: 'unresolve_mr_discussion', description: 'Mark a discussion on a merge request as unresolved', inputSchema: { type: 'object', properties: { project_id: { type: 'string', description: 'Project ID or path', }, merge_request_iid: { type: 'number', description: 'Merge request internal ID', }, discussion_id: { type: 'string', description: 'The ID of the discussion to unresolve', }, }, required: ['project_id', 'merge_request_iid', 'discussion_id'], }, }, { name: 'update_mr_discussion_note', description: 'Modify an existing merge request discussion note', inputSchema: { type: 'object', properties: { project_id: { type: 'string', description: 'Project ID or path', }, merge_request_iid: { type: 'number', description: 'Merge request internal ID', }, discussion_id: { type: 'string', description: 'The ID of the discussion', }, note_id: { type: 'number', description: 'The ID of the note to update', }, body: { type: 'string', description: 'The new content of the note (supports Markdown)', }, }, required: ['project_id', 'merge_request_iid', 'discussion_id', 'note_id', 'body'], }, }, { name: 'create_mr_discussion_note', description: 'Add a new note to an existing merge request discussion thread', inputSchema: { type: 'object', properties: { project_id: { type: 'string', description: 'Project ID or path', }, merge_request_iid: { type: 'number', description: 'Merge request internal ID', }, discussion_id: { type: 'string', description: 'The ID of the discussion to add the note to', }, body: { type: 'string', description: 'The content of the note (supports Markdown)', }, }, required: ['project_id', 'merge_request_iid', 'discussion_id', 'body'], }, }, { name: 'delete_mr_discussion_note', description: 'Delete a note from a merge request discussion', inputSchema: { type: 'object', properties: { project_id: { type: 'string', description: 'Project ID or path', }, merge_request_iid: { type: 'number', description: 'Merge request internal ID', }, discussion_id: { type: 'string', description: 'The ID of the discussion', }, note_id: { type: 'number', description: 'The ID of the note to delete', }, }, required: ['project_id', 'merge_request_iid', 'discussion_id', 'note_id'], }, }, { name: 'mark_mr_as_draft', description: 'Mark a merge request as draft (work in progress, not ready for review)', inputSchema: { type: 'object', properties: { project_id: { type: 'string', description: 'Project ID or path', }, merge_request_iid: { type: 'number', description: 'Merge request internal ID', }, }, required: ['project_id', 'merge_request_iid'], }, }, { name: 'mark_mr_as_ready', description: 'Mark a merge request as ready (remove draft status, ready for review)', inputSchema: { type: 'object', properties: { project_id: { type: 'string', description: 'Project ID or path', }, merge_request_iid: { type: 'number', description: 'Merge request internal ID', }, }, required: ['project_id', 'merge_request_iid'], }, }, { name: 'list_mr_templates', description: 'List available merge request description templates in a project', inputSchema: { type: 'object', properties: { project_id: { type: 'string', description: 'Project ID or path', }, }, required: ['project_id'], }, }, { name: 'get_mr_template', description: 'Get a specific merge request description template by name', inputSchema: { type: 'object', properties: { project_id: { type: 'string', description: 'Project ID or path', }, name: { type: 'string', description: 'Template name (without .md extension)', }, }, required: ['project_id', 'name'], }, }, ];