get_pull_request_comments
Fetch comments from any pull request by specifying repository owner, name, and pull number. Paginate results with per_page and page parameters.
Instructions
Get comments for a specific pull request
Input Schema
| Name | Required | Description | Default |
|---|---|---|---|
| owner | Yes | Repository owner | |
| repo | Yes | Repository name | |
| pullNumber | Yes | Pull request number | |
| per_page | No | Results per page (default 10, max 100) | |
| page | No | Page number (default 1) |
Implementation Reference
- src/tools/pullrequests.ts:532-618 (handler)Handler function that fetches and formats pull request comments. It calls both octokit.rest.issues.listComments and octokit.rest.pulls.listReviewComments in parallel, combines/sorts them by creation date, and formats the output as markdown.
async ({ owner, repo, pullNumber, per_page, page }) => { try { // Get both issue comments and review comments const [issueComments, reviewComments] = await Promise.all([ octokit.rest.issues.listComments({ owner, repo, issue_number: pullNumber, per_page, page, }), octokit.rest.pulls.listReviewComments({ owner, repo, pull_number: pullNumber, per_page, page, }), ]) // Combine and sort all comments by creation date const allComments = [ ...issueComments.data.map(c => ({ ...c, type: "issue" })), ...reviewComments.data.map(c => ({ ...c, type: "review" })), ].sort( (a, b) => new Date(a.created_at).getTime() - new Date(b.created_at).getTime(), ) if (allComments.length === 0) { return { content: [ { type: "text", text: "No comments found for this pull request.", }, ], } } // Format as clean markdown let markdown = `# Comments for Pull Request #${pullNumber}\n\n` markdown += `Showing ${allComments.length} comment(s) - Page ${page}\n` if ( issueComments.data.length === per_page || reviewComments.data.length === per_page ) { markdown += `*Note: More comments may be available. Use 'page' parameter to see next page.*\n` } markdown += `\n` allComments.forEach((comment, index) => { const isReviewComment = comment.type === "review" markdown += `## Comment ${index + 1}${isReviewComment ? " (Code Review)" : ""}\n\n` markdown += `- **Author:** ${comment.user?.login || "Unknown"}\n` markdown += `- **Created:** ${new Date(comment.created_at).toLocaleDateString()}\n` if (comment.updated_at !== comment.created_at) { markdown += `- **Updated:** ${new Date(comment.updated_at).toLocaleDateString()}\n` } // For review comments, show the file and line context if (isReviewComment && "path" in comment) { markdown += `- **File:** ${comment.path}\n` if (comment.line) { markdown += `- **Line:** ${comment.line}\n` } if (comment.commit_id) { markdown += `- **Commit:** ${comment.commit_id.substring(0, 7)}\n` } } markdown += `\n**Content:**\n${comment.body}\n\n` markdown += `---\n\n` }) return { content: [{ type: "text", text: markdown }], } } catch (e: any) { return { content: [{ type: "text", text: `Error: ${e.message}` }], } } }, ) - src/tools/pullrequests.ts:517-531 (schema)Zod schema defining the input parameters: owner, repo, pullNumber (required), per_page (optional, default 10), page (optional, default 1).
{ owner: z.string().describe("Repository owner"), repo: z.string().describe("Repository name"), pullNumber: z.number().describe("Pull request number"), per_page: z .number() .optional() .default(10) .describe("Results per page (default 10, max 100)"), page: z .number() .optional() .default(1) .describe("Page number (default 1)"), }, - src/tools/pullrequests.ts:514-618 (registration)Registration of the tool via server.tool('get_pull_request_comments', ...) with description and handler.
server.tool( "get_pull_request_comments", "Get comments for a specific pull request", { owner: z.string().describe("Repository owner"), repo: z.string().describe("Repository name"), pullNumber: z.number().describe("Pull request number"), per_page: z .number() .optional() .default(10) .describe("Results per page (default 10, max 100)"), page: z .number() .optional() .default(1) .describe("Page number (default 1)"), }, async ({ owner, repo, pullNumber, per_page, page }) => { try { // Get both issue comments and review comments const [issueComments, reviewComments] = await Promise.all([ octokit.rest.issues.listComments({ owner, repo, issue_number: pullNumber, per_page, page, }), octokit.rest.pulls.listReviewComments({ owner, repo, pull_number: pullNumber, per_page, page, }), ]) // Combine and sort all comments by creation date const allComments = [ ...issueComments.data.map(c => ({ ...c, type: "issue" })), ...reviewComments.data.map(c => ({ ...c, type: "review" })), ].sort( (a, b) => new Date(a.created_at).getTime() - new Date(b.created_at).getTime(), ) if (allComments.length === 0) { return { content: [ { type: "text", text: "No comments found for this pull request.", }, ], } } // Format as clean markdown let markdown = `# Comments for Pull Request #${pullNumber}\n\n` markdown += `Showing ${allComments.length} comment(s) - Page ${page}\n` if ( issueComments.data.length === per_page || reviewComments.data.length === per_page ) { markdown += `*Note: More comments may be available. Use 'page' parameter to see next page.*\n` } markdown += `\n` allComments.forEach((comment, index) => { const isReviewComment = comment.type === "review" markdown += `## Comment ${index + 1}${isReviewComment ? " (Code Review)" : ""}\n\n` markdown += `- **Author:** ${comment.user?.login || "Unknown"}\n` markdown += `- **Created:** ${new Date(comment.created_at).toLocaleDateString()}\n` if (comment.updated_at !== comment.created_at) { markdown += `- **Updated:** ${new Date(comment.updated_at).toLocaleDateString()}\n` } // For review comments, show the file and line context if (isReviewComment && "path" in comment) { markdown += `- **File:** ${comment.path}\n` if (comment.line) { markdown += `- **Line:** ${comment.line}\n` } if (comment.commit_id) { markdown += `- **Commit:** ${comment.commit_id.substring(0, 7)}\n` } } markdown += `\n**Content:**\n${comment.body}\n\n` markdown += `---\n\n` }) return { content: [{ type: "text", text: markdown }], } } catch (e: any) { return { content: [{ type: "text", text: `Error: ${e.message}` }], } } }, ) - src/tools/pullrequests.ts:5-5 (helper)Export function registerPullRequestTools which is the container for registering all pull request tools including get_pull_request_comments.
export function registerPullRequestTools(server: McpServer, octokit: Octokit) { - src/index.ts:14-19 (registration)Parent registration: registerAllToolsAndResources calls registerPullRequestTools which setups the get_pull_request_comments tool.
export function registerAllToolsAndResources(server: McpServer, octokit: Octokit): void { registerSearchTools(server, octokit) registerIssueTools(server, octokit) registerRepositoryTools(server, octokit) registerPullRequestTools(server, octokit) registerRepositoryResource(server, octokit)