关于 dotnet-mcp-builder
面向 C#/.NET 开发者的技能,用于基于官方 ModelContextProtocol 包构建 MCP 服务端和基础客户端。重点涵盖稳定版 2.x API、当前协议规范、传输配置与故障排查。
主要功能
- 01服务端与客户端实现指南
- 02STDIO 和 HTTP 传输配置
- 03工具、提示词与资源
- 04当前 SDK 和规范指南
- 05测试与故障排查参考
适用场景
- 01搭建 .NET MCP 服务端
- 02为 C# 项目添加 MCP 基元
- 03排查传输或注册问题
MCP 相关
指导使用官方 .NET SDK 实现 MCP 服务端和基础客户端,涵盖传输配置与协议功能。
安装
复制下面的命令,在终端中运行。
npx skills add https:/ / github.com/ github/ awesome-copilot --skill dotnet-mcp-builder安装后在 Claude Code 中输入/dotnet-mcp-builder确认已加载。
包含的文件
除 SKILL.md 外,安装时一起下载的参考资料和脚本。
references/client.mdelicitation.mdmcp-apps.mdpackages.mdprompt-primitive.mdresource-primitive.mdroots.mdsampling.mdserver-features.mdtesting.mdtool-primitive.mdtransport-http.mdtransport-stdio.md详细介绍
在 .NET 中构建 MCP 服务
本技能可帮助你使用 C#/.NET,基于由 Microsoft 和 MCP 项目维护的官方 ModelContextProtocol NuGet 包,编写生产级质量的 MCP 服务和基础客户端。它面向稳定的 2.x 版本线以及当前规范(2026-07-28)。
本技能何时值得一用
.NET MCP SDK 在达到 1.0 之前,经历了数年的预览包(0.x-preview),而 v2 又翻转了若干默认值。如果没有帮助,模型往往会:
- 固定到一个过时的预览版本,无法针对当前示例编译。
- 套用 1.x 时代的默认值,而 v2 已将其反转(HTTP 过去默认是有状态的;在 2.x 中
Stateless默认为true)。 - 推荐 2026-07-28 规范已弃用的能力(roots、sampling、MCP 通道日志记录——现已标记为
[Obsolete],警告MCP9005)。 - 遗漏近期的规范特性(多轮往返
input_required、发现优先协商、MCP Apps/Tasks 扩展包、elicitation URL 模式、结构化内容块)。 - 搞错 HTTP 传输的细节(有状态/无状态、代理缓冲、OAuth 接线)。
- 忘记 STDIO 的 stdout/stderr 陷阱。
如果任务属于上述之一,加载匹配的参考文档并遵循它。如果任务确实微不足道(例如“重命名这个工具方法”),你不需要读完所有内容——下面的核心规则就是最低要求。
30 秒心智模型
一个 .NET MCP 服务就是一个普通的 Microsoft.Extensions.Hosting(或 WebApplication)应用,通过 DI 接入一个 MCP 服务:
builder.Services
.AddMcpServer()
.WithStdioServerTransport() // OR .WithHttpTransport(...)
.WithToolsFromAssembly() // discover [McpServerToolType] classes
.WithPrompts<MyPrompts>() // optional
.WithResources<MyResources>(); // optional
原语就是类上带有特性的普通 C# 方法([McpServerToolType] + [McpServerTool]、[McpServerPromptType] + [McpServerPrompt]、[McpServerResourceType] + [McpServerResource])。参数从 JSON-RPC 绑定;SDK 会根据签名以及 [Description] 特性构建 JSON Schema。
服务到客户端的功能(elicitation、进度通知,以及现已弃用的 sampling/roots/日志通知)是注入的 IMcpServer 上的方法。
决策树 → 该加载哪些参考文档
如果你要创建新项目,或不确定当前的包版本,请始终加载 references/packages.md。
| 任务 | 加载 |
|---|---|
| 新建 STDIO 服务 | references/transport-stdio.md |
| 新建 HTTP(Streamable)服务 | references/transport-http.md |
| 添加/修改工具 | references/tool-primitive.md |
| 添加/修改提示词 | references/prompt-primitive.md |
| 添加/修改资源 | references/resource-primitive.md |
| 在工具执行中途向用户提问 | references/elicitation.md |
| 从工具中调用客户端的 LLM(在 2026-07-28 中已弃用) | references/sampling.md |
| 读取用户的项目 roots(在 2026-07-28 中已弃用) | references/roots.md |
| 返回交互式 UI | references/mcp-apps.md |
| 参数补全、日志/进度通知、过滤器、服务指令 | references/server-features.md |
| 编写一个消费 MCP 服务的 .NET 程序 | references/client.md |
| MCP Inspector、内存测试、mocks、CI | references/testing.md |
对于涉及多个原语的任务,请一次加载多个。对于现有文件中的琐碎编辑,你通常不需要加载任何参考文档。
核心规则(始终适用;这些规则可防止最高频的故障)
- 固定使用当前稳定版包,而非预览版。 使用最新的 2.x 版本的
ModelContextProtocol/ModelContextProtocol.AspNetCore/ModelContextProtocol.Core。如果你发现自己正在写0.3-preview或0.4-preview,停下来检查 NuGet —— 预览版 API 存在破坏性差异。1.x 仍然可用,但早于 2026-07-28 规范。 - STDIO 服务绝不能写入 stdout。 stdout 是 JSON-RPC 通道。在做任何其他事情之前,先配置
LogToStandardErrorThreshold = LogLevel.Trace,并且绝不要在工具中调用Console.WriteLine。 - 在 2.x 中 HTTP 默认是无状态的(v1.x 默认为有状态 —— 这是影响最大的 v2 破坏性变更)。2026-07-28 修订版完全没有 HTTP 会话:设置
Stateless = false会使服务拒绝该修订版,并通过旧版initialize回退为客户端提供服务。在当前协议的 HTTP 上实现“在工具执行中途向用户询问”,请使用多轮往返的InputRequiredException模式;将有状态 HTTP(或 STDIO)保留给旧版ElicitAsync/采样/roots 路径和推送通知。 - 仅支持 SSE 已被弃用。 请使用 Streamable HTTP。仅为你必须支持的旧客户端启用旧版 SSE(
EnableLegacySse = true),并明确指出这一点。 - 不要围绕已弃用的能力设计新服务。 2026-07-28 规范弃用了 roots、采样和 MCP 通道日志;SDK 将它们标记为
[Obsolete](警告MCP9005)。它们对降级客户端仍然有效,但对于新设计,请优先使用多轮往返的input_required模式和ILogger日志。仅在有文档记录的过渡措施下才抑制MCP9005。 - 始终为工具和参数添加
[Description]。 这是大模型在选择和构造调用时看到的内容。描述含糊是工具不被使用的第一大原因。 - 每次添加原语时都要展示注册代码行。 一个新的
[McpServerPromptType]类如果没有.WithPrompts<...>()(或.WithPromptsFromAssembly())就是不可见的。 - 不要臆造 API。 如果不确定某个方法是否存在,就说明这一点并查阅 API 参考 —— 错误的方法名会导致静默失败。这对新的 v2 扩展包(
ModelContextProtocol.Extensions.Tasks、ModelContextProtocol.Extensions.Apps)尤其适用 —— 在针对它们编写代码之前,先查阅其文档。
工作风格
- 进行最小化、增量式的更改。 在现有的工具类中添加方法,而不是重构项目。
- 对于非平凡的配置,运行
dotnet build。 在用户看到之前就捕获缺失的 using、特性拼写错误和 TFM 不匹配。 - 在搭建脚手架之前确认传输方式 + .NET 版本 + 原语,如果上下文尚未明确这些内容。新项目默认使用 .NET 10。
当用户卡住时
在猜测之前,先走一遍这份清单:
- STDIO: 有东西正在写入 stdout(日志 sink、
Console.WriteLine、库的横幅信息)。 - HTTP 404: 路径不匹配 ——
app.MapMcp()挂在根路径,app.MapMcp("/mcp")则挂在/mcp下。 - 工具不出现: 类上缺少
[McpServerToolType],或者没有注册.WithToolsFromAssembly()/.WithTools<T>()。 - 参数未绑定: 参数名必须与 JSON-RPC 的
arguments键一致;复杂类型通过System.Text.Json绑定。 - Sampling/elicitation/roots 失败: 这些旧式的服务端到客户端调用无法在当前协议的 HTTP 上运行 —— 请迁移到多轮往返的
InputRequiredException模式,或者(仅限旧式路径)设置Stateless = false,但要知道这会把 HTTP 客户端固定到降级的initialize修订版本。同时检查客户端是否真的声明了该能力。 - 升级到 2.x 后出现
MCP9005构建警告: 代码使用了已弃用的 roots/sampling/logging API。请规划迁移;只可暂时抑制。
还是卡住?把用户引向 EverythingServer 示例 —— 它覆盖了每一项功能。