Skip to main content
Glama
djm81

Log Analyzer MCP

by djm81

analyze_tests

Analyze recent test runs to identify failures and provide detailed diagnostics, enabling developers to troubleshoot issues efficiently.

Instructions

Analyze the most recent test run and provide detailed information about failures.

Args:
    summary_only: Whether to return only a summary of the test results

Input Schema

TableJSON Schema
NameRequiredDescriptionDefault
summary_onlyNo

Output Schema

TableJSON Schema
NameRequiredDescriptionDefault

No arguments

Implementation Reference

  • The primary handler for the 'analyze_tests' tool. Decorated with @mcp.tool() for registration. Reads the test log file, parses it using the helper analyze_pytest_log_content, augments with metadata, and returns structured results or errors.
    @mcp.tool()
    async def analyze_tests(summary_only: bool = False) -> dict[str, Any]:
        """Analyze the most recent test run and provide detailed information about failures.
    
        Args:
            summary_only: Whether to return only a summary of the test results
        """
        logger.info("Analyzing test results (summary_only=%s)...", summary_only)
    
        log_file = test_log_file
    
        if not os.path.exists(log_file):
            error_msg = f"Test log file not found at: {log_file}. Please run tests first."
            logger.error(error_msg)
            return {"error": error_msg, "summary": {"status": "ERROR", "passed": 0, "failed": 0, "skipped": 0}}
    
        try:
            with open(log_file, encoding="utf-8", errors="ignore") as f:
                log_contents = f.read()
    
            if not log_contents.strip():
                error_msg = f"Test log file is empty: {log_file}"
                logger.warning(error_msg)
                return {"error": error_msg, "summary": {"status": "EMPTY", "passed": 0, "failed": 0, "skipped": 0}}
    
            analysis = analyze_pytest_log_content(log_contents, summary_only=summary_only)
    
            # Add metadata similar to the old analyze_test_log function
            log_time = datetime.fromtimestamp(os.path.getmtime(log_file))
            time_elapsed = (datetime.now() - log_time).total_seconds() / 60  # minutes
            analysis["log_file"] = log_file
            analysis["log_timestamp"] = log_time.isoformat()
            analysis["log_age_minutes"] = round(time_elapsed, 1)
    
            # The analyze_pytest_log_content already returns a structure including 'overall_summary'.
            # If summary_only is true, it returns only that. Otherwise, it returns more details.
            # We can directly return this analysis dictionary.
    
            # Ensure there's always a summary structure for consistent access, even if minimal
            if "overall_summary" not in analysis:
                analysis["overall_summary"] = {"status": "UNKNOWN", "passed": 0, "failed": 0, "skipped": 0}
            if "summary" not in analysis:  # for backward compatibility or general access
                analysis["summary"] = analysis["overall_summary"]
    
            logger.info(
                "Test log analysis completed using test_log_parser. Summary status: %s",
                analysis.get("summary", {}).get("status"),
            )
            return analysis
    
        except Exception as e:  # pylint: disable=broad-exception-caught
            error_msg = f"Error analyzing test log file with test_log_parser: {e}"
            logger.error(error_msg, exc_info=True)
            return {"error": error_msg, "summary": {"status": "ERROR", "passed": 0, "failed": 0, "skipped": 0}}
  • Pydantic input schema/model for the analyze_tests tool, defining the optional summary_only parameter.
    class AnalyzeTestsInput(BaseModel):
        """Parameters for analyzing tests."""
    
        summary_only: bool = Field(default=False, description="Whether to return only a summary of the test results")
  • Key helper function implementing the pytest log parsing logic. Extracts overall summary and list of failed tests using sub-helpers extract_overall_summary and extract_failed_tests. Invoked by the main handler.
    def analyze_pytest_log_content(log_contents: str, summary_only: bool = False) -> Dict[str, Any]:
        """
        Analyzes the full string content of a pytest log.
    
        Args:
            log_contents: The string content of the pytest log.
            summary_only: If True, returns only the overall summary.
                          Otherwise, includes details like failed tests.
    
        Returns:
            A dictionary containing the analysis results.
        """
        overall_summary = extract_overall_summary(log_contents)
    
        if summary_only:
            return {"overall_summary": overall_summary}
    
        failed_tests = extract_failed_tests(log_contents)
        # Placeholder for other details to be added once their extraction functions are moved/implemented
        # error_details = extract_error_details(log_contents)
        # exception_traces = extract_exception_traces(log_contents)
        # module_statistics = extract_module_statistics(log_contents)
    
        return {
            "overall_summary": overall_summary,
            "failed_tests": failed_tests,
            # "error_details": error_details, # Uncomment when available
            # "exception_traces": exception_traces, # Uncomment when available
            # "module_statistics": module_statistics, # Uncomment when available
        }
Behavior2/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

No annotations are provided, so the description carries the full burden of behavioral disclosure. It mentions analyzing 'the most recent test run' and providing 'detailed information about failures', but lacks critical details: whether this is a read-only operation, what happens if no test run exists, the format of the output (though an output schema exists), or any rate limits or permissions required. For a tool with zero annotation coverage, this is insufficient.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is concise and well-structured: a clear purpose statement followed by a parameter explanation. Both sentences earn their place by providing essential information without redundancy. However, it could be slightly more front-loaded by integrating the parameter info into the main flow, but this is minor.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness3/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

Given the tool's moderate complexity (analyzing test runs with failures), no annotations, and an existing output schema, the description is partially complete. It covers the purpose and parameter semantics adequately, but lacks behavioral context (e.g., error handling, dependencies on other tools). The output schema mitigates the need to describe return values, but gaps in usage and transparency remain.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

The description adds meaningful context for the single parameter 'summary_only' by explaining it controls whether to 'return only a summary of the test results'. This goes beyond the schema's minimal title ('Summary Only') and default value. With 0% schema description coverage, the description effectively compensates by clarifying the parameter's purpose, though it doesn't detail edge cases or interactions.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description clearly states the tool's purpose: 'Analyze the most recent test run and provide detailed information about failures.' It specifies the verb ('analyze'), resource ('most recent test run'), and output focus ('detailed information about failures'). However, it doesn't explicitly differentiate from sibling tools like 'run_tests_*' or 'create_coverage_report', which would be needed for a perfect score.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines2/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description provides no guidance on when to use this tool versus alternatives. It doesn't mention prerequisites (e.g., whether a test run must exist), nor does it compare to siblings like 'run_tests_verbose' or 'create_coverage_report'. The only implied usage is analyzing failures, but this is too vague for effective tool selection.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

Install Server

Other Tools

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/djm81/log_analyzer_mcp'

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