Skip to main content
Glama

evaluate_readme_health

Analyze README files to assess community health, accessibility, and onboarding effectiveness for open-source projects.

Instructions

Evaluate README files for community health, accessibility, and onboarding effectiveness

Input Schema

TableJSON Schema
NameRequiredDescriptionDefault
readme_pathYesPath to the README file to evaluate
project_typeNoType of project for tailored evaluationcommunity_library
repository_pathNoOptional path to repository for additional context

Implementation Reference

  • Main handler function for the 'evaluate_readme_health' tool. Validates input, reads README, evaluates health across components (community, accessibility, onboarding, content), computes overall score, generates report and recommendations, returns formatted MCP response.
    export async function evaluateReadmeHealth(input: EvaluateReadmeHealthInput) { const startTime = Date.now(); try { // Validate input const validatedInput = EvaluateReadmeHealthSchema.parse(input); // Read README file const readmePath = path.resolve(validatedInput.readme_path); const readmeContent = await fs.readFile(readmePath, "utf-8"); // Get repository context if available let repoContext: any = null; if (validatedInput.repository_path) { repoContext = await analyzeRepositoryContext( validatedInput.repository_path, ); } // Evaluate all health components const communityHealth = evaluateCommunityHealth(readmeContent, repoContext); const accessibility = evaluateAccessibility(readmeContent); const onboarding = evaluateOnboarding( readmeContent, validatedInput.project_type, ); const contentQuality = evaluateContentQuality(readmeContent); // Calculate overall score const totalScore = communityHealth.score + accessibility.score + onboarding.score + contentQuality.score; const maxTotalScore = communityHealth.maxScore + accessibility.maxScore + onboarding.maxScore + contentQuality.maxScore; const percentage = (totalScore / maxTotalScore) * 100; // Generate grade const grade = getGrade(percentage); // Generate recommendations and insights const recommendations = generateHealthRecommendations( [communityHealth, accessibility, onboarding, contentQuality], "general", ); const strengths = identifyStrengths([ communityHealth, accessibility, onboarding, contentQuality, ]); const criticalIssues = identifyCriticalIssues([ communityHealth, accessibility, onboarding, contentQuality, ]); const report: ReadmeHealthReport = { overallScore: Math.round(percentage), maxScore: 100, grade, components: { communityHealth, accessibility, onboarding, contentQuality, }, recommendations, strengths, criticalIssues, estimatedImprovementTime: estimateImprovementTime( recommendations.length, criticalIssues.length, ), }; const response = { readmePath: validatedInput.readme_path, projectType: validatedInput.project_type, healthReport: report, summary: generateSummary(report), nextSteps: generateNextSteps(report), }; return formatMCPResponse({ success: true, data: response, metadata: { toolVersion: "1.0.0", executionTime: Date.now() - startTime, timestamp: new Date().toISOString(), }, }); } catch (error) { return formatMCPResponse({ success: false, error: { code: "README_HEALTH_EVALUATION_FAILED", message: `Failed to evaluate README health: ${error}`, resolution: "Ensure README path is valid and file is readable", }, metadata: { toolVersion: "1.0.0", executionTime: Date.now() - startTime, timestamp: new Date().toISOString(), }, }); } }
  • Zod schema defining the input validation for the tool: readme_path (required string), project_type (optional enum), repository_path (optional string).
    const EvaluateReadmeHealthSchema = z.object({ readme_path: z.string().min(1, "README path is required"), project_type: z .enum([ "community_library", "enterprise_tool", "personal_project", "documentation", ]) .optional() .default("community_library"), repository_path: z.string().optional(), });
  • TypeScript interface matching the input expected by the handler, used for type safety.
    export interface EvaluateReadmeHealthInput { readme_path: string; project_type?: | "community_library" | "enterprise_tool" | "personal_project" | "documentation"; repository_path?: string; }
  • Helper function evaluating community health aspects like code of conduct, contributing guidelines, etc., via regex checks on README content.
    function evaluateCommunityHealth( content: string, _repoContext: any, ): HealthScoreComponent { const checks: HealthCheckDetail[] = [ { check: "Code of Conduct linked", passed: /code.of.conduct|conduct\.md|\.github\/code_of_conduct/i.test( content, ), points: 0, maxPoints: 5, recommendation: "Add a link to your Code of Conduct to establish community standards", }, { check: "Contributing guidelines visible", passed: /contributing|contribute\.md|\.github\/contributing/i.test( content, ), points: 0, maxPoints: 5, recommendation: "Include contributing guidelines to help new contributors get started", }, { check: "Issue/PR templates mentioned", passed: /issue.template|pull.request.template|\.github\/issue_template|\.github\/pull_request_template/i.test( content, ), points: 0, maxPoints: 5, recommendation: "Reference issue and PR templates to streamline contributions", }, { check: "Security policy linked", passed: /security\.md|security.policy|\.github\/security/i.test(content), points: 0, maxPoints: 5, recommendation: "Add a security policy to handle vulnerability reports responsibly", }, { check: "Support channels provided", passed: /support|help|discord|slack|discussions|forum|community/i.test( content, ), points: 0, maxPoints: 5, recommendation: "Provide clear support channels for users seeking help", }, ]; // Award points for passed checks checks.forEach((check) => { if (check.passed) { check.points = check.maxPoints; } }); const totalScore = checks.reduce((sum, check) => sum + check.points, 0); const maxScore = checks.reduce((sum, check) => sum + check.maxPoints, 0); return { name: "Community Health", score: totalScore, maxScore, details: checks, }; }
  • Additional helper functions for accessibility, onboarding, content quality evaluations, and utility functions for grading, recommendations, etc.
    } function evaluateCommunityHealth( content: string, _repoContext: any, ): HealthScoreComponent { const checks: HealthCheckDetail[] = [ { check: "Code of Conduct linked", passed: /code.of.conduct|conduct\.md|\.github\/code_of_conduct/i.test( content, ), points: 0, maxPoints: 5, recommendation: "Add a link to your Code of Conduct to establish community standards", }, { check: "Contributing guidelines visible", passed: /contributing|contribute\.md|\.github\/contributing/i.test( content, ), points: 0, maxPoints: 5, recommendation: "Include contributing guidelines to help new contributors get started", }, { check: "Issue/PR templates mentioned", passed: /issue.template|pull.request.template|\.github\/issue_template|\.github\/pull_request_template/i.test( content, ), points: 0, maxPoints: 5, recommendation: "Reference issue and PR templates to streamline contributions", }, { check: "Security policy linked", passed: /security\.md|security.policy|\.github\/security/i.test(content), points: 0, maxPoints: 5, recommendation: "Add a security policy to handle vulnerability reports responsibly", }, { check: "Support channels provided", passed: /support|help|discord|slack|discussions|forum|community/i.test( content, ), points: 0, maxPoints: 5, recommendation: "Provide clear support channels for users seeking help", }, ]; // Award points for passed checks checks.forEach((check) => { if (check.passed) { check.points = check.maxPoints; } }); const totalScore = checks.reduce((sum, check) => sum + check.points, 0); const maxScore = checks.reduce((sum, check) => sum + check.maxPoints, 0); return { name: "Community Health", score: totalScore, maxScore, details: checks, }; } function evaluateAccessibility(content: string): HealthScoreComponent {

Latest Blog Posts

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/tosin2013/documcp'

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