OpenClaw、iOS および Android 向けコンパニオンノードアプリをリリースし、スマートフォンを自己ホスト型 AI エージェントゲートウェイに接続
OpenClaw が iOS および Android 向けネイティブコンパニオンアプリをリリースし、端末を自己ホスト型 AI エージェントゲートウェイのノードとして機能させるアーキテクチャを実現した。
キーポイント
分離されたアーキテクチャの実装
スマートフォンはスタンドアロンのチャットボットではなく、カメラや位置情報などのハードウェアリソースを提供する「ノード」として機能し、実際の AI エージェント処理はユーザーが管理するゲートウェイ上で実行される。
プライバシー重視の設計
各ノードは WebSocket 経由でゲートウェイと接続し、明示的な承認が必要であり、機密性の高いコマンドはホワイトリスト化された場合のみ実行可能となる。
多様なプラットフォーム対応
iOS と Android の両アプリがリリースされ、それぞれ QR コードや設定コードによるペアリング、リアルタイム通話モード、画面共有機能などをサポートしている。
高度なデバイス機能と使用制限
iOS と Android はカメラ、位置情報、通知などの強力な機能を提供しますが、カメラ撮影や画面キャプチャはアプリがフォアグラウンドにある場合のみ動作し、バックグラウンドではエラーになります。
厳格なセキュリティと権限管理
ペアリングにはゲートウェイでの承認が必要で、カメラや画面録画などの機密コマンドはデフォルトで無効化され、設定ファイルでの明示的なオプトインが必要です。
多様な通信モードと活用事例
リアルタイム音声対話(Talk Mode)、ライブキャンバスの共有、位置情報に基づく文脈対応リマインダーなど、現場データ収集やハンズフリー操作など多岐にわたるユースケースに対応しています。
モバイルデバイスとのシームレスな連携
OpenClaw がリリースした iOS および Android のコンパニオンアプリにより、スマートフォンをセルフホスト型 AI エージェントゲートウェイに直接接続できるようになり、ユーザーは外出先からでもエージェントの管理や対話が可能になります。
影響分析・編集コメントを表示
影響分析
この発表は、AI エージェントの「所有権」と「プライバシー」をユーザーが完全に管理できる分散型アーキテクチャの実用化に向けた重要な一歩です。特に、端末側のリソース(カメラ、位置情報など)を安全に活用しつつ、処理ロジックをローカル環境に留める設計は、企業や個人による高度な自律型 AI の導入における信頼性向上に寄与します。
編集コメント
AI エージェントの普及において最大の課題である「プライバシーとデータ制御」に対し、端末をノード化することで解決を図るユニークなアプローチが示されました。
OpenClaw はこのほど、iOS および Android 向けのネイティブコンパニオンアプリをリリースしました。iOS アプリは「OpenClaw – AI that does things.」としてリストされています。両方のアプリは無料でダウンロード可能です。これらは単体のチャットボートではありません。それぞれのスマートフォンが、セルフホスト型のエージェントネットワークにおけるノードとなります。アシスタント自体は、別のゲートウェイ上で動作します。この分離こそが、本システムの設計の核心です。
TL;DR
OpenClaw の iOS および Android アプリは、単体のアシスタントではなく、コンパニオンノードです。
ゲートウェイがエージェントを実行し、スマートフォンはカメラ、位置情報、音声、Canvas を追加します。
ノード間はポート 18789 上の WebSocket でペアリングされ、明示的な承認を必要とします。
プライバシーに配慮したコマンドは、ホワイトリストに登録するまで無効化されます。
macOS、Linux、または Windows (WSL2) 上で動作するゲートウェイが必要です。
OpenClaw とは何か?
OpenClaw は、Peter Steinberger 氏によってコミュニティの貢献者と共に開発されたオープンソースのパーソナル AI アシスタント/エージェントです。このプロジェクトは独立しており、Anthropic とは一切関係ありません。そのコアは TypeScript で記述されています。ランタイムには Node 24(推奨)または Node 22.19 以上が必要です。ゲートウェイは macOS、Linux、または Windows (WSL2) 上で動作します。既存のチャットアプリから操作可能です。対応するチャンネルには WhatsApp、Telegram、Discord、Slack、Signal、iMessage が含まれます。エージェントはウェブ閲覧、シェルコマンドの実行、ファイルの読み書きが可能です。ホスト型、サブスクリプション型、ゲートウェイ型、またはローカルモデルとも連携します。利用者は選択したプロバイダーから API キーを取得して使用します。永続的なメモリを保持し、コミュニティ製のスキルやプラグインもサポートしています。
ゲートウェイとノードのアーキテクチャはどのように動作するのか?
ゲートウェイは単一の制御プレーンです。セッション、ルーティング、チャネル、ツール、イベントをすべて管理します。ご自身のマシンまたはサーバー上で 1 つの Gateway プロセスを実行するだけです。チャットメッセージは常にゲートウェイに届き、電話機には直接届くことはありません。ノードは、そのゲートウェイに接続するコンパニオンデバイスです。ノードはデフォルトポート 18789 の WebSocket を介して接続します。各ノードはペアリング時に role: "node" で登録されます。ノードは node.invoke を通じてコマンド表面(コマンドインターフェース)を公開します。そのコマンドファミリーには、canvas.*, camera.*, device.*, notifications.*, system.* が含まれます。ドキュメントでは明確に「ノードは周辺機器であり、ゲートウェイではない」と記されています。ローカルネットワーク上では、アプリは mDNS/Bonjour を経由してゲートウェイを発見します。リモートアクセスについては、OpenClaw は wss:// エンドポイントを持つ Tailscale の使用を推奨しています。
モバイルアプリは何を追加するのか?
電話機はエージェントに身体を与えます。ワークフローにデバイス固有のハードウェアを提供します。iOS アプリは QR コードまたはセットアップコードでペアリングされます。チャット、リアルタイムおよびバックグラウンドの Talk モード、承認機能をサポートしています。テキスト、リンク、メディアを iOS から OpenClaw へ共有できます。オプション機能にはカメラ、画面共有、位置情報、写真、連絡先、カレンダー、リマインダーが含まれます。Android アプリはスタンドアロンのゲートウェイではなく、コンパニオンノードです。ストリーミングチャット返信、画像添付、完全なセッション履歴を提供します。Talk モードでは ElevenLabs またはシステム TTS(Text-to-Speech:テキスト読み上げ)を使用します。ライブ Canvas 表面により、エージェントがダッシュボードやツールをレンダリングできます。Android では権限を一つずつ付与する必要があります。フォアグラウンドサービスによってゲートウェイ接続が生きた状態に保たれます。
iOS ノードと Android ノードの比較
CapabilityiOS — OpenClaw – AI that does thingsAndroid — OpenClaw’ node
RoleCompanion nodeCompanion node
PairingQR code or setup codeSetup code or manual host/port
ChatChat from iPhoneStreaming replies, image attachments, full session history
VoiceRealtime and background Talk modeTalk Mode (ElevenLabs or system TTS)
CanvasCanvas surfaceLive Canvas surface
Device capabilitiesCamera, screen, location, photos, contacts, calendar, remindersCamera, photos, screen capture, location, notifications, contacts, calendar, SMS, motion sensors
Action approvalsReviewable from the iPhoneManaged on the Gateway
Data collectionNone declared (App Store)None declared (Google Play)
RequirementiOS 18.0+ and a running GatewayA running Gateway on macOS, Linux, or Windows (WSL2)
Use Cases With Examples
Consider field data collection on a job site. The agent uses iOS camera capture to photograph conditions. Location tags each photo with GPS coordinates. Consider a context-aware reminder. The agent triggers a task when you reach a place. Consider an incoming notification on Android. The agent reads it and drafts a reply. Consider a live dashboard. The agent pushes a Canvas surface to your screen. Consider hands-free use. Talk Mode holds a continuous voice conversation. One caveat applies to camera and screen capture. They require the app in the foreground. Background calls return an error.
Pairing a Phone: A Minimal Walk-Through
First, run the Gateway on a supported host.
異なるブラウザを使用する
ゲートウェイホスト(macOS、Linux、または WSL2 を介した Windows)上で
npm install -g openclaw@latest
openclaw onboard --install-daemon
次にアプリを開き、検出されたゲートウェイを選択します。あるいは、手動でホストとポートを入力してください。このアプリは「node」のロールで接続し、デバイスペアリングリクエストを送信します。これをゲートウェイ CLI から承認してください。
異なるブラウザを使用する
openclaw devices list
openclaw devices approve
openclaw nodes status # ノードがペアリングされ、接続されていることを確認
プライバシー重視のコマンドはデフォルトでオフになっています。例としては camera.snap、camera.clip、screen.record などがあります。これらのコマンドは、設定ファイル内の gateway.nodes.allowCommands を通じて明示的にオプトインする必要があります。
異なるブラウザを使用する
// ~/.openclaw/openclaw.json
{
"gateway": {
"nodes": {
"allowCommands": ["camera.snap", "screen.record"],
},
},
}
deny リスト(gateway.nodes.denyCommands)は、allow リストよりも常に優先されます。
セキュリティと承認
ペアリング認証情報はデバイス上に保存されます。すべてのノード接続は、ゲートウェイに到達する前に承認が必要です。デバイスペアリング記録は、永続的なロール契約です。トークンのローテーションによって、ノードが異なるロールに昇格することはありません。カメラおよび画面キャプチャは権限管理されており、フォアグラウンドでのみ実行されます。平文の ws:// は LAN および .local ホストに限定されています。パブリックまたは Tailscale エンドポイントには、実際の wss:// TLS エンドポイントが必要です。
インタラクティブ解説
OpenClaw Gateway & Nodes — インタラクティブ解説
:root {
--bg:#fbf6f2; /* ウォームクリーム */
--card:#ffffff;
--ink:#26190f; /* ウォームのほぼ黒 */
--muted:#7c6a5e; /* ウォームのくすんだ色 */
--line:#efe2d8; /* ウォームのボーダー */
--soft:#f8efe7; /* ウォームのソフトな塗りつぶし */
--accent:#ff5a36; /* OpenClaw のサンゴ色 / ロブスター色 */
--accent-deep:#df4326; /* より濃いサンゴ色 */
--accent-soft:#ffe6dd; /* ピーチ */
--accent-bd:#ffc9b8; /* ピーチのボーダー */
--teal:#0d9488; /* "完了"状態 — サンゴ色とは区別 */
--amber:#b45309;
--amber-soft:#fdeccc;
--green:#76B900; /* Marktechpost ブランドカラー */
--code-bg:#21130f;
--code-ink:#f1e4dc;
--code-coral:#ff8a6b;
--code-green:#7ee787;
--code-blue:#ffb59e;
--code-mut:#a18a7e;
--radius:14px;
--mono:"JetBrains Mono",ui-monospace,SFMono-Regular,Menlo,Consolas,monospace;
--sans:Inter,-apple-system,BlinkMacSystemFont,"Segoe UI",Roboto,Helvetica,Arial,sans-serif;
}
*{box-sizing:border-box}
body{margin:0;background:var(--bg);color:var(--ink);font-family:var(--sans);line-height:1.5;-webkit-font-smoothing:antialiased}
.wrap{max-width:880px;margin:0 auto;padding:22px 18px 8px}
.eyebrow{font-family:var(--mono);font-size:11px;letter-spacing:.14em;text-transform:uppercase;color:var(--accent);font-weight:600}
h1{font-size:26px;line-height:1.18;margin:6px 0 6px;letter-spacing:-.01em}
.sub{color:var(--muted);font-size:14.5px;margin:0 0 6px;max-width:640px}
.note{font-family:var(--mono);font-size:11px;color:var(--muted);background:var(--soft);border:1px solid var(--line);border-radius:8px;padding:6px 10px;display:inline-block;margin-top:8px}
.tabs{display:flex;gap:6px;margin:20px 0 14px;flex-wrap:wrap}
.tab{font-family:var(--mono);font-size:12.5px;font-weight:600;letter-spacing:.02em;border:1px solid var(--line);background:var(--card);color:var(--muted);
padding:9px 14px;border-radius:10px;cursor:pointer;transition:.15s;user-select:none}
.tab:hover{border-color:var(--accent);color:var(--accent)}
.tab.active{background:var(--accent);border-color:var(--accent);color:#fff}
.panel{display:none;animation:fade .25s ease}
.panel.active{display:block}
@keyframes fade{from{opacity:0;transform:translateY(4px)}to{opacity:1;transform:none}}
.card{background:var(--card);border:1px solid var(--line);border-radius:var(--radius);padding:18px}
.card+.card{margin-top:14px}
.card h3{margin:0 0 4px;font-size:15px}
.card p.lead{margin:0 0 14px;color:var(--muted);font-size:13.5px}
/* アーキテクチャマップ */
.archwrap{position:relative}
.lane{display:grid;grid-template-columns:1fr;gap:14px}
.row{display:grid;gap:10px}
.row.chan{grid-template-columns:repeat(4,1fr)}
.gw-row{display:flex;justify-content:center}
.row.outs{grid-template-columns:repeat(3,1fr)}
.blk{border:1px solid var(--line);background:var(--card);border-radius:11px;padding:11px 10px;text-align:center;cursor:pointer;transition:.15s;position:relative}
.blk:hover{border-color:var(--accent);box-shadow:0 4px 14px rgba(255,90,54,.14);transform:translateY(-1px)}
.blk .t{font-size:12.5px;font-weight:600}
.blk .d{font-size:10.5px;color:var(--muted);margin-top:2px;font-family:var(--mono)}
.blk.gw{background:linear-gradient(180deg,#fff1ec,#ffe6dd);border-color:var(--accent-bd);min-width:230px;padding:14px}
.blk.gw .t{font-size:14px;color:var(--accent)}
.blk.active{border-color:var(--accent);box-shadow:0 0 0 3px var(--accent-soft)}
.conn{height:16px;display:flex;align-items:center;justify-content:center}
.conn svg{display:block}
.archlabel{font-family:var(--mono);font-size:10px;color:var(--muted);text-transform:uppercase;letter-spacing:.12em;text-align:center;margin:2px 0 -2px}
.detail{margin-top:14px;border:1px dashed var(--line);border-radius:11px;padding:13px 14px;background:var(--soft);min-height:64px}
.detail .dt{font-family:var(--mono);font-size:11px;color:var(--accent);font-weight:600;letter-spacing:.04em}
.detail .dd{font-size:13px;color:var(--ink);margin-top:4px}
/* シミュレーター */
.controls { display: grid; grid-template-columns: 1fr 1fr; gap: 14px; margin-bottom: 14px }
@media (max-width: 560px) { .controls { grid-template-columns: 1fr } }
.ctl label { font-family: var(--mono); font-size: 11px; text-transform: uppercase; letter-spacing: .1em; color: var(--muted); display: block; margin-bottom: 6px }
.chips { display: flex; flex-wrap: wrap; gap: 6px }
.chip { font-size: 12px; font-family: var(--mono); border: 1px solid var(--line); background: var(--card); color: var(--muted); padding: 7px 11px; border-radius: 8px; cursor: pointer; transition: .12s }
.chip:hover { border-color: var(--accent); color: var(--accent) }
.chip.active { background: var(--accent-soft); border-color: var(--accent); color: var(--accent); font-weight: 600 }
.runbtn{font-family:var(--mono);font-weight:700;font-size:13px;letter-spacing:.03em;background:var(--accent);color:#fff;border:none;
padding:11px 18px;border-radius:10px;cursor:pointer;transition:.15s;display:inline-flex;align-items:center;gap:8px}
.runbtn:hover{filter:brightness(1.06)}
.runbtn:disabled{opacity:.55;cursor:default}
.pipe{display:flex;align-items:stretch;gap:0;margin:16px 0 8px;overflow-x:auto;padding-bottom:4px}
.stage{min-width:104px;flex:1;border:1px solid var(--line);border-radius:10px;padding:9px 8px;text-align:center;background:var(--card);transition:.2s;opacity:.45}
.stage .sn{font-size:11px;font-weight:600}
.stage .sc{font-family:var(--mono);font-size:9.5px;color:var(--muted);margin-top:3px;word-break:break-word}
.stage.lit{opacity:1;border-color:var(--accent);box-shadow:0 0 0 3px var(--accent-soft)}
.stage.done{opacity:1;border-color:var(--teal);box-shadow:none}
.arrow{display:flex;align-items:center;color:var(--line);font-size:18px;padding:0 2px;min-width:14px}
.arrow.lit{color:var(--accent)}
.console{background:var(--code-bg);border-radius:11px;padding:14px 15px;font-family:var(--mono);font-size:12px;color:var(--code-ink);
min-height:120px;white-space:pre-wrap;overflow-x:auto;border:1px solid #3a241c}
.console .c-mut{color:var(--code-mut)}
.console .c-grn{color:var(--code-green)}
.console .c-blu{color:var(--code-blue)}
.console .c-cor{color:var(--code-coral)}
.console .c-amb{color:#e3b341}
.cursor{display:inline-block;width:7px;height:14px;background:var(--code-coral);vertical-align:-2px;animation:blink 1s steps(2) infinite}
@keyframes blink{0%,50%{opacity:1}50.01%,100%{opacity:0}}
/* ペアリング */
.steps { display: flex; flex-direction: column; gap: 0 }
.step { display: flex; gap: 12px; padding: 10px 0; border-bottom: 1px solid var(--line); opacity: .4; transition: .25s }
.step:last-child { border-bottom: none }
.step.lit { opacity: 1 }
.stepnum { flex: 0 0 26px; height: 26px; border-radius: 50%; background: var(--soft); border: 1px solid var(--line); display: flex; align-items: center; justify-content: center;
font-family: var(--mono); font-size: 12px; font-weight: 700; color: var(--muted); transition: .25s }
.step.lit .stepnum { background: var(--accent); border-color: var(--accent); color: #fff }
.step.done .stepnum { background: var(--teal); border-color: var(--teal); color: #fff }
.stepbody .st { font-size: 13px; font-weight: 600 }
.stepbody .sd { font-size: 12px; color: var(--muted); margin-top: 2px }
.stepbody code { font-family: var(--mono); font-size: 11.5px; background: var(--soft); border: 1px solid var(--line); padding: 1px 5px; border-radius: 5px; color: var(--accent) }
.legend { display: flex; gap: 14px; flex-wrap: wrap; margin-top: 12px; font-size: 11px; color: var(--muted); font-family: var(--mono) }
.legend span { display: inline-flex; align-items: center; gap: 5px }
.dot { width: 9px; height: 9px; border-radius: 3px; display: inline-block }
footer{max-width:880px;margin:18px auto 0;padding:14px 18px 22px;border-top:1px solid var(--line);display:flex;justify-content:space-between;align-items:center;flex-wrap:wrap;gap:8px}
footer .brand{font-family:var(--mono);font-size:12px;font-weight:700;color:var(--green);letter-spacing:.02em}
footer .fnote{font-size:11px;color:var(--muted);font-family:var(--mono)}
インタラクティブ解説
OpenClaw:スマートフォンが AI エージェントネットワークのノードとなる仕組み
ゲートウェイとノードのアーキテクチャ(※アーキテクチャ)を探求し、チャットコマンドがスマートフォンのハードウェアへ流れる様子をシミュレーションし、デバイスのペアリング手順をブラウザ上で体験できます。
概念的なシミュレーション · ローカルで実行 · 実際のゲートウェイは接続されていません
① アーキテクチャマップ
② コマンドフローシミュレーター
③ ペアリング手順ガイド
ゲートウェイが唯一の真実(ソース・オブ・トゥルース)です
任意のブロックをクリックすると、その役割を確認できます。メッセージは常にゲートウェイに届き、スマートフォンに直接届くことはありません。
チャットアプリとプラグイン
チャンネル
Telegram
チャンネル
Discord
チャンネル
iMessage
チャンネル
⬡ ゲートウェイ
セッション · ルーティング · チャンネル · イベント
ゲートウェイが提供するサーフェス
OpenClaw エージェント
ツール · メモリ
CLI / Web UI
コントロールプレーン
iOS / Android ノード
役割:"ノード"
⬡ ゲートウェイ
単一の制御プレーン。macOS、Linux、または Windows (WSL2) で実行されます。セッション、ルーティング、チャネル、ツール、イベントを管理します。1 つのゲートウェイプロセスがすべてのチャネルとすべてのノードを同時に処理します。
スマホのハードウェアにコマンドが届く様子をシミュレートする
チャネルとタスクを選択して実行してください。リクエストがゲートウェイを経由し、ノードの node.invoke コマンド表面へ流れる様子を見守ります。
1 · メッセージを送信するチャネル
Telegram
Discord
2 · エージェントのタスク
私の前にある棚を写真に撮る
私は今どこにいる?
スマホでライブダッシュボードを表示する
最新の通知を読み、返信文を作成する
image コマンドを実行
チャネル
→
ゲートウェイ
ルーティング + セッション
→
エージェント
プランニング + ツール
→
node.invoke
camera.snap
→
返信
チャットへ戻る
# 上記のオプションを選択して「実行」を押してください。
アクティブなホップ
完了
フォアグラウンド/オプトインが必要
スマホをノードとしてペアリングする
ノードはポート 18789 の WebSocket を経由して接続され、明示的な承認が必要です。手順を確認するために「再生」ボタンを押してください。
ペアリングフローを実行
1
ゲートウェイをホスト上で起動
macOS、Linux、または Windows (WSL2) で openclaw onboard --install-daemon を実行します。
2
アプリがゲートウェイを検出
同じ Wi-Fi 環境内では、アプリは mDNS/Bonjour を経由してゲートウェイを見つけます。リモート接続の場合は wss:// Tailscale エンドポイントを使用します。
3
スマートフォンからペアリングリクエストを送信
ノードは WebSocket に接続し、ロールを「node」として、かつデバイス ID を含めて送信します。
4
オペレーターがゲートウェイ上で承認
openclaw devices list → openclaw devices approve
5
ノードがペアリングされ接続完了
openclaw nodes status で「paired · connected」が表示されます。プライバシー重視のコマンドは、ホワイトリストに登録されるまで実行されません。
Marktechpost
インタラクティブ解説 · OpenClaw ゲートウェイ & ノード
(function(){
/* ---------- Tabs ---------- */
var tabs=document.querySelectorAll('.tab'), panels=document.querySelectorAll('.panel');
tabs.forEach(function(t){t.addEventListener('click',function(){
tabs.forEach(function(x){x.classList.remove('active')});
panels.forEach(function(p){p.classList.remove('active')});
t.classList.add('active');
document.getElementById(t.dataset.tab).classList.add('active');
resize();
});});}
/* ---------- アーキテクチャの詳細 ---------- */
var arch={
wa:["WhatsApp · チャネル","着信チャネルです。ユーザーのメッセージはゲートウェイに配信され、そこでセッションとルーティングが管理されます。"],
tg:["Telegram · チャネル","同じ単一のゲートウェイプロセスへの着信チャネルです。チャネル自体はエージェントロジックを実行しません。"],
dc:["Discord · チャネル","チャットチャネルです。OpenClaw は、1 つのゲートウェイを介して Slack、Signal、iMessage など多数のプラットフォームもサポートしています。"],
im:["iMessage · チャネル","チャットインターフェースです。すべてのチャネルは 1 つのコントロールプレーンに接続され、返信は元のチャットへ返されます。"],
gw:["⬡ ゲートウェイ","単一のコントロールプレーンです。macOS、Linux、または Windows (WSL2) で実行されます。セッション、ルーティング、チャネル、ツール、イベントを管理します。1 つのゲートウェイがすべてのチャネルとノードを担当します。"],
agent:["OpenClaw エージェント","ツールと永続的メモリを備えた推論ランタイム。
ウェブを閲覧し、シェルコマンドを実行し、ファイルの読み書きも可能です。],
cli:["CLI / Web 制御 UI","セットアップ、ペアリング承認、セッション、設定のためのオペレーター用インターフェース。ノードの承認は CLI で行います。"],
node:["iOS / Android ノード","WebSocket を介して接続し、ロールが「node」であるコンパニオンデバイスです。node.invoke を通じて canvas.*, camera.*, device.*, notifications.*, system.* を公開します。ノードは周辺機器であり、ゲートウェイではありません。"]
};
var blks=document.querySelectorAll('#arch .blk'), det=document.getElementById('archDetail');
blks.forEach(function(b){b.addEventListener('click',function(){
blks.forEach(function(x){x.classList.remove('active')});
b.classList.add('active');
var d=arch[b.dataset.k];
det.innerHTML=''+d[0]+'
+d[1]+
';
});});
/* ---------- Simulator ---------- */
var chan="WhatsApp", task="cam";
var taskMap={
cam:{cmd:"camera.snap",fam:"camera.*",label:"Photograph the shelf",fg:true,
result:'image captured · 1 attachment returned to chat'},
loc:{cmd:"location.get",fam:"location.*",label:"Get current location",fg:false,
原文を表示
OpenClaw just released native companion apps for iOS and Android. The iOS app is listed as ‘OpenClaw – AI that does things.’ Both apps are free to download. They are not standalone chatbots. Each phone becomes a node in a self-hosted agent network. The assistant itself runs on a separate Gateway. That separation is the whole design.
TL;DR
OpenClaw’s iOS and Android apps are companion nodes, not standalone assistants.
The Gateway runs the agent; phones add camera, location, voice, and Canvas.
Nodes pair over WebSocket on port 18789 and require explicit approval.
Privacy-heavy commands stay off until you allowlist them.
A Gateway on macOS, Linux, or Windows (WSL2) is required.
What is OpenClaw?
OpenClaw is an open-source personal AI assistant/agent. It was created by Peter Steinberger with community contributors. The project is independent and not affiliated with Anthropic. Its core is written in TypeScript. The runtime is Node 24 (recommended) or Node 22.19+. The Gateway runs on macOS, Linux, or Windows via WSL2. You talk to it from chat apps you already use. Supported channels include WhatsApp, Telegram, Discord, Slack, Signal, and iMessage. The agent can browse the web, run shell commands, and read and write files. It works with hosted, subscription-backed, gateway, or local models. You bring an API key from your chosen provider. It keeps persistent memory and supports community skills and plugins.
How the Gateway-and-Nodes Architecture Works?
The Gateway is the single control plane. It owns sessions, routing, channels, tools, and events. You run one Gateway process on your own machine or server. Chat messages always land on the Gateway, never on a phone. A node is a companion device that connects to that Gateway. Nodes connect over a WebSocket on default port 18789. Each node registers with role: "node" during pairing. Nodes expose a command surface through node.invoke. Those command families include canvas.*, camera.*, device.*, notifications.*, and system.*. The documentation is explicit:’Nodes are peripherals, not gateways.’ On a local network, apps discover the Gateway via mDNS/Bonjour. For remote access, OpenClaw recommends Tailscale with a wss:// endpoint.
What does Mobile Apps Add?
The phone gives the agent a body. It grants device-specific hardware to your workflows. The iOS app pairs by QR code or setup code. It supports chat, realtime and background Talk mode, and approvals. You can share text, links, and media from iOS into OpenClaw. Optional capabilities include camera, screen, location, photos, contacts, calendar, and reminders. The Android app is a companion node, not a standalone gateway. It offers streaming chat replies, image attachments, and full session history. Talk Mode uses ElevenLabs or system TTS. A live Canvas surface lets the agent render dashboards and tools. Android grants permissions one by one. A foreground service keeps the Gateway connection alive.
iOS Node vs Android Node
CapabilityiOS — OpenClaw – AI that does thingsAndroid — OpenClaw’ node
RoleCompanion nodeCompanion node
PairingQR code or setup codeSetup code or manual host/port
ChatChat from iPhoneStreaming replies, image attachments, full session history
VoiceRealtime and background Talk modeTalk Mode (ElevenLabs or system TTS)
CanvasCanvas surfaceLive Canvas surface
Device capabilitiesCamera, screen, location, photos, contacts, calendar, remindersCamera, photos, screen capture, location, notifications, contacts, calendar, SMS, motion sensors
Action approvalsReviewable from the iPhoneManaged on the Gateway
Data collectionNone declared (App Store)None declared (Google Play)
RequirementiOS 18.0+ and a running GatewayA running Gateway on macOS, Linux, or Windows (WSL2)
Use Cases With Examples
Consider field data collection on a job site. The agent uses iOS camera capture to photograph conditions. Location tags each photo with GPS coordinates. Consider a context-aware reminder. The agent triggers a task when you reach a place. Consider an incoming notification on Android. The agent reads it and drafts a reply. Consider a live dashboard. The agent pushes a Canvas surface to your screen. Consider hands-free use. Talk Mode holds a continuous voice conversation. One caveat applies to camera and screen capture. They require the app in the foreground. Background calls return an error.
Pairing a Phone: A Minimal Walk-Through
First, run the Gateway on a supported host.
Copy CodeCopiedUse a different Browser
On the Gateway host (macOS, Linux, or Windows via WSL2)
npm install -g openclaw@latest
openclaw onboard --install-daemon
Next, open the app and select a discovered Gateway. Or enter the host and port manually. The app connects with role: "node" and sends a device pairing request. Approve it from the Gateway CLI.
Copy CodeCopiedUse a different Browser
openclaw devices list
openclaw devices approve <requestId>
openclaw nodes status # confirm the node is paired and connected
Privacy-heavy commands stay off by default. Examples include camera.snap, camera.clip, and screen.record. You opt in explicitly through gateway.nodes.allowCommands in your config.
Copy CodeCopiedUse a different Browser
// ~/.openclaw/openclaw.json
{
gateway: {
nodes: {
allowCommands: ["camera.snap", "screen.record"],
},
},
}
A deny list (gateway.nodes.denyCommands) always wins over the allowlist.
Security and Approvals
Pairing credentials are stored on the device. Every node connection requires approval before it reaches the Gateway. The device pairing record is the durable role contract. Token rotation cannot upgrade a node into a different role. Camera and screen capture are permission-gated and run only in the foreground. Cleartext ws:// is limited to LAN and .local hosts. Public or Tailscale endpoints require a real wss:// TLS endpoint.
Interactive Explainer
OpenClaw Gateway & Nodes — Interactive Explainer
:root{
--bg:#fbf6f2; /* warm cream */
--card:#ffffff;
--ink:#26190f; /* warm near-black */
--muted:#7c6a5e; /* warm muted */
--line:#efe2d8; /* warm border */
--soft:#f8efe7; /* warm soft fill */
--accent:#ff5a36; /* OpenClaw coral / lobster */
--accent-deep:#df4326; /* darker coral */
--accent-soft:#ffe6dd; /* peach */
--accent-bd:#ffc9b8; /* peach border */
--teal:#0d9488; /* "completed" state — distinct from coral */
--amber:#b45309;
--amber-soft:#fdeccc;
--green:#76B900; /* Marktechpost brand */
--code-bg:#21130f;
--code-ink:#f1e4dc;
--code-coral:#ff8a6b;
--code-green:#7ee787;
--code-blue:#ffb59e;
--code-mut:#a18a7e;
--radius:14px;
--mono:"JetBrains Mono",ui-monospace,SFMono-Regular,Menlo,Consolas,monospace;
--sans:Inter,-apple-system,BlinkMacSystemFont,"Segoe UI",Roboto,Helvetica,Arial,sans-serif;
}
*{box-sizing:border-box}
body{margin:0;background:var(--bg);color:var(--ink);font-family:var(--sans);line-height:1.5;-webkit-font-smoothing:antialiased}
.wrap{max-width:880px;margin:0 auto;padding:22px 18px 8px}
.eyebrow{font-family:var(--mono);font-size:11px;letter-spacing:.14em;text-transform:uppercase;color:var(--accent);font-weight:600}
h1{font-size:26px;line-height:1.18;margin:6px 0 6px;letter-spacing:-.01em}
.sub{color:var(--muted);font-size:14.5px;margin:0 0 6px;max-width:640px}
.note{font-family:var(--mono);font-size:11px;color:var(--muted);background:var(--soft);border:1px solid var(--line);border-radius:8px;padding:6px 10px;display:inline-block;margin-top:8px}
.tabs{display:flex;gap:6px;margin:20px 0 14px;flex-wrap:wrap}
.tab{font-family:var(--mono);font-size:12.5px;font-weight:600;letter-spacing:.02em;border:1px solid var(--line);background:var(--card);color:var(--muted);
padding:9px 14px;border-radius:10px;cursor:pointer;transition:.15s;user-select:none}
.tab:hover{border-color:var(--accent);color:var(--accent)}
.tab.active{background:var(--accent);border-color:var(--accent);color:#fff}
.panel{display:none;animation:fade .25s ease}
.panel.active{display:block}
@keyframes fade{from{opacity:0;transform:translateY(4px)}to{opacity:1;transform:none}}
.card{background:var(--card);border:1px solid var(--line);border-radius:var(--radius);padding:18px}
.card+.card{margin-top:14px}
.card h3{margin:0 0 4px;font-size:15px}
.card p.lead{margin:0 0 14px;color:var(--muted);font-size:13.5px}
/* Architecture map */
.archwrap{position:relative}
.lane{display:grid;grid-template-columns:1fr;gap:14px}
.row{display:grid;gap:10px}
.row.chan{grid-template-columns:repeat(4,1fr)}
.gw-row{display:flex;justify-content:center}
.row.outs{grid-template-columns:repeat(3,1fr)}
.blk{border:1px solid var(--line);background:var(--card);border-radius:11px;padding:11px 10px;text-align:center;cursor:pointer;transition:.15s;position:relative}
.blk:hover{border-color:var(--accent);box-shadow:0 4px 14px rgba(255,90,54,.14);transform:translateY(-1px)}
.blk .t{font-size:12.5px;font-weight:600}
.blk .d{font-size:10.5px;color:var(--muted);margin-top:2px;font-family:var(--mono)}
.blk.gw{background:linear-gradient(180deg,#fff1ec,#ffe6dd);border-color:var(--accent-bd);min-width:230px;padding:14px}
.blk.gw .t{font-size:14px;color:var(--accent)}
.blk.active{border-color:var(--accent);box-shadow:0 0 0 3px var(--accent-soft)}
.conn{height:16px;display:flex;align-items:center;justify-content:center}
.conn svg{display:block}
.archlabel{font-family:var(--mono);font-size:10px;color:var(--muted);text-transform:uppercase;letter-spacing:.12em;text-align:center;margin:2px 0 -2px}
.detail{margin-top:14px;border:1px dashed var(--line);border-radius:11px;padding:13px 14px;background:var(--soft);min-height:64px}
.detail .dt{font-family:var(--mono);font-size:11px;color:var(--accent);font-weight:600;letter-spacing:.04em}
.detail .dd{font-size:13px;color:var(--ink);margin-top:4px}
/* Simulator */
.controls{display:grid;grid-template-columns:1fr 1fr;gap:14px;margin-bottom:14px}
@media(max-width:560px){.controls{grid-template-columns:1fr}}
.ctl label{font-family:var(--mono);font-size:11px;text-transform:uppercase;letter-spacing:.1em;color:var(--muted);display:block;margin-bottom:6px}
.chips{display:flex;flex-wrap:wrap;gap:6px}
.chip{font-size:12px;font-family:var(--mono);border:1px solid var(--line);background:var(--card);color:var(--muted);padding:7px 11px;border-radius:8px;cursor:pointer;transition:.12s}
.chip:hover{border-color:var(--accent);color:var(--accent)}
.chip.active{background:var(--accent-soft);border-color:var(--accent);color:var(--accent);font-weight:600}
.runbtn{font-family:var(--mono);font-weight:700;font-size:13px;letter-spacing:.03em;background:var(--accent);color:#fff;border:none;
padding:11px 18px;border-radius:10px;cursor:pointer;transition:.15s;display:inline-flex;align-items:center;gap:8px}
.runbtn:hover{filter:brightness(1.06)}
.runbtn:disabled{opacity:.55;cursor:default}
.pipe{display:flex;align-items:stretch;gap:0;margin:16px 0 8px;overflow-x:auto;padding-bottom:4px}
.stage{min-width:104px;flex:1;border:1px solid var(--line);border-radius:10px;padding:9px 8px;text-align:center;background:var(--card);transition:.2s;opacity:.45}
.stage .sn{font-size:11px;font-weight:600}
.stage .sc{font-family:var(--mono);font-size:9.5px;color:var(--muted);margin-top:3px;word-break:break-word}
.stage.lit{opacity:1;border-color:var(--accent);box-shadow:0 0 0 3px var(--accent-soft)}
.stage.done{opacity:1;border-color:var(--teal);box-shadow:none}
.arrow{display:flex;align-items:center;color:var(--line);font-size:18px;padding:0 2px;min-width:14px}
.arrow.lit{color:var(--accent)}
.console{background:var(--code-bg);border-radius:11px;padding:14px 15px;font-family:var(--mono);font-size:12px;color:var(--code-ink);
min-height:120px;white-space:pre-wrap;overflow-x:auto;border:1px solid #3a241c}
.console .c-mut{color:var(--code-mut)}
.console .c-grn{color:var(--code-green)}
.console .c-blu{color:var(--code-blue)}
.console .c-cor{color:var(--code-coral)}
.console .c-amb{color:#e3b341}
.cursor{display:inline-block;width:7px;height:14px;background:var(--code-coral);vertical-align:-2px;animation:blink 1s steps(2) infinite}
@keyframes blink{0%,50%{opacity:1}50.01%,100%{opacity:0}}
/* Pairing */
.steps{display:flex;flex-direction:column;gap:0}
.step{display:flex;gap:12px;padding:10px 0;border-bottom:1px solid var(--line);opacity:.4;transition:.25s}
.step:last-child{border-bottom:none}
.step.lit{opacity:1}
.stepnum{flex:0 0 26px;height:26px;border-radius:50%;background:var(--soft);border:1px solid var(--line);display:flex;align-items:center;justify-content:center;
font-family:var(--mono);font-size:12px;font-weight:700;color:var(--muted);transition:.25s}
.step.lit .stepnum{background:var(--accent);border-color:var(--accent);color:#fff}
.step.done .stepnum{background:var(--teal);border-color:var(--teal);color:#fff}
.stepbody .st{font-size:13px;font-weight:600}
.stepbody .sd{font-size:12px;color:var(--muted);margin-top:2px}
.stepbody code{font-family:var(--mono);font-size:11.5px;background:var(--soft);border:1px solid var(--line);padding:1px 5px;border-radius:5px;color:var(--accent)}
.legend{display:flex;gap:14px;flex-wrap:wrap;margin-top:12px;font-size:11px;color:var(--muted);font-family:var(--mono)}
.legend span{display:inline-flex;align-items:center;gap:5px}
.dot{width:9px;height:9px;border-radius:3px;display:inline-block}
footer{max-width:880px;margin:18px auto 0;padding:14px 18px 22px;border-top:1px solid var(--line);display:flex;justify-content:space-between;align-items:center;flex-wrap:wrap;gap:8px}
footer .brand{font-family:var(--mono);font-size:12px;font-weight:700;color:var(--green);letter-spacing:.02em}
footer .fnote{font-size:11px;color:var(--muted);font-family:var(--mono)}
Interactive Explainer
OpenClaw: how a phone becomes a node in your AI agent network
Explore the Gateway-and-Nodes architecture, simulate a chat command flowing to a phone’s hardware, and walk through device pairing — all in your browser.
Illustrative simulation · runs locally · no real Gateway is connected
① Architecture map
② Command-flow simulator
③ Pairing walkthrough
The Gateway is the single source of truth
Click any block to see its role. Messages always land on the Gateway — never directly on a phone.
Chat apps + plugins
channel
Telegram
channel
Discord
channel
iMessage
channel
⬡ Gateway
sessions · routing · channels · events
Surfaces the Gateway drives
OpenClaw agent
tools · memory
CLI / Web UI
control plane
iOS / Android nodes
role: “node”
⬡ Gateway
The single control plane. Runs on macOS, Linux, or Windows (WSL2). It owns sessions, routing, channels, tools, and events. One Gateway process serves every channel and every node at once.
Simulate a command reaching your phone’s hardware
Pick a channel and a task, then run it. Watch the request flow through the Gateway to a node’s node.invoke command surface.
1 · Channel you message from
Telegram
Discord
2 · Task for the agent
Photograph the shelf in front of me
Where am I right now?
Show a live dashboard on my phone
Read my latest notification and draft a reply
image Run command
Channel
→
Gateway
route + session
→
Agent
plan + tool
→
node.invoke
camera.snap
→
Reply
back to chat
# Select options above and press Run.
active hop
completed
requires foreground / opt-in
Pair a phone as a node
Nodes connect over WebSocket on port 18789 and require explicit approval. Press play to step through the handshake.
image Run pairing flow
1
Start the Gateway on a host
Run openclaw onboard --install-daemon on macOS, Linux, or Windows (WSL2).
2
App discovers the Gateway
On the same Wi-Fi, the app finds it via mDNS/Bonjour. Remote uses a wss:// Tailscale endpoint.
3
Phone sends a pairing request
The node connects to the WebSocket with role: "node" and a device identity.
4
Operator approves on the Gateway
openclaw devices list → openclaw devices approve <requestId>
5
Node is paired and connected
openclaw nodes status shows paired · connected. Privacy-heavy commands stay off until allowlisted.
Marktechpost
Interactive explainer · OpenClaw Gateway & Nodes
(function(){
/* ---------- Tabs ---------- */
var tabs=document.querySelectorAll('.tab'), panels=document.querySelectorAll('.panel');
tabs.forEach(function(t){t.addEventListener('click',function(){
tabs.forEach(function(x){x.classList.remove('active')});
panels.forEach(function(p){p.classList.remove('active')});
t.classList.add('active');
document.getElementById(t.dataset.tab).classList.add('active');
resize();
});});
/* ---------- Architecture detail ---------- */
var arch={
wa:["WhatsApp · channel","An inbound channel. The user's message is delivered to the Gateway, where the session and routing live."],
tg:["Telegram · channel","An inbound channel into the same single Gateway process. Channels do not run any agent logic themselves."],
dc:["Discord · channel","A chat channel. OpenClaw also supports Slack, Signal, iMessage and many more through one Gateway."],
im:["iMessage · channel","A chat surface. All channels feed one control plane; replies are returned to the originating chat."],
gw:["⬡ Gateway","The single control plane. Runs on macOS, Linux, or Windows (WSL2). It owns sessions, routing, channels, tools, and events. One Gateway serves every channel and node."],
agent:["OpenClaw agent","The reasoning runtime with tools and persistent memory. It can browse the web, run shell commands, and read or write files."],
cli:["CLI / Web Control UI","Operator surfaces for setup, pairing approvals, sessions, and config. The CLI is where you approve nodes."],
node:["iOS / Android nodes","Companion devices that connect over WebSocket with role: \"node\". They expose canvas.*, camera.*, device.*, notifications.*, and system.* via node.invoke. Nodes are peripherals, not gateways."]
};
var blks=document.querySelectorAll('#arch .blk'), det=document.getElementById('archDetail');
blks.forEach(function(b){b.addEventListener('click',function(){
blks.forEach(function(x){x.classList.remove('active')});
b.classList.add('active');
var d=arch[b.dataset.k];
det.innerHTML=''+d[0]+'
'+d[1]+'
';
});});
/* ---------- Simulator ---------- */
var chan="WhatsApp", task="cam";
var taskMap={
cam:{cmd:"camera.snap",fam:"camera.*",label:"Photograph the shelf",fg:true,
result:'image captured · 1 attachment returned to chat'},
loc:{cmd:"location.get",fam:"location.*",label:"Get current location",fg:false,
関連記事
今日のまとめ
AI日報で今日の重要ニュースをまとめ読み