comments
Fetch and display GitHub pull request comments, including reviews and issue discussions, to track feedback and collaboration.
Instructions
Fetch and display comments on a pull request, including review comments and issue comments.
Input Schema
TableJSON Schema
| Name | Required | Description | Default |
|---|---|---|---|
| prUrl | Yes | Full GitHub PR URL to fetch comments for | |
| showBots | No | If true, include bot comments in the output |
Implementation Reference
- The runComments function implements the logic for fetching and categorizing comments on a GitHub PR.
export async function runComments(options: CommentsOptions): Promise<CommentsOutput> { validateUrl(options.prUrl); validateGitHubUrl(options.prUrl, PR_URL_PATTERN, 'PR'); const token = requireGitHubToken(); const stateManager = getStateManager(); const octokit = getOctokit(token); // Parse PR URL const parsed = parseGitHubUrl(options.prUrl); if (!parsed || parsed.type !== 'pull') { throw new Error('Invalid PR URL format'); } const { owner, repo, number: pull_number } = parsed; // Get PR details const { data: pr } = await octokit.pulls.get({ owner, repo, pull_number }); // Fetch review comments, issue comments, and reviews in parallel const [reviewComments, issueComments, reviews] = await Promise.all([ paginateAll((page) => octokit.pulls.listReviewComments({ owner, repo, pull_number, per_page: 100, page, }), ), paginateAll((page) => octokit.issues.listComments({ owner, repo, issue_number: pull_number, per_page: 100, page, }), ), paginateAll((page) => octokit.pulls.listReviews({ owner, repo, pull_number, per_page: 100, page, }), ), ]); // Filter out own comments, optionally show bots const username = stateManager.getState().config.githubUsername; const filterComment = (c: { user?: { login?: string; type?: string } | null }) => { if (!c.user) return false; if (c.user.login === username) return false; if (c.user.type === 'Bot' && !options.showBots) return false; return true; }; const relevantReviewComments = reviewComments .filter(filterComment) .sort((a, b) => new Date(b.created_at).getTime() - new Date(a.created_at).getTime()); const relevantIssueComments = issueComments .filter(filterComment) .sort((a, b) => new Date(b.created_at).getTime() - new Date(a.created_at).getTime()); const relevantReviews = reviews .filter((r) => filterComment(r) && r.body && r.body.trim()) .sort((a, b) => new Date(b.submitted_at || 0).getTime() - new Date(a.submitted_at || 0).getTime()); return { pr: { title: pr.title, state: pr.state, mergeable: pr.mergeable, head: pr.head.ref, base: pr.base.ref, url: pr.html_url, }, reviews: relevantReviews.map((r) => ({ user: r.user?.login, state: r.state, body: r.body ?? null, submittedAt: r.submitted_at ?? null, })), reviewComments: relevantReviewComments.map((c) => ({ user: c.user?.login, body: c.body, path: c.path, createdAt: c.created_at, })), issueComments: relevantIssueComments.map((c) => ({ user: c.user?.login, body: c.body, createdAt: c.created_at, })), summary: { reviewCount: relevantReviews.length, inlineCommentCount: relevantReviewComments.length, discussionCommentCount: relevantIssueComments.length, }, }; } - packages/mcp-server/src/tools.ts:171-183 (registration)The 'comments' tool is registered in the MCP server using runComments as its handler.
// 8. comments — Show PR comments server.registerTool( 'comments', { description: 'Fetch and display comments on a pull request, including review comments and issue comments.', inputSchema: { prUrl: z.string().describe('Full GitHub PR URL to fetch comments for'), showBots: z.boolean().optional().describe('If true, include bot comments in the output'), }, annotations: { readOnlyHint: true }, }, wrapTool(runComments), );