Hacktoberfest 2026:维护者为十月标记出来的 issue,仍然开放、适合新手。 浏览 Hacktoberfest issue

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

未关闭
#1,389 1 条评论 1 个 reaction 已指派 0 人 在 GitHub 查看

还没有人认领这个 Issue。

评估

难度
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 小时
30 天内合并 PR
4

贡献指南

打开贡献指南

从这里开始

  1. 先读完整个 Issue,再读项目的贡献指南。
  2. 在 Issue 下留言说明你要接手 —— 这能避免两个人做同样的事。
  3. Fork 仓库,在一个分支上完成修改。
  4. 提交 Pull Request,并在描述里引用这个 Issue 编号。

modelcontextprotocol/csharp-sdk 的其他 Issue

查看 modelcontextprotocol/csharp-sdk 的全部 Issue

相似的 Issue

更多 C# Issue

把新 issue 发到你的邮箱

精选适合新手参与的 GitHub issue 摘要。