01 Overview

Background

OpenClaw is an open-source AI orchestration platform that allows an AI agent to control devices through a gateway server. By default, the gateway and the devices it controls run on the same machine. This guide covers a more useful setup: the gateway runs on a remote server (AWS EC2), and the macOS companion app runs on your local MacBook — connected over the internet.

Once connected, the AI agent can:

  • Open URLs and navigate pages in a WebView on your Mac
  • Take screenshots and read page content
  • Run shell commands via system.run
  • Trigger all of the above from any messaging channel (e.g. Telegram)

Architecture

User (Telegram / any channel)
    ↕  chat
AI Agent (Claude / any model)
    ↕  WebSocket  wss://your-domain.com/openclaw-ws
OpenClaw Gateway  (AWS EC2, Linux)
    ↕  WebSocket  (approved device connection)
macOS Companion App  (MacBook)
    ↕  native macOS APIs
Browser / Shell / Screen

The key insight is that the macOS app acts as a node: it connects outbound to the gateway, so there is no need to expose any port on the Mac itself. All inbound traffic goes to the server.


02 Setup

Step 1 — Deploy the Gateway

On an AWS EC2 instance (Ubuntu recommended), install OpenClaw:

npm install -g openclaw
openclaw gateway start

By default the gateway binds to localhost only. To accept connections from outside, change the bind address:

openclaw config set gateway.bind lan
systemctl --user restart openclaw-gateway

The gateway now listens on all interfaces on its default port. Open that port in your AWS Security Group (EC2 → Security Groups → Inbound Rules → Custom TCP).

The gateway requires a token for all connections, so opening the port does not expose the server to unauthorized access. For extra security, restrict the source IP or use a VPN like Tailscale.

Step 2 — Expose WSS via Nginx and Cloudflare

The macOS companion app requires a secure WebSocket (wss://) for non-local connections. The simplest way to provide this is to proxy the gateway through Nginx, with Cloudflare handling TLS termination in front.

Add the following location block to your Nginx server config:

location /openclaw-ws {
    proxy_pass http://127.0.0.1:<gateway-port>;
    proxy_http_version 1.1;
    proxy_set_header Upgrade $http_upgrade;
    proxy_set_header Connection "upgrade";
    proxy_set_header Host $host;
    proxy_set_header X-Real-IP $remote_addr;
    proxy_read_timeout 86400;
}

Reload Nginx:

sudo nginx -t && sudo systemctl reload nginx

wss://your-domain.com/openclaw-ws is now a valid WSS endpoint. Cloudflare terminates TLS; Nginx forwards the upgraded WebSocket connection to the local gateway. No manual certificate management required.

If Cloudflare's SSL mode is set to Flexible, the origin only needs to serve HTTP. The gateway itself does not need a TLS certificate.

Step 3 — Install the macOS Companion App

Download the macOS companion app from the OpenClaw GitHub releases page and open it on your MacBook.

In the app settings, configure the remote connection:

  • OpenClaw runs: Remote (ws/wss)
  • Gateway URL: wss://your-domain.com/openclaw-ws
  • Token: your gateway token (run openclaw config get gateway.token on the server)

Save the settings. The app will connect and register itself as a pending device.

Step 4 — Approve the Device

On the server, list pending devices and approve the Mac:

openclaw devices list
openclaw devices approve <request-id>

Verify the connection:

openclaw nodes status

The MacBook should appear as paired · connected with capabilities including canvas, screen, and system.run.


03 Usage

Browser Control

Open a URL in the Mac's WebView canvas:

openclaw nodes invoke \
  --node "<node-name>" \
  --command canvas.navigate \
  --params '{"url":"https://example.com"}'

Take a screenshot:

openclaw nodes canvas snapshot \
  --node "<node-name>" \
  --format jpg

The AI agent receives the screenshot as an image, can read the page content, and continue navigating — all using your Mac's network identity and any active sessions.

Shell Commands

With system.run available, the AI can also execute shell commands on the Mac — subject to the exec approval policy configured in the companion app.


04 Troubleshooting

  • "node not connected" — The WebSocket connection dropped. Check that the companion app is running, the gateway process is alive (openclaw gateway status), and the port is still open in the cloud security group.
  • Must use wss:// — The macOS app rejects plaintext ws:// for non-localhost connections. The Nginx proxy approach described above is the recommended solution.
  • system.run fails with a format error — This only affects the headless CLI node. The companion app handles system.run correctly.
  • App connects but node shows as disconnected — The app connects as an operator by default. After approving the device pairing request, it registers as a node as well.