プラットフォーム概要

macOSアプリ

macOSアプリは、OpenClawのメニューバーコンパニオンです。権限を所有し、ローカルでゲートウェイを管理/接続し(launchdまたは手動)、macOSの機能をノードとしてエージェントに公開します。

機能

  • ネイティブ通知とステータスをメニューバーに表示します。
  • TCCプロンプト(通知、アクセシビリティ、画面録画、マイク、音声認識、自動化/AppleScript)を所有します。
  • ゲートウェイ(ローカルまたはリモート)を実行または接続します。
  • macOS専用ツール(Canvas、カメラ、画面録画、system.run)を公開します。
  • リモートモード(launchd)でローカルノードホストサービスを開始し、ローカルモードでは停止します。
  • オプションでUI自動化のためのPeekabooBridgeをホストします。
  • グローバルCLI(openclaw)を要求に応じてnpm/pnpm経由でインストールします(ゲートウェイランタイムにはbunは推奨されません)。

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

  • ローカル(デフォルト):アプリは、実行中のローカルゲートウェイが存在する場合にそれに接続します。存在しない場合は、openclaw gateway installを介してlaunchdサービスを有効にします。
  • リモート:アプリはSSH/Tailscale経由でゲートウェイに接続し、ローカルプロセスを起動することはありません。アプリはローカルのノードホストサービスを開始し、リモートゲートウェイがこのMacに到達できるようにします。アプリはゲートウェイを子プロセスとして生成しません。

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.present, canvas.navigate, canvas.eval, canvas.snapshot, canvas.a2ui.*
  • カメラ: camera.snap, camera.clip
  • 画面: screen.record
  • システム: system.run, system.notify

ノードはpermissionsマップを報告するため、エージェントは許可される内容を決定できます。ノードサービス + アプリIPC:

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

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

ディープリンク

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

openclaw://agent

ゲートウェイの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. ローカルモードがアクティブで、ゲートウェイが実行中であることを確認します。
  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

ゲートウェイ接続のデバッグ(macOS CLI)

デバッグCLIを使用して、アプリを起動せずに、macOSアプリが使用するのと同じゲートウェイ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>:設定から解決(デフォルト:設定またはローカル)
  • --probe:新規のヘルスプローブを強制
  • --timeout <ms>:リクエストタイムアウト(デフォルト:15000
  • --json:差分用の構造化出力

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

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

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

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

macOSアプリがリモートモードで実行されるとき、ローカルUIコンポーネントがリモートゲートウェイと通信できるように、あたかもlocalhost上にあるかのようにSSHトンネルを開きます。

コントロールトンネル(ゲートウェイWebSocketポート)

  • 目的: ヘルスチェック、ステータス、Webチャット、設定、およびその他のコントロールプレーン呼び出し。
  • ローカルポート: ゲートウェイポート(デフォルト18789)、常に安定。
  • リモートポート: リモートホスト上の同じゲートウェイポート。
  • 動作: ランダムなローカルポートは使用せず、アプリは既存の正常なトンネルを再利用するか、必要に応じて再起動します。
  • SSH形状: ssh -N -L <local>:127.0.0.1:<remote>(BatchMode + ExitOnForwardFailure + keepaliveオプション付き)。
  • IP報告: SSHトンネルはループバックを使用するため、ゲートウェイはノードIPを127.0.0.1として認識します。実際のクライアントIPを表示したい場合は、Direct (ws/wss) トランスポートを使用してください(macOSリモートアクセスを参照)。

セットアップ手順については、macOSリモートアクセスを参照してください。プロトコルの詳細については、ゲートウェイプロトコルを参照してください。

関連ドキュメント

プラットフォームLinuxアプリ