get_pr_comments
Retrieve GitHub pull request comments including file paths, line ranges, and reply threads to review code feedback and discussions.
Input Schema
TableJSON Schema
| Name | Required | Description | Default |
|---|---|---|---|
| owner | Yes | Repository owner (username or organization) | |
| repo | Yes | Repository name | |
| pull_number | Yes | Pull request number |
Implementation Reference
- src/server.ts:43-65 (handler)MCP handler function that processes input arguments, calls the GitHub service to retrieve PR comments, formats the response as MCP content with JSON-stringified comments, and handles errors.async (args: { owner: string; repo: string; pull_number: number }) => { try { const params: GetPRCommentsParams = { owner: args.owner, repo: args.repo, pull_number: args.pull_number }; const comments = await githubService.getPRComments(params); return { content: [ { type: 'text' as const, text: JSON.stringify({ comments }, null, 2) } ] }; } catch (error) { console.error('Error in get_pr_comments tool:', error); throw error; } },
- src/github-service.ts:13-75 (helper)Main logic for fetching GitHub PR review comments using Octokit, processing and grouping top-level comments with their replies into structured Comment objects.async getPRComments({ owner, repo, pull_number }: GetPRCommentsParams): Promise<Comment[]> { try { // Fetch review comments on the pull request (line comments) const { data: reviewComments } = await this.octokit.pulls.listReviewComments({ owner, repo, pull_number, per_page: 100 }); // Group comments by their path and in_reply_to_id const groupedComments = new Map<number, Comment>(); const replyMap = new Map<number, CommentReply[]>(); // Process all comments and separate top-level comments from replies for (const comment of reviewComments) { if (comment.in_reply_to_id) { // This is a reply to another comment const reply: CommentReply = { id: comment.id, body: comment.body, user: { login: comment.user?.login || 'unknown' }, created_at: comment.created_at }; if (!replyMap.has(comment.in_reply_to_id)) { replyMap.set(comment.in_reply_to_id, []); } replyMap.get(comment.in_reply_to_id)?.push(reply); } else { // This is a top-level comment const newComment: Comment = { id: comment.id, path: comment.path, body: comment.body, line: comment.line || undefined, start_line: comment.start_line || undefined, user: { login: comment.user?.login || 'unknown' }, created_at: comment.created_at, replies: [] }; groupedComments.set(comment.id, newComment); } } // Attach replies to their parent comments for (const [commentId, replies] of replyMap.entries()) { const parentComment = groupedComments.get(commentId); if (parentComment) { parentComment.replies = replies; } } return Array.from(groupedComments.values()); } catch (error) { console.error('Error fetching PR comments:', error); throw error; } }
- src/server.ts:36-69 (registration)Registration of the 'get_pr_comments' tool with MCP server, including input Zod schema, handler function, and tool description.server.tool( 'get_pr_comments', { owner: z.string().min(1).describe('Repository owner (username or organization)'), repo: z.string().min(1).describe('Repository name'), pull_number: z.number().int().positive().describe('Pull request number') }, async (args: { owner: string; repo: string; pull_number: number }) => { try { const params: GetPRCommentsParams = { owner: args.owner, repo: args.repo, pull_number: args.pull_number }; const comments = await githubService.getPRComments(params); return { content: [ { type: 'text' as const, text: JSON.stringify({ comments }, null, 2) } ] }; } catch (error) { console.error('Error in get_pr_comments tool:', error); throw error; } }, { description: 'Fetches comments from a GitHub pull request with their file paths, line ranges, and replies' } );
- src/types.ts:23-27 (schema)TypeScript interface defining input parameters for getPRComments.export interface GetPRCommentsParams { owner: string; repo: string; pull_number: number; }
- src/types.ts:1-21 (schema)TypeScript interfaces defining the structure of Comment and CommentReply used in the tool response.export interface CommentReply { id: number; body: string; user: { login: string; }; created_at: string; } export interface Comment { id: number; path: string; body: string; line?: number; start_line?: number; user: { login: string; }; created_at: string; replies: CommentReply[]; }