UNPKG

coderabbitai-mcp

Version:

MCP server for interacting with CodeRabbit AI reviews on GitHub pull requests. Enables LLMs to analyze, implement, and resolve CodeRabbit suggestions programmatically.

112 lines 4.71 kB
import { z } from 'zod'; const GetReviewCommentsSchema = z.object({ owner: z.string().min(1, "Repository owner is required"), repo: z.string().min(1, "Repository name is required"), pullNumber: z.number().int().positive("Pull request number must be positive"), reviewId: z.number().int().positive("Review ID must be positive").optional() }); /** * Parse CodeRabbit comment body to extract structured information */ function parseCoderabbitComment(comment) { const body = comment.body; // Determine severity from markers let severity = 'info'; let category = 'General'; if (body.includes('⚠️ Potential issue') || body.includes('_⚠️ Potential issue_')) { severity = 'warning'; category = 'Potential Issue'; } else if (body.includes('🛠️ Refactor suggestion') || body.includes('_🛠️ Refactor suggestion_')) { severity = 'suggestion'; category = 'Refactor Suggestion'; } else if (body.includes('🧹 Nitpick')) { severity = 'info'; category = 'Nitpick'; } else if (body.includes('🔒 Security')) { severity = 'error'; category = 'Security'; } // Extract AI prompt const aiPromptMatch = body.match(/🤖 Prompt for AI Agents[\s\S]*?```\n([\s\S]*?)\n```/); const aiPrompt = aiPromptMatch ? aiPromptMatch[1].trim() : undefined; // Extract committable suggestion const committableMatch = body.match(/📝 Committable suggestion[\s\S]*?```suggestion\n([\s\S]*?)\n```/); const committableSuggestion = committableMatch ? committableMatch[1].trim() : undefined; // Extract main description (first substantial paragraph) const descLines = body.split('\n').filter(line => line.trim() && !line.includes('_⚠️') && !line.includes('_🛠️') && !line.includes('🤖 Prompt') && !line.includes('📝 Committable') && !line.trim().startsWith('<') && !line.trim().startsWith('```')); const description = descLines.slice(0, 3).join(' ').trim() || 'CodeRabbit suggestion'; // Parse line range from diff_hunk or comment position let lineRange = { start: 1, end: 1 }; if (comment.original_start_line && comment.original_line) { lineRange = { start: comment.original_start_line, end: comment.original_line }; } else if (comment.original_line) { lineRange = { start: comment.original_line, end: comment.original_line }; } // Check if comment is resolved (GitHub doesn't provide this directly, so we check for resolution indicators) const isResolved = body.includes('✅ Addressed') || body.includes('✅ Fixed') || body.includes('✅ Resolved'); return { id: comment.id, body: comment.body, path: comment.path, line_range: lineRange, side: comment.side, severity, category, description, ai_prompt: aiPrompt, committable_suggestion: committableSuggestion, html_url: comment.html_url, diff_hunk: comment.diff_hunk, created_at: comment.created_at, updated_at: comment.updated_at, is_resolved: isResolved }; } /** * Get all CodeRabbit comments for a pull request or specific review */ export async function getReviewComments(input, githubClient) { // Validate input const validatedInput = GetReviewCommentsSchema.parse(input); const { owner, repo, pullNumber, reviewId } = validatedInput; try { // Get all comments for the PR using GitHub API const allComments = await githubClient.getPullRequestComments(owner, repo, pullNumber); // Filter for CodeRabbit comments let coderabbitComments = allComments.filter(comment => comment.user.login === 'coderabbitai[bot]'); // If reviewId is specified, filter for that specific review if (reviewId) { coderabbitComments = coderabbitComments.filter(comment => comment.pull_request_review_id === reviewId); } // Parse and enrich each comment const enrichedComments = coderabbitComments.map(parseCoderabbitComment); // Sort by file path and line number for better organization enrichedComments.sort((a, b) => { if (a.path !== b.path) { return a.path.localeCompare(b.path); } return a.line_range.start - b.line_range.start; }); return enrichedComments; } catch (error) { throw new Error(`Failed to get review comments: ${error instanceof Error ? error.message : String(error)}`); } } //# sourceMappingURL=get-comments.js.map