2026 OpenClaw macOS Dual LaunchAgent Coexistence: ai.openclaw.gateway + ai.openclaw.mac in Parallel — launchctl Repairs, Unified Config & Dedicated Remote Mac SSH Headless Checklist + FAQ
On a single macOS host, OpenClaw often splits responsibilities: a gateway (ai.openclaw.gateway) that terminates HTTP/WebSockets and routes work, and a Mac runtime (ai.openclaw.mac) that owns Apple-only CLIs, UI automation hooks, and local model endpoints. Running both under launchd is correct—but mis-ordered starts, duplicate environments, and port collisions are the usual failure modes. This article gives a reproducible launchctl repair sequence, a single-source OPENCLAW_* layout, and a headless dedicated remote Mac SSH checklist. For cross-platform gateway autostart patterns (WSL2 / Linux systemd), see 2026 OpenClaw Cross-Platform Install & Always-On Operations: Windows WSL2 vs Linux (systemd) Checklist + Gateway Autostart Troubleshooting & Dedicated Remote Mac SSH Hybrid Workflow FAQ; for macOS service ergonomics comparable to long-lived runner daemons, see 2026 GitHub Actions Self-Hosted macOS Runner Operations: Version Floor, Registration & Service Troubleshooting, Dedicated Remote Mac Selection Matrix.
1. Why two LaunchAgents exist
Gateway (ai.openclaw.gateway): binds the public or VPN-facing port, handles TLS termination (when used with a local reverse proxy), fans out RPC to workers, and should start only after loopback dependencies are reachable.
Mac agent (ai.openclaw.mac): executes macOS-specific tasks—xcodebuild, notary flows, AppleScript shortcuts, screen-capture based tooling—without requiring the gateway process to inherit a GUI session.
Keeping labels distinct prevents launchctl list ambiguity and lets you restart one side without tearing down the other.
2. TL;DR — coexistence rules
- One env file, two plists: both agents read the same
EnvironmentVariablesdictionary or a shared~/.config/openclaw/envsourced viaProgramArgumentswrapper—never fork divergentOPENCLAW_HOMEvalues. - Ports are contracts: gateway listens on
OPENCLAW_GATEWAY_PORT(example); the Mac agent uses loopback RPC or a UNIX socket—document the pair in your runbook. - ThrottlePolicy matters: use
ThrottleIntervalon the Mac agent if it respawns faster than Keychain or Xcode license daemons can initialize. - Headless Macs: ensure a persistent GUI login context when you need window-server APIs; pure SSH sessions without accessibility permissions will fail mysteriously.
3. Inventory: what launchd thinks is running
SSH into the host and capture state before mutating plists:
launchctl print gui/$(id -u)/ai.openclaw.gatewayand the same forai.openclaw.maclaunchctl blame gui/$(id -u)/ai.openclaw.gateway(macOS 13+) to see last exit reasonlog show --style syslog --predicate 'process == "launchd"' --last 15mfiltered for your labels
4. launchctl repair sequence (safe order)
- Boot out stale jobs:
launchctl bootout gui/$(id -u) ~/Library/LaunchAgents/ai.openclaw.gateway.plist(repeat forai.openclaw.mac). This removes the running instance without deleting the file. - Reload plists:
launchctl bootstrap gui/$(id -u) ~/Library/LaunchAgents/ai.openclaw.gateway.plist— start with the gateway first, then the Mac agent. - Kickstart if
RunAtLoadis false:launchctl kickstart -k gui/$(id -u)/ai.openclaw.gateway - Verify exit codes:
launchctl print gui/$(id -u)/ai.openclaw.gateway | grep -i lastexit
If you recently edited plists, always bootout before bootstrap; load/unload semantics differ across macOS generations, so prefer the modern pair.
5. Unified configuration checklist
| Concern | Gateway plist | Mac agent plist |
|---|---|---|
OPENCLAW_HOME |
Must match absolute install root. | Identical path; no tilde expansion bugs—use /Users/…. |
PATH |
Include Homebrew bin for node if not using absolute ProgramArguments. |
Add xcodebuild toolchain paths if you shell out without xcode-select fixes. |
| Secrets | API keys via EnvironmentVariables or launchd-readable file with 0600. |
Same file; avoid duplicating rotated keys between plists. |
| Working directory | WorkingDirectory → gateway package root. |
Often the same; if different, still share OPENCLAW_CONFIG path. |
| Throttle / crashes | KeepAlive with SuccessfulExit false to absorb clean shutdowns. |
Add ThrottleInterval ≥ 5s if Keychain prompts race on boot. |
6. Dedicated remote Mac — SSH headless exclusivity checklist
Treat the machine as single-tenant for automation: overlapping GUI sessions from multiple admins break Screen Recording and Accessibility consent caches.
- SSH hardening: key-only auth,
AllowUsers automation,ClientAliveIntervalfor long builds. - Session strategy: use a dedicated automation user whose Keychain holds signing identities; avoid sharing with human desktop accounts.
- Headless GUI: confirm
Auto loginor a kept-alive console session when tools require window server APIs; document which flows are pure TTY-safe. - Observability: tee logs to
~/Library/Logs/OpenClaw/with rotation; shiplaunchctl printsnapshots after incidents. - Updates: gate macOS upgrades; rerun
xcode-selectand notary smoke tests before promoting plist changes.
7. FAQ — symptom → suspect → fix
| Symptom | Likely cause | Fix |
|---|---|---|
| Only one job starts; the other exits immediately | Mismatched OPENCLAW_HOME or missing binary in ProgramArguments |
Run the same argv in an interactive shell, then paste absolute paths into both plists. |
EADDRINUSE in gateway logs |
Stale gateway or tunnel still bound | lsof -nP -iTCP:<port> -sTCP:LISTEN; bootout gateway; align tunnel upstream. |
Mac agent works manually via SSH, fails under launchd |
Different env (HOME, TMPDIR, Keychain ACL) |
Mirror shell env into plist; unlock Keychain once in the automation GUI session. |
| Flapping restart every few seconds | Crash before network or DNS ready | Add ThrottleInterval; delay dependant starts until gateway health endpoint returns 200. |
| Permissions errors on screen capture | Headless user never approved TCC prompts | Complete consent on a physical/console session; export MDM profile if enterprise-managed. |
8. Run this stack on hardware that stays out of the way
Dual LaunchAgent topologies are exactly the kind of workload Apple Silicon Mac minis handle well: native Unix services, predictable thermal behavior, and enough headroom for gateway plus local inference without the fan noise of tower workstations. macOS pairs cleanly with launchd, SSH, and developer tools—no hypervisor shim required for the Mac agent path.
A Mac mini M4 idles around a few watts yet keeps unified memory bandwidth high for concurrent gateway I/O and Xcode-side jobs, and Gatekeeper plus SIP reduce the attack surface compared with typical Windows automation hosts. If you need an exclusive, always-on remote Mac for OpenClaw without buying racks of gear, Mac mini M4 remains the most balanced entry point—compact, quiet, and easy to lock down for single-tenant SSH automation.
If you want the dual-agent pattern above on hardware that will not fight you on thermals or power draw, start from Mac mini M4 on the home page and map the same plist layout to your rented or owned host.