get_pr_comments
Fetch detailed GitHub pull request comments, including file paths, line ranges, and replies, for efficient code review and collaboration.
Input Schema
TableJSON Schema
| Name | Required | Description | Default |
|---|---|---|---|
| owner | Yes | Repository owner (username or organization) | |
| pull_number | Yes | Pull request number | |
| repo | Yes | Repository name |
Implementation Reference
- src/github-service.ts:13-75 (handler)Core handler function that fetches GitHub PR review comments using Octokit, processes them to group top-level comments and attach replies, and returns structured Comment[]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)MCP tool registration for 'get_pr_comments', including input schema (Zod), handler wrapper, and 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-31 (schema)TypeScript interfaces defining input parameters (GetPRCommentsParams) and response structure (GetPRCommentsResponse) for the get_pr_comments tool.export interface GetPRCommentsParams { owner: string; repo: string; pull_number: number; } export interface GetPRCommentsResponse { comments: Comment[]; }
- src/types.ts:10-21 (schema)TypeScript interface for Comment, including replies, used in the tool's response.export interface Comment { id: number; path: string; body: string; line?: number; start_line?: number; user: { login: string; }; created_at: string; replies: CommentReply[]; }
- src/types.ts:1-8 (schema)TypeScript interface for CommentReply, supporting nested replies in PR comments.export interface CommentReply { id: number; body: string; user: { login: string; }; created_at: string; }