mirror of
https://github.com/openclaw/openclaw.git
synced 2026-05-08 06:20:44 +00:00
Replaced 60 typography characters (curly quotes, apostrophes, em/en dashes, non-breaking hyphens) with ASCII equivalents per docs/CLAUDE.md heading and content hygiene rules. - docs/start/openclaw.md: 10 chars; removed the duplicate '# Building a personal assistant with OpenClaw' H1 (Mintlify renders title from frontmatter). - docs/platforms/mac/remote.md: 10 chars; removed the duplicate '# Remote OpenClaw (macOS ⇄ remote host)' H1 (the U+21C4 codepoint and parens both produced brittle anchors). - docs/tools/thinking.md: 10 chars - docs/reference/templates/BOOTSTRAP.md: 10 chars (kept the in-body '# BOOTSTRAP.md - Hello, World' heading because the page is a template whose content is meant to be copied verbatim into a workspace BOOTSTRAP.md). - docs/plugins/sdk-provider-plugins.md: 10 chars - docs/platforms/macos.md: 10 chars
101 lines
6.1 KiB
Markdown
101 lines
6.1 KiB
Markdown
---
|
|
summary: "macOS app flow for controlling a remote OpenClaw gateway over SSH"
|
|
read_when:
|
|
- Setting up or debugging remote mac control
|
|
title: "Remote control"
|
|
---
|
|
|
|
This flow lets the macOS app act as a full remote control for an OpenClaw gateway running on another host (desktop/server). It's the app's **Remote over SSH** (remote run) feature. All features-health checks, Voice Wake forwarding, and Web Chat-reuse the same remote SSH configuration from _Settings → General_.
|
|
|
|
## Modes
|
|
|
|
- **Local (this Mac)**: Everything runs on the laptop. No SSH involved.
|
|
- **Remote over SSH (default)**: OpenClaw commands are executed on the remote host. The mac app opens an SSH connection with `-o BatchMode` plus your chosen identity/key and a local port-forward.
|
|
- **Remote direct (ws/wss)**: No SSH tunnel. The mac app connects to the gateway URL directly (for example, via Tailscale Serve or a public HTTPS reverse proxy).
|
|
|
|
## Remote transports
|
|
|
|
Remote mode supports two transports:
|
|
|
|
- **SSH tunnel** (default): Uses `ssh -N -L ...` to forward the gateway port to localhost. The gateway will see the node's IP as `127.0.0.1` because the tunnel is loopback.
|
|
- **Direct (ws/wss)**: Connects straight to the gateway URL. The gateway sees the real client IP.
|
|
|
|
In SSH tunnel mode, discovered LAN/tailnet hostnames are saved as
|
|
`gateway.remote.sshTarget`. The app keeps `gateway.remote.url` on the local
|
|
tunnel endpoint, for example `ws://127.0.0.1:18789`, so CLI, Web Chat, and
|
|
the local node-host service all use the same safe loopback transport.
|
|
|
|
Browser automation in remote mode is owned by the CLI node host, not by the
|
|
native macOS app node. The app starts the installed node host service when
|
|
possible; if you need browser control from that Mac, install/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
|
|
|
|
1. Install Node + pnpm and build/install the OpenClaw CLI (`pnpm install && pnpm build && pnpm link --global`).
|
|
2. Ensure `openclaw` is on PATH for non-interactive shells (symlink into `/usr/local/bin` or `/opt/homebrew/bin` if needed).
|
|
3. Open SSH with key auth. We recommend **Tailscale** IPs for stable reachability off-LAN.
|
|
|
|
## macOS app setup
|
|
|
|
1. Open _Settings → General_.
|
|
2. Under **OpenClaw runs**, pick **Remote over SSH** and set:
|
|
- **Transport**: **SSH tunnel** or **Direct (ws/wss)**.
|
|
- **SSH target**: `user@host` (optional `:port`).
|
|
- If the gateway is on the same LAN and advertises Bonjour, pick it from the discovered list to auto-fill this field.
|
|
- **Gateway URL** (Direct only): `wss://gateway.example.ts.net` (or `ws://...` for local/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 `openclaw` entrypoint/binary (auto-filled when advertised).
|
|
3. Hit **Test remote**. Success indicates the remote `openclaw status --json` runs correctly. Failures usually mean PATH/CLI issues; exit 127 means the CLI isn't found remotely.
|
|
4. Health checks and Web Chat will now run through this SSH tunnel automatically.
|
|
|
|
## Web Chat
|
|
|
|
- **SSH tunnel**: Web Chat connects to the gateway over the forwarded WebSocket control port (default 18789).
|
|
- **Direct (ws/wss)**: Web Chat connects straight to the configured gateway URL.
|
|
- There is no separate WebChat HTTP server anymore.
|
|
|
|
## Permissions
|
|
|
|
- The remote host needs the same TCC approvals as local (Automation, Accessibility, Screen Recording, Microphone, Speech Recognition, Notifications). Run onboarding on that machine to grant them once.
|
|
- Nodes advertise their permission state via `node.list` / `node.describe` so agents know what's available.
|
|
|
|
## Security notes
|
|
|
|
- Prefer loopback binds on the remote host and connect via SSH or Tailscale.
|
|
- SSH tunneling uses strict host-key checking; trust the host key first so it exists in `~/.ssh/known_hosts`.
|
|
- If you bind the Gateway to a non-loopback interface, require valid Gateway auth: token, password, or an identity-aware reverse proxy with `gateway.auth.mode: "trusted-proxy"`.
|
|
- See [Security](/gateway/security) and [Tailscale](/gateway/tailscale).
|
|
|
|
## WhatsApp login flow (remote)
|
|
|
|
- Run `openclaw channels login --verbose` **on the remote host**. Scan the QR with WhatsApp on your phone.
|
|
- Re-run login on that host if auth expires. Health check will surface link problems.
|
|
|
|
## Troubleshooting
|
|
|
|
- **exit 127 / not found**: `openclaw` isn't on PATH for non-login shells. Add it to `/etc/paths`, your shell rc, or symlink into `/usr/local/bin`/`/opt/homebrew/bin`.
|
|
- **Health probe failed**: check SSH reachability, PATH, and that Baileys is logged in (`openclaw status --json`).
|
|
- **Web Chat stuck**: confirm the gateway is running on the remote host and the forwarded port matches the gateway WS port; the UI requires a healthy WS connection.
|
|
- **Node IP shows 127.0.0.1**: 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**: this means the app's operator/control connection is healthy, but the companion node connection is not connected or is missing its command surface. Open the menu bar device section and check whether the Mac is `paired · disconnected`. For `wss://*.ts.net` Tailscale Serve endpoints, the app detects stale legacy TLS leaf pins after certificate rotation, clears the stale pin when macOS trusts the new certificate, and retries automatically. If the certificate is not system-trusted or the host is not a Tailscale Serve name, review the certificate or switch to **Remote over SSH**.
|
|
- **Voice Wake**: trigger phrases are forwarded automatically in remote mode; no separate forwarder is needed.
|
|
|
|
## Notification sounds
|
|
|
|
Pick sounds per notification from scripts with `openclaw` and `node.invoke`, e.g.:
|
|
|
|
```bash
|
|
openclaw nodes notify --node <id> --title "Ping" --body "Remote gateway ready" --sound Glass
|
|
```
|
|
|
|
There is no global "default sound" toggle in the app anymore; callers choose a sound (or none) per request.
|
|
|
|
## Related
|
|
|
|
- [macOS app](/platforms/macos)
|
|
- [Remote access](/gateway/remote)
|