Hacktoberfest 2026: le issue che i maintainer hanno segnato per ottobre, aperte e adatte ai principianti. Sfoglia le issue Hacktoberfest

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

Aperta
#1,389 1 commento 1 reazione 0 assegnatari Vedi su GitHub

Nessuno ha ancora preso questa issue.

Valutazione

Difficoltà
3/5
Tempo stimato
1-2 giorni
Idoneità per principianti
68/100
Tipo di issue
Funzionalità
Chiarezza
Specificata chiaramente
Stato di attività
Tranquilla
Stack tecnologico
csharp
Ambito
api, cli

Direzione di ricerca

Inizia con l’entry point proposto samples/StdioToHttpBridge e l’utilizzo raw di ITransport descritto nell’issue. Eseguilo con un endpoint HTTP MCP e un client stdio, verificando l’inoltro bidirezionale dei messaggi, gli header API-key, le variabili d’ambiente e l’avviso di insicurezza. Il lavoro è completato quando il sample connette entrambi i transport in modo trasparente senza implementare direttamente la gestione del protocollo.

Scritto dal modello di indicizzazione a partire dal testo della issue.

Descrizione

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.

Lingua principale
C#
Stelle
4.5k
Fork
814
Merge medio
9g 19h
PR unite (30g)
4

Guida per i contributori

Apri la guida per i contributori

Come iniziare

  1. Leggi tutta la issue e poi la guida ai contributi del progetto.
  2. Commenta sulla issue per dire che te ne occupi tu — evita che due persone facciano lo stesso lavoro.
  3. Fai un fork del repository e lavora su un branch.
  4. Apri una pull request che faccia riferimento al numero della issue.

Altre issue di modelcontextprotocol/csharp-sdk

Tutte le issue di modelcontextprotocol/csharp-sdk

Issue simili

Altre issue su C#

Ricevi le nuove issue nella tua casella

Un breve riepilogo di issue GitHub adatte ai principianti.