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 onPATH - 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
- Place sources under something like
- An MCP-capable editor/client (e.g., VS Code with MCP integration)
Installation & Configuration
-
Clone and install:
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.