mcpField
D
dotnet-coverage-mcp

dotnet-coverage-mcp

本地服务
github.com开发工具28 周前更新

关于 dotnet-coverage-mcp

dotnet-coverage-mcp 通过 MCP 工具让 AI 助手运行 .NET 测试并检查覆盖率。它支持分支级分析、覆盖率差异比较、按会话隔离产物及追加测试代码。

主要功能

  1. 01发现 C# 源文件并分批
  2. 02运行筛选测试并收集覆盖率
  3. 03汇总类和方法的覆盖率
  4. 04查找未覆盖分支并比较测试运行
  5. 05以原子写入方式追加测试代码
  6. 06按会话隔离覆盖率产物

适用场景

  1. 01找出 .NET 项目中覆盖率较低的方法
  2. 02添加测试前定位未覆盖分支
  3. 03比较代码更改前后的覆盖率
  4. 04在不同项目上并行运行覆盖率工作流

MCP 相关

该服务通过 stdio 与 MCP 客户端通信,并提供源文件发现、测试运行、覆盖率分析和插入测试代码的工具。它会调用 `dotnet test` 和 `reportgenerator`。

配置

本地服务的配置在各客户端中通用,复制后粘贴到客户端的 MCP 配置文件即可。

暂未收录安装方式

我们还没有获取到这个服务的安装包或远程地址,请按项目 README 中的说明安装。

代码仓库
安装包
nugetdotnet-coverage-mcp0.1.1

工具

还没有获取到工具列表

本地服务需要在你的电脑上运行后才能读取工具,维护者暂未提供工具列表。

详细介绍

dotnet-coverage-mcp

build tests NuGet License: MIT

一个 MCP(Model Context Protocol)服务,可让 AI 助手(Claude Code、Gemini CLI 等)直接使用 .NET 测试覆盖率工具。通过 stdio 运行 dotnet test、解析 Cobertura XML、识别未覆盖分支、比较不同运行之间的覆盖率差异,以及追加测试代码。

用途

此服务可让 AI 助手运行单元测试、收集覆盖率数据并分析结果,无需离开聊天界面。AI 无需手动运行 dotnet test 并解析报告,而是可以直接调用服务的工具来:

  • 发现源文件,并根据行数预算智能分组
  • 运行经过筛选的测试集并收集覆盖率
  • 读取精简、针对 AI 优化的覆盖率摘要(方法级行覆盖率和分支覆盖率)
  • 根据可配置的目标比例(默认为 80%)检查每个文件的覆盖率
  • 将未覆盖分支识别为结构化 JSON
  • 比较不同运行之间的覆盖率,仅查看发生变化的部分
  • 通过原子写入向现有测试文件追加新的测试代码

工作原理

服务以控制台进程启动,并使用 MCP 协议通过 stdio 通信。兼容 MCP 的客户端(Claude Code、Gemini CLI 等)会启动此进程,并像调用函数一样调用其中的工具。

AI Client  <--stdio/MCP-->  dotnet-coverage-mcp  <--shell-->  dotnet test + reportgenerator

可用工具

工具描述
GetSourceFiles从文件、文件夹或 .csproj 项目中发现 .cs 文件。返回文件元数据(行数、方法数量)以及按 lineBudget 分组的智能批次。
RunTestsWithCoverage使用 XPlat Code Coverage 运行 dotnet test,并通过 reportgenerator 生成 JSON 摘要。返回 Summary.json 和 coverage.cobertura.xml 的路径。支持 forceRestore 和 sessionId,以实现并发隔离。
GetCoverageSummary将 Summary.json 解析为结构化的类和方法覆盖率数据,并按分支覆盖率从低到高排序。可选的 belowTarget/topN/methodsPerClass 筛选器会精简响应,仅保留仍需改进的内容。
GetFileCoverage从 Cobertura XML 中获取单个源文件的覆盖率。当所有类的行覆盖率和分支覆盖率都达到配置的 targetRate 时,返回 allMeetTarget(默认值为 0.8)。支持 sessionId。
GetUncoveredBranches查找方法名匹配的未覆盖分支条件。返回所有匹配的方法,并支持部分名称匹配。支持 sessionId。
GetCoverageDiff将当前 Cobertura XML 与基线进行比较。显示方法级变化,包括新增和移除的方法。支持 sessionId,以实现并发隔离。
AppendTestCode在测试文件中插入或追加 C# 测试代码。支持基于锚点的插入,并在无法精确匹配时回退到忽略空白字符的匹配方式。通过原子写入防止文件损坏。
CleanupSession移除会话状态文件和 TestResults/coveragereport 目录。传入 sessionId 可限定清理范围;省略该参数时,则清理超过 maxAgeMinutes(默认值为 120)的构建产物。

批量工作流

对于包含许多源文件的项目,建议采用以下工作流:

  1. 发现 — 对文件夹或 .csproj 调用 GetSourceFiles,获取所有文件和智能批次
  2. 运行一次 — 使用宽泛的筛选器(例如 *)调用 RunTestsWithCoverage,收集所有文件的覆盖率
  3. 检查单个文件 — 对当前批次中的每个文件调用 GetFileCoverage(即时解析 XML,无需重新运行测试)
  4. 聚焦 — 选出分支覆盖率最低的 3 个方法,并分别调用 GetUncoveredBranches
  5. 编写测试 — 使用 AppendTestCode 添加测试方法
  6. 重新运行并比较差异 — 运行一次测试,然后调用 GetCoverageDiff 验证是否有所改进
  7. 重复 — 继续操作,直到批次文件达到目标比率(默认 80%),或连续 3 个周期没有改进,然后转到下一批次

这样可以最大限度减少 dotnet test 的调用次数(这是主要瓶颈),同时仍能跟踪每个文件的进展。

并发

多个 AI Agent 可以并行运行:为每次工具调用传入 sessionId,以隔离各自的覆盖率产物:

  • 隔离输出目录 — RunTestsWithCoverage 会为每个会话创建 TestResults-{hash}/ 和 coveragereport-{hash}/,防止一个 Agent 在另一个 Agent 解析 XML 的过程中删除该 XML
  • 限定作用域的状态文件 — 覆盖率状态写入 .mcp-coverage/.coverage-state-{hash},因此 ResolveCoberturaPath 会为每个会话解析到正确的 XML
  • 限定作用域的基线 — GetCoverageDiff 会将基线按会话存储为 .coverage-prev-{hash}.xml
  • 原子写入 — 所有文件写入(状态文件和测试代码)都采用先写入临时文件再重命名的方式,避免竞态条件或进程崩溃造成文件损坏

限制 — 构建输出不按会话隔离。 sessionId 隔离的是覆盖率产物,而不是 .NET 构建。dotnet test 会将目标项目编译到共享的 obj/ 和 bin/ 中,这些目录并非按会话划分。因此,两个 Agent 同时对同一个测试项目运行 RunTestsWithCoverage 时,会在这些输出上发生冲突并以 buildError 失败(例如 CS2012: the file is being used by another process)。请让并行 Agent 对不同的测试项目运行,或使用仓库的不同工作副本。只要它们的 dotnet test 构建不重叠,多个 Agent 操作同一个项目也没有问题。

不传入 sessionId 时,工具会使用共享默认值,适合单个 Agent 使用。

要求

  • .NET 9.0 SDK(或更高版本) — https://dotnet.microsoft.com/download

  • reportgenerator 全局工具 — 服务会调用它来生成覆盖率报告(请在下方的 安装 步骤中安装)

  • 兼容 MCP 的客户端(Claude Code、Gemini CLI 等)

  • COVERAGE_MCP_ALLOWED_ROOT — 建议设置。将其设为仓库根目录,以将每个工具的文件系统访问范围限制在该子树内。客户端传入的任何位于此根目录之外的路径都会被拒绝,并返回 pathNotAllowed。未设置时,服务会记录一次警告并接受任意路径(向后兼容,但不建议在共享环境中使用)。

    export COVERAGE_MCP_ALLOWED_ROOT=/path/to/your/repo
    

安装

通过 NuGet 将服务安装为全局 .NET 工具:

dotnet tool install --global dotnet-coverage-mcp

服务依赖 reportgenerator 全局工具来生成覆盖率报告 — 请一并安装:

dotnet tool install --global dotnet-reportgenerator-globaltool

安装后,dotnet-coverage-mcp 命令即可在 PATH 中使用。

构建和运行(从源代码)

cd <path-to-dotnet-coverage-mcp>

# Restore dependencies
dotnet restore

