OpenClaw macOS Companion (Menüleiste + Gateway-Broker)

Die macOS-App ist der Menüleisten-Companion für OpenClaw. Sie verwaltet Berechtigungen, steuert den Gateway lokal (über launchd oder manuell) und stellt macOS-Funktionen als Node für den Agent bereit.

Was die App macht

  • Zeigt native Benachrichtigungen und Status in der Menüleiste.
  • Verwaltet TCC-Berechtigungen (Benachrichtigungen, Bedienungshilfen, Bildschirmaufnahme, Mikrofon, Spracherkennung, Automation/AppleScript).
  • Startet oder verbindet sich mit dem Gateway (lokal oder remote).
  • Stellt macOS-spezifische Tools bereit (Canvas, Camera, Screen Recording, system.run).
  • Startet den lokalen Node-Host-Service im Remote-Modus (launchd) und stoppt ihn im Local-Modus.
  • Hostet optional PeekabooBridge für UI-Automation.
  • Installiert die globale CLI (openclaw) über npm/pnpm auf Anfrage (bun wird für die Gateway-Runtime nicht empfohlen).

Local vs Remote Modus

  • Local (Standard): Die App verbindet sich mit einem laufenden lokalen Gateway, falls vorhanden; andernfalls aktiviert sie den launchd-Service über openclaw gateway install.
  • Remote: Die App verbindet sich über SSH/Tailscale mit einem Gateway und startet nie einen lokalen Prozess. Die App startet den lokalen Node-Host-Service, damit der Remote-Gateway diesen Mac erreichen kann. Die App startet den Gateway nicht als Child-Prozess.

Launchd-Steuerung

Die App verwaltet einen per-User LaunchAgent mit dem Label bot.molt.gateway (oder bot.molt.<profile> bei Verwendung von --profile/OPENCLAW_PROFILE; das alte com.openclaw.* wird weiterhin entladen).

launchctl kickstart -k gui/$UID/bot.molt.gateway
launchctl bootout gui/$UID/bot.molt.gateway

Ersetze das Label durch bot.molt.<profile>, wenn du ein benanntes Profil verwendest.

Falls der LaunchAgent nicht installiert ist, aktiviere ihn über die App oder führe openclaw gateway install aus.

Node-Funktionen (mac)

Die macOS-App präsentiert sich als Node. Gängige Befehle:

  • Canvas: canvas.present, canvas.navigate, canvas.eval, canvas.snapshot, canvas.a2ui.*
  • Camera: camera.snap, camera.clip
  • Screen: screen.record
  • System: system.run, system.notify

Der Node meldet eine permissions-Map, damit Agents entscheiden können, was erlaubt ist.

Node-Service + App-IPC:

  • Wenn der Headless-Node-Host-Service läuft (Remote-Modus), verbindet er sich als Node mit dem Gateway-WS.
  • system.run wird in der macOS-App (UI/TCC-Kontext) über einen lokalen Unix-Socket ausgeführt; Prompts und Output bleiben in der App.

Diagramm (SCI):

Gateway -> Node Service (WS)
                 |  IPC (UDS + token + HMAC + TTL)
                 v
             Mac App (UI + TCC + system.run)

Exec-Freigaben (system.run)

system.run wird über Exec-Freigaben in der macOS-App gesteuert (Einstellungen → Exec approvals). Sicherheitseinstellungen, Nachfragen und Allowlist werden lokal auf dem Mac gespeichert:

~/.openclaw/exec-approvals.json

Beispiel:

{
  "version": 1,
  "defaults": {
    "security": "deny",
    "ask": "on-miss"
  },
  "agents": {
    "main": {
      "security": "allowlist",
      "ask": "on-miss",
      "allowlist": [{ "pattern": "/opt/homebrew/bin/rg" }]
    }
  }
}

Hinweise:

  • allowlist-Einträge sind Glob-Patterns für aufgelöste Binary-Pfade.
  • Wenn du im Prompt “Always Allow” wählst, wird der Befehl zur Allowlist hinzugefügt.
  • system.run-Umgebungsvariablen werden gefiltert (entfernt werden PATH, DYLD_*, LD_*, NODE_OPTIONS, PYTHON*, PERL*, RUBYOPT) und dann mit der App-Umgebung zusammengeführt.

