Edition scope. The harness depends on the SKU, which is baked into the root-owned
/etc/clawbox/edition.env at install time: OpenClaw (the openclaw gateway),
Hermes (the Hermes CLI + dashboard, with the gateway stopped, disabled and masked),
or dual. Everything below that names clawbox-gateway, port 18789,
gateway-pre-start.sh or ~/.openclaw applies to OpenClaw / dual only — see
Hermes Edition for the Hermes shape.The big picture
The user never talks to the gateway directly — everything enters through port 80, and on OpenClaw/dual the web app proxies chat/WebSocket traffic to the gateway. (The gateway itself listens on the private LAN with token auth — browsing:18789 directly is a classic mistake: it loads, but it will never accept your password.) On Hermes there is nothing on 18789 at all: the browser gets connection-refused, and chat runs over /setup-api/hermes/chat.
Services
Everything runs under systemd. The two you will interact with most are clawbox-setup (the web OS) and your edition’s AI unit —clawbox-gateway on OpenClaw/dual, clawbox-hermes-dashboard on Hermes/dual.
Two more servers run as children of the web app (no systemd unit): the terminal PTY WebSocket server (port 3006) and the optional llama.cpp server (port 8080), both supervised by
src/instrumentation-node.ts. Reached directly, that PTY has no authentication of its own — which is why 3006 is firewalled off the LAN and the terminal is only ever served through the session-gated /terminal-ws proxy on port 80.
What is actually reachable from your network
Most of those ports are not exposed. The box ships a default-deny inbound firewall (ufw, from scripts/clawbox-firewall.sh, applied on fresh installs and on in-app updates alike) that opens only 22, 80, 443, 18789 and 8090 (the Hermes dashboard proxy — the rule is present on every edition, but nothing binds it on OpenClaw). On IPv4 those are scoped to private source ranges (10/8, 172.16/12, 192.168/16, 169.254/16, plus 100.64/10 so Tailscale keeps working); IPv6 is not source-scoped. 5353/udp mDNS and the hotspot’s own DHCP/DNS are the other exceptions. Everything else in the table is loopback-only in practice: VNC/noVNC on 5900/6080 (noVNC arrives through the port-80 /novnc-ws proxy), CDP on 18800, Ollama on 11434. Outgoing and routed traffic are untouched, so hotspot internet sharing and the Cloudflare tunnel behave exactly as before — full rules and rationale in Networking → Firewall.
How the unprivileged web app does root things
clawbox-setup runs as the clawbox user. Anything privileged (updates, password change, hostname, reboot) is delegated to the clawbox-root-update@<step> systemd template, which runs install.sh --step <step> as root. A polkit rule plus a narrow sudoers file allow the clawbox user to start exactly these units — the web app never runs arbitrary root commands.
Desktop or headless
The GNOME desktop is shipped and on by default. Turning it off is a setting, not a different image — nothing is uninstalled, so it is one switch away from coming back. Settings → System → Desktop environment posts to/setup-api/system/desktop, which runs the root-owned clawbox-desktop-mode.sh. Off sets the boot target to multi-user.target and disables the display manager; on sets it back to graphical.target. The change applies at the next reboot, and the UI says so: tearing the graphical session down under a logged-in user would kill their Remote Desktop view and any Chromium the agent is driving. Running headless gives back roughly 700 MB.
The automation browser is unaffected either way — clawbox-browser.service has no [Install] section, so it is only ever started on demand, never at boot.
Power profile and memory guards
Balanced is the default.clawbox-performance.service applies whatever profile is persisted in the root-owned /etc/clawbox/power-mode, defaulting to a nvpmodel cap with jetson_clocks off and the cpuidle states on. Earlier releases ran nvpmodel -m MAXN_SUPER && jetson_clocks unconditionally at every boot, which pinned all six CPU cores to 1,728 MHz and the GPU to 1,020 MHz at 4% load — 7.2 W and ~58 °C doing nothing, and 74.8 °C median Tj under sustained 3B inference, just over the 74 °C passive-cooling trip.
Settings → System → Performance mode (off by default) restores that pinned behaviour for owners who want it and have airflow. It applies immediately — no reboot.
Three cgroup v2 memory guards ship as 50-clawbox-memory.conf drop-ins, written by clawbox-resource-limits.sh from config/clawbox-resource-limits.env — the single place every one of these numbers is defined, with the measurement behind it:
MemoryHigh throttles, MemoryMax kills, and every unit gets High well below Max on purpose: pressure should show up as slowness first and an OOM kill last. The same env file sets OLLAMA_NUM_PARALLEL=2 — one slot serialised every caller, so the eighth concurrent turn waited 24.5 s; a second slot costs ~170 MB and cut 2–4-way concurrent latency by ~41%.
Request routing (port 80)
production-server.jswraps the Next.js standalone server. On boot it seeds secrets fromdata/into env (SESSION_SECRET, MCP + local-AI tokens) and attaches a WebSocket upgrade proxy:/terminal-ws→ port 3006,/novnc-ws→ port 6080, everything else → gateway 18789. On Hermes that fallback target is closed, so only the two named routes carry traffic.- Next.js rewrites proxy
/api/*,/assets/*, and any path no ClawBox route claims → the gateway. These are compiled at build time on every edition; on Hermessrc/middleware.tsand the catch-all route run first and return 404 for them. src/middleware.tsenforces, in order: captive-portal probe redirects → public-path allowlist (/login,/setup, …) → pre-setup bypass (untilsetup_complete) → MCP bearer bypass → session cookie check (else redirect to/login)./(desktop) — after setup, the root serves a Chrome-OS-style desktop (window manager, taskbar, built-in apps). The setup wizard lives at/setup.- Gateway HTML (OpenClaw / dual) — when the OpenClaw Control UI is served,
gateway-proxy.tsinjects a ClawBox nav bar and the gateway auth token so the SPA connects without manual token entry. On Hermes, chat is an ordinary HTTP route (/setup-api/hermes/chat) instead of a gateway WebSocket.
Boot lifecycle
1
Power on — AP mode (first boot / unconfigured)
clawbox-ap raises the ClawBox-Setup hotspot at 10.42.0.1 (falls back to 10.43.0.1 on subnet collision). dnsmasq forwards DNS upstream (8.8.8.8 / 8.8.4.4 / 1.1.1.1) and only maps clawbox.local to the AP — there is no DNS hijack, and the legacy port-80 DNAT rule is deleted on every AP start. src/middleware.ts answers OS captive-portal probe paths that reach the box, but nothing forces them there, so the owner browses to http://10.42.0.1.2
Setup wizard
Wi-Fi → update → password → AI provider → Telegram (optional, skippable). The update step is unconditional, not optional. State persists in
data/config.json (setup_complete, password_configured).3
Steady state — home network
The box joins your Wi-Fi/Ethernet, announces
clawbox.local over mDNS (avahi), and serves the desktop at its LAN IP. The AP watchdog stands down once setup is complete.4
Every gateway start (OpenClaw / dual)
gateway-pre-start.sh runs before OpenClaw: it normalizes openclaw.json (bind/auth/origins), enforces a strong gateway token, repairs provider config (see AI Providers), registers the ClawBox MCP server, and seeds the agent workspace.5
Every web-server boot (Hermes / dual)
There is no gateway pre-start on Hermes, so
scripts/register-mcp.sh runs from production-server.js at every web-server boot (and again at install time) to reconcile mcp_servers.clawbox into ~/.hermes/config.yaml. It is idempotent.ClawBox ↔ its AI harness
OpenClaw / dual editions- OpenClaw is installed globally via npm at
~/.npm-global/bin/openclaw, version-pinned along with its@openclaw/*plugins — see Update System for how the pin works. - Config lives in
~/.openclaw/openclaw.json. ClawBox writes it directly (setup wizard, Settings) and heals it on every gateway start. - MCP: the gateway is configured with an
mcp.servers.clawboxentry that launchesmcp/clawbox-mcp.ts(via bun) — this is how the AI agent gets device control tools (files, shell, browser, apps, system). See Agent Interface. - Control UI: the OpenClaw dashboard is reachable through the ClawBox desktop (OpenClaw app) — an iframe wired to the gateway WebSocket with the token injected automatically.
- Hermes is installed at
~/.local/bin/hermes(a shim into~/.hermes/hermes-agent/venv), with its configuration and pooled-auth credential store under~/.hermes. - Config lives in
~/.hermes/config.yaml. Every writer does a full read-modify-write, so hand-added comments and formatting in that file are not preserved — treat it as generated state. - MCP:
scripts/register-mcp.shwritesmcp_servers.clawboxinto~/.hermes/config.yamlat every web-server boot and at install time. - Dashboard: reachable through the ClawBox desktop (Hermes app) via the session-gated proxy on port
8090; there is no Control UI and/chat404s.
Stack
Networking details
AP mode, captive portal, mDNS, ports.
Filesystem layout
Where everything lives on the box.

