mirror of
https://github.com/openclaw/openclaw.git
synced 2026-07-16 21:01:34 +00:00
* docs(gateway): add launchd supervisor loop troubleshooting * docs(gateway): warn before disabling node LaunchAgent * chore: trigger CI after rebase onto main Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com> * docs(gateway): modernize launchd recovery runbook --------- Co-authored-by: Claude Opus 4.7 <noreply@anthropic.com> Co-authored-by: Peter Steinberger <steipete@gmail.com>
125 lines
4.2 KiB
Markdown
125 lines
4.2 KiB
Markdown
---
|
|
summary: "Gateway runtime on macOS (external launchd service)"
|
|
read_when:
|
|
- Packaging OpenClaw.app
|
|
- Debugging the macOS gateway launchd service
|
|
- Installing the gateway CLI for macOS
|
|
title: "Gateway on macOS"
|
|
---
|
|
|
|
OpenClaw.app does not bundle Node/Bun or the Gateway runtime. The macOS app
|
|
expects an **external** `openclaw` CLI install, does not spawn the Gateway as
|
|
a child process, and manages a per-user launchd service to keep the Gateway
|
|
running (or attaches to an already-running local Gateway).
|
|
|
|
## Automatic setup
|
|
|
|
On a fresh Mac, choose **This Mac** during onboarding. The app runs its
|
|
signed, bundled installer script before the Gateway wizard: it installs a
|
|
user-space Node runtime and the matching `openclaw` CLI under `~/.openclaw`,
|
|
then installs and starts the per-user launchd service. This path needs no
|
|
Terminal, Homebrew, or administrator access.
|
|
|
|
The app bundles the installer script only, not the Node or Gateway payload;
|
|
setup needs an internet connection to download the runtime and matching
|
|
OpenClaw package.
|
|
|
|
## Manual recovery
|
|
|
|
Node 24 is recommended for a manual install; Node 22.19+ also works. Install
|
|
`openclaw` globally:
|
|
|
|
```bash
|
|
npm install -g openclaw@<version>
|
|
```
|
|
|
|
Use **Retry setup** after a failed automatic setup. If that still fails,
|
|
install the CLI manually with the command above, then choose **Check again**
|
|
in onboarding.
|
|
|
|
## Launchd (Gateway as LaunchAgent)
|
|
|
|
Label: `ai.openclaw.gateway` (default profile), or `ai.openclaw.<profile>`
|
|
for a named profile.
|
|
|
|
Plist location (per-user): `~/Library/LaunchAgents/ai.openclaw.gateway.plist`
|
|
(or `ai.openclaw.<profile>.plist`).
|
|
|
|
The macOS app owns LaunchAgent install/update for the default profile in
|
|
Local mode. The CLI can also install it directly: `openclaw gateway install`
|
|
(named profiles are selected via the `OPENCLAW_PROFILE` env var).
|
|
|
|
Behavior:
|
|
|
|
- "OpenClaw Active" enables/disables the LaunchAgent.
|
|
- Quitting the app does **not** stop the Gateway (launchd keeps it alive).
|
|
- If a Gateway is already running on the configured port, the app attaches to
|
|
it instead of starting a new one.
|
|
|
|
Logging:
|
|
|
|
- launchd stdout: `~/Library/Logs/openclaw/gateway.log` (profiles use
|
|
`gateway-<profile>.log`)
|
|
- launchd stderr: suppressed
|
|
- If the host loops with repeated `EADDRINUSE` or fast restarts, check for
|
|
duplicate `ai.openclaw.gateway` / `ai.openclaw.node` LaunchAgents and the
|
|
launchd-marker workaround in
|
|
[Gateway troubleshooting](/gateway/troubleshooting#macos-launchd-supervisor-loop-with-duplicate-gatewaynode-launchagents).
|
|
|
|
## Version compatibility
|
|
|
|
The macOS app checks the Gateway version against its own version. Onboarding
|
|
automatically runs managed setup when an existing CLI is missing or
|
|
incompatible. Use **Retry setup** to repeat installation, or **Check again**
|
|
after repairing an external CLI.
|
|
|
|
## State directory on macOS
|
|
|
|
Keep OpenClaw state on a local, non-synced disk. Avoid iCloud Drive and other
|
|
cloud-synced folders; sync latency and file locks can affect sessions,
|
|
credentials, and Gateway state.
|
|
|
|
Set `OPENCLAW_STATE_DIR` to a local path only when you need an override.
|
|
`openclaw doctor` warns about common cloud-synced state paths and recommends
|
|
moving back to local storage. See
|
|
[environment variables](/help/environment#path-related-env-vars) and
|
|
[Doctor](/gateway/doctor).
|
|
|
|
## Debug app connectivity
|
|
|
|
Use the macOS debug CLI from a source checkout to exercise the same Gateway
|
|
WebSocket handshake and discovery logic the app uses:
|
|
|
|
```bash
|
|
cd apps/macos
|
|
swift run openclaw-mac connect --json
|
|
swift run openclaw-mac discover --timeout 3000 --json
|
|
```
|
|
|
|
`connect` accepts `--url`, `--token`, `--timeout`, `--probe`, and `--json`
|
|
(plus client-identity overrides; run with `--help` for the full list).
|
|
`discover` accepts `--timeout`, `--json`, and `--include-local`. Compare
|
|
discovery output with `openclaw gateway discover --json` when you need to
|
|
separate CLI discovery from app-side connection issues.
|
|
|
|
## Smoke check
|
|
|
|
```bash
|
|
openclaw --version
|
|
|
|
OPENCLAW_SKIP_CHANNELS=1 \
|
|
OPENCLAW_SKIP_CANVAS_HOST=1 \
|
|
openclaw gateway --port 18999 --bind loopback
|
|
```
|
|
|
|
Then:
|
|
|
|
```bash
|
|
openclaw gateway call health --url ws://127.0.0.1:18999 --timeout 3000
|
|
```
|
|
|
|
## Related
|
|
|
|
- [macOS app](/platforms/macos)
|
|
- [Gateway runbook](/gateway)
|