Skip to main content
Glama
amyfan7
by amyfan7
README.md
# MCP Java Testing Agent

This repository provides an MCP (Model Context Protocol) server that exposes tools to automate test generation, coverage analysis, and style checking for Java/Maven projects. It is designed to be driven by an MCP-aware client using the `tester.prompt.md` prompt.

---

## Overview

The MCP server (in `main.py`) exposes tools that:

- Discover public methods in a Java codebase
- Generate skeleton JUnit tests
- Run Maven (`mvn clean test`)
- Analyze JaCoCo coverage reports
- Analyze Checkstyle reports

The higher-level loop (iterating until coverage/style goals are met) is described in `tester.prompt.md` and executed by the LLM client, not hard-coded in Python.

---

## Requirements

- Python 3.x
- Java JDK installed and on `PATH`
- Maven (`mvn`) installed and on `PATH`
- Maven project configured to:
  - Place sources under something like `A2/src/main/java`
  - Generate JaCoCo XML at `A2/target/site/jacoco/jacoco.xml`
  - Generate Checkstyle XML at `A2/target/checkstyle-result.xml`
- An MCP-capable editor/client (e.g., VS Code with MCP integration)

---

## Installation & Configuration

1. **Clone and install:**

   ```bash
   git clone <your-repo-url>
   cd <your-repo-folder>
   pip install fastmcp

    Verify:

    java -version
    mvn -v

    Ensure your Maven pom.xml is set up to:

        Run tests

        Produce JaCoCo and Checkstyle reports at the paths above

Running the MCP Server

From the project root:

python server.py

This starts the MCP server over SSE:

if __name__ == "__main__":
    mcp.run(transport="sse")

Your MCP client should be configured to connect to this server.
Using the tester Prompt

Assuming you’re in an editor like VS Code with MCP enabled:

    Open the project folder (containing main.py and tester.prompt.md).

    Open tester.prompt.md (or tester.md) in the editor.

    Press Ctrl+Shift+P to open the Command Palette.

    Select “Run Prompt” (or the equivalent command).

    Choose the tester prompt.

The MCP client will then:

    Call the tools defined in tester.prompt.md:

    - mcp-final/generate-tests
    - mcp-final/run_tests
    - mcp-final/analyze-coverage
    - mcp-final/get_all_public_methods
    - mcp-final/analyze-checkstyle
    - mcp-final/run-checkstyle
    - mcp-final/git-add-all
    - mcp-final/git-commit
    - mcp-final/git_pull_request
    - mcp-final/git_push
    - mcp-final/git_status

    Iterate to generate tests, run coverage/style checks, and produce a final summary.

Project Structure (Typical)

├── main.py                   # MCP server and tools
├── .github/prompts/
│   └── tester.prompt.md      # Agent configuration/prompt
├── A2/
│   ├── pom.xml
│   ├── src/main/java/...     # Java sources
│   └── target/
│       ├── site/jacoco/jacoco.xml
│       └── checkstyle-result.xml

Adjust paths as needed; defaults are used in the tool implementations.
MCP Tools
generate_tests(source_file: str) -> str

Generate a skeleton JUnit test class for a given .java file.

    Extracts the class name and public method names via regex.

    Creates {ClassName}Test with stub methods:

    @Test
    void test_methodName() {
        // TODO: implement test
    }

    Writes to: codebase/src/test/java/{ClassName}Test.java.

Returns: Path message on success, or an error string if the file/class/methods can’t be found.
get_all_public_methods(dir: str = "A2/src/main/java") -> List[str]

Recursively scan dir for .java files and return all lines starting with public.

    Uses os.walk to find .java files.

    Reads each file line-by-line and keeps line.strip().startswith("public").

Returns: List of raw lines (method signatures, constructors, or public fields).
analyze_coverage(xml_path: str = "A2/target/site/jacoco/jacoco.xml") -> dict

Parse a JaCoCo XML report and list methods with <100% instruction coverage.

Output structure:

{
  "uncovered_methods": [
    {
      "class": "com/example/MyClass",
      "method": "myMethod",
      "coverage": 0.75,
      "missed": 10,
      "covered": 30
    },
    ...
  ],
  "count": 3
}

Returns an "error" key if the XML file is missing.
run_checkstyle() -> str

Run the Maven build and tests:

mvn clean test

Assumes your Maven config runs Checkstyle and JaCoCo as part of the build.

Returns: stdout from the Maven process (errors are visible in this text).
analyze_checkstyle(xml_path: str = "A2/target/checkstyle-result.xml") -> dict

Parse a Checkstyle XML report and list all style violations.

Output structure:

{
  "violations": [
    {
      "file": "/path/to/Foo.java",
      "line": "42",
      "column": "13",
      "severity": "warning",
      "message": "Line is longer than 100 characters",
      "source": "com.puppycrawl.tools.checkstyle.checks.sizes.LineLengthCheck"
    },
    ...
  ],
  "count": 5
}

Returns an "error" key if the XML file is missing.
Agent Workflow Summary

A typical workflow implemented in tester.prompt.md:

    Call get_all_public_methods to discover public methods.

    Call generate_tests to create initial JUnit tests.

    Call run_checkstyle to run mvn clean test and produce JaCoCo + Checkstyle reports.

    Call analyze_coverage to find uncovered methods.

    Call analyze_checkstyle to find style violations.

    Update tests and code (by the agent using file edits), then repeat steps 3–5.

    Stop when:

        100% coverage and zero Checkstyle issues are reached, or

        A maximum iteration count (e.g., 10) is reached.

    Produce a final summary report (tests created, coverage, style status, recommendations).

Notes & Limitations

    Regex-based parsing is simple and may not handle all Java edge cases (complex generics, annotations, inner classes).

    Default paths (A2/src/main/java, codebase/src/test/java, etc.) can be customized; keep tool defaults in sync with your project layout.

    run_checkstyle only runs mvn clean test; ensure your pom.xml actually binds JaCoCo and Checkstyle to this phase.

    The iterative “improve coverage & style” loop is implemented by the MCP client/LLM using these tools, not within server.py itself.