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の環境変数オーバーライドはフィルタリングされ(PATH、DYLD_*、LD_*、NODE_OPTIONS、PYTHON*、PERL*、RUBYOPT、SHELLOPTS、PS4が削除されます)、その後アプリの環境とマージされます。- シェルラッパー(
bash|sh|zsh ... -c/-lc)の場合、リクエストスコープの環境変数オーバーライドは、小さな明示的な許可リスト(TERM、LANG、LC_*、COLORTERM、NO_COLOR、FORCE_COLOR)に削減されます。 - 許可リストモードでの常に許可の決定において、既知のディスパッチラッパー(
env、nice、nohup、stdbuf、timeout)は、ラッパーパスではなく内部実行可能ファイルのパスを保持します。安全にアンラップできない場合、許可リストエントリは自動的には保持されません。
ディープリンク
アプリはローカルアクション用に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がある場合、実行は無人モードになります(個人の自動化を想定)。
オンボーディングフロー(典型的)
- OpenClaw.appをインストールして起動します。
- 権限チェックリスト(TCCプロンプト)を完了します。
- ローカルモードがアクティブで、ゲートウェイが実行中であることを確認します。
- ターミナルアクセスが必要な場合はCLIをインストールします。
状態ディレクトリの配置(macOS)
OpenClawの状態ディレクトリをiCloudや他のクラウド同期フォルダに置かないでください。同期されたパスは遅延を引き起こし、セッションや認証情報のファイルロック/同期競合を時々引き起こす可能性があります。以下のようなローカルで非同期の状態パスを推奨します:
OPENCLAW_STATE_DIR=~/.openclaw
openclaw doctorが以下の下に状態を検出した場合:
~/Library/Mobile Documents/com~apple~CloudDocs/...~/Library/CloudStorage/...
警告を表示し、ローカルパスに戻すことを推奨します。
ビルド&開発ワークフロー(ネイティブ)
cd apps/macos && swift buildswift 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リモートアクセスを参照してください。プロトコルの詳細については、ゲートウェイプロトコルを参照してください。