Skip to content

🚀 Transport Subsystem & Subprocess Lifecycle ​

This document details the transport abstraction layer, STDIO subprocess isolation, process tree lifecycle management, signal handling, and secure stream multiplexing in the Model Context Gateway (MCG).


📑 Table of Contents ​

  1. Strategy Pattern (ITransport)
  2. Subprocess STDIO Architecture & Security Hardening
  3. Child Process Tree Lifecycle & Signal Handling
  4. Stderr Log Capture & PII Token Masking
  5. Sequence Diagram: STDIO Subprocess Execution

1. Strategy Pattern (ITransport) ​

The gateway shields core routing coordinators from network and IPC transport protocols through the ITransport strategy interface:

csharp
public interface ITransport : IAsyncDisposable
{
    string TransportType { get; }
    bool IsConnected { get; }
    Task InitializeAsync(McpServer server, CancellationToken cancellationToken = default);
    Task<JsonRpcResponse> SendRequestAsync(JsonRpcRequest request, CancellationToken cancellationToken = default);
    Task SendNotificationAsync(JsonRpcNotification notification, CancellationToken cancellationToken = default);
    Task CloseAsync(CancellationToken cancellationToken = default);
    Task<bool> IsHealthyAsync(CancellationToken cancellationToken = default);
}

The gateway provides three production transport implementations:

Transport ImplementationProtocol / ChannelConcurrency & MultiplexingTarget Systems
SseTransportHTTP Server-Sent Events + POSTFull-Duplex MultiplexedDocker containers, remote network MCP servers, persistent services
HttpTransportHalf-Duplex HTTP POST / StreamStateless / Single-ShotServerless functions, cloud endpoints, webhooks
StdioTransportStandard Input / Output (NDJSON)Serialized via Async LockLocal CLI tools, Python scripts (uvx), Node.js packages (npx)

2. Subprocess STDIO Architecture & Security Hardening ​

The StdioTransport manages local CLI processes, Python virtual environments, and Node runtimes with strict security sandboxing:

  1. Command Line Tokenization: StdioTransport.ParseCommandLine parses single/double quoted paths and arguments cleanly into an executable and distinct argument array without passing raw string blocks to the OS.

  2. Strict Process Security Policy:

    • UseShellExecute = false and CreateNoWindow = true.
    • Executables are invoked directly without intermediate command interpreters (sh, bash, cmd.exe, powershell.exe). This completely prevents shell injection vulnerabilities and command chaining attacks (&&, ;, |, $(...)).
  3. Zero-Leakage Credential Injection:

    • Downstream secrets resolved from Vault, DPAPI, or Gateway Environment are injected strictly via ProcessStartInfo.Environment.
    • Credentials are never passed as command-line arguments, preventing credential exposure in host process listings (ps aux, /proc/$PID/cmdline, Windows Task Manager).
  4. Stream Synchronization & Buffer Draining:

    • Requests are written to StandardInput as newline-delimited JSON (NDJSON) guarded by asynchronous write locks (SemaphoreSlim).
    • StandardOutput is read line-by-line using asynchronous loops to avoid standard pipe buffer deadlocks.

3. Child Process Tree Lifecycle & Signal Handling ​

Subprocesses follow a deterministic lifecycle that ensures processes and their spawned worker threads exit cleanly without leaving zombie or orphaned processes:

Lifecycle Rules ​

  • Graceful Termination: When a session terminates or the gateway shuts down, the router closes StandardInput. MCP compliant tools detect EOF on standard input and exit cleanly.
  • Process Tree Killing: If a subprocess hangs or fails to terminate within the configured grace period (default: 5 seconds), process.Kill(entireProcessTree: true) is invoked. This recursively terminates the root process and all child processes spawned by it (e.g., Python scripts spawning native binaries or compilers).

4. Stderr Log Capture & PII Token Masking ​

Local CLI processes often emit diagnostic, debugging, or error information to StandardError. The gateway continuously monitors this stream while safeguarding sensitive data:

  1. Continuous Drainer Loop: An asynchronous background worker continuously drains StandardError to prevent standard pipe buffer saturation from blocking process execution.
  2. Mandatory PII Masking: Every log line emitted by the subprocess passes through PiiSanitizer.SanitizePayload. Regex patterns automatically redact Bearer tokens, API keys, passwords, and private connection strings before the entry is written to AuditLogs or forwarded to console monitors.

5. Sequence Diagram: STDIO Subprocess Execution ​

The following sequence diagram illustrates the lifecycle of a tool request dispatched over the STDIO transport, including background stderr log capture, secret injection, and asynchronous response completion:


Related Specifications:

Released under the Apache 2.0 License.