Hacktoberfest 2026: những issue maintainer đã đánh dấu cho tháng Mười, đang mở và phù hợp người mới. Xem issue Hacktoberfest

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

Đang mở
#1,389 1 bình luận 1 reaction 0 người được giao Xem trên GitHub

Maintainer thường phản hồi trong vòng 2 ngày

Chưa có ai nhận issue này.

Đánh giá

Độ khó
3/5
Thời gian dự kiến
1-2 ngày
Mức phù hợp với người mới
68/100
Loại issue
Tính năng
Độ rõ ràng
Đặc tả rõ ràng
Mức độ hoạt động
Ít trao đổi
Công nghệ
csharp
Lĩnh vực
api, cli

Hướng nghiên cứu

Bắt đầu với entry point được đề xuất samples/StdioToHttpBridge và cách sử dụng thô ITransport được mô tả trong issue. Chạy nó với một HTTP MCP endpoint và một stdio client, kiểm tra việc chuyển tiếp message hai chiều, các API-key header, các biến môi trường và cảnh báo không an toàn. Được xem là hoàn tất khi sample kết nối trong suốt cả hai transport mà không tự triển khai việc xử lý protocol.

Do mô hình lập chỉ mục viết ra từ nội dung của issue.

Mô tả

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.

Ngôn ngữ chính
C#
Star
4.5k
Fork
814
Merge trung bình
8 ngày 7 giờ
Pull request đã merge (30 ngày)
3

Chuẩn bị môi trường

Bắt đầu từ đâu

  1. Đọc hết issue, rồi đọc hướng dẫn đóng góp của dự án.
  2. Bình luận trên issue rằng bạn sẽ nhận — tránh hai người làm cùng một việc.
  3. Fork repository và làm thay đổi trên một nhánh.
  4. Mở pull request có tham chiếu số hiệu của issue.

Issue khác của modelcontextprotocol/csharp-sdk

Tất cả issue của modelcontextprotocol/csharp-sdk

Issue tương tự

Thêm issue về C#

Nhận issue mới trong hộp thư của bạn

Bản tóm tắt ngắn những issue GitHub phù hợp với người mới.