Download

name: container-conduit author: Noah description: "Use when the user wants to manage remote containers via Container Conduit — connecting satellite containers, running commands remotely, transferring files, opening interactive PTY shells, viewing the Conduit dashboard, or installing the Conduit agent on new containers. Covers the WebSocket bridge between a main Gallia container and satellite Adom containers."

Container Conduit

Container Conduit is a WebSocket bridge that connects a main Gallia container to one or more satellite Adom containers. It enables remote command execution, file transfer, system status queries, and interactive PTY terminal sessions — all from Claude Code or the Gallia Viewer dashboard.

Architecture

Main Container (Gallia)                  Satellite Container(s)
  server.js (WS port 8800)  ←──WS──→  agent.js
  HTTP API  (port 8801)                   ↑
       ↑                              install.sh (bootstrap)
  MCP tools (mcp/server.js)
       ↑
  Claude Code / Dashboard
  • server.js — WebSocket server on port 8800 that accepts agent connections, plus an HTTP API on port 8801 for MCP tools and the dashboard
  • agent.js — Lightweight satellite agent that connects back to the main container and handles exec, file, status, and PTY commands
  • mcp/server.js — MCP stdio server exposing Container Conduit tools to Claude Code
  • dashboard.html — Interactive management dashboard displayed in Gallia Viewer with Shell (xterm.js), Terminal, and Prompts tabs

Key Files

File Location Purpose
server.js services/container-conduit/server.js Main WS+HTTP server
agent.js services/container-conduit/agent/agent.js Satellite agent
install.sh services/container-conduit/agent/install.sh One-line agent bootstrap
mcp/server.js services/container-conduit/mcp/server.js MCP tool definitions
dashboard.html services/container-conduit/dashboard.html GV management dashboard
service.json services/container-conduit/service.json Auto-start manifest

MCP Tools

All tools are prefixed container_ in the MCP server:

Tool Description
container_list List all connected satellite containers
container_exec Execute a shell command on a specific container
container_exec_all Execute a command on ALL connected containers
container_file_read Read a file from a remote container (base64)
container_file_write Write a file to a remote container (base64)
container_file_list List directory contents on a remote container
container_status Get system status (memory, disk, uptime) of a container
container_kick Disconnect a container (it will auto-reconnect)
container_shell_start Start a persistent interactive shell session (returns sessionId)
container_shell_exec Run a command in a persistent shell (state persists across calls)
container_shell_stop Stop a persistent shell session
container_dashboard Display the Conduit dashboard in Gallia Viewer
container_create Create a new Adom container (repo + curium + container)
container_install_cmd Generate the one-liner install command for a satellite

Installing the Agent on a Satellite Container

One-liner install (direct network)

curl -sL http://<MAIN_IP>:8800/agent/install | CC_NAME=my-service bash

Proxy install (Coder proxy for cross-container communication)

curl -sL https://coder.<SLUG>.containers.adom.inc/proxy/8800/agent/install | \
  CC_BASE_URL=https://coder.<SLUG>.containers.adom.inc/proxy/8800 \
  CC_NAME=my-service sudo -E bash

The install script:

  1. Creates /opt/container-conduit/ owned by adom
  2. Downloads agent.js and package.json from the main container
  3. Runs npm install
  4. Writes config.json with WebSocket URL and token
  5. Starts the agent from ~/project
  6. Adds a cron @reboot entry for auto-start

Environment variables

Variable Default Description
CC_HOST (required) Main container IP
CC_PORT 8800 Main container WS port
CC_TOKEN adom-container-token-2025 Authentication token
CC_NAME $(hostname) Container name shown in dashboard
CC_BASE_URL http://$CC_HOST:$CC_PORT Override download URL (for proxy setups)
CC_WS_URL auto-detected Override WebSocket URL (e.g. wss://...)

Dashboard (Gallia Viewer)

Open the dashboard via MCP tool:

container_dashboard()

The dashboard has three tabs:

  1. Shell — Interactive xterm.js terminal connected to a remote container via PTY WebSocket relay. Supports full TTY (nano, vim, htop, etc.)
  2. Terminal — Simple command execution with output display (non-interactive)
  3. Claude Prompts — Pre-built prompts for common container management tasks

The left panel shows all connected containers with name, hostname, IP, capabilities, and connection age.

Persistent Shell Sessions (MCP)

The container_shell_* tools give Claude Code a persistent interactive shell on any satellite container. Unlike container_exec (which spawns a new process per call), shell sessions preserve state:

container_shell_start("service-test1")  → sessionId
container_shell_exec(sessionId, "cd /tmp")
container_shell_exec(sessionId, "pwd")  → /tmp  (cwd persists!)
container_shell_exec(sessionId, "export FOO=bar")
container_shell_exec(sessionId, "echo $FOO")  → bar  (env vars persist!)
container_shell_stop(sessionId)

How it works: The server spawns a PTY on the agent, then wraps each command with SOH-byte sentinel markers to detect completion and extract output. Sessions auto-cleanup after 30 minutes of inactivity.

PTY Terminal (Dashboard)

The Shell tab provides a full interactive terminal via:

Dashboard (xterm.js) → WS port 8801 /pty → server.js relay → agent.js → script -qfc 'bash -i' /dev/null

The agent uses script to allocate a real PTY without requiring node-pty. This supports curses-based applications (nano, vim, htop, etc.).

Auto-Start

The service.json manifest registers Container Conduit with the gallia auto-start system:

{
  "name": "container-conduit",
  "port": 8800,
  "health": "tcp",
  "start": "node server.js",
  "cwd": "."
}

Both gallia-start.sh and gallia-watchdog.sh auto-discover this manifest. The server starts on boot and restarts automatically if it crashes.

Troubleshooting

Symptom Cause Fix
Agent can't connect Internal hostname not routable between containers Use CC_BASE_URL with the Coder proxy URL
\r': command not found during install CRLF line endings in agent files Run sed -i 's/\r$//' /opt/container-conduit/agent.js
Permission denied on /opt/container-conduit Script not run with sudo Use sudo -E bash to preserve env vars
Dashboard shows 0 containers API URL detection fails in srcdoc iframe MCP server injects __CONDUIT_API_BASE__ — restart MCP if stale
PTY timeout on Connect Agent running old code without PTY support Restart agent with updated agent.js
Shell tab WebSocket error Port 8801 not reachable via proxy Ensure server.js binds 8801 to 0.0.0.0