# Build
dotnet build

# Run
dotnet run

服务将启动并等待通过 stdin/stdout 传入的 MCP 消息。

MCP 客户端配置

安装全局工具(dotnet tool install --global dotnet-coverage-mcp)后, 在 MCP 客户端中注册该服务。将 COVERAGE_MCP_ALLOWED_ROOT 设置为 要让服务操作的仓库路径。

Claude Code
claude mcp add coverage --env COVERAGE_MCP_ALLOWED_ROOT=/path/to/your/repo -- dotnet-coverage-mcp
Claude Desktop

将以下内容添加到 claude_desktop_config.json(Settings → Developer → Edit Config):

{
  "mcpServers": {
    "coverage": {
      "command": "dotnet-coverage-mcp",
      "env": {
        "COVERAGE_MCP_ALLOWED_ROOT": "/path/to/your/repo"
      }
    }
  }
}
Cursor

将以下内容添加到 ~/.cursor/mcp.json(全局)或 .cursor/mcp.json(按项目):

{
  "mcpServers": {
    "coverage": {
      "command": "dotnet-coverage-mcp",
      "env": {
        "COVERAGE_MCP_ALLOWED_ROOT": "/path/to/your/repo"
      }
    }
  }
}
VS Code(GitHub Copilot)

将以下内容添加到 .vscode/mcp.json:

{
  "servers": {
    "coverage": {
      "type": "stdio",
      "command": "dotnet-coverage-mcp",
      "env": {
        "COVERAGE_MCP_ALLOWED_ROOT": "/path/to/your/repo"
      }
    }
  }
}
从源码运行

如需直接从源码运行,而不是使用全局工具,请使用 dotnet run:

{
  "mcpServers": {
    "coverage": {
      "command": "dotnet",
      "args": ["run", "--project", "<path-to-dotnet-coverage-mcp>"],
      "transport": "stdio"
    }
  }
}

或者直接指定已编译的可执行文件:

{
  "mcpServers": {
    "coverage": {
      "command": "<path-to-dotnet-coverage-mcp>\\bin\\Debug\\net9.0\\DotNetCoverageMcp.exe",
      "transport": "stdio"
    }
  }
}

工具参数

GetSourceFiles
参数类型必需描述
pathstring是.cs 文件、文件夹或 .csproj 项目的路径
lineBudgetint否每批次的最大总行数(默认值:300)。较小的文件会合并处理;较大的文件会单独成批。
RunTestsWithCoverage
参数类型必需描述
testProjectPathstring是.csproj 测试项目的完整路径
filterstring是测试筛选字符串(与 FullyQualifiedName 匹配)。使用 * 或 , 可跨多个测试类进行广泛筛选。
workingDirstring否工作目录;默认为项目目录
forceRestorebool否设为 true 时,跳过 --no-restore 标志。创建新的测试项目框架或添加 NuGet 包后使用。
sessionIdstring否为并发多 Agent 使用隔离输出目录(TestResults-{hash}/、coveragereport-{hash}/)和状态文件。
includeClassstring否将覆盖率收集限制为名称与此项匹配的类型(coverlet Include 筛选器,通过生成的 runsettings 文件传递给 --settings)。此项独立于 filter;传入明确值可限定覆盖率范围,省略则收集本次运行涉及的所有内容的覆盖率。不支持带命名空间限定的名称。
skipReportbool否设为 true 时,跳过 reportgenerator JSON 摘要步骤,只返回 Cobertura XML 路径。适用于快速迭代测试,此时 GetFileCoverage/GetUncoveredBranches/GetCoverageDiff 会直接读取 XML。需要 GetCoverageSummary 的 Summary.json 时,保持为 false(默认值)。
GetCoverageSummary
参数类型必需描述
summaryJsonPathstring是生成的 Summary.json 文件的完整路径
belowTargetdouble否设置后(取值为 [0,1] 内的小数,例如 0.8),仅返回行覆盖率或分支覆盖率低于此阈值的类。省略则返回所有类。
topNint否仅返回分支覆盖率最低的 N 个类(结果按覆盖率从低到高排序)。省略则返回所有类。
methodsPerClassint否每个类最多保留此数量的分支覆盖率最低的方法,其余方法会被删减。省略则保留所有方法。
GetFileCoverage
参数类型必需描述
coberturaXmlPathstring是coverage.cobertura.xml 的路径(若未找到,则回退到 .mcp-coverage/.coverage-state)
sourceFileNamestring是要查找的源文件名(例如 ExampleService.cs)
sessionIdstring否解析按会话隔离的状态文件,以实现并发隔离。
targetRatedouble否用于计算 allMeetTarget 的覆盖率阈值(0.0–1.0)。默认值为 0.8。
GetUncoveredBranches
参数类型必需描述
coberturaXmlPathstring是coverage.cobertura.xml 的路径(若未找到,则回退到 .mcp-coverage/.coverage-state)
methodNamestring是要检查的方法名(支持部分匹配;会返回所有匹配的方法)
sessionIdstring否解析按会话隔离的状态文件,以实现并发隔离。
GetCoverageDiff
参数类型必填说明
coberturaXmlPathstring是当前 coverage.cobertura.xml 的路径
workingDirstring否用于存储基线的目录;默认为 XML 文件所在的父目录
sessionIdstring否将基线隔离为 .coverage-prev-{hash}.xml,并解析会话范围内的状态文件。
AppendTestCode
参数类型必填说明
testFilePathstring是目标 .cs 测试文件的完整路径
codeToAppendstring是要插入的 C# 代码
insertAfterAnchorstring否如果提供,则在此字符串最后一次出现的位置之后插入代码(并支持忽略空白差异的回退匹配)。如果省略,则在最后一个 } 之前追加。
CleanupSession
参数类型必填说明
workingDirstring是包含 .mcp-coverage/ 和 TestResults 工件的项目工作目录
sessionIdstring否设置后,仅删除限定于此会话的状态文件和目录。
maxAgeMinutesint否省略 sessionId 时,删除超过此分钟数的工件。默认值为 120。

