io.github.felixgeelhaar/coverctl

编码与调试

by felixgeelhaar

面向 Go 代码覆盖率分析的工具,结合 MCP server 支持 AI-powered coverage workflows。

什么是 io.github.felixgeelhaar/coverctl

面向 Go 代码覆盖率分析的工具,结合 MCP server 支持 AI-powered coverage workflows。

README

coverctl

Agent-loop coverage governance — coverage your AI coding agent calls before commit, not a dashboard you read after CI.

Get started ↓ · What it looks like ↓ · MCP tools ↓ · CLI reference ↓ · Why this exists ↓ · Community ↓

MCP Releases

"Our AI agents ship code fast, but they're blind to coverage policy while editing. We only see breakage in CI, after context is gone, and the same agent then guesses its way to a fix."

Works best on standard Go/Python/JavaScript/Java/Rust projects with conventional layouts. Mock-heavy code or exotic monorepos may need an explicit domains: block in .coverctl.yaml.

Get started

bash
brew install klarlabs-studio/tap/coverctl

Wire into Claude Code (~/.config/claude-code/mcp.json):

json
{
  "mcpServers": {
    "coverctl": {
      "command": "coverctl",
      "args": ["mcp", "serve"]
    }
  }
}

Ask the agent: "Run coverctl check and tell me which domains regressed."

For Cursor / Cline / Claude Desktop / Aider / Continue / OpenCode and other MCP clients, see docs/src/content/docs/mcp.mdx. All MCP-capable clients work; coverctl mcp serve runs in agent mode by default (3 tools: check, suggest, debt). Use --mode=ci for the full nine-tool surface.

Validate the install end-to-end:

bash
coverctl mcp doctor   # PASS/FAIL per step with remediation

What it looks like in the agent loop

Rendered for clarity — your client may format tool-calls differently.

text
You:    Add the email-validation feature to the api domain.

Claude: I'll add EmailValidator + tests in internal/api/email.

  [edits: internal/api/email.go, internal/api/email_test.go]

  Tool call → coverctl check
  Result   → passed: false; failing: api (78.2%, required 80%)
             uncovered: internal/api/email.go:42-58 (error paths)

  Tool call → coverctl suggest api
  Result   → uncovered files: email.go (16 lines), retry.go (4 lines)

  Two error branches in EmailValidator.Validate are uncovered.
  I'll add cases for empty-input and malformed-domain so api meets
  the 80% threshold before we commit.

The regression that used to surface in CI 8 minutes later is fixed in the same agent turn.

The agent does well: reads check output verbatim, calls suggest to find uncovered files, calls debt to rank smallest fixes, re-runs check to confirm.

