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