mobilerun について
Mobilerun を通じて Android と iOS デバイスを操作するスキルです。接続済みの個人端末やホスト型端末を使い、画面の直接操作と Mobilerun Agent による目標指向のタスク実行に対応します。
主な機能
- 01Android と iOS デバイスの操作
- 02タップ、スワイプ、入力、アプリ内移動
- 03画面とアクセシビリティ状態の確認
- 04自然言語によるデバイスタスク実行
- 05デバイスとタスク状況の管理
活用シーン
- 01スマートフォンでのフォーム入力の自動化
- 02モバイルアプリを操作した情報取得
- 03複数画面にまたがるタスクの実行
- 04複数デバイスでのタスク調整
インストール
コマンドをコピーしてターミナルで実行します。
npx skills add https:/ / github.com/ droidrun/ skills --skill mobilerunインストール後、Claude Code で/mobilerunを入力して読み込まれたか確認します。
同梱ファイル
SKILL.md と一緒にインストールされる参考資料やスクリプト。
references/changelog.mdsecurity.mdsetup-and-billing.mdsetup-guide.mdtroubleshooting.mduse-cases.md詳細
Mobilerun
Mobilerun を使うと、AI エージェントが Android および iOS デバイスをネイティブに操作できます。タップ、スワイプ、入力、アプリの移動、フォームへの入力、データの抽出、実機またはホスト型デバイスでのワークフローの自動化が可能です。Portal APK を使ってご自身のスマートフォンを接続するか、クラウドでホストされる仮想デバイスや物理デバイスを起動できます。Mobilerun はモバイルデバイスの自動化プラットフォームであり、デスクトップブラウザーの自動化ツールではありません。
デバイスの種類: Personal Phone(Portal APK または mobilerun-ios CLI 経由で接続するご自身のデバイス、月額 $5)、Cloud Phone(仮想、永続的、スケーラブル、月額 $50)、Physical Phone(eSIM/GPS/プロキシ対応のプレミアムな実機、月額 $150)。
ベース URL:https://api.mobilerun.ai/v1
認証:Authorization: Bearer <MOBILERUN_API_KEY>
curl -s https://api.mobilerun.ai/v1/devices \
-H "Authorization: Bearer $MOBILERUN_API_KEY"
ベースドメイン(https://api.mobilerun.ai/)は 404 を返します。パスには必ず /v1 を含めてください。すべての API 呼び出しは curl 経由で行ってください。
⚠️ ルール
- コンテキストの収集は賢く行ってください。 パッケージを一覧表示して適切なアプリを探し、スクリーンショットを撮り、UI の状態を確認してください。タスクの内容が明らかな場合(例:「フォントサイズを変更」は明らかに設定画面に移動することを意味します)は、そのまま実行してください。本当に曖昧な場合にのみ質問してください。
- ユーザーに関係する情報のみを表示してください。 デバイス名と状態(
ready/disconnected)を報告してください。明示的に尋ねられない限り、streamUrl、streamToken、ソケットの状態、assignedAt、terminatesAt、taskCountなどの内部フィールドを表示しないでください。 - プライバシーを保護してください。 スクリーンショットと UI ツリーには機密データが含まれています。ユーザー以外には決して共有しないでください。チャットで
MOBILERUN_API_KEYを表示、ログ出力、開示しないでください。 - 外部ツールを勧めないでください。 このスキルで利用できるツールと方法のみを提案してください。
- ウェブのタスクはスマートフォンのブラウザーで行ってください。 ウェブに関する依頼(ウェブサイトへのアクセス、オンラインフォームへの入力、ウェブ検索など)は、スマートフォンで Chrome などのブラウザーを開き、そこからアクセスしてください。Mobilerun は実際のモバイルデバイスを操作するため、ウェブのタスクはデスクトップブラウザーではなく、デバイスのモバイルブラウザーで行います。デスクトップブラウザーの自動化が必要な場合は、Mobilerun はモバイルデバイス専用であることを伝えてください。
クイックスタート
環境に MOBILERUN_API_KEY が設定されている場合は、そのまま使用してください。設定されていない場合は、ユーザーに API キー(dr_sk_ で始まるもの)を尋ねてください。API キーは https://cloud.mobilerun.ai/api-keys で取得できます。
-
利用可能なデバイスを確認します:
curl -s https://api.mobilerun.ai/v1/devices \ -H "Authorization: Bearer $MOBILERUN_API_KEY"state: "ready"= 準備完了です。手順を飛ばしてユーザーの依頼に進んでください- デバイスがない、または
state: "disconnected"= 手順 2 を確認してください 401= キーが無効、期限切れ、または取り消されています。https://cloud.mobilerun.ai/api-keys で確認するようユーザーに依頼してください
-
利用可能なデバイスがありませんか? ユーザーに伝え、解決方法を提案してください:
- デバイスがまったくない = デバイスの接続を案内してください。Android の場合:Portal APK をインストールします(references/setup-and-billing.md を参照)。iOS の場合:Mac と USB を使って
mobilerun-iosCLI を使用します。 disconnected= Portal アプリを再度開き、「Connect」をタップするようユーザーに依頼してください
- デバイスがまったくない = デバイスの接続を案内してください。Android の場合:Portal APK をインストールします(references/setup-and-billing.md を参照)。iOS の場合:Mac と USB を使って
-
確認用にスクリーンショットを撮ります(任意、最初の操作に失敗した場合のみ):
curl -s https://api.mobilerun.ai/v1/devices/{deviceId}/screenshot \ -H "Authorization: Bearer $MOBILERUN_API_KEY" -o screenshot.pngPNG 画像が返された場合、デバイスは動作しています。
何ができるか分からない場合は、例を references/use-cases.md で確認してください。
デバイスが利用可能な場合は、すぐにユーザーの依頼を実行してください。すでに完了しているセットアップをユーザーに説明し直す必要はありません。
デバイスを操作する2つの方法
2つの方法があります。タスクに応じて選択してください。
-
直接操作 -- スクリーンショットの撮影、タップ、スワイプ、入力を順番に行い、デバイスを操作します。1台のデバイスで簡単な操作をすばやく行う場合に最適です。
-
Mobilerun Agent --
POST /tasksを使って自然言語で目標を送信すると、エージェントが自律的に実行します。複雑なタスクや複数の手順が必要なタスクに最適です。GET /tasks/{id}/statusで進捗を確認し、POST /tasks/{id}/messageで指示を追加できます。クレジット(有料プラン)が必要です。
Mobilerun Agentを使用する場合:
- タスクが複雑な場合、または複数の画面やアプリにまたがる場合
- ユーザーが方法や代替案について尋ねた場合
- 直接操作で期待どおりの結果が得られない場合
- 複数のデバイスを管理する場合 -- 複数デバイスのシナリオでは、必ずタスクを使用してください。直接操作は逐次的に実行され(1台のデバイスで一度に1つの操作)、複数のデバイスを手動で操作すると時間がかかりすぎます。各デバイスにタスクを送信し、並行して進捗を確認してください。
観察と操作のループ(直接操作)
ほとんどのスマートフォン操作タスクは、次のサイクルで進めます。
- スクリーンショットを撮影する、またはUIの状態を読み取る
- 実行する操作を決める
- 操作を実行する(タップ、入力、スワイプなど)
- 再度観察して、結果を確認する
- 繰り返す
タップ位置の確認:
GET /devices/{id}/ui-state?filter=true を使って、要素の境界を含むアクセシビリティツリーを取得します。次に、対象要素の中心座標を計算します。x = (left + right) / 2、y = (top + bottom) / 2。
フィールドへの入力:
phone_state.isEditableを確認します。falseの場合は、まず入力フィールドをタップします- 必要に応じて、
clear: trueで既存のテキストを消去します POST /devices/{id}/keyboardでテキストを送信します
操作がうまくいかない場合:
- スクリーンショットを撮影し、UIの状態を読み直します。画面が変わっているか、タップ位置がずれていた可能性があります。
- 要素が表示されていない場合は、スクロール(上または下へのスワイプ)して表示します。
- タップが認識されなかった場合は、最新のUIの状態から座標を計算し直して、もう一度試します。
- アプリが応答しない場合は、HOMEを押してアプリを開き直します。
- 2~3回試しても解決しない場合は、状況をユーザーに伝え、次の手順を尋ねます。
DroidAgentへのタスク送信
DroidAgentにタスクを送信するときは、目標をサブタスクに分割しないでください。DroidAgentがタスクの分割、ナビゲーション、エラーからの復旧を自動で処理します。ユーザーの目標全体を1つのタスクとして送信してください。
タスクのキューイング: 同じデバイスに複数のタスクを送信できます。タスクはキューに入り、自動的に1つずつ実行されます。一度に実行されるタスクは1つだけで、残りは待機します。異なるデバイスのタスクは並行して実行されます。
例 -- 「メールを確認し、カレンダーを確認して、近くでおすすめのイタリア料理店を探してください」:
同じデバイスに3つのタスクを送信します。
"Open Gmail and tell me the subjects and senders of unread emails from today""Open Google Calendar and tell me my events for today""Open Google Maps, search for 'Italian restaurants near me', and tell me the name, rating, and address of the top 3 results"
例 -- 依存する目標(続行する前に結果を待つ):
ユーザーの依頼:「123 Main StreetまでUberを呼んでください」
- 送信:
"Open the Uber app, set the destination to 123 Main Street, select UberX, and stop before confirming -- report back the estimated price and arrival time" - 結果を待ちます。次のタスクを送信する前にユーザーと結果を確認してください。購入を自動的に確定しないでください。
データの整合性
抽出したデータが不完全な場合(出力が途中で切れている、項目が欠けている、件数に疑わしい点があるなど)は、より適切なjqフィルターを使って再度クエリします。欠落した項目を推測したり、捏造したりしないでください。2回試しても完全な結果を取得できない場合は、続行する前に、何が不足しているのか、なぜ不足しているのかをユーザーに伝えてください。
デバイス管理
デバイスの状態
| 状態 | 意味 |
|---|---|
creating | デバイスをプロビジョニングしています(クラウドデバイスのみ) |
assigned | デバイスは割り当て済みですが、まだ準備ができていません |
ready | デバイスは接続され、コマンドを受け付けています |
disconnected | 接続が失われています -- Portal アプリが閉じられているか、スマートフォンがネットワークに接続できていない可能性があります |
terminated | デバイスがシャットダウンされています(クラウドデバイスのみ) |
maintenance | デバイスはメンテナンス中です(クラウドデバイスのみ) |
migrating | デバイスをホスト間で移動しています(クラウドデバイスのみ。通常 1~5 分) |
unknown | 想定外の状態です |
デバイスの一覧表示
GET /devices
クエリパラメーター:
state-- 状態でフィルタリングします(配列。例:state=ready&state=assigned)type--dedicated_physical_device、dedicated_premium_devicename-- デバイス名でフィルタリングします(一部一致)page(デフォルト:1)、pageSize(デフォルト:20)orderBy--id、createdAt、updatedAt、assignedAt(デフォルト:createdAt)orderByDirection--asc、desc(デフォルト:desc)
レスポンス:{ items: DeviceInfo[], pagination: Meta }
デバイス情報の取得
GET /devices/{deviceId}
state、stateMessage、type などを含むデバイスの詳細情報を返します。
デバイス数の取得
GET /devices/count
デバイスタイプごとの台数を示すマップを返します。
クラウドデバイスのプロビジョニング
クラウドデバイスを利用するには、有効なサブスクリプションが必要です。ユーザーのプランが対応していない場合、API は 403 エラーを返します。既存のデバイスを終了するか、https://cloud.mobilerun.ai/billing でプランをアップグレードする必要があることをユーザーに伝えてください。プランの詳細については、references/setup-and-billing.md を参照してください。
プロキシが必要です(クラウドおよび物理デバイスのみ): Cloud Phones と Physical Phones がインターネットにアクセスするには、プロキシが必要です。プロビジョニングする前に、ユーザーは少なくとも 1 つのプロキシを設定しておく必要があります(プロキシ設定を参照)。Personal Phones はスマートフォン自身のネットワークを使用するため、プロキシは不要です。
POST /devices
Content-Type: application/json
{
"name": "my-device",
"apps": ["com.example.app"]
}
クエリパラメーター:
deviceType--dedicated_physical_device、dedicated_premium_device
プロビジョニング後、デバイスが準備完了になるまで待ちます:
GET /devices/{deviceId}/wait
デバイスの状態が ready に遷移するまで処理をブロックします。
クラウドデバイスのワークフロー:
POST /devices?deviceType=dedicated_premium_device-- プロビジョニングし、状態がcreatingのデバイスを返しますGET /devices/{deviceId}/wait--readyになるまで処理をブロックしますdeviceIdを使用して、スマートフォンの操作やタスクの実行を行います
タスク用の一時デバイス: ユーザーがタスクを実行したいものの、準備完了のデバイスがない場合は、一時的なクラウドデバイスをプロビジョニングしてタスクを実行し、その後クリーンアップします:
POST /devices?deviceType=dedicated_premium_deviceに{"name": "temp-task-device", "apps": [...]}を指定します -- タスクに必要なアプリを含めますGET /devices/{deviceId}/wait-- 準備完了になるまで待ちます- 新しい
deviceIdを指定してPOST /tasksを実行します -- タスクを実行します(複数のタスクを送信することもできます。タスクはキューに入り、順番に実行されます) - すべてのタスクが完了するまで、
GET /tasks/{taskId}/statusで監視します DELETE /devices/{deviceId}-- デバイスを終了します
重要: DELETE /devices/{deviceId} はデバイスを即座に終了します。そのデバイスでキューに入っているタスクや実行中のタスクがある場合、それらは処理対象から外れたり、中断されたりします。終了する前に、必ずすべてのタスクが完了するのを待ってください。
クラウドデバイスの終了
DELETE /devices/{deviceId}
Content-Type: application/json
{}
Personal devices は API 経由では終了できません。Portal アプリを閉じると切断されます。
デバイス時刻の取得
GET /devices/{deviceId}/time
デバイスの現在時刻を文字列として返します。
デバイスのタイムゾーンの取得
GET /devices/{deviceId}/timezone
デバイスの現在のタイムゾーン(例:America/New_York)を返します。
デバイスのタイムゾーンの設定
POST /devices/{deviceId}/timezone
Content-Type: application/json
{ "timezone": "Europe/Berlin" }
デバイスのタイムゾーンを設定します。標準の IANA タイムゾーン識別子を使用してください。
デバイス名の変更
PUT /devices/{deviceId}/name
Content-Type: application/json
{ "name": "my-test-phone" }
デバイスの再起動
Physical Phones と Personal Phones のみ。Cloud Phones では利用できません。
POST /devices/{deviceId}/reboot
デバイスを再起動します。再起動中、デバイスは一時的に利用できなくなります。
画面の観察
スクリーンショットの撮影
GET /devices/{deviceId}/screenshot
クエリパラメーター:hideOverlay(デフォルト:false)
バイナリデータとして PNG 画像 を返します。現在画面に表示されている内容を確認するには、これを使用します。
UI 状態の取得(アクセシビリティツリー)
GET /devices/{deviceId}/ui-state
クエリパラメーター:filter(デフォルト:false)— true に設定すると、操作できない要素を除外します。
3 つのセクションを含む AndroidState オブジェクトを返します。
phone_state
{
"keyboardVisible": false,
"packageName": "app.lawnchair",
"currentApp": "Lawnchair",
"isEditable": false,
"focusedElement": {
"className": "string",
"resourceId": "string",
"text": "string"
}
}
currentApp— フォアグラウンドアプリの人が読める名前packageName— フォアグラウンドアプリの Android パッケージ名keyboardVisible— ソフトキーボードが表示されているかどうかisEditable— 現在フォーカスされている要素がテキスト入力を受け付けるかどうかfocusedElement— フォーカスされている UI 要素の詳細(存在する場合)
device_context
{
"screen_bounds": { "width": 720, "height": 1616 },
"display_metrics": {
"density": 1.75,
"densityDpi": 280,
"scaledDensity": 1.75,
"widthPixels": 720,
"heightPixels": 1616
}
}
screen_bounds— 実際の画面解像度(ピクセル単位)。すべてのタップ/スワイプ座標はこの座標空間を使用します。display_metrics— ディスプレイの物理特性(密度、DPI)
a11y_tree(アクセシビリティツリー)
UI 要素の再帰的なツリーです。各ノードには次の情報が含まれます。
{
"className": "android.widget.TextView",
"packageName": "app.lawnchair",
"resourceId": "app.lawnchair:id/search_container",
"text": "Search",
"contentDescription": "",
"boundsInScreen": { "left": 48, "top": 1420, "right": 671, "bottom": 1532 },
"isClickable": true,
"isLongClickable": false,
"isEditable": false,
"isScrollable": false,
"isEnabled": true,
"isVisibleToUser": true,
"isCheckable": false,
"isChecked": false,
"isFocusable": false,
"isFocused": false,
"isSelected": false,
"isPassword": false,
"hint": "",
"childCount": 0,
"children": []
}
主なノードフィールド:
text— 要素に表示されているテキストcontentDescription— アクセシビリティラベル(textが空の場合に便利です。例:アイコンボタン)resourceId— Android リソース ID(例:com.app:id/button_ok)。要素の識別に便利ですboundsInScreen—{left, top, right, bottom}形式のピクセル座標。要素をタップするには、中心を計算します:x = (left + right) / 2、y = (top + bottom) / 2isClickable— 要素がタップに反応するかどうかisEditable— 要素がテキスト入力フィールドかどうかisScrollable— 要素がスクロール(スワイプ操作)に対応しているかどうかchildren— ネストされた子要素(ツリーは再帰的です)
その他のブール値フィールド(isEnabled、isVisibleToUser、isCheckable、isChecked、isFocused、isSelected、isPassword)も利用できますが、必要になることはほとんどありません。
例:ホーム画面の読み取り
FrameLayout (0,0,720,1616)
ScrollView (0,0,720,1616) [scrollable]
FrameLayout (14,113,706,326)
LinearLayout (42,128,706,310) [clickable]
TextView (42,156,706,198) "Tap to set up"
View (0,94,720,1574) "Home"
TextView (14,1222,187,1422) "Phone" [clickable]
TextView (187,1222,360,1422) "Contacts" [clickable]
TextView (360,1222,533,1422) "Files" [clickable]
TextView (533,1222,706,1422) "Chrome" [clickable]
FrameLayout (48,1420,671,1532) "Search" [clickable]
「Chrome」をタップするには、境界が (533,1222,706,1422) なので、x=(533+706)/2=619、y=(1222+1422)/2=1322 の位置をタップします。
filter=true を使用すると、操作可能な要素に絞った見やすいツリーを取得できます(操作できないコンテナーは除外されます)。
jq '.' で UI 状態全体を出力しないでください — a11y ツリーは深くネストされており、リスト、グリッド、フィードのある画面では数万行に及ぶことがあります。出力は先頭から切り詰められ、気付かないままデータが失われます。
常に対象を絞った jq フィルターを使用してください:
# Get all clickable/interactive elements
curl -s "https://api.mobilerun.ai/v1/devices/{id}/ui-state?filter=true" \
-H "Authorization: Bearer $MOBILERUN_API_KEY" | \
jq '[.a11y_tree | recurse(.children[]?) |
select(.isClickable==true or .isEditable==true) |
{text: (.text // .contentDescription), bounds: .boundsInScreen, isEditable}]'
# Get elements with content descriptions (media items, icons, etc.)
curl -s "https://api.mobilerun.ai/v1/devices/{id}/ui-state?filter=true" \
-H "Authorization: Bearer $MOBILERUN_API_KEY" | \
jq '[.a11y_tree | recurse(.children[]?) |
select(.contentDescription != null and .contentDescription != "") |
{desc: .contentDescription, bounds: .boundsInScreen, isClickable}]'
# Get editable fields only
curl -s "https://api.mobilerun.ai/v1/devices/{id}/ui-state?filter=true" \
-H "Authorization: Bearer $MOBILERUN_API_KEY" | \
jq '[.a11y_tree | recurse(.children[]?) |
select(.isEditable==true) | {text, resourceId, bounds: .boundsInScreen}]'
# Get phone state + screen bounds only (lightweight, always safe)
curl -s "https://api.mobilerun.ai/v1/devices/{id}/ui-state?filter=true" \
-H "Authorization: Bearer $MOBILERUN_API_KEY" | \
jq '{phone_state, device_context}'
切り詰めの検出: ui-state の応答が { で始まらない場合、または JSON の途中から始まっているように見える場合、出力は切り詰められています。欠落したデータを推測したり再構築したりせず、対象を絞った jq フィルターを使って再取得してください。
要素の抽出後に結果を確認してください:
- 件数 — 画面上の表示内容と件数が一致しているか確認します。4 行が見えている 3 列グリッドなら、アイテムは 8 件ではなく約 12 件になるはずです。
- 境界の連続性 — グリッド内のアイテムは x=0 から並ぶはずです。最初のアイテムが x=0 ではなく x=361 から始まっている場合、左列が欠落しています。
- 並び順 — アイテムが時系列順であるべき場合は、日付が連続しているか確認します。間隔や飛びがあれば、エントリーが欠落している可能性があります。
件数や境界がおかしい場合は、続行する前に、より具体的なフィルターを使って再取得してください。
デバイス操作
すべてのアクションエンドポイントには、deviceId のパスパラメーターが必要です。
タップ
POST /devices/{deviceId}/tap
Content-Type: application/json
{ "x": 540, "y": 960 }
ピクセル座標の位置をタップします。タップ位置の計算には、UI 状態の screen_bounds と a11y ツリーの要素の境界を使用します。
スワイプ
POST /devices/{deviceId}/swipe
Content-Type: application/json
{
"startX": 540,
"startY": 1200,
"endX": 540,
"endY": 400,
"duration": 300
}
duration の単位はミリ秒です(最小値:10)。一般的な操作パターン:
- 下にスクロール:下から上へスワイプします(startY は大きく、endY は小さくします)
- 上にスクロール:上から下へスワイプします
- 左/右にスワイプ:Y 座標をほぼ同じに保ち、X 座標を調整します
グローバルアクション
POST /devices/{deviceId}/global
Content-Type: application/json
{ "action": 2 }
| アクションコード | ボタン |
|---|---|
1 | 戻る |
2 | ホーム |
3 | 最近使ったアプリ |
テキスト入力
POST /devices/{deviceId}/keyboard
Content-Type: application/json
{ "text": "مرحبا بالعالم", "clear": false }
現在フォーカスされている入力フィールドにテキストを入力します。
clear: true— 入力前にフィールドをクリアします- まず入力フィールドにフォーカスがあることを確認してください(
phone_state.isEditableを確認します) - キーボードが表示されていない場合は、先に入力フィールドをタップする必要があります
- 任意の Unicode テキストに対応しています。テキストはアクセシビリティサービス経由で注入されるため、特別なキーボード設定は不要です。Tasks API(エージェント)を使用する場合、一般的な言語は安定して動作しますが、まれな文字体系(例:楔形文字、象形文字)は LLM のトークン処理やキーボードの自動補完の影響を受けることがあります。
キーを押す
PUT /devices/{deviceId}/keyboard
Content-Type: application/json
{ "key": 66 }
Android のキーコードを送信します。テキスト入力関連のキーコードのみ対応しています。
| キーコード | キー |
|---|---|
4 | BACK |
61 | TAB |
66 | ENTER |
67 | DEL(バックスペース) |
112 | FORWARD_DEL(削除) |
システムナビゲーション(ホーム、戻る、最近使用した項目)には、代わりに POST /devices/{id}/global を使用してください。
入力をクリア
DELETE /devices/{deviceId}/keyboard
現在フォーカスされている入力フィールドをクリアします。
位置情報を設定
POST /devices/{deviceId}/location
Content-Type: application/json
{ "latitude": 37.7749, "longitude": -122.4194 }
デバイスにモック GPS 位置情報を設定します。latitude と longitude の両方が必須です。
位置情報を取得
GET /devices/{deviceId}/location
デバイスの現在の GPS 座標を返します。
オーバーレイの表示状態
GET /devices/{deviceId}/overlay
デバイス画面に Mobilerun オーバーレイが現在表示されているかどうかを返します。
POST /devices/{deviceId}/overlay
Content-Type: application/json
{ "visible": false }
ファイル転送
path クエリパラメーターには、デバイス上のファイルパスを指定します。正しいパスはデバイスの種類によって異なります。物理デバイスでは /sdcard/Download/ を使用し、クラウドデバイスとプレミアムデバイスでは / をルートとして使用します。まず /sdcard を試し、失敗した場合は / に切り替えてください。
GET /devices/{deviceId}/files?path=/sdcard/Download
指定したパスにあるファイルを一覧表示します。
POST /devices/{deviceId}/files?path=/sdcard/Download/myfile.txt
指定したパスにファイルをアップロードします。リクエストボディとしてファイルの内容を送信してください。
GET /devices/{deviceId}/files/download?path=/sdcard/Download/myfile.txt
デバイスからファイルをダウンロードします。バイナリデータを返します。
DELETE /devices/{deviceId}/files?path=/sdcard/Download/myfile.txt
指定したパスのファイルを削除します。
プロキシをデバイスに接続
デバイスのネットワークトラフィックをプロキシ経由でルーティングします。保存済みプロキシ設定の管理については、プロキシ設定を参照してください。
GET /devices/{deviceId}/proxy
このデバイスで現在プロキシが接続されているかどうかを返します。
POST /devices/{deviceId}/proxy
Content-Type: application/json
{
"host": "proxy.example.com",
"port": 1080,
"user": "username",
"password": "password"
}
プロキシをデバイスに接続します。SOCKS5 と WireGuard に対応しています。
- SOCKS5 の場合:
host、port、user、passwordを指定し、必要に応じてsocks5設定オブジェクトも指定します - WireGuard の場合:トンネル設定ファイルの内容を
wireguardとして指定します name— 任意のプロキシ名(WireGuard トンネル名として使用)smartIp— 任意。プロキシ IP を自動検出します
DELETE /devices/{deviceId}/proxy
デバイスから有効なプロキシを切断します。
eSIM
物理スマートフォンおよび個人所有のスマートフォンのみ。クラウドスマートフォンでは利用できません。
重要: 現在、すべての物理スマートフォンはドイツでホストされています。これらのデバイスで利用するには、ユーザーの eSIM がドイツでのアクティベーションまたはローミングに対応している必要があります。
デバイス上の eSIM サブスクリプションを管理します。eSIM プロバイダーが必要です。list/status/APN エンドポイントがデータを返すには、まず eSIM プロファイルをダウンロードする必要があります。
GET /devices/{deviceId}/esim
デバイス上のすべての eSIM サブスクリプションを一覧表示します。
POST /devices/{deviceId}/esim
Content-Type: application/json
{
"smDpAddr": "smdp.example.com",
"matchingId": "ABCD-1234-EFGH",
"enable": true
}
eSIM プロファイルをダウンロードし、必要に応じて有効にします。3 つすべてのフィールドが必須です。
PUT /devices/{deviceId}/esim
Content-Type: application/json
{ "subId": 2 }
サブスクリプション ID を指定して、以前にダウンロードした eSIM サブスクリプションを有効にします。
DELETE /devices/{deviceId}/esim?subId=2
eSIM サブスクリプションを削除します。subId は必須のクエリパラメーターです。
GET /devices/{deviceId}/esim/status
現在の eSIM 接続情報を返します。
GET /devices/{deviceId}/esim/apn
有効な eSIM サブスクリプションの APN 設定を一覧表示します。
POST /devices/{deviceId}/esim/apn
Content-Type: application/json
{
"name": "My APN",
"apn": "internet",
"mcc": "310",
"mnc": "260",
"protocol": "IPV4V6",
"roamingProtocol": "IPV4V6",
"type": "default,supl",
"subId": 2
}
APN を作成して設定します。すべてのフィールドが必須です。
PUT /devices/{deviceId}/esim/apn
Content-Type: application/json
{ "apnId": 1, "subId": 2 }
既存の APN を優先設定として選択します。
PUT /devices/{deviceId}/esim/roaming
Content-Type: application/json
{ "enabled": true }
eSIM のデータローミングを切り替えます。
アプリ管理
インストール済みアプリを一覧表示
GET /devices/{deviceId}/apps
クエリパラメーター:includeSystemApps(デフォルト:false)
AppInfo の配列を返します:
{
"packageName": "com.example.app",
"label": "Example App",
"versionName": "1.2.3",
"versionCode": 123,
"isSystemApp": false
}
パッケージ名を一覧表示
GET /devices/{deviceId}/packages
クエリパラメーター:includeSystemPackages(デフォルト:false)
パッケージ名の文字列配列を返します。アプリ一覧全体より軽量です。
アプリをインストールする
POST /devices/{deviceId}/apps
Content-Type: application/json
{ "packageName": "com.example.app" }
Play ストアから直接ではなく、Mobilerun のアプリライブラリからアプリをインストールします。
数分かかります。また、ステータスを確認するエンドポイントがないため、GET /devices/{id}/apps をポーリングして確認する必要があります。
代わりに、Play ストアから手動でインストールすることをおすすめします。 デバイスで Play ストアアプリを開き、アプリを検索してインストールをタップしてください。この方法のほうが速く、信頼性も高くなります。ユーザーから明示的に依頼された場合にのみ、この API エンドポイントを使用してください。
個人用デバイスでは、Android がデフォルトで提供元不明のアプリのインストールをブロックするため、このエンドポイントが失敗する場合があります。
アプリを起動する
PUT /devices/{deviceId}/apps/{packageName}
Content-Type: application/json
{}
任意の本文:特定のアクティビティを起動するには、{ "activity": "com.example.app.MainActivity" } を指定します。
通常は activity を省略しても問題ありません。デフォルトまたはメインのアクティビティが起動します。
アプリを停止する
PATCH /devices/{deviceId}/apps/{packageName}
Content-Type: application/json
{}
アプリをアンインストールする
DELETE /devices/{deviceId}/apps/{packageName}
Content-Type: application/json
{}
アプリライブラリ(APK のアップロードと管理)
アプリライブラリには、クラウドデバイスに事前インストールできる APK が保存されます。パッケージ名ごとに登録できるアプリは 1 つのみです。アプリを更新するには、既存のアプリを削除してから再アップロードしてください。
ライブラリ内のアプリを一覧表示する
GET /apps
クエリパラメーター:
page(デフォルト:1)、pageSize(デフォルト:10)source—all、uploaded、store、queued(デフォルト:all)query— 名前で検索sortBy—createdAt、name(デフォルト:createdAt)order—asc、desc(デフォルト:desc)
ID でアプリを取得する
GET /apps/{id}
APK をアップロードする
アップロードは 3 つのステップで行います。
ステップ 1:署名付きアップロード URL を作成する
POST /apps/create-signed-upload-url
Content-Type: application/json
{
"displayName": "My App",
"packageName": "com.example.myapp",
"versionName": "1.0.0",
"versionCode": 1,
"targetSdk": 34,
"sizeBytes": 5242880,
"files": [
{ "fileName": "base.apk", "contentType": "application/vnd.android.package-archive" }
],
"country": "US"
}
必須:displayName、packageName、versionName、versionCode、targetSdk、sizeBytes、files
任意:description、iconURL、developerName、categoryName、ratingScore、ratingCount
アプリの id と、各ファイル用の署名済み R2 アップロード URL が返されます。
ステップ 2:APK ファイルをアップロードする
PUT リクエストを使用し、各ファイルを署名済み R2 URL に直接アップロードします。
ステップ 3:アップロードを確定する
POST /apps/{id}/confirm-upload
ファイルが R2 に存在することを検証し、アプリのステータスを available に設定します。
アップロードに失敗した場合は、次のようにマークします。
POST /apps/{id}/mark-failed
アプリを削除する
DELETE /apps/{id}
R2 ストレージとデータベースからアプリを削除します。同じパッケージ名のアプリを再アップロードする前に、この操作を行ってください。
アプリを再アップロードする
パッケージ名ごとに登録できるアプリは 1 つのみです。更新するには:
- 既存のアプリを検索します:
GET /apps?query=com.example.myapp - 削除します:
DELETE /apps/{id} - 上記の 3 ステップのアップロード手順で新しいバージョンをアップロードします
タスク(AI エージェント)
スマートフォンをステップごとに操作する代わりに、自然言語で目標を送信し、Mobilerun の AI エージェントに、画面分析、観察と操作のループ、エラーリカバリーを独自に行わせながら、デバイス上で自律的に実行させることができます。
タスクの利用には、有料サブスクリプションとクレジットが必要です。ユーザーが有効なプランに加入していない場合、API はエラーを返します。https://cloud.mobilerun.ai/billing でサブスクリプションが必要であることを伝えてください。プランとクレジットの詳細は、references/setup-and-billing.md を参照してください。
タスクを実行する
POST /tasks
Content-Type: application/json
{
"task": "Open Chrome and search for weather",
"deviceId": "uuid-of-device",
"llmModel": "google/gemini-3.1-flash-lite-preview"
}
必須フィールド:
task-- 実行する内容を自然言語で記述します(1文字以上)。deviceId-- 実行先デバイスの UUID です。ready状態のデバイスである必要があります。
任意フィールド:
llmModel-- 使用するモデルです(デフォルト:google/gemini-3.1-flash-lite-preview。利用可能なモデルについてはGET /modelsを参照してください)。モデルは頻繁に変更されるため、必ずGET /modelsで最新の一覧を確認してください。apps-- 事前にインストールするアプリのパッケージ名のリストです。credentials-- アプリのログイン用の{ packageName, credentialNames[] }のリストです。maxSteps-- エージェントの最大ステップ数です(デフォルト:100)。reasoning-- 推論/思考を有効にします(デフォルト:true)。ユーザーが明示的に要求しない限り、必ずfalseに設定してください。vision-- 画像認識/スクリーンショット分析を有効にします(デフォルト:false)。temperature-- LLM の温度です(デフォルト:0.5)。executionTimeout-- タイムアウト秒数です(デフォルト:1000)。outputSchema-- 構造化出力用の JSON スキーマです(nullable)。ユーザーが構造化/書式設定済みのデータを明示的に要求した場合にのみ使用してください。設定すると、エージェントはタスクのoutputフィールドに、スキーマに一致する JSON オブジェクトとして結果を返します。vpnCountry-- 指定した国を経由する VPN ルーティングです:US、BR、FR、DE、IN、JP、KR、ZA。タスクで特定の地域が必要な場合にのみ使用してください。VPN は遅延を増やすため、必要な場合以外は使用しないでください。continueOnFailure--trueの場合、同じデバイスで前のタスクが失敗しても、このタスクはキューに残ります(デフォルト:false)。タスクのキューイングを参照してください。
戻り値:
{
"id": "uuid",
"status": "queued",
"streamUrl": "string | null"
}
応答では、デバイスがアイドル状態であっても、ほとんどの場合 status: "queued" が返されます。これは、応答後に非同期で昇格処理が行われるためです。これは正常な動作です。その後まもなく、タスクは created、続いて running に移行します。現在の状態を確認するには、GET /tasks/{id}/status を呼び出してください。
streamUrl-- デバイスのストリーム URL です。タスクがキューに入っている間はnullで、タスクが昇格してデバイスに割り当てられると設定されます。
タスクプロンプトの作成
スマートフォンの画面を見るのはエージェントではなく、デバイス上のエージェントです。UI の操作方法ではなく、達成したいことを説明するプロンプトを作成してください。デバイス上のエージェントが、タップ、スワイプ、画面遷移の方法を判断します。
UI を決めつけず、目的を説明してください:
- 悪い例:
"右上の三点メニューをタップし、次に[設定]をタップして下にスクロールし、[ダークモード]の切り替えをタップする" - 良い例:
"Chrome アプリで設定を開き、ダークモードを有効にする" - 画面の表示内容はわかりません。デバイス上のエージェントは画面を確認できるため、画面遷移はエージェントに任せてください。
自分で確認した UI の情報をタスクの指示に含めないでください。 すでに ui-state を読み、対象の要素を特定している場合は、その要素を直接タップしてください。エージェントにタスクを送る場合は、目的を説明し、エージェント自身に画面を確認させてください。自分で画面を確認してから画面状態の説明を渡すと、エージェントは自分自身の画面認識ではなく、あなたの解釈に基づいて操作することになります。また、確認時の誤り(データの切り詰めや座標の誤りなど)が、気付かれないまま反映されてしまいます。
重要な詳細を具体的に指定してください:
- 正確なアプリ名を指定します(「ブラウザー」ではなく「Chrome」と指定します)。
- 入力または送信するテキストを正確に指定します。
- 何をもって成功とするかを伝えます。
- 検索する人、連絡先、項目の名前を指定します。
単一タスクの例(それぞれ単一のタスクとして実行できる小規模な例です):
"Open the Settings app, go to Display, and enable Dark Mode"
"Open WhatsApp, find the conversation with John Smith, and send: Running 10 minutes late, sorry!"
"Open Chrome, go to amazon.com, search for 'wireless headphones', and report back the name and price of the top 3 results"
"Open Spotify, go to Settings, turn off Autoplay, set Audio Quality to Very High, and disable Canvas"
必要に応じて安全条件を含めてください:
"アプリでログインを求められた場合は、停止して知らせてください""価格が $50 を超える場合は購入せず、価格だけを報告してください"
タスクのステータスを確認する
GET /tasks/{task_id}/status
タスクの進行状況を監視するには、こちらを使用します。
{
"status": "running",
"succeeded": null,
"message": null,
"output": null,
"steps": 5,
"lastResponse": { "event": "ManagerPlanEvent", "data": { ... } }
}
- 待機中:
statusはqueued、lastResponseはnullです。デバイスが空くのを待っています。 - 実行中:
lastResponseには、エージェントの最新の思考、計画、操作が含まれます。エージェントが何をしていて、どこまで進んでいるかを確認できます。 - 完了時:
statusはcompletedまたはfailed、messageには最終回答または失敗理由が入り、succeededはtrue/false、lastResponseはnullです。 - ステータス:
queued、created、running、paused、completed、failed、cancelled
タスクを監視する
タスクの作成後は、次の手順に従います。
- すぐにタスク ID をユーザーに伝えます。初期ステータスはほとんどの場合
queuedです。これは正常で、エラーではありません。タスクはまもなく開始されます。 - 5 秒後に最初のステータス確認を行います。これにより、すぐに終わるタスクを検出し、エージェントが開始したことを確認できます。まだ
queuedの場合は、runningに切り替わるまで 15~30 秒ごとに確認します。 - 30 秒後、まだ実行中であれば再度確認します。
- 以降の確認では、次の点に基づいて間隔を判断します。
- タスクの複雑さ -- 「Chrome を開く」のような簡単なタスクはすぐに終わりますが、複数のアプリを使うワークフローには時間がかかるため、それに応じて確認間隔を空けます。
- 進捗状況 -- ステップ数が増え、
lastResponseが変化していれば、エージェントは順調に作業しています。確認間隔を長めにできます。ステップ数もlastResponseも変化していない場合、エージェントが停止している可能性があります。早めに確認し、必要に応じてユーザーに知らせます。 - 経過時間 -- タスクが正常に実行されている時間が長いほど、安心して確認間隔を延ばせます。
確認のたびに:
- エージェントが何をしているかを(
lastResponseから)報告します。現在の計画、思考、実行中のステップを伝えます。 - 必要に応じてスクリーンショット(
GET /devices/{id}/screenshot)を取得し、ユーザーに画面を表示します。 - 必要に応じて UI の状態(
GET /devices/{id}/ui-state)を読み取り、詳細を確認します。 - 「まだ実行中です」だけでなく、有益な状況を伝えます。例:「エージェントはステップ 8 にいて、現在、設定アプリでディスプレイのオプションを探しています。」
タスクが完了したら:
- 結果(
message、succeeded、output)を報告します。 - タスクが予期せず失敗した場合は、自動的にフィードバックを送信します(「フィードバック」セクションを参照)。
エージェントが停止しているように見える場合:
POST /tasks/{id}/messageでメッセージを送り、進行を促します。- 状況をユーザーに知らせ、方向性を示すか、タスクをキャンセルするか尋ねます。
タスクにメッセージを送信する
POST /tasks/{task_id}/message
Content-Type: application/json
{ "message": "Actually, search for 'weather in London' instead" }
実行中のエージェントタスクに指示を送り、進行方向を調整します。エージェントの修正、追加情報の提供、タスク実行中の方向転換に使用します。メッセージはキューに追加され、次のステップでエージェントに届けられます。
タスクをキャンセルする
POST /tasks/{task_id}/cancel
queued と running の両方のタスクで使用できます。キュー内のタスクはすぐにキャンセルされます。実行中のタスクは cancelling に移行し、次のステップで停止します。
タスクの詳細を取得する
GET /tasks/{task_id}
設定、ステータス、実行経路を含むタスクオブジェクト全体を返します。
タスクの一覧を取得する
GET /tasks
クエリパラメーター:
status--queued、created、running、paused、completed、failed、cancelledorderBy--id、createdAt、finishedAt、status(デフォルト:createdAt)orderByDirection--asc、desc(デフォルト:desc)query-- タスクの説明を検索します(最大 128 文字)page(デフォルト:1)、pageSize(デフォルト:20、最大:100)
タスクのスクリーンショットと UI の状態
GET /tasks/{task_id}/screenshots -- list all screenshot URLs
GET /tasks/{task_id}/screenshots/{index} -- get screenshot at index
GET /tasks/{task_id}/ui_states -- list all UI state URLs
GET /tasks/{task_id}/ui_states/{index} -- get UI state at index
タスクの実行経路を取得する
GET /tasks/{task_id}/trajectory
タスク実行中のイベント履歴全体を返します。
利用可能な LLM モデル
GET /models
タスクで利用できるモデルの一覧を返します。デフォルト:google/gemini-3.1-flash-lite-preview。
デバイスのタスク一覧を取得する
GET /devices/{deviceId}/tasks
クエリパラメーター:page、pageSize、orderBy、orderByDirection
エージェント
エージェント一覧
GET /agents
利用可能なすべてのエージェントと、デフォルト設定を返します。各エージェントには、担当領域に合わせて最適化されたモデルと設定が事前に構成されています。
{
"id": 0,
"name": "Default",
"description": "General-purpose agent for any Android task.",
"llmModel": "google/gemini-3.1-flash-lite-preview",
"reasoning": true,
"vision": false,
"maxSteps": 100
}
エージェントのプリセットをモデル選択の参考にしてください。たとえば、ソーシャルメディア関連のタスクでは、Instagram/TikTok/X エージェントに設定されたモデルが役立つ場合があります。
認証情報
アプリのログイン認証情報を管理します。認証情報は、パッケージ名(アプリ)と認証情報名(アカウント)ごとに整理されています。タスクの実行時に認証情報を渡すと、エージェントが自動的にアプリにログインできます。
すべての認証情報を一覧表示
GET /credentials
クエリパラメーター:page(デフォルト:1)、pageSize(デフォルト:10)
認証済みユーザーのすべてのパッケージにわたる、すべての認証情報を返します。
パッケージを初期化
POST /credentials/packages
Content-Type: application/json
{ "packageName": "com.instagram.android" }
認証情報を追加する前に、パッケージを登録します。
パッケージの認証情報を一覧表示
GET /credentials/packages/{packageName}
指定したパッケージのすべての認証情報名とフィールドを返します。
認証情報を作成
POST /credentials/packages/{packageName}
Content-Type: application/json
パッケージ用のフィールドを含む、新しい名前付き認証情報を作成します。
認証情報を取得
GET /credentials/packages/{packageName}/credentials/{credentialName}
認証情報とそのすべてのフィールドを返します。
認証情報を削除
DELETE /credentials/packages/{packageName}/credentials/{credentialName}
認証情報とそのすべてのフィールドを削除します。
認証情報にフィールドを追加
POST /credentials/packages/{packageName}/credentials/{credentialName}/fields
Content-Type: application/json
{ "fieldType": "email", "value": "[email protected]" }
フィールドの種類:email、username、password、api_token、phone_number、two_factor_secret。
認証情報のフィールドを更新
PATCH /credentials/packages/{packageName}/credentials/{credentialName}/fields/{fieldType}
Content-Type: application/json
{ "value": "new-value" }
認証情報のフィールドを削除
DELETE /credentials/packages/{packageName}/credentials/{credentialName}/fields/{fieldType}
プロキシ設定
保存済みの SOCKS5 プロキシ設定を管理します。Cloud Phone または Physical Phone をプロビジョニングする前に、プロキシを設定する必要があります。サポートされているプロトコルは SOCKS5 のみです。
プロキシ設定を一覧表示
GET /proxies
アカウントに保存されているすべてのプロキシ設定を返します。
プロキシ設定を作成
POST /proxies
Content-Type: application/json
{
"name": "US Residential",
"host": "proxy.example.com",
"port": 1080,
"user": "username",
"password": "password",
"protocol": "socks5"
}
すべてのフィールドが必須です。
プロキシ設定を削除
DELETE /proxies/{proxyId}
保存済みのプロキシ設定を削除します。デバイスにすでに接続されているプロキシは切断されません。
Webhook(フック)
Webhook を通じてタスクイベントを購読します。イベント(タスクの作成、実行中、完了、失敗など)が発生すると、Mobilerun は指定した URL に POST を送信します。
フックを一覧表示
GET /hooks
クエリパラメーター:page(デフォルト:1)、pageSize(デフォルト:20)、orderBy(デフォルト:createdAt)、orderByDirection(デフォルト:desc)
フックを取得
GET /hooks/{hook_id}
Webhook を購読
POST /hooks/subscribe
Content-Type: application/json
{
"targetUrl": "https://example.com/webhook",
"events": ["created", "running", "completed", "failed", "cancelled"]
}
必須:targetUrl。任意:events(フィルターするタスクイベントのリスト)、service(受信サービス)。
フックを編集
POST /hooks/{hook_id}/edit
Content-Type: application/json
{
"events": ["completed", "failed"],
"state": "active"
}
フックのイベントフィルターまたは状態(active、disabled、deleted)を更新します。
購読を解除
POST /hooks/{hook_id}/unsubscribe
購読を完全に削除します。
サンプルデータを取得
GET /hooks/sample
サンプルの Webhook ペイロードデータを返します。テストやフィールドのマッピングに役立ちます。
フックを実行(Zapier)
POST /hooks/perform
Webhook ペイロードを処理します。Zapier 連携で使用されます。
フィードバック
Mobilerun プラットフォームの改善に役立つフィードバックを送信します。バグの特定やエージェントのパフォーマンス向上に重要です。
フィードバックを自動送信するタイミング:
- タスクが予期せず失敗したとき
- エージェントが正しく動作しない、または誤った結果を生成したとき
- プラットフォームのバグと思われる API エラーが発生したとき
taskId、エラーの詳細、および発生したことを含めてください
ユーザーからフィードバックの送信を求められたとき:
- 詳細(何が起きたか、どうなると期待していたか)をいくつか尋ねますが、回答を強く求めないでください
- 詳細を伝えたくない場合は、把握している情報だけで送信してください
POST /feedback
Content-Type: application/json
{
"title": "Task failed unexpectedly",
"feedback": "The agent got stuck on the login screen and timed out after 50 steps.",
"rating": 2,
"taskId": "uuid-of-related-task"
}
必須フィールド:
title-- 短い概要(3~100 文字)feedback-- 詳細な説明(10~4000 文字)rating-- 1~5
任意フィールド:
taskId-- 関連タスクの UUID
| ステータス | 意味 |
|---|---|
201 | フィードバックを送信しました |
400 | 検証エラー |
401 | API キーが無効、または指定されていません |
429 | レート制限 -- 1 日あたりの上限 15 件に達しました |
エラー処理
すべての API エラーは次の形式に従います。
{
"title": "Unauthorized",
"status": 401,
"detail": "Invalid API key.",
"errors": []
}
| エラー | 考えられる原因 | 対処方法 |
|---|---|---|
401 | API キーが無効または期限切れです | ユーザーに https://cloud.mobilerun.ai/api-keys でキーを確認するよう案内します |
POST /tasks の 402 | クレジットが不足しています | ユーザーはクレジットを追加するか、プランをアップグレードする必要があります |
"limit reached" を伴う 403 | プランの上限に達しています(同時接続デバイス数の上限) | ユーザーはデバイスを終了するか、プランをアップグレードする必要があります |
デバイス操作での 404 / 500 | デバイスが見つからないか、ID が無効です | デバイス ID を確認し、デバイス一覧を再取得します |
| デバイス一覧が空 | 接続されているデバイスがありません | Portal APK 経由で接続するようユーザーに案内します(references/setup-and-billing.md を参照) |
デバイスが disconnected | Portal アプリが終了しているか、スマートフォンがネットワークに接続されていません | ユーザーにスマートフォンを確認し、Portal を再度開くよう案内します |
POST /devices での請求/プランエラー | デバイスのサブスクリプションがありません | https://cloud.mobilerun.ai/billing でデバイスを追加するようユーザーに案内します |
| 有効なデバイスで操作が失敗する | デバイスが使用中、ロック中、または応答していない可能性があります | まずスクリーンショットを撮って状態を確認します |
よくある問題(デバイスの切断、キーボードの不具合、スクリーンショットのエラー、アプリのインストール問題など)の詳しいトラブルシューティングについては、references/troubleshooting.md を参照してください。
参考資料
- references/setup-and-billing.md — 次の場合に読みます:初回セットアップ(認証、Portal APK、デバイス接続)を支援するとき、請求/料金/クレジットに関する質問に回答するとき、またはウェブフックを設定するとき。
- references/setup-guide.md — Cloud または Physical Phones をプロビジョニングするときに読みます。プロキシ、Google アカウント、アプリのインストールに関するベストプラクティスが記載されています。
- references/troubleshooting.md — デバイス操作が失敗するとき、API 呼び出しで予期しないエラーが返されるとき、またはユーザーからスマートフォン/Portal の問題が報告されたときに読みます。
- references/use-cases.md — Mobilerun で何ができるかユーザーが分からないときに読みます。
- references/security.md — データの取り扱い、認証情報、デバイスの権限について記載されています。
- references/changelog.md — バージョン履歴と主な変更点が記載されています。