Skip to main content
Glama

Python Code Review MCP Agent

by JJJHoons
report-formatter.tsโ€ข13.4 kB
/** * Detailed Report Formatter for Python Code Review * Generates comprehensive, consistent reports for code analysis */ import { AnalysisResult, CodeIssue } from './python-analyzer.js'; export class ReportFormatter { public generateDetailedReport(result: AnalysisResult): string { const sections = [ this.generateHeader(result), this.generateExecutiveSummary(result), this.generateScorecard(result), this.generateIssuesBreakdown(result), this.generateDetailedIssues(result), this.generateRecommendations(result), this.generateFooter() ]; return sections.join('\n\n'); } public generateSummaryReport(result: AnalysisResult): string { const sections = [ this.generateHeader(result), this.generateScorecard(result), this.generateTopIssues(result, 5), this.generateQuickRecommendations(result) ]; return sections.join('\n\n'); } public generateSecurityReport(result: AnalysisResult): string { const securityIssues = result.issues.filter(issue => issue.type === 'security'); const sections = [ '๐Ÿ”’ **SECURITY ANALYSIS REPORT**', '=' + '='.repeat(50), `**File:** ${result.fileName}`, `**Security Score:** ${result.securityScore}/100 ${this.getSecurityRating(result.securityScore)}`, `**Security Issues Found:** ${securityIssues.length}`, '', this.generateSecurityIssuesDetail(securityIssues), this.generateSecurityRecommendations(securityIssues) ]; return sections.join('\n'); } private generateHeader(result: AnalysisResult): string { const timestamp = new Date().toISOString().replace('T', ' ').substring(0, 19); return [ '๐Ÿ“‹ **PYTHON CODE REVIEW REPORT**', '=' + '='.repeat(50), `**File:** ${result.fileName}`, `**Analysis Date:** ${timestamp}`, `**Total Lines:** ${result.totalLines}`, `**Total Issues:** ${result.totalIssues}` ].join('\n'); } private generateExecutiveSummary(result: AnalysisResult): string { const riskLevel = this.calculateRiskLevel(result); const deploymentReady = result.criticalIssues === 0 && result.highIssues <= 2; return [ '## ๐Ÿ“Š **EXECUTIVE SUMMARY**', '', `**Overall Risk Level:** ${riskLevel}`, `**Production Ready:** ${deploymentReady ? 'โœ… YES' : 'โŒ NO'}`, `**Summary:** ${result.summary}`, '', this.generateRiskBreakdown(result) ].join('\n'); } private generateScorecard(result: AnalysisResult): string { return [ '## ๐ŸŽฏ **QUALITY SCORECARD**', '', `| Metric | Score | Rating |`, `|--------|-------|--------|`, `| Code Quality | ${result.codeQualityScore}/100 | ${this.getRating(result.codeQualityScore)} |`, `| Security | ${result.securityScore}/100 | ${this.getSecurityRating(result.securityScore)} |`, `| Issues Density | ${(result.totalIssues / result.totalLines * 100).toFixed(2)} per 100 lines | ${this.getDensityRating(result.totalIssues / result.totalLines)} |`, '' ].join('\n'); } private generateIssuesBreakdown(result: AnalysisResult): string { const typeBreakdown = this.getIssueTypeBreakdown(result.issues); return [ '## ๐Ÿ” **ISSUES BREAKDOWN**', '', '### By Severity:', `- ๐Ÿ”ด **Critical:** ${result.criticalIssues} issues`, `- ๐ŸŸ  **High:** ${result.highIssues} issues`, `- ๐ŸŸก **Medium:** ${result.mediumIssues} issues`, `- ๐Ÿ”ต **Low:** ${result.lowIssues} issues`, '', '### By Category:', ...Object.entries(typeBreakdown).map(([type, count]) => `- ${this.getTypeIcon(type)} **${this.capitalize(type)}:** ${count} issues` ) ].join('\n'); } private generateDetailedIssues(result: AnalysisResult): string { if (result.issues.length === 0) { return '## โœ… **NO ISSUES FOUND**\n\nExcellent work! Your code follows best practices.'; } const sections = ['## ๐Ÿšจ **DETAILED ISSUES**', '']; const groupedIssues = this.groupIssuesBySeverity(result.issues); Object.entries(groupedIssues).forEach(([severity, issues]) => { if (issues.length > 0) { sections.push(`### ${this.getSeverityIcon(severity)} ${this.capitalize(severity)} Issues (${issues.length})`); sections.push(''); issues.forEach((issue, index) => { sections.push(this.formatDetailedIssue(issue, index + 1)); sections.push(''); }); } }); return sections.join('\n'); } private generateRecommendations(result: AnalysisResult): string { return [ '## ๐Ÿ’ก **RECOMMENDATIONS**', '', ...result.recommendations.map(rec => `- ${rec}`), '', '### Next Steps:', this.generateNextSteps(result) ].join('\n'); } private generateTopIssues(result: AnalysisResult, limit: number): string { const topIssues = result.issues .slice(0, limit) .map((issue, index) => this.formatBriefIssue(issue, index + 1)); if (topIssues.length === 0) { return '## โœ… **NO MAJOR ISSUES**\n\nYour code looks great!'; } return [ `## ๐Ÿ” **TOP ${limit} ISSUES**`, '', ...topIssues ].join('\n'); } private generateSecurityIssuesDetail(issues: CodeIssue[]): string { if (issues.length === 0) { return 'โœ… **NO SECURITY VULNERABILITIES DETECTED**\n\nYour code appears secure from common vulnerabilities.'; } const sections = ['## ๐Ÿ›ก๏ธ **SECURITY VULNERABILITIES**', '']; issues.forEach((issue, index) => { sections.push(`### ${index + 1}. ${issue.message}`); sections.push(`**Severity:** ${this.getSeverityIcon(issue.severity)} ${issue.severity.toUpperCase()}`); sections.push(`**Line:** ${issue.line}`); sections.push(`**Rule:** ${issue.rule}`); if (issue.codeSnippet) { sections.push(`**Code:** \`${issue.codeSnippet}\``); } if (issue.suggestion) { sections.push(`**Fix:** ${issue.suggestion}`); } sections.push(''); }); return sections.join('\n'); } private generateSecurityRecommendations(issues: CodeIssue[]): string { const recommendations = [ '## ๐Ÿ› ๏ธ **SECURITY RECOMMENDATIONS**', '' ]; if (issues.length === 0) { recommendations.push('- Continue following secure coding practices'); recommendations.push('- Regular security audits and dependency updates'); recommendations.push('- Consider implementing automated security scanning in CI/CD'); return recommendations.join('\n'); } const criticalCount = issues.filter(i => i.severity === 'critical').length; const highCount = issues.filter(i => i.severity === 'high').length; if (criticalCount > 0) { recommendations.push('๐Ÿšจ **IMMEDIATE ACTIONS REQUIRED:**'); recommendations.push(`- Fix all ${criticalCount} critical vulnerabilities before production deployment`); recommendations.push('- Conduct thorough penetration testing'); recommendations.push('- Review access controls and authentication mechanisms'); recommendations.push(''); } if (highCount > 0) { recommendations.push('โš ๏ธ **HIGH PRIORITY ACTIONS:**'); recommendations.push(`- Address ${highCount} high-priority security issues`); recommendations.push('- Implement input validation and sanitization'); recommendations.push('- Review error handling and information disclosure'); recommendations.push(''); } recommendations.push('๐Ÿ“‹ **GENERAL SECURITY BEST PRACTICES:**'); recommendations.push('- Use parameterized queries for database operations'); recommendations.push('- Store sensitive data in environment variables'); recommendations.push('- Enable SSL/TLS verification'); recommendations.push('- Use cryptographically secure random number generation'); recommendations.push('- Implement proper error handling without information leakage'); return recommendations.join('\n'); } private formatDetailedIssue(issue: CodeIssue, index: number): string { const lines = [ `#### ${index}. ${issue.message}`, '', `**Type:** ${this.getTypeIcon(issue.type)} ${this.capitalize(issue.type)}`, `**Severity:** ${this.getSeverityIcon(issue.severity)} ${issue.severity.toUpperCase()}`, `**Line:** ${issue.line}`, `**Rule:** \`${issue.rule}\`` ]; if (issue.codeSnippet) { lines.push(`**Code:**`); lines.push('```python'); lines.push(issue.codeSnippet); lines.push('```'); } if (issue.suggestion) { lines.push(`**๐Ÿ’ก Suggestion:** ${issue.suggestion}`); } return lines.join('\n'); } private formatBriefIssue(issue: CodeIssue, index: number): string { return `${index}. ${this.getSeverityIcon(issue.severity)} **Line ${issue.line}:** ${issue.message}`; } private generateNextSteps(result: AnalysisResult): string { const steps = []; if (result.criticalIssues > 0) { steps.push('1. ๐Ÿšจ **CRITICAL:** Address all critical security vulnerabilities immediately'); } if (result.highIssues > 0) { steps.push(`${steps.length + 1}. โš ๏ธ **HIGH:** Fix ${result.highIssues} high-priority issues`); } if (result.mediumIssues > 0) { steps.push(`${steps.length + 1}. ๐Ÿ“‹ **MEDIUM:** Plan to address ${result.mediumIssues} medium-priority issues`); } if (result.lowIssues > 0) { steps.push(`${steps.length + 1}. ๐Ÿ”ง **MAINTENANCE:** Address ${result.lowIssues} low-priority issues during refactoring`); } steps.push(`${steps.length + 1}. โœ… **VERIFY:** Run tests and verify all fixes work correctly`); steps.push(`${steps.length + 1}. ๐Ÿ”„ **REPEAT:** Re-run code review after fixes are applied`); return steps.join('\n'); } private generateQuickRecommendations(result: AnalysisResult): string { const quickRecs = result.recommendations.slice(0, 3); return [ '## ๐ŸŽฏ **QUICK WINS**', '', ...quickRecs.map(rec => `- ${rec}`) ].join('\n'); } private generateFooter(): string { return [ '---', '**Report Generated by Python Code Review MCP Agent**', '', '๐Ÿ’ก *This automated analysis focuses on code quality and security.*', '๐Ÿ”„ *Re-run analysis after applying fixes to track improvements.*' ].join('\n'); } // Helper methods private calculateRiskLevel(result: AnalysisResult): string { if (result.criticalIssues > 0) return '๐Ÿ”ด **CRITICAL RISK**'; if (result.highIssues > 3) return '๐ŸŸ  **HIGH RISK**'; if (result.mediumIssues > 5) return '๐ŸŸก **MEDIUM RISK**'; return '๐ŸŸข **LOW RISK**'; } private generateRiskBreakdown(result: AnalysisResult): string { const risks = []; if (result.criticalIssues > 0) { risks.push(`- ๐Ÿšจ ${result.criticalIssues} critical security vulnerabilities`); } if (result.securityScore < 70) { risks.push(`- ๐Ÿ”’ Security score below acceptable threshold (${result.securityScore}/100)`); } if (result.codeQualityScore < 70) { risks.push(`- ๐Ÿ“‰ Code quality needs improvement (${result.codeQualityScore}/100)`); } if (risks.length === 0) { return '- โœ… No significant risks identified'; } return risks.join('\n'); } private getIssueTypeBreakdown(issues: CodeIssue[]): Record<string, number> { const breakdown: Record<string, number> = {}; issues.forEach(issue => { breakdown[issue.type] = (breakdown[issue.type] || 0) + 1; }); return breakdown; } private groupIssuesBySeverity(issues: CodeIssue[]): Record<string, CodeIssue[]> { const groups: Record<string, CodeIssue[]> = { critical: [], high: [], medium: [], low: [] }; issues.forEach(issue => { groups[issue.severity].push(issue); }); return groups; } private getRating(score: number): string { if (score >= 90) return '๐Ÿ† Excellent'; if (score >= 80) return 'โœ… Good'; if (score >= 70) return 'โš ๏ธ Fair'; if (score >= 60) return 'โŒ Poor'; return '๐Ÿšจ Critical'; } private getSecurityRating(score: number): string { if (score >= 90) return '๐Ÿ”’ Secure'; if (score >= 70) return 'โš ๏ธ Moderate Risk'; if (score >= 50) return 'โŒ High Risk'; return '๐Ÿšจ Critical Risk'; } private getDensityRating(density: number): string { if (density < 0.05) return '๐Ÿ† Excellent'; if (density < 0.1) return 'โœ… Good'; if (density < 0.2) return 'โš ๏ธ Moderate'; return 'โŒ High'; } private getSeverityIcon(severity: string): string { const icons = { critical: '๐Ÿšจ', high: '๐Ÿ”ด', medium: '๐ŸŸก', low: '๐Ÿ”ต' }; return icons[severity as keyof typeof icons] || 'โ“'; } private getTypeIcon(type: string): string { const icons = { security: '๐Ÿ”’', quality: '๐Ÿ“Š', style: '๐Ÿ’…', performance: 'โšก', maintainability: '๐Ÿ”ง' }; return icons[type as keyof typeof icons] || '๐Ÿ“‹'; } private capitalize(str: string): string { return str.charAt(0).toUpperCase() + str.slice(1); } }

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/JJJHoons/python_code_review_mcp'

If you have feedback or need assistance with the MCP directory API, please join our Discord server