Die App registriert das URL-Schema openclaw:// für lokale Aktionen.

openclaw://agent

Löst eine Gateway-agent-Anfrage aus.

open 'openclaw://agent?message=Hello%20from%20deep%20link'

Query-Parameter:

  • message (erforderlich)
  • sessionKey (optional)
  • thinking (optional)
  • deliver / to / channel (optional)
  • timeoutSeconds (optional)
  • key (optionaler Unattended-Mode-Key)

Sicherheit:

  • Ohne key fragt die App nach Bestätigung.
  • Mit einem gültigen key läuft die Ausführung unbeaufsichtigt (gedacht für persönliche Automationen).

Onboarding-Ablauf (typisch)

  1. Installiere und starte OpenClaw.app.
  2. Schließe die Berechtigungs-Checkliste ab (TCC-Prompts).
  3. Stelle sicher, dass der Local-Modus aktiv ist und der Gateway läuft.
  4. Installiere die CLI, wenn du Terminal-Zugriff möchtest.

Build & Dev-Workflow (nativ)

  • cd apps/macos && swift build
  • swift run OpenClaw (oder Xcode)
  • App paketieren: scripts/package-mac-app.sh

Gateway-Konnektivität debuggen (macOS CLI)

Nutze die Debug-CLI, um denselben Gateway-WebSocket-Handshake und die Discovery-Logik zu testen, die die macOS-App verwendet, ohne die App zu starten.

cd apps/macos
swift run openclaw-mac connect --json
swift run openclaw-mac discover --timeout 3000 --json

Connect-Optionen:

  • --url <ws://host:port>: Config überschreiben
  • --mode <local|remote>: Aus Config auflösen (Standard: config oder local)
  • --probe: Frischen Health-Probe erzwingen
  • --timeout <ms>: Request-Timeout (Standard: 15000)
  • --json: Strukturierte Ausgabe zum Vergleichen

Discovery-Optionen:

  • --include-local: Gateways einschließen, die als “local” gefiltert würden
  • --timeout <ms>: Gesamtes Discovery-Fenster (Standard: 2000)
  • --json: Strukturierte Ausgabe zum Vergleichen

Tipp: Vergleiche mit openclaw gateway discover --json, um zu sehen, ob sich die Discovery-Pipeline der macOS-App (NWBrowser + Tailnet-DNS-SD-Fallback) von der dns-sd-basierten Discovery der Node-CLI unterscheidet.

Remote-Verbindungs-Plumbing (SSH-Tunnel)

Wenn die macOS-App im Remote-Modus läuft, öffnet sie einen SSH-Tunnel, damit lokale UI-Komponenten mit einem Remote-Gateway kommunizieren können, als wäre er auf localhost.

Control-Tunnel (Gateway-WebSocket-Port)

  • Zweck: Health-Checks, Status, Web-Chat, Config und andere Control-Plane-Aufrufe.
  • Lokaler Port: Der Gateway-Port (Standard 18789), immer stabil.
  • Remote-Port: Derselbe Gateway-Port auf dem Remote-Host.
  • Verhalten: Kein zufälliger lokaler Port; die App verwendet einen bestehenden gesunden Tunnel wieder oder startet ihn bei Bedarf neu.
  • SSH-Form: ssh -N -L <local>:127.0.0.1:<remote> mit BatchMode + ExitOnForwardFailure + Keepalive-Optionen.
  • IP-Reporting: Der SSH-Tunnel nutzt Loopback, daher sieht der Gateway die Node-IP als 127.0.0.1. Verwende Direct (ws/wss)-Transport, wenn die echte Client-IP erscheinen soll (siehe macOS Remote-Zugriff).

Für Setup-Schritte siehe macOS Remote-Zugriff. Für Protokoll-Details siehe Gateway-Protokoll.

Verwandte Docs