github.getReviewComments
Fetch user review comments from GitHub pull requests within a time range to analyze review quality, quantity, and engagement metrics for performance assessment.
Instructions
Fetch all inline and general review comments authored by a user within a time range, filtered by repository. Returns structured JSON with PR-level grouping, total PRs reviewed, total comments, user ID, date range, and for each PR: array of comment bodies and total comments count. Automatically filters out auto-generated comments and comments on auto-created PRs. All comment bodies are properly JSON-escaped. Use this tool to analyze review comment quality and quantity.
Example use cases:
Count review comments to assess review thoroughness
Analyze comment patterns across different PRs
Track review engagement metrics
Extract review feedback for analysis
Returns: Object with userId, dateRange, totalPRsReviewed, totalComments, and array of PR objects (each with prId, prNumber, prTitle, prRepo, prUrl, prCreatedAt, comments array, totalComments)
Input Schema
| Name | Required | Description | Default |
|---|---|---|---|
| username | Yes | GitHub username (case-insensitive, @ prefix optional). Examples: "octocat", "@octocat" | |
| repo | Yes | Repository in owner/repo format. Required - only comments for PRs in this repository will be returned. Example: "owner/repo" | |
| from | Yes | Start timestamp in ISO 8601 format. Example: "2024-01-01T00:00:00Z" | |
| to | Yes | End timestamp in ISO 8601 format. Example: "2024-12-31T23:59:59Z" |
Implementation Reference
- src/mcp/tools.ts:555-615 (handler)Primary handler implementation for github.getReviewComments tool. Validates parameters, fetches raw review comments, applies filters (repository matching, auto-generated content exclusion), groups comments by PR, computes totals, and structures the response.async getReviewComments( username: string, repos: string[], from?: string, to?: string ): Promise<ReviewCommentsResponse> { const { normalizedUsername, normalizedRepos, from: validatedFrom, to: validatedTo } = this.validateCommonParameters(username, repos, from, to); const allComments = await this.getReviewCommentsAsObjects(normalizedUsername, validatedFrom, validatedTo); // Group comments by PR const prsMap = new Map<string, PRReviewComments>(); for (const comment of allComments) { // Use shared filter method if (!this.filterReviewComment(comment, normalizedRepos)) { continue; } const prKey = comment.prId; if (!prsMap.has(prKey)) { prsMap.set(prKey, { prId: comment.prId, prNumber: comment.prNumber, prTitle: comment.prTitle, prRepo: comment.prRepo, prUrl: comment.prUrl || '', prCreatedAt: comment.prCreatedAt || '', comments: [], totalComments: 0, }); } const prData = prsMap.get(prKey)!; // Store comment body as-is (JSON.stringify will handle escaping when serializing) prData.comments.push(comment.body); prData.totalComments = prData.comments.length; } // Convert map to array (already filtered for auto PRs) const prs = Array.from(prsMap.values()); // Calculate totals - count only comments that passed all filters const totalPRsReviewed = prs.length; const totalComments = prs.reduce((sum, pr) => sum + pr.totalComments, 0); const response: ReviewCommentsResponse = { userId: normalizedUsername, dateRange: { from: validatedFrom, to: validatedTo, }, totalPRsReviewed, totalComments, prs, }; // Return the response - JSON.stringify in server.ts will properly escape all content return response; }
- src/mcp/tools.ts:1211-1247 (schema)Input schema and description definition for the github.getReviewComments tool within getToolDefinitions().name: 'github.getReviewComments', description: `Fetch all inline and general review comments authored by a user within a time range, filtered by repository. Returns structured JSON with PR-level grouping, total PRs reviewed, total comments, user ID, date range, and for each PR: array of comment bodies and total comments count. Automatically filters out auto-generated comments and comments on auto-created PRs. All comment bodies are properly JSON-escaped. Use this tool to analyze review comment quality and quantity. Example use cases: - Count review comments to assess review thoroughness - Analyze comment patterns across different PRs - Track review engagement metrics - Extract review feedback for analysis Returns: Object with userId, dateRange, totalPRsReviewed, totalComments, and array of PR objects (each with prId, prNumber, prTitle, prRepo, prUrl, prCreatedAt, comments array, totalComments)`, inputSchema: { type: 'object', properties: { username: { type: 'string', description: 'GitHub username (case-insensitive, @ prefix optional). Examples: "octocat", "@octocat"', examples: ['octocat', '@octocat'], }, repo: { type: 'string', description: 'Repository in owner/repo format. Required - only comments for PRs in this repository will be returned. Example: "owner/repo"', examples: ['owner/repo', 'radireddy/AiApps'], }, from: { type: 'string', description: 'Start timestamp in ISO 8601 format. Example: "2024-01-01T00:00:00Z"', examples: ['2024-01-01T00:00:00Z'], }, to: { type: 'string', description: 'End timestamp in ISO 8601 format. Example: "2024-12-31T23:59:59Z"', examples: ['2024-12-31T23:59:59Z'], }, }, required: ['username', 'repo', 'from', 'to'], }, },
- src/mcp/server.ts:95-110 (registration)Registration and dispatching logic in the MCP server's CallToolRequestSchema handler switch statement, which calls the tool implementation and formats the response.case 'github.getReviewComments': { const result = await tools.getReviewComments( args.username as string, args.repos as string[], args.from as string | undefined, args.to as string | undefined ); return { content: [ { type: 'text', text: JSON.stringify(result, null, 2), }, ], }; }
- src/mcp/server.ts:43-47 (registration)Registration of the ListToolsRequestSchema handler which exposes the tool definitions including github.getReviewComments via getToolDefinitions().server.setRequestHandler(ListToolsRequestSchema, async () => { return { tools: getToolDefinitions(), }; });
- src/mcp/tools.ts:490-540 (helper)Helper method that performs the core data fetching of review comments using GitHub GraphQL API (QUERIES.ReviewComments), initial filtering, and pagination.private async getReviewCommentsAsObjects( username: string, from: string, to: string ): Promise<ReviewComment[]> { const normalizedUsername = this.normalizeUsername(username); validateTimeRange(from, to); const allComments = await fetchAllPages( async (cursor: string | null) => { const response = await this.client.query(QUERIES.ReviewComments, { username: normalizedUsername, from: validateTimestamp(from), to: validateTimestamp(to), after: cursor, }); return response.data; }, (data: any) => { const contributions = data.user?.contributionsCollection ?.pullRequestReviewContributions?.nodes || []; const comments: ReviewComment[] = []; for (const contribution of contributions) { const review = contribution.pullRequestReview; const pr = review.pullRequest; // Filter out auto-created PRs if (this.isAutoCreatedPR(pr.title)) { continue; } const reviewComments = mapReviewComments(contribution); // Filter out auto-generated comments for (const comment of reviewComments) { if (!this.isAutoGeneratedComment(comment.body)) { comments.push(comment); } } } return comments; }, (data: any) => { const pageInfo = data.user?.contributionsCollection ?.pullRequestReviewContributions?.pageInfo || {}; return extractPageInfo(pageInfo); } ); return allComments; }