Watch for: agents lowering thresholds in .coverctl.yaml to "fix" a failure (it's not a fix). Agents claiming coverage rose without a new check call (hallucination). Agents ignoring rejection error_code and retrying with the same input.

coverctl returns deterministic structured signals; the agent's fix still needs a human reading. The full contract is in docs/src/content/docs/mcp.mdx.

Why this exists

AI coding agents write code blind to coverage. They edit, you commit, the regression surfaces in CI minutes or hours later — too late to course-correct in the same session. Existing coverage tools (Codecov, Coveralls, native go test -cover) target humans reading dashboards or PR comments, not agents reasoning inline.

coverctl is built for the agent loop:

  • Catches regressions before commit. Coverage feedback in the agent's edit turn — not minutes after CI fails. The wedge metric is regressions caught pre-commit.
  • Agent-callable via MCP. Speaks MCP — the multi-vendor agent-tool standard now governed by Anthropic, OpenAI, Google, Microsoft, AWS. Works with every MCP-capable client today; works with whatever ships next without modification.
  • Polyglot governance, one config. One .coverctl.yaml enforces per-domain thresholds across 15 languages. Agents touch any language; coverage tooling must too.
  • Local-first. Your source never leaves the machine. Agent calls coverctl over stdio, not over a SaaS API. No account, no upload, no third-party dependency in the agent's reach.
  • Hardened MCP surface. Input + output sanitization defends against prompt-injection through test-runner flags and hostile filenames in coverage profiles (Lethal Trifecta).

The CLI and MCP server are Apache-2.0 licensed and stay free. A hosted layer for cross-repo coverage history is on the roadmap (see docs/strategy/monetization-decision.md) — additive, not a paywall.

MCP tools

Agent mode advertises three tools (check, suggest, debt) for reliable agent tool selection. CI mode (--mode=ci) adds the rest.

ToolModePurpose
checkagent + ciRun tests with coverage and enforce policy. Returns per-domain pass/fail, files, warnings.
suggestagent + ciRecommend thresholds (current / aggressive / conservative).
debtagent + ciCoverage gap per domain — where to spend effort, ranked.
initciAuto-detect project structure and create .coverctl.yaml with domain policies.
reportciAnalyze an existing coverage profile without running tests.
recordciRecord current coverage to history for trend tracking.
compareciDiff two coverage profiles. Returns delta, improved/regressed files, domain changes.
badgeciGenerate SVG coverage badge.
pr-commentciPost coverage report to GitHub / GitLab / Bitbucket PR.

MCP resources (read-only context)

URIContent
coverctl://debtCoverage debt as JSON.
coverctl://trendTrend over recorded history.
coverctl://suggestThreshold suggestions.
coverctl://configDetected project config.

Security boundaries

coverctl treats MCP traffic as untrusted in both directions, per the Lethal Trifecta threat model.

  • Input boundary. Test-runner flags that allow arbitrary code loading (--rootdir, --cov-config, -D, -I, --require, --init-script, --node-options, ...) are rejected when they come from MCP. Rejection responses use a stable schema with error_code and agent-actionable remediation. CLI invocations from a human terminal are not sanitized; the human is the trust boundary there.
  • Output boundary. User-controlled strings flowing back to the agent (filenames in coverage profiles, test names, profile-derived paths, PR description content in pr-comment) are canonicalized before return. Prevents return-trip prompt injection through a hostile PR or attacker-named test file.

coverctl is local-first. The default install transmits nothing — no telemetry, no analytics, no source data. An opt-in --mcp-telemetry flag emits structured tool-call events to stderr for users who want to instrument their own pipelines (format documented in docs/design/mcp-metrics-spec.md). Adversarial evals (50+ scenarios under internal/eval/) gate every release on rejection-schema integrity and prompt-injection resistance.

Full threat model + residual risk: docs/security/mcp-threat-model.md.

CLI reference

The CLI is the substrate behind the MCP server; humans can use it directly.

CommandPurpose
init / iInteractive wizard, auto-detects language and domains. --no-interactive for CI.
check / cRun coverage and enforce policy. -o json for machine output, --fail-under N, --ratchet, --from-profile.
run / rProduce coverage artifacts without policy evaluation.
watch / wRe-run coverage on file change during development.
reportEvaluate an existing profile. -o html, --uncovered, --diff <ref>, --merge <profile>.
detectAuto-detect domains and write config. --dry-run to preview.
badgeSVG coverage badge. --style flat-square.
compareDiff two profiles.
debtCoverage debt report.
trendCoverage trend from recorded history.
recordAppend current coverage to history. --commit, --branch for CI.
suggestThreshold suggestions. --write-config to apply.
pr-commentPost coverage to GitHub/GitLab/Bitbucket PR.
ignoreShow configured excludes and tracked domains.
mcp serveStart MCP server (stdio). --mode=agent|ci|auto.
mcp doctorFirst-run validation: PASS/FAIL per step with remediation.
surveySean Ellis 40% PMF prompt; appends to ~/.coverctl/survey.jsonl.

Global flags: -q/--quiet, --no-color, --ci (combines quiet + GitHub Actions annotations).

Test-execution flags

check, run, record accept toolchain flags forwarded to the underlying test runner:

FlagExample
--tags--tags integration,e2e
--race(Go race detector)
--shortSkip long-running tests
-vVerbose test output
--run--run TestFoo
--timeout--timeout 30m
--test-argRepeatable: --test-arg=-count=1 --test-arg=-parallel=4
--language / -lOverride autodetection: go, python, nodejs, rust, java, ...

Terminal flow (without an agent)

If you prefer running coverctl directly:

bash
coverctl init      # auto-detect language + domains, write .coverctl.yaml
coverctl check     # enforce policy; exit 1 on violation
coverctl suggest --strategy current
coverctl record

If a step fails: coverctl detect --dry-run previews init output; coverctl check -o json surfaces structured failure detail; coverctl record --commit "$(git rev-parse HEAD)" --branch "$(git rev-parse --abbrev-ref HEAD)" provides metadata explicitly in CI.

Configuration

.coverctl.yaml (schema: schemas/coverctl.schema.json):

yaml
version: 1
policy:
  default:
    min: 75
  domains:
    - name: auth
      match: ["./internal/auth/..."]
      min: 90       # critical path — stricter
    - name: api
      match: ["./internal/api/..."]
      min: 80
    - name: utils
      match: ["./internal/utils/..."]
      # falls back to default min: 75
exclude:
  - internal/generated/*

Per-domain enforcement is the point: overall coverage hides regressions in critical paths. coverctl evaluates each domain against its own minimum and fails the build if any domain falls below.

Why these numbers differ from go test ./...

coverctl runs tests with -coverpkg spanning the configured domains, so a package is credited for the tests of other packages that exercise it. Plain go test ./... credits only a package's own test files. The same code therefore gets two legitimate numbers, and coverctl's is the higher, more accurate one:

packagego test ./...coverctl
a package exercised only through its callers0.0%80%

If a package looks untested under go test, check it here before writing tests for it — a helper called from everywhere but tested nowhere directly will read as 0% and be fully covered in practice. The reverse case is real too: a package can look fine in aggregate while one file inside it has no tests at all, which is what files: rules exist for.

Note that --from-profile reports whatever the supplied profile measured. If that profile came from a plain go test ./..., the numbers are per-package and the distinction above does not apply.

Advanced

yaml
files:
  - match: ["internal/core/*.go"]
    min: 90                          # per-file overrides
diff:
  enabled: true
  base: origin/main                  # only enforce on changed files
integration:
  enabled: true                      # Go 1.20+ GOCOVERDIR integration tests
  packages: ["./internal/integration/..."]
  cover_dir: ".cover/integration"
  profile: ".cover/integration.out"
merge:
  profiles: [".cover/unit.out", ".cover/integration.out"]
annotations:
  enabled: true                      # // coverctl:ignore, // coverctl:domain=NAME

Multi-package monorepo? Use extends: for inherited policies. Starting point: copy templates/coverctl.yaml.

Supported languages

LanguageFormatDetection markers
GoNative cover profilego.mod, go.sum
PythonCobertura, LCOVpyproject.toml, setup.py, requirements.txt
TypeScript / JavaScriptLCOVtsconfig.json, package.json
JavaJaCoCo, Coberturapom.xml, build.gradle
RustLCOV (cargo-llvm-cov)Cargo.toml
C# / .NETCobertura (coverlet)*.csproj, *.sln
C / C++LCOV (gcov/lcov)CMakeLists.txt, meson.build
PHPCobertura (PHPUnit)composer.json, phpunit.xml
RubyLCOV (SimpleCov)Gemfile, Rakefile
SwiftLCOV (llvm-cov)Package.swift
DartLCOV (dart test)pubspec.yaml
ScalaCobertura (scoverage)build.sbt
ElixirLCOV (mix test)mix.exs
ShellCobertura (kcov)*.bats

GitHub Action

yaml
jobs:
  coverage:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v6
      - uses: actions/setup-go@v6
        with:
          go-version: "1.25"
      - uses: ./.github/actions/coverctl
        with:
          command: check
          config: .coverctl.yaml
          output: text

For platform & devex teams

Standardizing coverage policy across many polyglot repos? coverctl ships with the artifacts your security and procurement reviews will ask for:

Considering coverctl org-wide? Open a GitHub issue with label platform-evaluation — happy to walk through architecture and trust boundaries.

Community

Used coverctl for a few weeks? Run coverctl survey to share PMF feedback (local-only by default; nothing transmitted unless you opt in).

Built by Felix Geelhaar with contributions from the polyglot AI-coding community.

Contributing

  • TDD: tests before behavior changes.
  • Coverage ≥80% (go test ./... -cover).
  • Conventional Commits (feat:, fix:, chore:, ...) for Relicta version-bump logic.
  • main is protected; merge via PR after CI green (.github/workflows/go.yml + .github/workflows/eval.yml).
  • Run gofmt -w and golangci-lint v2 before pushing.

Architecture details for contributors: ARCHITECTURE.md.

Releases

Managed by Relicta. Do not push v* tags manually.

Security

See SECURITY.md for disclosure policy. MCP-input sanitization (internal/mcp/sanitize.go) and output canonicalization (internal/mcp/sanitize_output.go) are the primary defenses against prompt-injection-driven argument and content attacks; report bypasses privately.

常见问题

io.github.felixgeelhaar/coverctl 是什么?

面向 Go 代码覆盖率分析的工具,结合 MCP server 支持 AI-powered coverage workflows。

相关 Skills

前端设计

by anthropics

Universal
热门

面向组件、页面、海报和 Web 应用开发,按鲜明视觉方向生成可直接落地的前端代码与高质感 UI,适合做 landing page、Dashboard 或美化现有界面,避开千篇一律的 AI 审美。

想把页面做得既能上线又有设计感,就用前端设计:组件到整站都能产出,难得的是能避开千篇一律的 AI 味。

编码与调试
未扫描165.3k

网页应用测试

by anthropics

Universal
热门

用 Playwright 为本地 Web 应用编写自动化测试,支持启动开发服务器、校验前端交互、排查 UI 异常、抓取截图与浏览器日志,适合调试动态页面和回归验证。

借助 Playwright 一站式验证本地 Web 应用前端功能,调 UI 时还能同步查看日志和截图,定位问题更快。

编码与调试
未扫描165.3k

网页构建器

by anthropics

Universal
热门

面向复杂 claude.ai HTML artifact 开发,快速初始化 React + Tailwind CSS + shadcn/ui 项目并打包为单文件 HTML,适合需要状态管理、路由或多组件交互的页面。

在 claude.ai 里做复杂网页 Artifact 很省心,多组件、状态和路由都能顺手搭起来,React、Tailwind 与 shadcn/ui 组合效率高、成品也更精致。

编码与调试
未扫描165.3k

相关 MCP Server

GitHub

编辑精选

by GitHub

热门

GitHub 是 MCP 官方参考服务器,让 Claude 直接读写你的代码仓库和 Issues。

这个参考服务器解决了开发者想让 AI 安全访问 GitHub 数据的问题,适合需要自动化代码审查或 Issue 管理的团队。但注意它只是参考实现,生产环境得自己加固安全。

编码与调试
89.1k

by Context7

热门

Context7 是实时拉取最新文档和代码示例的智能助手,让你告别过时资料。

它能解决开发者查找文档时信息滞后的问题,特别适合快速上手新库或跟进更新。不过,依赖外部源可能导致偶尔的数据延迟,建议结合官方文档使用。

编码与调试
60.0k

by tldraw

热门

tldraw 是让 AI 助手直接在无限画布上绘图和协作的 MCP 服务器。

这解决了 AI 只能输出文本、无法视觉化协作的痛点——想象让 Claude 帮你画流程图或白板讨论。最适合需要快速原型设计或头脑风暴的开发者。不过,目前它只是个基础连接器,你得自己搭建画布应用才能发挥全部潜力。

编码与调试
49.5k

评论