Skip to content

feat(sandbox): MCP server isolation via Unix socket bridge #641

Description

@decko

Context

Sub-issue of #568. Depends on #640 (MCP sandbox support). Future improvement over #640's "disable netns" approach.

Summary

Run MCP servers outside the sandbox and bridge communication via Unix sockets, providing full network isolation for the agent while MCP servers retain host network access.

Design

Architecture

Host                              Sandbox (Landlock + seccomp + cgroups + netns)
  |                                  |
  MCP Server (jira)  <--Unix socket-->  Claude Code / Opencode
  MCP Server (github) <--Unix socket-->   (network namespace: loopback only)
  |                                  |
  Host network                       No host network

How it works

  1. SODA starts MCP servers on the host side before launching the sandbox
  2. Each MCP server listens on a Unix socket in a temp directory
  3. The socket directory is added to the sandbox's read+write paths
  4. The --mcp-config points to server entries with transport: "unix" socket paths
  5. Agent inside sandbox connects to MCP servers via the socket
  6. SODA manages MCP server lifecycle (start before phase, stop after)

Prerequisites

MCP server manager

New internal/mcp/ package:

type ServerManager struct {
    servers map[string]*runningServer
}

func (m *ServerManager) Start(ctx context.Context, name string, cfg MCPServerConfig) (socketPath string, err error)
func (m *ServerManager) Stop(name string) error
func (m *ServerManager) StopAll()
func (m *ServerManager) HealthCheck(name string) error

Fallback

If Unix socket transport is not supported by the agent CLI, fall back to #640's approach (disable netns, run MCP inside sandbox). Log which mode is active.

Acceptance criteria

  • internal/mcp/ package with ServerManager
  • MCP servers started on host side with Unix socket transport
  • Socket paths passed to sandbox read+write paths
  • Agent connects to MCP via socket from inside sandbox
  • Network namespace remains enabled (full isolation)
  • Graceful fallback to feat(sandbox): MCP server support inside arapuca sandbox #640 approach when socket transport unavailable
  • Health check verifies MCP server is responding on socket
  • MCP server lifecycle tied to phase execution (start/stop)
  • Tests: server lifecycle, socket communication, fallback

Estimated token budget

  • Read: ~10K (sandbox, mcp protocol, go-arapuca)
  • Write: ~15K (server manager, socket bridge, lifecycle, tests)
  • Total: ~70K / 80K

Depends on

Metadata

Metadata

Assignees

No one assigned

    Labels

    enhancementNew feature or request

    Projects

    No projects

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions