Hacktoberfest 2026:メンテナが10月に向けて印を付けた、オープンで初心者向けの issue。 Hacktoberfest の issue を見る

Sample: stdio-to-HTTP bridge for AI clients that only support stdio transport

オープン
#1,389 コメント 1 件 リアクション 1 件 担当者 0 名 GitHub で見る

まだ誰も着手していません。

評価

難易度
3/5
見積もり時間
1〜2日
初心者へのやさしさ
68/100
issue の種類
機能追加
明瞭さ
明確に書かれている
活発さ
静か
技術スタック
csharp
領域
api, cli

調査の方向性

提案されている samples/StdioToHttpBridge エントリーポイントと、issue で説明されている ITransport の生の使用方法から始めます。HTTP MCP エンドポイントと stdio クライアントに対して実行し、双方向のメッセージ転送、API-key ヘッダー、環境変数、および安全でないことを示す警告を確認します。sample 自体がプロトコル処理を実装せずに両方のトランスポートを透過的に接続できれば完了です。

索引モデルが issue の本文から書いたものです。

説明

documentation enhancement P3 ready for work

Is your feature request related to a problem?

Many AI clients (Claude Desktop, Cursor, VS Code, etc.) only support stdio MCP servers configured as local processes. When the actual MCP server runs over Streamable HTTP (e.g. a remote or self-hosted server with API key authentication), users need a lightweight bridge process to proxy messages between the two transports.

Today there is no sample showing this pattern, so developers end up implementing HTTP manually (handling mcp-session-id, SSE parsing, notifications, error mapping, etc.) without knowing the SDK already provides everything needed.

Describe the solution you'd like

Add a samples/StdioToHttpBridge sample showing how to proxy messages transparently between StdioServerTransport and HttpClientTransport using the raw ITransport layer:

using System.CommandLine;
using ModelContextProtocol.Client;
using ModelContextProtocol.Server;

var urlOption = new Option<string>("--url", ["-u"])
{
    Description = "MCP server endpoint URL. Env: MCP_URL",
    DefaultValueFactory = (_) => Environment.GetEnvironmentVariable("MCP_URL") ?? string.Empty
};

var apiKeyOption = new Option<string>("--api-key", ["-k"])
{
    Description = "API key for authentication. Env: MCP_API_KEY",
    DefaultValueFactory = (_) => Environment.GetEnvironmentVariable("MCP_API_KEY") ?? string.Empty
};

var insecureOption = new Option<bool>("--insecure", ["-i"])
{
    Description = "Disable SSL certificate validation. DANGEROUS: use only in development. Env: MCP_INSECURE",
    DefaultValueFactory = (_) => Environment.GetEnvironmentVariable("MCP_INSECURE") is "1" or "true"
};

var rootCommand = new RootCommand("stdio-to-HTTP MCP bridge") { urlOption, apiKeyOption, insecureOption };

rootCommand.SetAction(async action =>
{
    var mcpUrl   = action.GetValue(urlOption);
    var apiKey   = action.GetValue(apiKeyOption);
    var insecure = action.GetValue(insecureOption);

    if (string.IsNullOrWhiteSpace(mcpUrl) || string.IsNullOrWhiteSpace(apiKey))
    {
        if (string.IsNullOrWhiteSpace(mcpUrl)) Console.Error.WriteLine("Error: --url is required.");
        if (string.IsNullOrWhiteSpace(apiKey)) Console.Error.WriteLine("Error: --api-key is required.");
        Environment.Exit(1);
    }

    if (insecure) Console.Error.WriteLine("WARNING: SSL validation is DISABLED");

    var handler = insecure
        ? new HttpClientHandler { ServerCertificateCustomValidationCallback = HttpClientHandler.DangerousAcceptAnyServerCertificateValidator }
        : new HttpClientHandler();

    var httpTransport = new HttpClientTransport(
        new HttpClientTransportOptions
        {
            Endpoint         = new Uri(mcpUrl!),
            AdditionalHeaders = new Dictionary<string, string> { ["X-API-Key"] = apiKey! },
            TransportMode    = HttpTransportMode.StreamableHttp
        },
        new HttpClient(handler));

    await using var remoteTransport = await httpTransport.ConnectAsync();
    await using var stdioTransport  = new StdioServerTransport("mcp-bridge");

    // Proxy stdio → remote
    var stdioToRemote = Task.Run(async () =>
    {
        await foreach (var message in stdioTransport.MessageReader.ReadAllAsync())
            await remoteTransport.SendMessageAsync(message);
    });

    // Proxy remote → stdio
    var remoteToStdio = Task.Run(async () =>
    {
        await foreach (var message in remoteTransport.MessageReader.ReadAllAsync())
            await stdioTransport.SendMessageAsync(message);
    });

    await Task.WhenAny(stdioToRemote, remoteToStdio);
});

return await rootCommand.Parse(args).InvokeAsync();

Why this approach

  • Transparent proxy: works at raw ITransport level — all JSON-RPC messages (including initialize/initialized) are forwarded as-is, no double handshake
  • SDK handles complexity: HttpClientTransport manages mcp-session-id, Streamable HTTP protocol, reconnections automatically
  • Authentication via AdditionalHeaders: clean way to inject API keys or bearer tokens
  • Environment variable support: MCP_URL, MCP_API_KEY, MCP_INSECURE for container/CI use
  • Distributable: can be published as PublishSingleFile=true self-contained executable

Additional context

This is the pattern we use in cv4pve-admin to let Claude Desktop connect to our self-hosted Proxmox VE MCP server over HTTPS with API key authentication.

主要言語
C#
スター
4.5k
フォーク
814
平均マージ
9日 19時間
マージ済み PR(30日)
4

コントリビューションガイド

コントリビューションガイドを開く

はじめの一歩

  1. issue を最後まで読み、次にプロジェクトのコントリビューションガイドを読みます。
  2. 着手することを issue にコメントします — 二人が同じ作業をするのを防げます。
  3. リポジトリをフォークし、ブランチを切って変更します。
  4. issue 番号を参照したプルリクエストを送ります。

modelcontextprotocol/csharp-sdk のほかの issue

modelcontextprotocol/csharp-sdk の issue をすべて見る

似ている issue

C# の issue をもっと見る

新しい issue をメールで受け取る

初心者向けの GitHub issue を短くまとめたダイジェスト。