Configure OpenClaw macOS Companion: Gateway & TCC Setup
Managing permissions and background services on macOS can be a real headache when you are trying to build or use AI agents. You want something that stays out of the way in your menu bar but still gives you full control over how your Mac interacts with your tools.
The OpenClaw macOS companion is designed to be that bridge. It handles the messy parts of macOS permissions and gateway management so you can focus on what your agents are actually doing.
What it does
Section titled “What it does”- Shows native notifications and status in the menu bar.
- Owns TCC prompts (Notifications, Accessibility, Screen Recording, Microphone, Speech Recognition, Automation/AppleScript).
- Runs or connects to the Gateway (local or remote).
- Exposes macOS‑only tools (Canvas, Camera, Screen Recording,
system.run). - Starts the local node host service in remote mode (launchd), and stops it in local mode.
- Optionally hosts PeekabooBridge for UI automation.
- Installs the global CLI (
openclaw) via npm/pnpm on request (bun not recommended for the Gateway runtime).
Local vs remote mode
Section titled “Local vs remote mode”You have two ways to run this. In Local mode (the default), the app looks for a running local Gateway. If it doesn’t find one, it sets up the launchd service for you.
In Remote mode, the app connects to a Gateway over SSH or Tailscale. It won’t start a local gateway process, but it does start a local node host service so the remote Gateway can talk back to your Mac. The app now uses Tailscale MagicDNS names instead of raw IPs, which makes things much more reliable if your network changes.
Launchd control
Section titled “Launchd control”The app manages a per‑user LaunchAgent for you. It uses the label ai.openclaw.gateway (or ai.openclaw.<profile> if you are using a specific profile).
launchctl kickstart -k gui/$UID/ai.openclaw.gatewaylaunchctl bootout gui/$UID/ai.openclaw.gatewayReplace the label with ai.openclaw.<profile> when running a named profile.
If the LaunchAgent isn’t installed, you can enable it directly from the app or by running openclaw gateway install.
Node capabilities (mac)
Section titled “Node capabilities (mac)”The macOS app shows up as a node to your agents. Here are the common commands you can use:
- Canvas:
canvas.present,canvas.navigate,canvas.eval,canvas.snapshot,canvas.a2ui.* - Camera:
camera.snap,camera.clip - Screen:
screen.record - System:
system.run,system.notify
The node also shares a permissions map so agents know what they are allowed to do. When the node host service is running in remote mode, it connects to the Gateway via WebSockets. Commands like system.run happen inside the app’s context via a local Unix socket to keep your prompts and output secure.
Gateway -> Node Service (WS) | IPC (UDS + token + HMAC + TTL) v Mac App (UI + TCC + system.run)Exec approvals (system.run)
Section titled “Exec approvals (system.run)”Security is a big deal when you let an agent run commands. You can manage this in the app under Settings → Exec approvals. Your preferences and allowlists are stored locally:
~/.openclaw/exec-approvals.jsonHere is what that configuration looks like:
{ "version": 1, "defaults": { "security": "deny", "ask": "on-miss" }, "agents": { "main": { "security": "allowlist", "ask": "on-miss", "allowlist": [{ "pattern": "/opt/homebrew/bin/rg" }] } }}A few things to keep in mind:
- The
allowlistuses glob patterns for binary paths. - If a command uses shell expansion or control syntax (like
&&,|, or$), the app will ask for your approval unless you have allowlisted the shell itself. - Choosing “Always Allow” in a prompt automatically updates your allowlist.
- The app filters out sensitive environment variables like
PATHorNODE_OPTIONSbefore running commands.
Deep links
Section titled “Deep links”You can trigger actions using the openclaw:// URL scheme. This is great for local automations.
openclaw://agent
Section titled “openclaw://agent”This triggers a Gateway agent request.
open 'openclaw://agent?message=Hello%20from%20deep%20link'You can use these parameters:
message(required)sessionKey(optional)thinking(optional)deliver/to/channel(optional)timeoutSeconds(optional)key(optional unattended mode key)
If you don’t provide a key, the app will ask you to confirm the action and will limit the message length for safety.
Onboarding flow (typical)
Section titled “Onboarding flow (typical)”Getting started usually looks like this:
- Install and launch OpenClaw.app.
- Complete the permissions checklist (TCC prompts).
- Ensure Local mode is active and the Gateway is running.
- Install the CLI if you want terminal access.
State dir placement (macOS)
Section titled “State dir placement (macOS)”You should avoid putting your OpenClaw state directory in iCloud or any other cloud-synced folder. These services can cause lag or file-lock issues that mess with your sessions.
Stick to a local path:
OPENCLAW_STATE_DIR=~/.openclawIf openclaw doctor sees your files in ~/Library/Mobile Documents/ or ~/Library/CloudStorage/, it will suggest you move them.
Build & dev workflow (native)
Section titled “Build & dev workflow (native)”If you want to build the app from source, you can use these commands:
cd apps/macos && swift buildswift run OpenClaw# To package the app:scripts/package-mac-app.shDebug gateway connectivity (macOS CLI)
Section titled “Debug gateway connectivity (macOS CLI)”If you are having trouble connecting, you can use the debug CLI. This uses the same logic as the app but runs in your terminal.
cd apps/macosswift run openclaw-mac connect --jsonswift run openclaw-mac discover --timeout 3000 --jsonThe connect command lets you override the URL or mode, while discover helps you see which gateways are visible on your network. You can compare this output with openclaw gateway discover --json to spot any differences in how the app sees your network versus the Node CLI.
Remote connection plumbing (SSH tunnels)
Section titled “Remote connection plumbing (SSH tunnels)”In Remote mode, the app sets up an SSH tunnel. This makes the remote Gateway look like it is running on your local machine.
Control tunnel (Gateway WebSocket port)
Section titled “Control tunnel (Gateway WebSocket port)”- Purpose: health checks, status, Web Chat, config, and other control-plane calls.
- Local port: the Gateway port (default
18789), always stable. - Remote port: the same Gateway port on the remote host.
- Behavior: the app reuses existing tunnels or restarts them if they fail.
- SSH shape:
ssh -N -L <local>:127.0.0.1:<remote>with specific safety options. - IP reporting: Since it uses a loopback tunnel, the gateway sees the node as
127.0.0.1.
Related docs
Section titled “Related docs”Next Steps
Section titled “Next Steps”- Check out the macOS remote access guide for setup details.
- Learn more about the Gateway protocol.
Need help setting things up? Talk to the AI Setup Assistant.
OpenClaw Expert
Still stuck?
If this page didn't answer your case, ask OpenClaw Expert for step-by-step guidance.