mcp server
opencoverage
Self-hosted coverage API + dashboard for ingesting CI reports and tracking coverage deltas over time.
Set up
Runs on your computer. Pick your agent and operating system.
This project does not publish an install method we can turn into a config. Follow the README instead.
README
synced Oct 21, 2026coverage-api
Dashboard Preview
Self-hosted Go code coverage API and dashboard for ingesting test coverage, comparing deltas, and tracking trends across projects, branches, and teams.
coverage-api is part of the opencoverage project and is designed for developer teams that want coverage visibility in their own infrastructure.
Why coverage-api
- Ingest Go coverage results from local runs or CI pipelines
- Compute deterministic baseline comparisons and deltas
- Track project and package-level coverage history
- Group projects (for team-level reporting)
- Integrate with GitHub Actions and other CI systems
- Self-host API + frontend with PostgreSQL
Key Features
- REST API with
/v1endpoints for ingest, history, and latest comparison - Coverage CLI to convert
coverage.outinto API-ready JSON payloads - Dashboard frontend for project, multi-branch trend, comparison, and heatmap visualization
- Integration test result ingestion and heatmap visualization
- API key authentication for protected endpoints
- Hexagonal Architecture (ports and adapters)
Quick Start (Docker Compose)
Run the full local stack (PostgreSQL + API + seed + frontend + MCP):
make compose-up
If local port 5432 is already in use:
DB_PORT=5433 make compose-up
Access services:
- API:
http://localhost:8080 - Frontend dashboard:
http://localhost:8090 - Health check:
http://localhost:8080/healthz
Compose startup behavior:
dbstarts first and must pass its healthcheck.apistarts next and runs all DB migrations during startup.apiexposes/healthzonly after startup completes.seedruns only afterapiis healthy.mcpstarts afterseedcompletes successfully.
Stop the stack:
make compose-down
Local Development
Requirements:
- Go 1.23+
- PostgreSQL 14+
Core environment variables:
DATABASE_URL(required)MIGRATIONS_DIR(default./migrations, used by API startup migrations)API_KEY_SECRET(required)SERVER_ADDR(default:8080)API_KEY_HEADER(defaultX-API-Key)SHUTDOWN_TIMEOUT_SECONDS(default10)
Run API locally:
export DATABASE_URL="postgres://coverage:coverage@localhost:5432/coverage?sslmode=disable"
export API_KEY_SECRET="dev-local-key"
go run ./cmd/api
cmd/api runs migrations on startup before serving HTTP traffic.
Run MCP server locally:
export DATABASE_URL="postgres://coverage:coverage@localhost:5432/coverage?sslmode=disable"
export MCP_SERVER_NAME="opencoverage"
export MCP_SERVER_VERSION="dev"
go run ./cmd/mcp
cmd/mcp does not run migrations. Start the API first (or run make migrate-up) before starting MCP against a fresh database.
Optional MCP settings:
MCP_TRANSPORT(defaultstdio)MCP_ENABLE_PROMPTS(defaulttrue)MCP_LOG_LEVEL(defaultinfo) - MCP server log verbosity (for example:debug,info,warn,error).MCP_ENABLE_WRITE_TOOLS(defaultfalse) - enablesingest_coverage_runandingest_integration_run; write tools require a transport that can carry request headers and a non-emptyAPI_KEY_SECRETin your shell or deployment environment (for exampleexport API_KEY_SECRET="dev-local-key") before startinggo run ./cmd/mcp.MCP_MAX_PAGE_SIZE(default100)MCP_DEFAULT_RUNS_LIMIT(default20)
Run frontend locally:
make frontend-run
Useful developer commands:
make deps
make fmt
make test
make migrate-status
make migrate-up
API Overview
Main endpoints:
GET /v1/projectsPOST /v1/coverage-runsGET /v1/projects/{projectId}GET /v1/projects/{projectId}/coverage-runsGET /v1/projects/{projectId}/coverage-runs/latest-comparisonGET /v1/projects/{projectId}/branchesGET /v1/projects/{projectId}/contributorsPOST /v1/integration-test-runsGET /v1/integration-test-runs/heatmapGET /v1/projects/{projectId}/integration-test-runsGET /v1/projects/{projectId}/integration-test-runs/latest-comparisonGET /v1/projects/{projectId}/integration-test-runs/{runId}
For full API contract details, see SPEC.md.
Ingest Coverage With cURL
Set variables:
export BASE_URL="http://localhost:8080"
export API_KEY="dev-local-key"
Send a coverage run:
curl -i -X POST "$BASE_URL/v1/coverage-runs" \
-H "Content-Type: application/json" \
-H "X-API-Key: $API_KEY" \
-d '{
"projectKey": "org/repo-service",
"projectName": "repo-service",
"projectGroup": "platform-team",
"defaultBranch": "main",
"branch": "main",
"commitSha": "a1b2c3d4",
"author": "alice",
"triggerType": "push",
"runTimestamp": "2026-03-28T12:00:00Z",
"totalCoveragePercent": 83.42,
"packages": [
{"importPath": "github.com/acme/repo-service/internal/api", "coveragePercent": 85.10},
{"importPath": "github.com/acme/repo-service/internal/service", "coveragePercent": 80.70}
]
}'
Coverage CLI Workflow
Generate payload from Go coverage profile:
go run ./cmd/coveragecli \
-coverprofile coverage.out \
-out coverage-upload.json \
-project-key "github.com/example/repo" \
-project-name "repo" \
-project-group "platform" \
-default-branch "main" \
-branch "main" \
-commit-sha "abc123" \
-author "alice"
Generate and upload in one command:
make coverage-upload API_URL="http://localhost:8080/v1/coverage-runs" API_KEY="dev-local-key"
Install CLI from GitHub:
go install github.com/arxdsilva/opencoverage/cmd/coveragecli@latest
Upload Vitest Coverage Summary (npm)
Generate Vitest coverage summary:
npx vitest run --coverage --coverage.reporter=lcov --coverage.reporter=json-summary
Upload coverage/coverage-summary.json using the CLI:
go run ./cmd/coveragecli npm-upload \
-vitest-summary coverage/coverage-summary.json \
-api-url http://localhost:8080/v1/coverage-runs \
-api-key dev-local-key \
-project-key github.com/example/frontend-repo \
-project-name frontend-repo \
-project-group frontend \
-default-branch main \
-branch main \
-commit-sha abc123 \
-author alice \
-trigger-type push
Useful options:
-metric lines|statements|functions|branches(defaultlines)-group-by dir|file(defaultdir)-include-globand-exclude-glob(repeatable)-path-strip-prefixfor deterministic path normalization-dry-runand-out <payload.json>to inspect payload without upload
Architecture
This project follows Hexagonal Architecture (ports and adapters):
cmd/api- bootstrap and dependency wiringinternal/domain- entities, invariants, deterministic domain logicinternal/application- use cases and portsinternal/adapters/http- handlers, DTOs, middlewareinternal/adapters/postgres- repository implementationsinternal/adapters/auth- API key authentication adapterinternal/platform- config and infrastructure utilities
Database and Migrations
Migration files are in migrations/.
Migration ownership:
- API process owns automatic migration execution at startup.
- MCP and frontend processes never run migrations.
- In Docker Compose,
seedwaits for API health so seeding happens after migrations.
Common commands:
make migrate-status
make migrate-up
make migrate-down
make migrate-create name=add_new_table
Seed local database:
make seed
CI/CD and GitHub Actions
For complete CI examples (unit tests, coverage.out, CLI payload generation, upload to self-hosted API), see GITHUB_ACTIONS_INTEGRATION.md.
The examples include:
- Configurable project metadata (
project key,name,group) - Push and pull request workflows
- Multi-project matrix workflows for monorepos
- PR comments and threshold-based quality gates
Frontend and Product Docs
- Frontend behavior and UI notes: frontend.md
- API contract and response model: SPEC.md
- Contribution/PR workflow: making-a-PR.md
Frontend highlights:
- Project overview includes a multi-branch coverage trend chart.
- The trend view overlays the default branch with all discovered branches for the selected project.
- The branch selector is used for latest-comparison details, not for filtering the trend chart.
- Heatmap overlay shows all projects grouped by team, with tiles color-coded on a -3% to +3% delta scale (green = improved, red = regressed). A scale legend is displayed in the overlay header.
- Top Contributors overlay shows the leading commit contributors per project across all teams, grouped the same way as the heatmap.
- Integration Tests screen provides per-project integration test run history and failed spec details.
- Integration Run Chain is rendered oldest to newest (newest on the right) and shows up to 5 runs.
- Integration Pass Rate card shows run success ratio percentage computed as
passed runs / failed runs * 100over the returned run-list window (up to last 20 runs). - Integration Heatmap shows all projects grouped by team but displays default-branch runs only, with
✅/❌run markers and newest-run status tint per project row. - Integration Tests sidebar now supports group-first project navigation: filter by project group, then select a project from the filtered list (combined with project search).
Typical Integration Flow
- Run tests and produce
coverage.out. - Convert coverage profile to JSON payload with
coveragecli. - Upload payload to
POST /v1/coverage-runs. - Read comparison metadata (
thresholdStatus,deltaPercent) in CI. - Visualize trends and project groups in the dashboard.