list_mr_discussions
Retrieve threaded comments and inline code discussions from GitLab merge requests. Filter unresolved discussions to reduce token usage and focus on pending feedback.
Instructions
List discussions (threaded comments including inline code comments) on a merge request. Use unresolved_only=true to fetch only unresolved discussions (saves tokens).
Input Schema
TableJSON Schema
| Name | Required | Description | Default |
|---|---|---|---|
| project_id | Yes | Project ID or path | |
| merge_request_iid | Yes | Merge request internal ID | |
| unresolved_only | No | If true, fetches all discussions and returns only unresolved ones. This reduces tokens sent to the LLM by filtering server-side. | |
| page | No | Page number for pagination (default: 1). Ignored when unresolved_only=true (fetches all pages). | |
| per_page | No | Number of results per page (max 100) |
Implementation Reference
- src/handlers/merge-requests.ts:326-401 (handler)The core handler function that executes the tool logic. Fetches merge request discussions from GitLab API, supporting pagination and special filtering for unresolved discussions only.async listMRDiscussions(args: ListMRDiscussionsParams) { const encodedProjectId = encodeURIComponent(args.project_id); const perPage = args.per_page || 20; // If unresolved_only is true, fetch all pages and filter if (args.unresolved_only) { const allDiscussions: any[] = []; let page = 1; let hasMore = true; // Fetch all pages (use max per_page for efficiency) while (hasMore) { const { data, headers } = await this.client.getWithHeaders( `/projects/${encodedProjectId}/merge_requests/${args.merge_request_iid}/discussions?per_page=100&page=${page}` ); allDiscussions.push(...data); // Check if there are more pages const nextPage = headers['x-next-page']; hasMore = !!nextPage && nextPage !== ''; page++; // Safety limit to prevent infinite loops if (page > 100) break; } // Filter to only unresolved discussions // A discussion is unresolved if it has resolvable notes and at least one is not resolved const unresolvedDiscussions = allDiscussions.filter((discussion) => { // Check if any note in the discussion is resolvable and not resolved const hasUnresolvedNotes = discussion.notes?.some( (note: any) => note.resolvable === true && note.resolved === false ); return hasUnresolvedNotes; }); return { content: [ { type: 'text', text: JSON.stringify( { discussions: unresolvedDiscussions, metadata: { total_fetched: allDiscussions.length, unresolved_count: unresolvedDiscussions.length, filtered: true, }, }, null, 2 ), }, ], }; } // Normal pagination mode const params = new URLSearchParams(); if (args.page) params.append("page", String(args.page)); params.append("per_page", String(perPage)); const data = await this.client.get( `/projects/${encodedProjectId}/merge_requests/${args.merge_request_iid}/discussions?${params.toString()}` ); return { content: [ { type: "text", text: JSON.stringify(data, null, 2), }, ], }; }
- src/tools/merge-requests.ts:340-377 (schema)Tool definition including the name, description, and JSON input schema for validation.{ 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'], }, },
- src/server.ts:211-214 (registration)Registration in the main server switch statement that dispatches tool calls to the specific handler.case "list_mr_discussions": return await this.mergeRequestHandlers.listMRDiscussions( args as unknown as ListMRDiscussionsParams );
- src/types.ts:477-483 (schema)TypeScript interface defining the input parameters for type safety.export interface ListMRDiscussionsParams { project_id: string; merge_request_iid: number; unresolved_only?: boolean; page?: number; per_page?: number; }
- src/tools/merge-requests.ts:340-377 (registration)The tool is registered here as part of the exported mergeRequestTools array, used for listing available tools.{ 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'], }, },