OpenClaw macOSコンパニオン(メニューバー+Gatewayブローカー)

macOSアプリはOpenClawのメニューバーコンパニオンです。パーミッションを管理し、Gatewayへのローカル接続(launchdまたは手動)を担い、macOSの機能をノードとしてエージェントに公開します。

機能概要

  • メニューバーにネイティブ通知とステータスを表示。
  • TCC関連のプロンプトを管理(通知、アクセシビリティ、画面収録、マイク、音声認識、Automation/AppleScript)。
  • Gatewayを実行または接続(ローカルまたはリモート)。
  • macOS固有のツールを公開(Canvas、カメラ、画面収録、system.run)。
  • リモートモードではローカルノードホストサービスを起動(launchd)し、ローカルモードでは停止。
  • オプションでPeekabooBridgeをホストし、UI自動化に対応。
  • リクエストに応じてグローバルCLI(openclaw)をnpm/pnpm経由でインストール(bunはGatewayランタイムとして非推奨)。

ローカルモードとリモートモード

  • ローカル(デフォルト):ローカルで稼働中のGatewayがあればそれに接続。なければopenclaw gateway installでlaunchdサービスを有効化。
  • リモート:SSH/Tailscale経由でリモートGatewayに接続し、ローカルプロセスは起動しない。 リモートGatewayからこのMacに到達できるよう、ローカルのノードホストサービスを起動。 アプリはGatewayを子プロセスとして起動しない。

launchd制御

アプリはユーザーごとのLaunchAgentを管理します。ラベル:ai.openclaw.gateway--profile/OPENCLAW_PROFILE使用時はai.openclaw.<profile>、レガシーのcom.openclaw.*もアンロード対象)。

launchctl kickstart -k gui/$UID/ai.openclaw.gateway
launchctl bootout gui/$UID/ai.openclaw.gateway

名前付きプロファイル実行時はラベルをai.openclaw.<profile>に置き換えてください。

LaunchAgentが未インストールの場合は、アプリから有効化するかopenclaw gateway installを実行してください。

ノード機能(Mac)

macOSアプリはノードとして振る舞います。主要コマンド:

  • Canvas:canvas.presentcanvas.navigatecanvas.evalcanvas.snapshotcanvas.a2ui.*
  • カメラ:camera.snapcamera.clip
  • 画面:screen.record
  • システム:system.runsystem.notify

ノードはpermissionsマップを報告し、エージェントが許可された操作を判断できるようにします。

ノードサービス+アプリIPC:

  • ヘッドレスノードホストサービスが稼働中(リモートモード)の場合、Gateway WSにノードとして接続。
  • system.runはmacOSアプリ(UI/TCCコンテキスト)内でローカルUnixソケットを介して実行。プロンプトと出力はアプリ内に留まる。

図解(SCI):

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

実行承認(system.run)

system.runはmacOSアプリの実行承認で制御されます(設定 → 実行承認)。 セキュリティ、確認、許可リストはMac上のローカルに保存されます:

~/.openclaw/exec-approvals.json

例:

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

