コンテンツにスキップ

OpenClaw macOS版:メニューバーからゲートウェイを完全制御

macOS で AI エージェントを動かそうとすると、権限の管理やバックグラウンドプロセスの制御に苦労することがよくありますよね。特に、セキュリティを保ちながらローカルのリソースを安全にエージェントに開放するのは、意外と手間がかかるものです。

OpenClaw macOS Companion は、こうした課題を解決するために設計されました。メニューバーに常駐し、権限の管理から Gateway との接続までをスムーズに行うための強力なツールです。

OpenClaw macOS Companion (メニューバー + Gateway ブローカー)

Section titled “OpenClaw macOS Companion (メニューバー + Gateway ブローカー)”

この macOS アプリは、OpenClaw のためのメニューバーコンパニオンです。権限の所有、ローカル Gateway の管理とアタッチ(launchd または手動)、そして macOS の機能をノードとしてエージェントに公開する役割を担います。

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

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

Section titled “ローカルモード vs リモートモード”
  • Local (デフォルト): 実行中のローカル Gateway があれば、アプリはそれにアタッチします。存在しない場合は、openclaw gateway install を通じて launchd サービスを有効にします。
  • Remote: アプリは SSH や Tailscale を経由して Gateway に接続し、ローカルプロセスは開始しません。リモートの Gateway がこの Mac にアクセスできるように、アプリはローカルのノードホストサービスを開始します。この際、アプリは Gateway を子プロセスとして生成しません。Gateway の検出は、生の tailnet IP よりも Tailscale MagicDNS 名を優先するようになったため、tailnet IP が変更された場合でもより確実に復旧できます。

アプリは、ai.openclaw.gateway というラベルのユーザー単位の LaunchAgent を管理します(--profile または OPENCLAW_PROFILE を使用している場合は ai.openclaw.<profile> となります。古い com.openclaw.* も引き続きアンロードされます)。

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

名前付きプロファイルを使用している場合は、ラベルを ai.openclaw.<profile> に置き換えてください。

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

macOS アプリは自身をノードとして提示します。主なコマンドは以下の通りです:

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

ノードは permissions マップをレポートするため、エージェントは何が許可されているかを判断できます。

ノードサービスとアプリの IPC:

  • ヘッドリスなノードホストサービスが実行されている場合(リモートモード)、ノードとして Gateway の 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 は、macOS アプリ内の Exec approvals(Settings → Exec approvals)によって制御されます。セキュリティ設定、確認の有無、許可リストは 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 のエントリは、解決されたバイナリパスに対するグロブパターンです。
  • シェルの制御文字や展開構文(&&, ||, ;, |, `, $, <, >, (, )) を含む生のシェルコマンドテキストは、許可リストのミスとして扱われ、明示的な承認(またはシェルバイナリの許可リスト登録)が必要になります。
  • プロンプトで「Always Allow(常に許可)」を選択すると、そのコマンドが許可リストに追加されます。
  • 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 スキームを登録します。

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

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

クエリパラメータ:

  • message (必須)
  • sessionKey (任意)
  • thinking (任意)
  • deliver / to / channel (任意)
  • timeoutSeconds (任意)
  • key (自動実行モード用のキー、任意)

安全性について:

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

オンボーディングの流れ (一般的)

Section titled “オンボーディングの流れ (一般的)”
  1. OpenClaw.app をインストールして起動します。
  2. 権限のチェックリスト(TCC プロンプト)を完了させます。
  3. Local モードがアクティブで、Gateway が実行されていることを確認します。
  4. ターミナルからアクセスしたい場合は、CLI をインストールします。

OpenClaw の状態ディレクトリ(state dir)を iCloud や他のクラウド同期フォルダに置くのは避けてください。同期対象のパスはレイテンシを発生させ、セッションや認証情報のファイルロック/同期の競合を時折引き起こす可能性があります。

以下のような、同期されないローカルのパスを推奨します:

Terminal window
OPENCLAW_STATE_DIR=~/.openclaw

もし openclaw doctor が以下の配下に状態ディレクトリを検出した場合:

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

警告を表示し、ローカルパスへの移動を推奨します。

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

Section titled “ビルドと開発ワークフロー (ネイティブ)”
  • cd apps/macos && swift build
  • swift run OpenClaw (または Xcode)
  • アプリのパッケージング: scripts/package-mac-app.sh

アプリを起動せずに、macOS アプリが使用しているものと同じ Gateway WebSocket ハンドシェイクや検出ロジックを試すには、デバッグ CLI を使用します。

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

接続オプション:

  • --url <ws://host:port>: 設定をオーバーライド
  • --mode &lt;local|remote&gt;: 設定から解決 (デフォルト: 設定または local)
  • --probe: 新鮮なヘルスプローブを強制
  • --timeout <ms>: リクエストタイムアウト (デフォルト: 15000)
  • --json: 差分確認用の構造化出力

検出オプション:

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

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

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

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

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

制御トンネル (Gateway WebSocket ポート)

Section titled “制御トンネル (Gateway WebSocket ポート)”
  • 目的: ヘルスチェック、ステータス、Web Chat、設定、およびその他のコントロールプレーンの呼び出し。
  • ローカルポート: Gateway ポート(デフォルト 18789)、常に固定。
  • リモートポート: リモートホスト上の同じ Gateway ポート。
  • 挙動: ランダムなローカルポートは使用しません。アプリは既存の正常なトンネルを再利用するか、必要に応じて再起動します。
  • SSH の形式: ssh -N -L <local>:127.0.0.1:<remote> に BatchMode + ExitOnForwardFailure + keepalive オプションを付与。
  • IP レポート: SSH トンネルはループバックを使用するため、Gateway からはノードの IP が 127.0.0.1 として見えます。実際のクライアント IP を表示させたい場合は、Direct (ws/wss) トランスポートを使用してください(macOS remote access を参照)。

セットアップ手順については macOS remote access を、プロトコルの詳細については Gateway protocol を参照してください。


困ったときは、AI Setup Assistant に相談してみてください。

OpenClaw

OpenClaw Expert

まだ解決しませんか?

このページで解決しない場合は、OpenClaw Expertに直接質問してください。