gitlab_get_merge_request_details
Retrieve comprehensive details and file changes from a GitLab merge request to review code modifications and track development progress.
Instructions
Fetches detailed information about a GitLab Merge Request, including file diffs.
Input Schema
TableJSON Schema
| Name | Required | Description | Default |
|---|---|---|---|
| mrUrl | Yes | The URL of the GitLab Merge Request. |
Implementation Reference
- src/index.ts:69-82 (registration)Tool registration and input schema definition for gitlab_get_merge_request_details{ name: 'gitlab_get_merge_request_details', description: 'Fetches detailed information about a GitLab Merge Request, including file diffs.', inputSchema: { type: 'object', properties: { mrUrl: { type: 'string', description: 'The URL of the GitLab Merge Request.', }, }, required: ['mrUrl'], },
- src/index.ts:1214-1229 (handler)MCP server handler that dispatches the tool call to GitLabService.getMergeRequestDetailsFromUrlcase 'gitlab_get_merge_request_details': { if (!gitlabService) { throw new Error('GitLab service is not initialized.'); } const { mrUrl } = args as { mrUrl: string }; const result = await gitlabService.getMergeRequestDetailsFromUrl(mrUrl); return { content: [ { type: 'text', text: JSON.stringify(result, null, 2), }, ], }; }
- src/gitlab.service.ts:154-204 (handler)Core handler function that fetches MR details from GitLab API, processes changes, parses diffs, and returns structured GitLabMRDetailsasync getMergeRequestDetails( projectPath: string, mrIid: number, ): Promise<GitLabMRDetails> { const encodedProjectPath = encodeURIComponent(projectPath); const baseUrl = `projects/${encodedProjectPath}/merge_requests/${mrIid}`; const mrDetails = await this.callGitLabApi<any>(baseUrl); const mrChanges = await this.callGitLabApi<any>( `projects/${encodedProjectPath}/merge_requests/${mrIid}/changes`, ); // Map file diffs const fileDiffs = mrChanges.changes.map((change: any) => ({ old_path: change.old_path, new_path: change.new_path, new_file: change.new_file, deleted_file: change.deleted_file, renamed_file: change.renamed_file, diff: change.diff, })); const parsedDiffs = fileDiffs.map((diff: any) => ({ filePath: diff.new_path, oldPath: diff.old_path, isNew: diff.new_file, isDeleted: diff.deleted_file, isRenamed: diff.renamed_file, hunks: this.parseDiff(diff.diff), })); return { projectPath: mrDetails.path_with_namespace, mrIid: mrDetails.iid.toString(), projectId: mrDetails.project_id, title: mrDetails.title, authorName: mrDetails.author.name, webUrl: mrDetails.web_url, sourceBranch: mrDetails.source_branch, targetBranch: mrDetails.target_branch, base_sha: mrDetails.diff_refs.base_sha, start_sha: mrDetails.diff_refs.start_sha, head_sha: mrDetails.diff_refs.head_sha, fileDiffs: fileDiffs, diffForPrompt: fileDiffs.map((diff: any) => diff.diff).join('\n'), parsedDiffs: parsedDiffs, fileContents: new Map(), // fileContents will be populated by a separate tool discussions: [], // Discussions will be fetched by a separate tool existingFeedback: [], // Existing feedback will be derived from discussions }; }
- src/gitlab.service.ts:207-210 (handler)Convenience handler that parses MR URL and delegates to getMergeRequestDetails (directly called by MCP handler)async getMergeRequestDetailsFromUrl(mrUrl: string): Promise<GitLabMRDetails> { const { projectPath, mrIid } = this.parseMrUrl(mrUrl, this.config.url); return this.getMergeRequestDetails(projectPath, mrIid); }
- src/gitlab.service.ts:120-150 (helper)Helper function to parse GitLab MR URL into projectPath and mrIidprivate parseMrUrl( mrUrl: string, gitlabBaseUrl: string, ): { projectPath: string; mrIid: number } { try { const url = new URL(mrUrl); const baseUrl = new URL(gitlabBaseUrl); // Ensure the URL is from the same GitLab instance if (url.origin !== baseUrl.origin) { throw new Error( `MR URL is not from the configured GitLab instance: ${gitlabBaseUrl}`, ); } // Parse the path: /{namespace}/{project}/-/merge_requests/{iid} const pathMatch = url.pathname.match(/^\/(.+)\/-\/merge_requests\/(\d+)/); if (!pathMatch) { throw new Error(`Invalid GitLab MR URL format: ${mrUrl}`); } const projectPath = pathMatch[1]; const mrIid = parseInt(pathMatch[2], 10); return { projectPath, mrIid }; } catch (error) { throw new Error( `Failed to parse GitLab MR URL: ${error instanceof Error ? error.message : String(error)}`, ); } }
- src/gitlab.ts:96-119 (schema)Type definition for the output schema (GitLabMRDetails interface)export interface GitLabMRDetails { projectPath: string; mrIid: string; projectId: number; title: string; authorName: string; webUrl: string; sourceBranch: string; targetBranch: string; base_sha: string; start_sha: string; head_sha: string; fileDiffs: FileDiff[]; diffForPrompt: string; parsedDiffs: ParsedFileDiff[]; fileContents: Map<string, { oldContent?: string[]; newContent?: string[] }>; discussions: GitLabDiscussion[]; existingFeedback: ReviewFeedback[]; approvals?: { approved_by: Array<{ user: { name: string; username: string } }>; approvals_left: number; approvals_required: number; }; }