mcpField
M
mcp-csharp-create

mcp-csharp-create

github.com/dotnet开发5.8k722 次安装1 天前更新
代码仓库

关于 mcp-csharp-create

用于通过官方 SDK 和 .NET 模板创建 C# MCP 服务的技能,涵盖项目搭建、传输方式选择,以及工具、提示词和资源的实现。

主要功能

  1. 01搭建 C# MCP 服务项目
  2. 02选择 stdio 或 HTTP 传输
  3. 03实现工具、提示词和资源
  4. 04配置 ASP.NET Core 托管
  5. 05验证构建与服务启动

适用场景

  1. 01启动新的 MCP 服务项目
  2. 02为现有服务添加功能
  3. 03将 API 封装为 MCP 工具

MCP 相关

指导创建可通过 stdio 或 HTTP 向 MCP 客户端提供工具、提示词和资源的 MCP 服务。

安装

复制下面的命令,在终端中运行。

$npx skills add https://github.com/dotnet/skills --skill mcp-csharp-create

安装后在 Claude Code 中输入/mcp-csharp-create确认已加载。

附带文件references/api-patterns.mdreferences/transport-config.md

详细介绍

创建 C# MCP 服务

使用官方 C# SDK(ModelContextProtocol NuGet 包)和 dotnet new mcpserver 项目模板创建 Model Context Protocol 服务。服务会公开工具、提示词和资源,供大模型通过 MCP 协议发现和调用。

适用场景

  • 从零开始创建 MCP 服务项目
  • 向现有 MCP 服务添加工具、提示词或资源
  • 在 stdio(--transport local)和 HTTP(--transport remote)传输方式之间进行选择
  • 为 HTTP MCP 服务设置 ASP.NET Core 托管
  • 将外部 API 或服务封装为 MCP 工具

停止信号

  • 需要测试或评估? → 使用 mcp-csharp-test
  • 准备发布? → 使用 mcp-csharp-publish
  • 要构建 MCP 客户端,而非服务 → 此技能仅适用于服务端

输入

输入必需描述
传输类型是stdio(本地/命令行)或 http(远程/Web)。如未指定,请询问用户——默认使用 stdio
项目名称是项目的 PascalCase 名称(例如:WeatherMcpServer)
.NET SDK 版本建议需要 .NET 10.0+。使用 dotnet --version 检查
要封装的服务/API建议工具将与之交互的外部 API 或服务

工作流

提交策略: 完成每个步骤后都进行提交,以便分别审查项目搭建和实现。

