mcpField
M
mcp-csharp-create

mcp-csharp-create

github.com/dotnet開発5.8k722 回インストール1 日前に更新
リポジトリ

mcp-csharp-create について

公式 SDK と .NET テンプレートを使って C# MCP サーバーを作成するスキルです。プロジェクトの準備、トランスポートの選択、ツールやプロンプト、リソースの実装を案内します。

主な機能

  1. 01C# MCP サーバープロジェクトの作成
  2. 02stdio または HTTP の選択
  3. 03ツール、プロンプト、リソースの実装
  4. 04ASP.NET Core ホスティングの設定
  5. 05ビルドと起動の確認

活用シーン

  1. 01新しい MCP サーバーの開始
  2. 02既存サーバーへの機能追加
  3. 03API の 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 サーバーを作成します。サーバーは、LLM が検出し、MCP プロトコル経由で呼び出せるツール、プロンプト、リソースを公開します。

使用する場面

  • 新しい MCP サーバープロジェクトを一から始める
  • 既存の MCP サーバーにツール、プロンプト、リソースを追加する
  • stdio(--transport local)と HTTP(--transport remote)のトランスポートを選択する
  • HTTP MCP サーバー向けに ASP.NET Core ホスティングを設定する
  • 外部 API またはサービスを MCP ツールとしてラップする

中止の判断基準

  • テストや評価が必要ですか? → mcp-csharp-test を使用します
  • 公開する準備ができていますか? → mcp-csharp-publish を使用します
  • サーバーではなく MCP クライアントを構築しますか? → このスキルはサーバー側専用です

入力

入力必須説明
トランスポートの種類はいstdio(ローカル/CLI)または http(リモート/ウェブ)。指定されていない場合はユーザーに確認します。既定値は 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 を選ぶ場合…
ローカルの CLI ツールまたは IDE プラグインクラウド/ウェブサービスとしてのデプロイ
一度に 1 人のユーザーが利用複数のクライアントが同時に利用
サブプロセスとして実行(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] 属性を必ず付けます。LLM はこの情報を使ってツールを呼び出すタイミングを判断します
  • すべてのパラメーターに [Description] 属性を必ず付けます
  • すべての非同期ツールで CancellationToken を受け取ります
  • 既定のメソッド名が分かりにくい場合に限り、[McpServerTool(Name = "custom_name")] を使用します

DI の注入パターン — SDK は次の 2 つのスタイルをサポートしています。

  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:プロンプトとリソースを追加する(任意)

プロンプト — 再利用可能な LLM 対話テンプレート:

[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}");
}

リソース — LLM が読み取れるデータ:

[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:ログが stdout ではなく stderr に出力される
  • HTTP:Program.cs で app.MapMcp() が呼び出されている
  • dotnet run でサーバーが正常に起動する

よくある落とし穴

落とし穴解決策
stdio サーバーが文字化けしたデータを出力する、または応答しなくなるstdout へのログ出力は JSON-RPC プロトコルを破損させます。LogToStandardErrorThreshold = LogLevel.Trace を設定してください
LLM クライアントがツールを検出できないクラスに [McpServerToolType] がない、またはメソッドに [McpServerTool] がありません。Program.cs に .WithToolsFromAssembly() があることを確認してください
LLM がツールを使うタイミングを理解できないメソッドとすべてのパラメーターの両方に、明確な [Description] 属性を追加してください
AOT で WithToolsFromAssembly() が失敗するリフレクションベースの検出は 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 による可観測性。読み込む場面: 高度なトランスポートオプションや認証を設定する場合。

詳細情報

コメント