Remote Control for OpenClaw Gateway on macOS
Learn how to configure the macOS app to remotely control an OpenClaw gateway via SSH tunnel or direct connection. This guide covers local, remote over SSH, and remote direct modes for trusted networks.
Read this when
- Setting up or debugging remote mac control
This setup enables the macOS app to function as a complete remote control for an OpenClaw gateway located on a different machine (desktop or server). The app connects directly to trusted LAN or Tailnet gateway URLs, or establishes an SSH tunnel when the remote gateway only listens on loopback. Health checks, Voice Wake forwarding, and Web Chat all rely on the same remote configuration defined under Settings -> General.
Modes
- Local (this Mac): everything operates on the laptop; no SSH is involved.
- Remote over SSH (default): OpenClaw commands execute on the remote host. The app creates an SSH connection using
-o BatchMode, your chosen identity or key, and a local port-forward. - Remote direct (ws/wss): no SSH tunnel is used; the app connects directly to the gateway URL (LAN, Tailscale, Tailscale Serve, or a public HTTPS reverse proxy).
Remote transports
- SSH tunnel (default): employs
ssh -N -L ...to forward the gateway port to localhost. The gateway sees the node's IP as127.0.0.1because the tunnel uses loopback. - Direct (ws/wss): connects directly to the gateway URL. The gateway observes the actual client IP.
For its own SSH processes, the app disables connection multiplexing and post-authentication backgrounding. This allows it to monitor and restart the exact process, even if the chosen alias enables ControlMaster or ForkAfterAuthentication.
SSH host-key verification is strict by default because gateway credentials travel through this tunnel. To adopt the trust behavior of a managed SSH alias, set --ssh-host-key-policy openssh via openclaw-mac configure-remote, or directly set gateway.remote.sshHostKeyPolicy to "openssh". Before opting in, examine the alias and any matching Host * or system configuration. Changing the SSH target (in the app or via configure-remote) resets the policy back to strict, unless you explicitly opt in again for the new target.
In SSH tunnel mode, discovered LAN or tailnet hostnames are saved as gateway.remote.sshTarget. The app maintains gateway.remote.url on the local tunnel endpoint (for example ws://127.0.0.1:18789), so the CLI, Web Chat, and the local node-host service all use the same loopback transport. When discovery returns both raw Tailnet IPs and stable hostnames, the app prefers Tailscale MagicDNS or LAN names, making connections more resilient to address changes. If the local tunnel port differs from the remote gateway port, set gateway.remote.remotePort to the port on the remote host.
In remote mode, browser automation is managed by the CLI node host, not by the native macOS app node. The app starts the installed node host service when possible. To enable browser control from that Mac, install or start it with openclaw node install ... and openclaw node start (or run openclaw node run ... in the foreground), then target that browser-capable node.
Prereqs on the remote host
- Install Node and pnpm, then build and install the OpenClaw CLI (
pnpm install && pnpm build && pnpm link --global). - Ensure
openclawis on the PATH for non-interactive shells (symlink it into/usr/local/binor/opt/homebrew/binif necessary). - For SSH transport: configure key-based SSH authentication. Tailscale IPs are recommended for stable reachability when off-LAN.
macOS app setup
To preconfigure the app without the welcome flow, using SSH:
openclaw-mac configure-remote \
--ssh-target user@gateway-host \
--local-port 18789 \
--remote-port 18789 \
--token "$OPENCLAW_GATEWAY_TOKEN"
Or, for a gateway already reachable on a trusted LAN or Tailnet, bypass SSH entirely:
openclaw-mac configure-remote \
--direct-url ws://192.168.0.202:18789 \
--token "$OPENCLAW_GATEWAY_TOKEN"
openclaw-mac connect, wizard, and configure-remote resolve the active configuration in this order: OPENCLAW_CONFIG_PATH, then $OPENCLAW_STATE_DIR/openclaw.json, then ~/.openclaw/openclaw.json. Both configuration forms write that active file, mark onboarding as complete, and let the app take ownership of the selected transport on the next start. --local-port and --remote-port default to 18789. Additional flags include --password, --identity <path>, --ssh-host-key-policy <strict|openssh>, --project-root <path>, --cli-path <path>, and --json. Run openclaw-mac configure-remote --help for the complete reference.
To configure from the UI instead:
- Open Settings -> General.
- Under OpenClaw runs, select Remote and configure:
- Transport: SSH tunnel or Direct (ws/wss).
- SSH target:
user@host(optional:port). If the gateway is on the same LAN and advertises Bonjour, choose it from the discovered list to auto-populate this field. - Gateway URL (Direct only):
wss://gateway.example.ts.net(orws://...for local or LAN). - Identity file (advanced): path to your key.
- Project root (advanced): remote checkout path used for commands.
- CLI path (advanced): optional path to a runnable
openclawentrypoint or binary (auto-filled when advertised).
- Click Test remote. Success indicates the remote
openclaw status --jsonexecuted correctly. Failures typically point to PATH or CLI issues; exit 127 means the CLI was not found on the remote machine. - Health checks and Web Chat now automatically use the selected transport.
Web Chat
- SSH tunnel: connects to the gateway through the forwarded WebSocket control port (default 18789).
- Direct (ws/wss): connects directly to the configured gateway URL.
- No separate Web Chat HTTP server exists.
Permissions
- The remote host requires the same TCC approvals as the local machine (Automation, Accessibility, Screen Recording, Microphone, Speech Recognition, Notifications). Run onboarding on that machine once to grant them.
- Nodes advertise their permission state via
node.listandnode.describe, so agents know what is available.
Security notes
- On the remote host, prefer loopback bindings and connect through SSH, Tailscale Serve, or a trusted Tailnet or LAN direct URL.
- By default, SSH tunneling expects a host key that is already trusted. Either trust the host key first by adding it to the configured known-hosts file, or explicitly set
gateway.remote.sshHostKeyPolicy: "openssh"for a managed alias whose OpenSSH trust policy you accept. - When binding the Gateway to a non-loopback interface, require valid Gateway authentication: a token, password, or an identity-aware reverse proxy with
gateway.auth.mode: "trusted-proxy". - A direct
wss://connection applies a single certificate policy to both operator and control traffic and the Mac companion node. Setgateway.remote.tlsFingerprintfor an explicit pin. Without one, the app records a first-use pin only after standard macOS trust succeeds. - Refer to Security and Tailscale.
WhatsApp login flow (remote)
- Execute
openclaw channels login --channel whatsapp --verboseon the remote host. Scan the QR code using WhatsApp on your phone. - If authentication expires, re-run login on that host. The health check surfaces any link issues.
Troubleshooting
| Symptom | Cause / fix |
|---|---|
exit 127 / not found | openclaw is missing from PATH for non-login shells. Add it to /etc/paths, your shell rc, or create a symlink in /usr/local/bin or /opt/homebrew/bin. |
| Health probe failed | Verify SSH reachability, PATH, and that Baileys (WhatsApp) is logged in with openclaw status --json. |
| Web Chat stuck | Ensure the gateway runs on the remote host and the forwarded port matches the gateway WS port; the UI depends on a healthy WS connection. |
Node IP shows 127.0.0.1 | This is expected with the SSH tunnel. Switch Transport to Direct (ws/wss) if you want the gateway to see the real client IP. |
| Dashboard works but Mac capabilities are offline | The operator and control connection is healthy, but the companion node connection is either not connected or lacks its command surface. Open the menu bar device section and check whether the Mac is paired · disconnected. Direct wss:// operator and node connections share the same configured or stored certificate policy. For trusted wss://*.ts.net Tailscale Serve endpoints, stale stored leaf pins are replaced after certificate rotation and retried automatically. Configured pins never rotate automatically; update gateway.remote.tlsFingerprint after reviewing the new certificate, or switch to Remote over SSH. |
| Voice Wake | Trigger phrases forward automatically in remote mode; no separate forwarder is required. |
Notification sounds
Select sounds per notification from scripts using openclaw nodes notify, for example:
openclaw nodes notify --node <id> --title "Ping" --body "Remote gateway ready" --sound Glass
The app has no global default-sound toggle; callers choose a sound or none per request.