Get Merge Request Context
get_merge_request_contextRetrieve complete merge request context including description, notes, commits, pipeline status, reviewers, and linked issues in one call to simplify investigation.
Instructions
Bundle MR body, all notes (paginated up to maxNotes, filtered to non-system by default), commits, pipeline summary, reviewers with approval state, and issues this MR will close into a single call. Use this instead of fanning out across get_merge_requests + get_notes + get_merge_request_commits + get_merge_request_pipelines when investigating an MR.
Input Schema
| Name | Required | Description | Default |
|---|---|---|---|
| projectPath | Yes | Full project path (e.g. "my-group/my-project") | |
| iid | Yes | Merge request IID | |
| maxNotes | No | Cap on notes fetched. Default 100. | |
| maxCommits | No | Cap on commits fetched. Default 50. | |
| includeSystemNotes | No | Include system-generated notes. Default false. | |
| userCredentials | No | Your GitLab credentials (optional — falls back to the configured env token if not provided) |
Implementation Reference
- src/tools.ts:1103-1149 (handler)Main handler function for the 'get_merge_request_context' tool. It takes projectPath, iid, maxNotes, maxCommits, and includeSystemNotes as input, then fetches MR detail (via client.getMergeRequestDetail), notes (via client.getNotes), commits (via client.getMergeRequestCommits), pipelines (via client.getMergeRequestPipelines), reviewers (via client.getMergeRequestReviewers), and closes issues (via client.getMergeRequestClosesIssues) in parallel using Promise.all. It assembles all these into a single bundled response with the merge request body, notes, commits, pipelines, reviewers/approval state, and closing issues.
handler: async (input, client, userConfig) => { const credentials = input.userCredentials ? validateUserConfig(input.userCredentials) : userConfig; const projectPath = input.projectPath.trim(); const iid = input.iid.trim(); const [detail, notesResult, commitsResult, pipelinesResult, reviewers, closesIssues] = await Promise.all([ client.getMergeRequestDetail(projectPath, iid, credentials), client.getNotes(projectPath, 'merge_request', iid, input.maxNotes, undefined, true, credentials), client.getMergeRequestCommits(projectPath, iid, input.maxCommits, undefined, true, credentials), client.getMergeRequestPipelines(projectPath, iid, 5, undefined, false, credentials).catch(() => null), client.getMergeRequestReviewers(projectPath, iid, credentials).catch(() => null), client.getMergeRequestClosesIssues(projectPath, iid, credentials).catch(() => []), ]); const mr = detail?.project?.mergeRequest; if (!mr) { throw new Error(`Merge request ${projectPath}!${iid} not found.`); } const allNotes: any[] = Array.isArray(notesResult?.nodes) ? notesResult.nodes : []; const notes = input.includeSystemNotes ? allNotes : allNotes.filter((n) => !n.system); return { project: { fullPath: projectPath }, mergeRequest: mr, notes: { count: notes.length, truncated: !!notesResult?.hasMore, nodes: notes, }, commits: { count: Array.isArray(commitsResult?.nodes) ? commitsResult.nodes.length : 0, truncated: !!commitsResult?.hasMore, nodes: commitsResult?.nodes ?? [], }, pipelines: pipelinesResult ?? null, reviewers: reviewers ?? null, closesIssues: closesIssues.map((i: any) => ({ iid: String(i.iid), title: i.title, state: i.state, webUrl: i.web_url ?? null, projectId: i.project_id ?? null, })), }; }, }; - src/tools.ts:1096-1102 (schema)Input schema (Zod) for the 'get_merge_request_context' tool. Defines projectPath (required), iid (required), maxNotes (default 100, max 500), maxCommits (default 50, max 500), and includeSystemNotes (default false). Uses withUserAuth to optionally accept user credentials.
inputSchema: withUserAuth(z.object({ projectPath: z.string().min(1).describe('Full project path (e.g. "my-group/my-project")'), iid: z.string().min(1).describe('Merge request IID'), maxNotes: z.number().int().min(1).max(500).default(100).describe('Cap on notes fetched. Default 100.'), maxCommits: z.number().int().min(1).max(500).default(50).describe('Cap on commits fetched. Default 50.'), includeSystemNotes: z.boolean().default(false).describe('Include system-generated notes. Default false.'), })), - src/tools.ts:2284-2284 (registration)The getMergeRequestContextTool is included in the readOnlyTools array (line 2284), which is spread into the exported tools array (line 2335-2346). It is also registered via the ListToolsRequestSchema and CallToolRequestSchema handlers in src/index.ts (lines 88-146) by matching tool.name.
getMergeRequestContextTool, - src/gitlab-client.ts:792-833 (helper)Client method getMergeRequestDetail() - fetches the detailed MR info (title, description, state, branches, author, assignees, labels, milestone, diff stats) via GraphQL query, used by the handler.
async getMergeRequestDetail( projectPath: string, iid: string, userConfig?: UserConfig, ): Promise<any> { const query = gql` query getMergeRequestDetail($projectPath: ID!, $iid: String!) { project(fullPath: $projectPath) { fullPath mergeRequest(iid: $iid) { id iid title description state draft createdAt updatedAt mergedAt closedAt webUrl sourceBranch targetBranch author { username name } assignees { nodes { username name } } mergeUser { username name } labels { nodes { title color } } milestone { title state dueDate webPath } userNotesCount upvotes downvotes diffStatsSummary { additions deletions fileCount } } } } `; return this.query(query, { projectPath, iid }, userConfig); } - src/gitlab-client.ts:2818-2827 (helper)Client method getMergeRequestClosesIssues() - fetches issues that a merge request will close via the GitLab REST API (GET /projects/:id/merge_requests/:iid/closes_issues). Used by the handler.
async getMergeRequestClosesIssues( projectPath: string, iid: string, userConfig?: UserConfig, ): Promise<any[]> { const encodedPath = encodeURIComponent(projectPath); return this.restRequest('GET', `/projects/${encodedPath}/merge_requests/${iid}/closes_issues`, { userConfig, }); }