步骤 1:验证先决条件
  1. 确认 .NET 10+ SDK:dotnet --version(如果版本低于 10.0,请从 https://dotnet.microsoft.com 安装)

  2. 检查是否已安装 MCP 服务模板:

    dotnet new list mcpserver
    

    如果显示“No templates found” → 安装:dotnet new install Microsoft.McpServer.ProjectTemplates

步骤 2:选择传输方式
选择 stdio 的情况…选择 HTTP 的情况…
本地命令行工具或 IDE 插件云端/Web 服务部署
一次仅供一位用户使用多个客户端同时使用
作为子进程运行(VS Code、GitHub Copilot)需要跨网络访问
设置更简单,无需配置网络容器化部署(Docker/Azure)

默认: stdio——设置更简单,适用于大多数本地开发场景。用户之后可以添加 HTTP。

步骤 3:搭建项目

stdio 服务:

dotnet new mcpserver -n <ProjectName>

如果模板超时或不可用,请使用 dotnet new console -n <ProjectName> 并添加 dotnet add package ModelContextProtocol。

HTTP 服务:

dotnet new web -n <ProjectName>
cd <ProjectName>
dotnet add package ModelContextProtocol.AspNetCore

这是推荐做法——比模板更快、更可靠。模板也支持通过 dotnet new mcpserver -n <ProjectName> --transport remote 使用 HTTP,但 dotnet new web 能让你更好地控制项目结构。

模板标志参考: --transport local(stdio,默认)、--transport remote(ASP.NET Core HTTP)、--aot、--self-contained。

步骤 4:实现工具

工具是 MCP 服务公开功能的主要方式。添加带有 [McpServerToolType] 的类和带有 [McpServerTool] 的方法:

using ModelContextProtocol.Server;
using System.ComponentModel;

[McpServerToolType]
public static class MyTools
{
    [McpServerTool, Description("Brief description of what the tool does.")]
    public static async Task<string> DoSomething(
        [Description("What this parameter controls")] string input,
        CancellationToken cancellationToken = default)
    {
        // Implementation
        return $"Result: {input}";
    }
}

重要规则:

  • 每个工具方法都必须带有 [Description] 特性——大模型会据此判断何时调用该工具
  • 每个参数都必须带有 [Description] 特性
  • 在所有异步工具中接受 CancellationToken
  • 仅在默认方法名称不明确时使用 [McpServerTool(Name = "custom_name")]

DI 注入模式——SDK 支持两种方式:

  1. 方法参数注入(静态类): DI 服务会作为方法参数出现。SDK 会自动解析这些服务——它们不会出现在工具架构中。

  2. 构造函数注入(非静态类): 当工具需要共享状态或多个服务时使用:

[McpServerToolType]
public class ApiTools(HttpClient httpClient, ILogger<ApiTools> logger)
{
    [McpServerTool, Description("Fetch a resource by ID.")]
    public async Task<string> FetchResource(
        [Description("Resource identifier")] string id,
        CancellationToken cancellationToken = default)
    {
        logger.LogInformation("Fetching {Id}", id);
        return await httpClient.GetStringAsync($"/api/{id}", cancellationToken);
    }
}

在 Program.cs 中注册服务:

var builder = Host.CreateApplicationBuilder(args);
builder.Logging.AddConsole(options =>
    options.LogToStandardErrorThreshold = LogLevel.Trace);

builder.Services.AddHttpClient();        // registers IHttpClientFactory + HttpClient
// ILogger<T> is registered by default — no extra setup needed.

builder.Services.AddMcpServer()
    .WithStdioServerTransport()
    .WithToolsFromAssembly();            // discovers non-static [McpServerToolType] classes

await builder.Build().RunAsync();

有关完整的特性参考、返回类型、DI 注入和构建器 API 模式,请参阅 references/api-patterns.md。

步骤 5:添加提示词和资源(可选)

提示词 — 可复用的大模型交互模板:

[McpServerPromptType]
public static class MyPrompts
{
    [McpServerPrompt, Description("Summarize content into one sentence.")]
    public static ChatMessage Summarize(
        [Description("Content to summarize")] string content) =>
        new(ChatRole.User, $"Summarize this into one sentence: {content}");
}

资源 — 大模型可读取的数据:

[McpServerResourceType]
public static class MyResources
{
    [McpServerResource(UriTemplate = "config://app", Name = "App Config",
        MimeType = "application/json"), Description("Application configuration")]
    public static string GetConfig() => JsonSerializer.Serialize(AppConfig.Current);
}
步骤 6:配置 Program.cs

stdio 传输:

using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
using Microsoft.Extensions.Logging;
using ModelContextProtocol.Server;

var builder = Host.CreateApplicationBuilder(args);
builder.Logging.AddConsole(options =>
    options.LogToStandardErrorThreshold = LogLevel.Trace); // CRITICAL: stderr only

builder.Services.AddMcpServer()
    .WithStdioServerTransport()
    .WithToolsFromAssembly();

await builder.Build().RunAsync();

HTTP 传输:

using ModelContextProtocol.Server;

var builder = WebApplication.CreateBuilder(args);
builder.Services.AddMcpServer()
    .WithHttpTransport()
    .WithToolsFromAssembly();

// Register services your tools need via DI
// builder.Services.AddHttpClient();
// builder.Services.AddSingleton<IMyService, MyService>();

var app = builder.Build();
app.MapMcp();                     // exposes MCP endpoint at /mcp (Streamable HTTP)
app.MapGet("/health", () => "ok"); // health check for container orchestrators
app.Run();

HTTP 关键细节: MapMcp() 默认使用 /mcp 路径。对于容器,请设置 ASPNETCORE_URLS=http://+:8080 和 EXPOSE 8080。MCP HTTP 协议使用 Streamable HTTP — 除了 URL 外,无需特殊的客户端配置。

有关传输配置的详情(无状态模式、身份验证、路径前缀、HttpContextAccessor),请参阅 references/transport-config.md。

步骤 7:验证服务是否启动
cd <ProjectName>
dotnet build
dotnet run

对于 stdio:进程启动后会等待从 stdin 接收 JSON-RPC 输入。 对于 HTTP:服务会在配置的端口上监听。

验证

  • 项目构建无错误(dotnet build)
  • 所有工具类都有 [McpServerToolType] 属性
  • 所有工具方法都有 [McpServerTool] 和 [Description] 属性
  • 所有参数都有 [Description] 属性
  • stdio:日志输出到 stderr,而不是 stdout
  • HTTP:在 Program.cs 中调用了 app.MapMcp()
  • 使用 dotnet run 成功启动服务

常见问题

问题解决方案
stdio 服务输出乱码或卡住输出到 stdout 的日志会破坏 JSON-RPC 协议。设置 LogToStandardErrorThreshold = LogLevel.Trace
大模型客户端无法发现工具类上缺少 [McpServerToolType],或方法上缺少 [McpServerTool]。请检查 Program.cs 中的 .WithToolsFromAssembly()
大模型无法理解何时使用工具为方法和所有参数添加清晰的 [Description] 属性
WithToolsFromAssembly() 在 AOT 下失败基于反射的发现方式与 Native AOT 不兼容。请改用 .WithTools<MyTools>()
参数未出现在工具架构中CancellationToken、IMcpServer 和 DI 服务会自动注入,不会出现在架构中。只有带有 [Description] 的参数才会公开
HTTP 服务返回 404必须调用 app.MapMcp()。请检查请求路径是否与配置的路由匹配

相关技能

  • mcp-csharp-test — 单元测试、集成测试、评估
  • mcp-csharp-publish — NuGet、Docker、Azure 部署

参考文件

  • references/api-patterns.md — 完整的属性参考、返回类型、DI 注入、构建器 API、动态工具、实验性 API。在以下情况加载: 实现超出上述基本模式的工具、提示词或资源时。
  • references/transport-config.md — 详细的传输配置:无状态 HTTP 模式、OAuth/身份验证、自定义路径前缀、HttpContextAccessor、OpenTelemetry 可观测性。在以下情况加载: 配置高级传输选项或身份验证时。

更多信息

评论

支持 Markdown