2026-04-20 10:00:00+00:00

In modern software development, agentic workflows (like Claude Code and Cline) are redefining how we write, test, and debug code. To protect host systems from runaway bash execution or malicious packages, the gold standard is running these agents inside isolated ephemeral Docker containers.

However, containerization introduces a severe networking roadblock for the Model Context Protocol (MCP).

When you run Claude Code inside a locked-down container sandbox, it expects to communicate with local MCP servers (such as a long-term database like Segnog) to fetch memory graphs, classify facts, or query local APIs. But because the sandbox has zero network permissions, it cannot connect to host ports directly, nor can it launch host processes.

To bridge this boundary, we must establish a translation layer. This article details how to build a high-performance Standard I/O to Server-Sent Events (SSE) Proxy to seamlessly connect sandboxed CLI agents to host-level MCP servers.


๐Ÿ—๏ธ The Networking Challenge: Stdio vs. SSE

The Model Context Protocol supports two primary transport layers:

  1. Standard I/O (stdio): The client spawns the server as a child process and communicates via stdin (standard input) and stdout (standard output). This is standard for local command-line tools.
  2. Server-Sent Events (SSE): The client connects to a server over HTTP, holding an open SSE stream (text/event-stream) to receive asynchronous notifications, and dispatches JSON-RPC payloads back to the server using standard HTTP POST requests.

Inside an isolated Docker container:

Our solution is to write an elegant, lightweight Node.js Proxy that runs inside the container, posing as a local stdio MCP server to Claude Code while translating all commands into HTTP-based SSE calls to the host system.

DOCKER SANDBOX (ISOLATED) Claude Code Engine Client App (Container) stdio-to-SSE Proxy index.js (Inside Sandbox) stdin/stdout HOST ENVIRONMENT (SECURE) Segnog MCP Server SSE Server Gateway FalkorDB & Embeddings Local Gemma Vector Graph Cypher Query SSE Stream (HTTP)

๐Ÿ› ๏ธ Implementing the Node.js stdio-to-SSE Proxy

The proxy's job is simple but requires meticulous stream handling:

  1. Initialize standard input/output channels: Read raw standard input JSON payloads dispatched by Claude Code.
  2. Open the SSE Endpoint: Trigger an HTTP request to the host-level SSE endpoint (http://host.docker.internal:9000/mcp/sse) to retrieve the EventSource endpoint and the unique session ID.
  3. Piping streams:

Below is the production-grade, highly resilient Node.js implementation:

// index.js (Piped stdio-to-SSE MCP Proxy)
import EventSource from 'eventsource';
import fetch from 'node-fetch';
import readline from 'readline';

const HOST_MCP_URL = 'http://host.docker.internal:9000/mcp/sse';
let eventSource = null;
let uploadUrl = null;

// Initialize standard input line reader to catch Claude's commands
const rl = readline.createInterface({
  input: process.stdin,
  output: process.stdout,
  terminal: false
});

/**
 * Initializes the Server-Sent Events (SSE) connection to the Host Server.
 */
function initSseConnection() {
  eventSource = new EventSource(HOST_MCP_URL);

  // 1. Listen for the initial endpoint registration
  eventSource.addEventListener('endpoint', (event) => {
    try {
      const urlParam = new URL(event.data, HOST_MCP_URL);
      uploadUrl = urlParam.toString();
      
      // Start processing queued input once the channel is ready
      process.stderr.write(`[Proxy] Channel established. Endpoint: ${uploadUrl}\n`);
    } catch (err) {
      process.stderr.write(`[Proxy] Error parsing endpoint registration: ${err.message}\n`);
    }
  });

  // 2. Relay incoming messages from Host SSE to Claude's stdout
  eventSource.onmessage = (event) => {
    // Write directly to stdout so Claude Code parses it natively
    process.stdout.write(event.data + '\n');
  };

  eventSource.onerror = (err) => {
    process.stderr.write(`[Proxy] EventSource critical error: ${err.message || 'Connection lost.'}\n`);
  };
}

/**
 * Relay standard input JSON commands from Claude to Host HTTP POST.
 */
rl.on('line', async (line) => {
  if (!line.trim()) return;

  // If the upload route hasn't registered yet, wait momentarily
  while (!uploadUrl) {
    await new Promise(resolve => setTimeout(resolve, 50));
  }

  try {
    // Send command to the active session URL on the host
    const res = await fetch(uploadUrl, {
      method: 'POST',
      headers: {
        'Content-Type': 'application/json'
      },
      body: line
    });

    if (res.status !== 202 && res.status !== 200) {
      process.stderr.write(`[Proxy] Post command failed. HTTP Status: ${res.status}\n`);
    }
  } catch (err) {
    process.stderr.write(`[Proxy] Error posting to host: ${err.message}\n`);
  }
});

// Start the bridge connection immediately on launch
process.stderr.write('[Proxy] Initiating SSE connection to host...\n');
initSseConnection();

๐Ÿ“ฆ Integrating the Proxy into Claude Code's Client Config

With the proxy script compiled, you can map it directly inside the Claude Code configuration file inside the container sandbox.

Configure Claude's local .claude.json configuration file:

{
  "mcpServers": {
    "segnog-memory-bridge": {
      "command": "node",
      "args": ["/mnt/segnog/mcp_servers/index.js"]
    }
  }
}

When Claude Code starts up, it executes node /mnt/segnog/mcp_servers/index.js as a child process. From Claude's perspective, it is executing standard standard I/O calls to a local service.

Behind the scenes, the proxy translates every single graph insertion, embedding request, and fact search into HTTP SSE streams going out to your hostโ€™s high-performance memory database.


๐Ÿ“ˆ Summary of Benefits

Bridging isolated sandboxes to host-level APIs using this pattern provides massive operational benefits:

  1. Perfect Isolation: Claude Code remains confined to its dynamic Docker container, retaining zero access to your primary host network interfaces or standard terminal sessions.
  2. Unified Transport Layer: Solves standard I/O process execution constraints inside container environments.
  3. High Performance: Reuses persistent, HTTP connection channels. Commands are relayed with sub-millisecond latency.
  4. Resiliency: If the container sandboxes are rapidly destroyed and recreated, the SSE server manages session persistence, keeping state records alive across sandboxes.

By implementing this proxy architecture, you can safely deploy highly autonomous coding agents inside locked-down sandbox environments while preserving their ability to query complex long-term knowledge graphs.