状态文件

所有状态文件都写入工作目录中的 .mcp-coverage/ 子目录,以保持项目根目录整洁。请将 .mcp-coverage/ 添加到目标仓库的 .gitignore。

文件用途
.coverage-state供单 Agent 使用的默认 Cobertura XML 路径
.coverage-state-{hash}会话范围内的 Cobertura XML 路径
.coverage-prev.xml用于差异比较的默认覆盖率基线
.coverage-prev-{hash}.xml会话范围内的覆盖率基线

插件(技能与 Agent)

此仓库包含一个 plugin/ 目录,其中提供 Claude Code 技能和 Agent 定义,用于引导测试覆盖率工作流:

plugin/
├── plugin.json
├── agents/
│   └── test-coverage.agent.md
└── skills/
    ├── scaffold-test-files/     — Create test directories and files mirroring source structure
    ├── run-coverage/            — Run tests and view coverage reports
    ├── analyze-coverage-gaps/   — Find uncovered branches and compare diffs
    └── improve-test-coverage/   — Iterative loop to reach 80% coverage

这些技能支持 NUnit、xUnit 和 MSTest,并在 references/unit.md 和 references/integration.md 中提供与框架无关的参考文档。

依赖项

包版本用途
Microsoft.Extensions.Hosting10.0.7依赖注入和托管
ModelContextProtocol1.2.0MCP 服务框架
Microsoft.CodeAnalysis.CSharp5.3.0用于安全插入代码和准确统计方法的 Roslyn AST(约 15MB)

安全性

dotnet-coverage-mcp 以本地 stdio 进程运行,并根据 COVERAGE_MCP_ALLOWED_ROOT 验证每个工具参数,以限制文件系统访问范围。有关威胁模型、加固建议以及如何报告漏洞,请参阅 SECURITY.md。

贡献

欢迎贡献。有关开发环境设置、拉取请求指南和代码规范,请参阅 CONTRIBUTING.md。重要变更记录在 CHANGELOG.md 中。

发布

仅限维护者——发布流程、NuGet 发布以及 MCP 注册表提交的文档见 RELEASING.md。

评论

支持 Markdown

第一次接触 MCP?

从协议是什么,到在客户端里装上第一个服务,这几条回答覆盖了大多数入门问题。

一个开放协议,规定了 AI 应用如何以统一方式连接外部工具与数据源。客户端负责与模型对话,MCP 服务负责提供工具、资源和提示模板,两者通过标准消息通信,同一个服务可以被不同客户端复用。