TestLedger
Imports JUnit XML test reports from Gradle build output into a local ledger, enabling comparison of builds, grouped failure analysis, and test history/evidence queries for triage.
Click on "Deploy Server".
Wait a few minutes for the server to deploy. Once ready, it will show a "Started" state.
In the chat, type
@followed by the MCP server name and your instructions, e.g., "@TestLedgerCompare the latest two checkout runs on main and explain the new failures."
That's it! The server will respond to your query, and you can continue using it as needed.
Here is a step-by-step guide with screenshots.
TestLedger
Test-run history and failure evidence for AI agents, written in Kotlin.
TestLedger imports JUnit XML into a local SQLite database and exposes seven read-only MCP tools. An agent can compare builds, inspect grouped failures, check a test's recent history, and cite the exact observation behind a conclusion.
It also finds tests that got slower against a median of earlier runs. The same analysis is available as an MCP tool and a CI command with separate exit codes for regressions and insufficient history.
It handles a common triage mistake: a failing test that disappears from the next run is not marked as recovered. Skipped tests, new failures, regressions, and confirmed passes have separate categories.
What it does
Imports reports from Gradle, Maven, and other runners that produce JUnit XML.
Stores immutable runs with project, branch, commit, and timestamp metadata.
Groups failures by exception type and stack location, with evidence for each group.
Compares runs and tracks adjacent pass/fail transitions within one branch.
Detects duration increases against a branch-specific median, with configurable thresholds, sample counts, and citations for each measurement.
Exposes MCP tools and a
triage-testsprompt for an agent's investigation.Produces a Markdown comparison report for a pull request or incident record.
There is no hosted model or API key inside TestLedger. Your MCP client supplies the agent and decides which tool results to send to its model provider. The included demo exercises the real protocol without making a model call.
Related MCP server: io.github.loopg/pramana-mcp
Install
Requires Java 21 or later. Download and extract testledger-0.2.0.zip. The archive includes dependencies and launchers for Windows and Unix systems.
./testledger-0.2.0/bin/testledger --helpPowerShell:
.\testledger-0.2.0\bin\testledger.bat --helpSet JAVA_HOME to your JDK directory, or make java available on PATH.
The following examples assume testledger is on your path; on Windows use the
.bat launcher. No global Gradle installation is needed to build from source.
Import a run
testledger import \
--reports ./build/test-results/test \
--id build-142 \
--project checkout \
--branch main \
--commit 9a13be2 \
--at 2026-10-30T12:00:00ZFor Maven, point --reports at target/surefire-reports. For multiple modules,
export their report directories under one root while preserving module paths.
Use the same root layout on later imports so test identities remain stable.
Reports are read recursively; build commands are never executed by TestLedger.
The database defaults to .testledger/ledger.db in the current directory.
Every command accepts --db PATH. Keep the database outside your report directory.
Importing the same run ID, reports, and metadata is idempotent. Reusing an ID with
different data fails; earlier evidence cannot be silently overwritten.
testledger runs --project checkout --branch main
testledger summary --run build-142
testledger failures --run build-142
testledger compare --base build-141 --head build-142
testledger history --project checkout --branch main --test TEST_ID --window 20
testledger test --run build-142 --test TEST_ID
testledger report --base build-141 --head build-142 > triage.md
testledger timings --run build-142
testledger timing-check --run build-142 --min-increase-ms 200 --min-increase-percent 50Commands return JSON except report, which returns Markdown. Invalid input and
missing data produce exit code 1. timing-check also returns 2 for detected timing
regressions and 3 for insufficient history. runs, failures, compare, and timings support
--offset and --limit; JSON responses include nextOffset when another page exists.
See timing analysis for baseline selection, coverage, pagination snapshots, and CI usage. Existing 0.1.0 databases work without migration.
Connect your agent
Import reports first, then add a stdio MCP server to your client's configuration. Use absolute paths because clients often start tools from a different directory.
{
"mcpServers": {
"testledger": {
"command": "java",
"args": [
"-cp",
"/absolute/path/testledger-0.2.0/lib/*",
"io.github.almeida96.testledger.MainKt",
"serve",
"--db",
"/absolute/path/checkout/.testledger/ledger.db"
]
}
}
}On Windows, use forward slashes in JSON paths, such as
C:/tools/testledger-0.2.0/lib/*. The Java launcher expands the classpath wildcard;
no shell wrapper is needed. Client configuration locations vary.
Tool | What the agent receives |
| Run metadata and final outcome counts for one project and branch |
| Passed, failed, skipped, and retry-hint counts |
| Shared failure signatures with up to three example evidence IDs |
| Paginated changes between two chronological runs |
| Recent observations, missing runs, and pass/fail transitions |
| One testcase's failure text, source report, XML line, and retry hints |
| Slower passed tests, baseline medians, coverage, and cited duration samples |
Select the triage-tests MCP prompt with a project and branch, or ask your agent:
Compare the latest two checkout runs on main. Inspect the new failures, check whether they appeared in earlier runs, and cite the evidence. Separate facts from hypotheses and list the next checks you would make.
For a timing investigation:
Check build-142 for tests that grew by at least 200 ms and 50% against earlier runs on the same branch. Show the baseline, sample counts, and evidence. State how many tests lacked enough history before suggesting what to investigate.
Evidence IDs have the form testledger://runs/RUN_ID/tests/TEST_ID. They are
stable references resolved through test_evidence using those two IDs, not HTTP
links or advertised MCP resources. The tool also returns a relative XML report
path and the testcase's starting line. The database retains the observation even
if the original report is later removed.
The server opens SQLite read-only. It cannot import reports, run a shell, change code, or start a build. The owner refreshes the ledger with the CLI. This release supports stdio only; it does not expose a public HTTP endpoint.
Comparison rules
Category | Base → head |
| Passed → failed/error |
| Failed/error → failed/error |
| Not present → failed/error |
| Skipped → failed/error |
| Failed/error → passed |
| Failed/error → skipped |
| Failed/error → not present |
Unchanged successful tests do not appear in the comparison. Runs must belong to the same project and branch, and the base timestamp must precede the head. These rules compare observations; they do not establish that a commit caused a failure. Keep separate project or branch labels for incompatible test environments.
test_history marks a sequence as intermittent after at least two adjacent
pass/fail transitions in the selected window. Missing and skipped observations
break the sequence. Different commits, dependencies, or environments may explain
the changes, so this signal is not proof of a flaky test.
Reproduce the example
git clone https://github.com/Almeida96/testledger.git
cd testledger
./gradlew test installDist
npm install --global pnpm@11.25.0
pnpm install --frozen-lockfile
pnpm test:mcp
pnpm demoUse gradlew.bat on Windows. JavaScript is used only for the independent MCP
client and protocol tests; the application, parser, persistence, CLI, and server
are Kotlin. These optional client scripts require Node 24 or later.
The demo imports four fictional shopping-service test runs and connects a TypeScript MCP client to the Kotlin server. It finds two regressions, four failure groups, and three outcome transitions for one test. It also keeps a missing test and a skipped test separate from the recovered test.
Results are saved to build/demo/report.md and build/demo/evidence.json.
See the checked-in sample report,
sample evidence, and demo walkthrough.
These fixtures test known scenarios; they are not a benchmark of an LLM's diagnosis.
Input and privacy boundaries
The parser accepts UTF-8 JUnit-style XML with testsuite or testsuites roots.
Nested suites, failures, errors, skipped cases, CDATA, and Surefire retry elements
are supported. Suite-level aggregate counters are ignored; counts come from
individual testcases. flakyFailure and flakyError entries record prior failed
attempts without changing a successful final outcome. rerunFailure and
rerunError preserve the final failure already present in the report.
Test identity combines the relative report path, suite path, class name, and test name. Renames and report moves create new identities. Duplicate identities in one import are rejected, so parameterized tests need distinct exported names.
DTD and external entities are rejected. Symlinks and hidden report paths are skipped. Imports are bounded to 1,000 XML files, 2 MiB per file, 25 MiB total, and 25,000 testcases. Failure details are capped at 12,000 characters and carry a truncation flag. Names are limited to 512 characters and suite paths to 1,024.
Suite properties, system-out, and system-err are not retained. Credential-like
assignments, bearer tokens, URL credentials, and selected token formats are
redacted before evidence is stored. This is pattern-based filtering, not a secret
scanner guarantee. Review reports before sharing them with any agent or provider.
The ledger contains test names and failure text; keep it out of source control.
Report contents are untrusted. The MCP prompt tells the agent to ignore embedded instructions, but client/model behavior remains outside the server's control.
Development
./gradlew test installDist distZip
pnpm test:mcp
pnpm demoJUnit tests cover parser limits, external-entity rejection, credential redaction,
retries, immutable imports, branch isolation, pagination, comparisons, and history.
Timing tests cover median baselines, threshold boundaries, exclusions, coverage,
backfilled runs, pagination snapshots, and finite extreme durations.
Protocol tests launch the installed JVM distribution and use the official
TypeScript MCP client. They also check UTF-8 on Windows and nonzero CLI exits.
CI runs Java 21 on Linux and Windows. JaCoCo reports are available under
build/reports/jacoco/test.
Dependencies are pinned and Gradle dependency locks are committed. The Gradle wrapper distribution has a SHA-256 checksum. See architecture for storage, grouping, and consistency details.
Contribution guide. MIT license.
This server cannot be deployed
Maintenance
Related MCP Connectors
Read-only lookup of tested agent tools and MCP servers: scores, test evidence, deprecation.
- HypAwareOAuthai.hypaware
Query your team's AI coding history and act on HypAware recommendations from any MCP client.
- SpecitaOAuthcom.specita
Read-only release evidence for coding agents: findings, deliveries, source and runtime data.
Your org's AI agents, tasks, runs, search, and brain files as MCP tools and resources.
Related MCP Servers
- AlicenseAqualityBmaintenanceEnables AI agents to run container forensics, generate container obituaries, and audit git repository history as native MCP tools, producing markdown reports they can reason over.34MIT
- AlicenseAqualityBmaintenanceLets an assistant read recorded production AI agent runs — steps, model and tool calls with arguments, and outcomes — along with the findings of comparison runs that checked a prompt or model change against those recordings, and verify a signed evidence bundle offline with no account or network. It is strictly read-only: no tool starts a replay or comparison, so nothing can spend money or act without a person deciding.5Apache 2.0
- AlicenseNot gradedqualityCmaintenanceEnables AI agents to inspect Autopsy forensic cases through read-only MCP tools for case metadata, filesystem and artifact search, timeline and account queries, evidence extraction, and hash-chained audit/seal verification.10 npm2GPL 3.0
- AlicenseBqualityBmaintenanceLets AI assistants inspect test run results, AI QA reports, and findings with their full evidence, and, when asked, start runs, re-run only failed tests, import API specs, or scan a website. Read-only tools are free, while work-starting tools consume the workspace's allowance and report usage limits.1915 npmMIT