关于 dotnetdevmcp
DotNetDevMCP 是供处理 .NET 解决方案的 AI 编码 Agent 使用的 MCP 服务。它通过 Roslyn 提供基于符号的代码操作,并整合构建、测试、分析和依赖式工作流工具。
主要功能
- 01基于 Roslyn 导航和编辑代码
- 02构建和测试 .NET 项目
- 03选择受改动影响的测试
- 04分析依赖关系和代码指标
- 05并发运行工具或执行工作流
适用场景
- 01在整个解决方案中重命名符号
- 02仅运行受代码改动影响的测试
- 03并发构建和测试互不依赖的项目
MCP 相关
向 MCP 客户端提供 .NET 代码智能、构建、测试、分析和编排工具。支持 stdio 和可选的 Streamable HTTP 传输。
配置
本地服务的配置在各客户端中通用,复制后粘贴到客户端的 MCP 配置文件即可。
我们还没有获取到这个服务的安装包或远程地址,请按项目 README 中的说明安装。
工具
本地服务需要在你的电脑上运行后才能读取工具,维护者暂未提供工具列表。
详细介绍
DotNetDevMCP
一个 MCP 服务,为 AI 编码 Agent 提供真正的 .NET 工具:Roslyn 代码智能、dotnet build/test、受影响测试的选择,以及一个可将这些工具作为依赖图并发运行的编排器。
处理 .NET 代码的 Agent 通常只能依赖 grep 和调用 dotnet 命令。这意味着它们读的是文件而非符号,编辑的是文本而非语法树,而且一次只运行一个命令。DotNetDevMCP 默认提供 37 个工具(启用下方可选组后为 53 个),利用编译器对解决方案的视角,并可并行运行构建、测试和分析。
初次使用?wiki 提供了首次会话教程、适用于每种 MCP 客户端的配置说明,以及故障排查指南。
安装
需要 .NET 10 SDK。
Claude Code
claude mcp add dotnetdevmcp -- dnx DotNetDevMCP --yes
VS Code / Visual Studio(.mcp.json 或 .vscode/mcp.json)
{
"servers": {
"dotnetdevmcp": {
"type": "stdio",
"command": "dnx",
"args": ["DotNetDevMCP", "--yes"]
}
}
}
Claude Desktop / Cursor / 任意 stdio 客户端(mcpServers 格式)
{
"mcpServers": {
"dotnetdevmcp": {
"command": "dnx",
"args": ["DotNetDevMCP", "--yes", "--", "--load-solution", "C:/src/MyApp/MyApp.sln"]
}
}
}
dnx 会在首次运行时从 NuGet.org 下载程序包。更喜欢永久安装?运行 dotnet tool install -g DotNetDevMCP,然后使用 dotnetdevmcp 作为命令。
传入 --load-solution <path>,让 Roslyn 在启动时加载你的解决方案;也可以在需要时让 Agent 调用 SharpTool_LoadSolution。--http --port 3001 会提供 Streamable HTTP 服务,而非 stdio(仅限 localhost,无身份验证:参见安全性);它会拒绝携带外部 Origin 标头或非 localhost Host 标头的请求。--allowed-origin <origin>(可重复使用)可将额外来源加入允许列表,例如,为转发其 Origin 的本地开发服务器代理设置 --allowed-origin http://localhost:5173——服务端不会发送 CORS 标头,因此这不会允许浏览器页面直接调用它。--clean-env 会在最小化环境下启动 dotnet 和 git,避免将环境变量中的令牌和云凭据传递给它们。dotnetdevmcp --help 会列出所有选项。
Git 和 Monitoring 工具(见下表)默认关闭——Agent 已有的 shell 可以满足这些需求,而且每个已注册的工具在每次会话中都会占用上下文令牌。传入 --enable git,monitoring(可用逗号分隔和/或重复传入,例如 --enable git --enable monitoring)即可启用其中一组或两组。
默认情况下,Roslyn 编辑工具(SharpTool_RenameSymbol、OverwriteMember、AddMember、MoveMember、FindAndReplace、CreateRoslynDocument、OverwriteRoslynDocument、ManageUsings、ManageAttributes)不会触及 git——它们会将更改应用到磁盘,并返回常规的编译检查输出,仅此而已。传入 --git-commit-edits 可选择启用旧行为:每次编辑都会创建一个 sharptools/<timestamp> 分支(如果当前尚未处于该分支上),并提交更改;SharpTool_Undo 也需要此选项才能还原更改。未启用该选项时,SharpTool_Undo 会返回说明性错误,而不是以不明原因的方式失败。(由于现在默认选择启用 git 集成,--disable-git 仍然存在,但不再执行任何操作。)
Agent 能获得什么
| 分组 | 工具 | 功能 |
|---|---|---|
| 代码智能(Roslyn) | 21 | 加载解决方案;搜索和查看定义;查找引用和实现;添加、覆盖、移动和重命名成员;管理 using 和特性;具备语法感知能力的查找与替换;复杂度分析;撤销。派生自 SharpTools。 |
| 测试 | 3 | dotnet_test_run(每个项目或解决方案运行一次 dotnet test,将 TRX 解析为包含消息和堆栈跟踪的逐项测试结果)、dotnet_test_discover 和 dotnet_test_affected:Roslyn 从你修改的文件开始遍历引用,找到能够到达这些文件的测试方法,并仅运行这些测试。 |
| 构建 | 4 | dotnet build、restore、clean、使用 MSBuild 属性进行构建。结构化错误和警告输出。 |
| 分析 | 5 | 项目依赖图、循环依赖检测、质量指标、过期包扫描。 |
| 编排 | 4 | orchestrate_parallel 并发运行该服务自身的任意工具;execute_workflow 将它们作为有向无环图运行。支持资源限制和指标。 |
| Git (可选启用) | 10 | 状态、分支、检出、暂存、提交、差异、日志、推送、拉取。使用 --enable git 启用。 |
| 监控 (可选启用) | 6 | 进程性能指标、GC 统计、资源利用率、运行状况检查、性能分析会话。使用 --enable monitoring 启用。 |
连接此服务后,你可以这样向 Agent 提出要求:
- “加载
MyApp.sln,找出IOrderRepository的所有实现,并在整个解决方案中将GetById重命名为FindById。” - “仅运行受我刚才所做更改影响的测试,并显示失败项及其堆栈跟踪。”
- “同时构建 API 和 worker 项目,然后运行这两个测试项目。”
- “哪些项目存在循环依赖?”
编排
上述工具单独使用也很实用,而编排器能让它们运行得更快。只需一次调用,就能按名称并行调度服务器上的任意工具,或将其作为依赖图调度:
{
"name": "execute_workflow",
"arguments": {
"workflowName": "ci",
"steps": [
{ "name": "build-tests", "toolName": "dotnet_build", "arguments": { "projectPath": "tests/Api.Tests/Api.Tests.csproj" } },
{ "name": "build-worker", "toolName": "dotnet_build", "arguments": { "projectPath": "src/Worker/Worker.csproj" } },
{ "name": "test-api", "toolName": "dotnet_test_run", "arguments": { "path": "tests/Api.Tests/Api.Tests.csproj", "noBuild": true }, "dependsOn": ["build-tests"] },
{ "name": "deps", "toolName": "dotnet_detect_circular_dependencies", "arguments": { "projectPath": "src/Api/Api.csproj" } }
]
}
}
build-tests、build-worker 和 deps 会立即启动;test-api 则会等待 build-tests。步骤由资源管理器限制并发(默认值:处理器数量,可通过 configure_resource_limits 调整)。失败会按步骤报告;某个依赖项失败时,其依赖步骤将停止运行。
在底层,这使用了 ConcurrentExecutor / WorkflowEngine / ResourceManager。它们是 DotNetDevMCP.Orchestration 中的普通 C# 类,无需 MCP 也可以使用。
数据
使用 BenchmarkDotNet 在 i7-10750H、.NET 10.0.9 上测得。编排基准测试使用 Task.Delay 模拟 I/O 密集型工作,因此测量的是引擎开销和调度性能,而非 dotnet 本身。
| 场景(20 项操作 × 50 毫秒) | 平均耗时 | 相较于顺序执行 |
|---|---|---|
| 顺序执行 | 1,237 毫秒 | 1.00 |
ConcurrentExecutor,并发限制为 5 | 246 毫秒 | 0.20 |
ConcurrentExecutor,不限制并发(12 个核心) | 123 毫秒 | 0.10 |
带依赖项的 WorkflowEngine | 185 毫秒 | 0.15 |
Task.WhenAll(下限) | 62 毫秒 | 0.05 |
| 包含依赖步骤和独立步骤的混合工作流 | 平均耗时 | 相较于顺序执行 |
|---|---|---|
| 顺序执行 | 308 毫秒 | 1.00 |
WorkflowEngine | 185 毫秒 | 0.60 |
受影响的测试
编辑后,Agent 通常会重新运行整个测试套件。dotnet_test_affected 则会请 Roslyn 来完成这项工作:获取已更改文件中声明的符号,沿引用关系遍历(最多 maxDepth 跳,默认值为 8),直到找到带有 [Fact]、[Theory]、[Test]、[TestCase] 或 [TestMethod] 的方法,然后仅运行这些测试。默认情况下,已更改文件取自 git 工作树;对于分支,可指定 gitBase: "main"。dryRun: true 会列出测试但不运行;framework: "net10.0" 则会运行多目标测试项目中的一个目标框架。
遍历有时间预算(maxSelectionSeconds,默认值为 10 秒)。如果某项代码更改影响的依赖范围太广,无法在合理时间内追踪,那么改为运行引用了已更改项目的测试项目(如果所有测试项目都受影响,则运行整个解决方案),并在响应中说明这一点(selectionComplete: false、ranScope)。当选中的测试超过全部测试的 20%(maxSelectedFraction)时,也会采用相同处理,因为筛选运行并不会更快。遍历无法追踪的已更改文件(.csproj、.razor、appsettings.json、已删除的文件)会触发相同的项目回退,并列在 untracedFiles 中;如果 Directory.Build.props、global.json 或 .editorconfig 有更改,则运行整个解决方案。绝不会悄无声息地只运行部分选中项。运行会在 timeoutSeconds(默认值为 600 秒)后终止,因此挂起的测试不会卡住 Agent;响应会列出未能完成的测试模块。maxDepth: 3 会缩小更多更改的范围,但也会漏掉更多测试。支持 VSTest 和 Microsoft.Testing.Platform(在 global.json 中设置 "test": { "runner": "Microsoft.Testing.Platform" })。项目回退也会追踪还原后的 NuGet 包引用(如果某个测试项目的 obj/project.assets.json 引用了另一个解决方案项目的包 ID,即使它们之间没有 ProjectReference,该测试项目仍会被选中)。只有在 Directory.Packages.props 是唯一更改文件(每个项目之外的文档除外)、实际更改的仅为 Version 属性(没有 Condition、GlobalPackageReference 或其他伴随修改),且解决方案中的每个项目都已还原时,才会将对 Directory.Packages.props 的更改缩小到实际使用了版本有变动的包 ID 的测试项目;如果该文件有其他更改、同时更改了其他文件,或解决方案中有任何项目尚未还原,则会改为运行整个解决方案,并说明适用的原因。
在此代码库中,编辑 ConcurrentExecutor.cs 会从 44 个测试中选中 22 个(ConcurrentExecutorTests,以及通过 OrchestrationService 调用它的 OrchestrationServiceTests)。通过 MCP 工具测得的结果(包括构建),测试环境为 i7-10750H:
| 测试数 | 耗时 | |
|---|---|---|
从 shell 运行 dotnet test | 44 | 9 s |
dotnet_test_run | 44 | 8.3 s |
dotnet_test_affected(更改 ConcurrentExecutor.cs) | 22 | 6.6 s |
此处的测试套件规模较小,因此节省的时间也不多。在真实的库中,效果会更明显:benchmarks/polly 会重放 40 个 Polly 提交,并向其代码注入故障。一次单文件更改运行了 5 个受影响的测试,用时 5.1 s;而同一会话中 net10.0 测试套件耗时 48.1 s。选中的测试包含了注入故障导致失败的 112 个测试中的 111 个(漏掉的测试通过反射构建其对象)。影响数百个测试的更改不会带来收益:最近 40 个提交中,16 个运行了筛选后的测试,24 个运行了整个测试套件。在繁忙代码上,每个会话中的首次选中会较慢(Roslyn 会绑定它触及的文件,然后缓存它们)。dryRun: true 会显示选中了哪些内容以及原因(via)。
安全
DotNetDevMCP 以你的身份运行,供你信任其处理代码的 Agent 使用。dotnet build 和 dotnet test 会执行解决方案包含的所有内容,因此恶意测试或 .csproj 会以你的权限运行,就像在终端中运行一样;服务不会添加沙箱。它能保证的是:工具参数无法向 dotnet 或 git 注入额外选项,Roslyn 编辑会限制在解决方案目录内,而 --clean-env 会阻止子进程访问环境变量中的机密信息。对于你不信任的代码,请在没有凭据的容器或虚拟机中同时运行 Agent 和服务;下方镜像仅包含服务,可让构建和测试在你的机器之外运行。不要将 --http 暴露给 localhost 以外的地址。详情见:SECURITY.md。
在容器中运行
服务可以在容器中运行,容器不联网、内存和进程数受限、没有任何能力,并且只挂载你的仓库,因此 Agent 触发的构建和测试无法访问你机器的其他部分。构建镜像(v0.3.4 是首个包含 Dockerfile 的版本),联网还原一次,然后注册这个沙箱化的服务:
docker build -t dotnetdevmcp https://github.com/csa7mdm/DotNetDevMCP.git#v0.3.4
docker run --rm -v "${PWD}:/src" -v dotnetdevmcp-nuget:/home/mcp/.nuget/packages --memory 8g --memory-swap 8g --pids-limit 512 --cap-drop ALL --security-opt no-new-privileges --entrypoint dotnet dotnetdevmcp restore /src/YourSolution.sln
claude mcp add dotnetdevmcp -- docker run -i --rm --network none -v "${PWD}:/src" -v dotnetdevmcp-nuget:/home/mcp/.nuget/packages:ro --memory 8g --memory-swap 8g --pids-limit 512 --cap-drop ALL --security-opt no-new-privileges dotnetdevmcp --load-solution /src/YourSolution.sln
这是 Docker Desktop 的配置形式(Windows、macOS):从 PowerShell、WSL 或 macOS 运行;如果使用 Git Bash,则在每条命令前加上 MSYS_NO_PATHCONV=1。原生 Linux 需要使用 --user 变体,而设置了 core.autocrlf 的 Windows 仓库需要为 git 模式额外添加一个设置;两者都见 SECURITY.md,其中还说明了各个标志的防护作用,以及用于验证这些防护的测试。
它并不能防护所有风险:挂载的仓库按设计可写;被隔离的只有服务,Agent 和 docker CLI 不受隔离(在 Linux 上,docker CLI 需要等同于 root 的守护进程访问权限);还原过程会在联网状态下运行解决方案自身的构建逻辑;共享的包缓存可能会将某个仓库植入的构建文件带到另一个仓库(对每个不可信仓库使用单独的卷);而 Docker Desktop 的隔离边界是由所有容器共享的虚拟机内核。
帮助、反馈与贡献
- 有问题、想法,或“不确定这是不是个 bug”?:前往 Discussions。
- 遇到故障:提交 bug 报告。最有用的信息是工具名称及其收到的参数。
- 想要贡献? 从一个适合新手的问题开始,或阅读 CONTRIBUTING。在自己的解决方案上运行 DotNetDevMCP 并报告结果,同样很有帮助。
- 文档:Wiki(教程、工具参考、故障排除)欢迎编辑。
- 安全问题:请私下报告。
- 在工作中使用?:在 Discussions 中告诉我:这会决定接下来开发什么。如果你的团队希望获得帮助,在解决方案中完成设置(受影响测试的调整、为私有源配置
--clean-env、CI),或者希望提前参与团队功能(共享配置、审计日志、沙箱化运行)的讨论,请在那里提出。 - 这里的每个人都遵守行为准则。如果 DotNetDevMCP 为你节省了时间,可以赞助其开发。
从源代码构建
git clone https://github.com/csa7mdm/DotNetDevMCP.git
cd DotNetDevMCP
dotnet build -c Release
dotnet test -c Release
dotnet run --project src/DotNetDevMCP.Server -- --help
要在 MCP 客户端中使用本地构建版本,请将 command 指向 src/DotNetDevMCP.Server/bin/Release/net10.0/dotnetdevmcp(Windows 上为 .exe)。
目录结构
src/
DotNetDevMCP.Server/ entry point; stdio or HTTP; packs as the `dotnetdevmcp` tool
DotNetDevMCP.CodeIntelligence/ Roslyn tools (SharpTools fork)
DotNetDevMCP.Testing/ dotnet test runner, TRX parsing, Roslyn affected-test selection
DotNetDevMCP.Build/ dotnet build/restore/clean
DotNetDevMCP.Analysis/ dependency graph, quality metrics
DotNetDevMCP.SourceControl/ git
DotNetDevMCP.Orchestration/ ConcurrentExecutor, WorkflowEngine, ResourceManager, orchestration tools
DotNetDevMCP.Monitoring/ process metrics
DotNetDevMCP.Core/ interfaces and models shared by the above
tests/ xUnit tests
benchmarks/ BenchmarkDotNet suite; polly/ measures the tools on Polly
docs/architecture/ design notes and ADRs
基于官方的 MCP C# SDK 2.x 构建。包版本由 Directory.Packages.props 集中管理。
状态
0.3.4。Roslyn 工具已成熟(来自 SharpTools)。测试、构建、git 和编排功能较新,已在此仓库和其他几个仓库中进行过验证;遇到不常见的项目布局时,可能会有一些问题。欢迎提交 Issues 和 PR,请参阅 CONTRIBUTING。
已知不足:dotnet_test_affected 仅沿 C# 引用关系追踪(不包括反射、按约定进行的 DI 或以字符串为键的查找),因此,如果某项更改仅通过这些路径产生影响,就不会选中对应测试;可使用 dryRun 检查它选中了哪些内容。通过接口或基类的调用会被追踪。项目回退逻辑会沿 ProjectReference 和 NuGet 包引用追踪:测试项目还原后,现在也会追踪包引用;不会追踪跨仓库的使用方。构建和测试未经过沙盒隔离(参见 Security)。测试若一直挂起而非失败,只有在运行结束时才会被捕获。测试特性检测依据特性名称,支持 xUnit、NUnit 和 MSTest。超过命令行长度限制后,筛选范围会从方法扩大到类,再扩大到整个项目(测试数量会增加,不会减少)。
致谢和许可证
MIT。代码智能模块是 SharpTools 的一个分支,原作者为 кɵɵѕнī,同样采用 MIT 许可证;关于为何选择分支而非引用,请参阅 LICENSE、NOTICE 和 ADR-001。
评论
一个开放协议,规定了 AI 应用如何以统一方式连接外部工具与数据源。客户端负责与模型对话,MCP 服务负责提供工具、资源和提示模板,两者通过标准消息通信,同一个服务可以被不同客户端复用。