注意:

  • allowlistエントリは解決済みバイナリパスのglobパターン。
  • シェル制御/展開構文(&&||;|`$<>())を含む生のシェルコマンドテキストは許可リストのミスとして扱われ、明示的な承認(またはシェルバイナリの許可リスト登録)が必要。
  • プロンプトで「常に許可」を選択すると、そのコマンドが許可リストに追加される。
  • system.runの環境変数オーバーライドはフィルタリングされ(PATHDYLD_*LD_*NODE_OPTIONSPYTHON*PERL*RUBYOPTSHELLOPTSPS4を除外)、アプリの環境変数とマージされる。
  • シェルラッパー(bash|sh|zsh ... -c/-lc)の場合、リクエストスコープの環境変数オーバーライドは小さな明示的許可リスト(TERMLANGLC_*COLORTERMNO_COLORFORCE_COLOR)に削減される。
  • 許可リストモードでの「常に許可」判定時、既知のディスパッチラッパー(envnicenohupstdbuftimeout)はラッパーパスではなく内部実行ファイルパスを永続化する。アンラップが安全でない場合、許可リストエントリは自動永続化されない。

ディープリンク

アプリはローカルアクション用にopenclaw:// URLスキームを登録しています。

openclaw://agent

GatewayへのAgentリクエストをトリガーします。

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

クエリパラメータ:

  • message(必須)
  • sessionKey(任意)
  • thinking(任意)
  • deliver / to / channel(任意)
  • timeoutSeconds(任意)
  • key(任意の無人モードキー)

セキュリティ:

  • keyなしの場合、アプリは確認プロンプトを表示。
  • keyなしの場合、確認プロンプト用にメッセージの短い文字数制限が適用され、deliver / to / channelは無視される。
  • 有効なkeyありの場合、実行は無人で行われる(個人的な自動化を想定)。

オンボーディングフロー(一般的)

  1. OpenClaw.appをインストールして起動。
  2. パーミッションチェックリストを完了(TCCプロンプト)。
  3. ローカルモードがアクティブでGatewayが稼働していることを確認。
  4. ターミナルアクセスが必要な場合はCLIをインストール。

ステートディレクトリの配置(macOS)

OpenClawのステートディレクトリをiCloudやその他のクラウド同期フォルダに置くのは避けてください。 同期パスはレイテンシの増加や、セッションや認証情報のファイルロック/同期レースを引き起こすことがあります。

以下のようなローカルの非同期パスを使用してください:

OPENCLAW_STATE_DIR=~/.openclaw

openclaw doctorが以下のパスでステートを検出した場合:

  • ~/Library/Mobile Documents/com~apple~CloudDocs/...
  • ~/Library/CloudStorage/...

ローカルパスへの移動を推奨する警告が表示されます。

ビルドと開発ワークフロー(ネイティブ)

  • cd apps/macos && swift build
  • swift run OpenClaw(またはXcode)
  • アプリのパッケージ化:scripts/package-mac-app.sh

Gatewayの接続デバッグ(macOS CLI)

デバッグCLIを使うと、macOSアプリを起動せずに、アプリと同じGateway WebSocketハンドシェイクおよびディスカバリロジックを実行できます。

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

接続オプション:

  • --url <ws://host:port>:設定を上書き
  • --mode <local|remote>:設定から解決(デフォルト:設定値またはlocal)
  • --probe:新規ヘルスプローブを強制実行
  • --timeout <ms>:リクエストタイムアウト(デフォルト:15000
  • --json:差分比較用の構造化出力

ディスカバリオプション:

  • --include-local:「ローカル」としてフィルタリングされるGatewayを含める
  • --timeout <ms>:全体のディスカバリウィンドウ(デフォルト:2000
  • --json:差分比較用の構造化出力

ヒント:openclaw gateway discover --jsonと比較して、macOSアプリのディスカバリパイプライン(NWBrowser + テールネットDNS-SDフォールバック)がNode CLIのdns-sdベースのディスカバリと異なるかどうかを確認できます。

リモート接続の仕組み(SSHトンネル)

macOSアプリがリモートモードで動作する場合、SSHトンネルを開いてローカルUIコンポーネントがリモートGatewayとlocalhostのように通信できるようにします。

コントロールトンネル(Gateway WebSocketポート)

  • 目的: ヘルスチェック、ステータス、Web Chat、設定、その他のコントロールプレーン呼び出し。
  • ローカルポート: Gatewayポート(デフォルト18789)、常に固定。
  • リモートポート: リモートホスト上の同じGatewayポート。
  • 動作: ランダムなローカルポートは使用せず、既存の健全なトンネルを再利用するか、必要に応じて再起動。
  • SSH構成: ssh -N -L <local>:127.0.0.1:<remote> + BatchMode + ExitOnForwardFailure + キープアライブオプション。
  • IP表示: SSHトンネルはループバックを使うため、GatewayにはノードIPが127.0.0.1として表示される。実際のクライアントIPを表示したい場合は**Direct (ws/wss)**トランスポートを使用(macOSリモートアクセス参照)。

セットアップ手順はmacOSリモートアクセスを参照してください。プロトコルの詳細はGatewayプロトコルを参照してください。

関連ドキュメント