android-device-automation について
スクリーンショットと自然言語コマンドで Android デバイスを操作する Midscene スキルです。Android コマンドラインを使い、AI エージェントが順に画面を確認し、操作と検証を行います。
主な機能
- 01自然言語による UI 操作
- 02画面の撮影と分析
- 03画面状態のアサーション
- 04一時的な UI の記録
- 05ADB コマンドとレポート
活用シーン
- 01Android アプリで複数手順を実行
- 02QA で表示状態を確認
- 03一時的な通知や画面遷移を記録
- 04ADB コマンドでデバイス情報を確認
MCP 対応
Android コマンドラインの各コマンドは MCP ツールに対応し、AI エージェントがスクリーンショットを基にデバイスを操作します。
インストール
コマンドをコピーしてターミナルで実行します。
npx skills add https:/ / github.com/ web-infra-dev/ midscene-skills --skill android-device-automationインストール後、Claude Code で/android-device-automationを入力して読み込まれたか確認します。
詳細
Android デバイスの自動化
重要なルール — 違反するとワークフローが破綻します:
- midscene コマンドをバックグラウンドで実行しないでください。 各コマンドは同期的に実行し、次の操作を決める前に出力(特にスクリーンショット)を確認してください。バックグラウンド実行では、スクリーンショットの確認・分析・操作のループが破綻します。
- midscene コマンドは一度に 1 つだけ実行してください。 前のコマンドが完了するまで待ち、スクリーンショットを確認してから次の操作を決めてください。複数のコマンドを連結して実行しないでください。
- 各コマンドが完了するのに十分な時間を確保してください。 Midscene のコマンドでは AI による推論と画面操作が行われるため、一般的なシェルコマンドより時間がかかることがあります。通常、コマンドの実行には約 1 分かかります。複雑な
actコマンドでは、さらに時間がかかる場合があります。- 終了前に必ずタスクの結果を報告してください。 自動化タスクの完了後、重要なデータ、完了した操作、撮影したスクリーンショット、関連する調査結果などを含めて、ユーザーに結果を積極的に要約して伝える必要があります。最後の自動化ステップの後に何も伝えずに終了しないでください。ユーザーは 1 回のやり取りで完了した応答を期待しています。
npx -y @midscene/android@1 を使用して Android デバイスを自動化します。各 CLI コマンドは MCP ツールに直接対応します。AI エージェントであるあなたが、スクリーンショットに基づいて実行する操作を判断します。
act でできること
Android で 1 回の act 呼び出しを行う間に、Midscene はタップ、ダブルタップ、長押し、文字入力、テキストの消去、任意の方向へのスクロールやスワイプ、下方向への引っ張り更新、項目のドラッグ、2 本指でのズーム、キーの押下、さらに「戻る」「ホーム」「最近使ったアプリ」などのシステムナビゲーションを、現在表示されている画面から実行できます。
前提条件
Midscene では、視覚的なグラウンディング能力の高いモデルが必要です。次の環境変数をシステム環境変数、または現在の作業ディレクトリにある .env ファイルで設定してください(Midscene は .env を自動的に読み込みます)。
MIDSCENE_MODEL_API_KEY="your-api-key"
MIDSCENE_MODEL_NAME="model-name"
MIDSCENE_MODEL_BASE_URL="https://..."
MIDSCENE_MODEL_FAMILY="family-identifier"
Gemini(Gemini-3-Flash)の例:
MIDSCENE_MODEL_API_KEY="your-google-api-key"
MIDSCENE_MODEL_NAME="gemini-3-flash"
MIDSCENE_MODEL_BASE_URL="https://generativelanguage.googleapis.com/v1beta/openai/"
MIDSCENE_MODEL_FAMILY="gemini"
Qwen 3.5 の例:
MIDSCENE_MODEL_API_KEY="your-aliyun-api-key"
MIDSCENE_MODEL_NAME="qwen3.5-plus"
MIDSCENE_MODEL_BASE_URL="https://dashscope.aliyuncs.com/compatible-mode/v1"
MIDSCENE_MODEL_FAMILY="qwen3.5"
MIDSCENE_MODEL_REASONING_ENABLED="false"
# If using OpenRouter, set:
# MIDSCENE_MODEL_API_KEY="your-openrouter-api-key"
# MIDSCENE_MODEL_NAME="qwen/qwen3.5-plus"
# MIDSCENE_MODEL_BASE_URL="https://openrouter.ai/api/v1"
Doubao Seed 2.0 Lite の例:
MIDSCENE_MODEL_API_KEY="your-doubao-api-key"
MIDSCENE_MODEL_NAME="doubao-seed-2-0-lite"
MIDSCENE_MODEL_BASE_URL="https://ark.cn-beijing.volces.com/api/v3"
MIDSCENE_MODEL_FAMILY="doubao-seed"
よく使用されるモデル:Doubao Seed 2.0 Lite、Qwen 3.5、Zhipu GLM-4.6V、Gemini-3-Pro、Gemini-3-Flash。
モデルが設定されていない場合は、ユーザーに設定を依頼してください。対応プロバイダーについては、モデルの設定を参照してください。
コマンド
Android CLI 共通フラグ
Android エージェントを作成または使用するコマンド(connect、take_screenshot、act、assert、tap など)で、次のフラグを使用してください。
--device-id <id>:adb devicesに表示される特定の Android デバイスを対象にします。--use-scrcpy:scrcpy による高速スクリーンショットを有効にします。通常のスクリーンショット取得が遅い場合や不安定な場合に使用してください。CLI の呼び出しはステートレスであるため、scrcpy によるスクリーンショットを使う Android の Midscene コマンドごとに、このフラグを指定してください。
デバイスに接続する
npx -y @midscene/android@1 connect
npx -y @midscene/android@1 connect --device-id emulator-5554
npx -y @midscene/android@1 connect --device-id emulator-5554 --use-scrcpy
アプリまたは URL を起動する
タスクの残りを始める前に、確実に決まった状態から開始したい場合は、専用の起動ステップを使用してください。
npx -y @midscene/android@1 launch --uri https://www.ebay.com
npx -y @midscene/android@1 launch --uri com.android.settings
npx -y @midscene/android@1 launch --uri com.android.settings/.Settings
Android シェルコマンドを直接実行する
表示される UI の操作では適切に表現できない、より低レベルなデバイス制御が必要な場合に使用してください。
npx -y @midscene/android@1 runadbshell --command "dumpsys battery"
このコマンドは、接続されたデバイス上で adb shell に転送されます。実際には、基盤となるコマンドは adb -s <deviceId> shell dumpsys battery です。環境によっては、adb -P 5037 -s <deviceId> shell dumpsys battery のように、既定の ADB サーバーポートも含まれることがあります。
スクリーンショットを撮る
npx -y @midscene/android@1 take_screenshot
npx -y @midscene/android@1 take_screenshot --device-id emulator-5554 --use-scrcpy
スクリーンショットを撮ったら、保存された画像ファイルを読み込み、次の操作を決める前に現在の画面の状態を確認してください。
操作を実行する
act を使用してデバイスを操作し、結果を取得します。タップ、文字入力、スクロール、スワイプ、待機、ナビゲーションなど、すべての UI 操作を内部で自律的に処理します。そのため、タスクを細かい手順に分けるのではなく、複雑で高レベルなタスク全体として指示してください。自然な言葉で、実行したいことと望ましい結果を説明してください。
# specific instructions
npx -y @midscene/android@1 act --prompt "type hello world in the search field and press Enter"
npx -y @midscene/android@1 act --prompt "long press the message bubble and tap Delete in the popup menu"
npx -y @midscene/android@1 act --device-id emulator-5554 --use-scrcpy --prompt "type hello world in the search field and press Enter"
# or target-driven instructions
npx -y @midscene/android@1 act --prompt "open Settings and navigate to Wi-Fi settings, tell me the connected network name"
現在の画面状態を検証する
assert を使用して、現在の画面が自然言語の条件を満たしているか検証します。UI 操作は実行せず、表示されている画面の状態を確認し、アサーションが真の場合にのみ成功します。検証、QA チェック、および act の後の最終状態の確認に使用します。
npx -y @midscene/android@1 assert --prompt "there is a login button visible"
npx -y @midscene/android@1 assert --prompt "the settings screen shows Wi-Fi and Bluetooth options"
npx -y @midscene/android@1 assert --device-id emulator-5554 --prompt "the app shows a successful login message"
npx -y @midscene/android@1 assert --device-id emulator-5554 --use-scrcpy --prompt "the app shows a successful login message"
デフォルトでは、アサーションに失敗すると AI が生成した理由がスローされます。代わりにカスタムエラーメッセージをスローするには --message を渡します。QA や CI のログに意図した結果を表示する場合に便利です。
npx -y @midscene/android@1 assert \
--prompt "the order confirmation screen is visible" \
--message "the order should be confirmed after tapping Pay"
アサーションで参照画像(アイコン、ロゴ、スクリーンショット)との比較が必要な場合は、URL/パスに --image を、表示名に --image-name を渡します。各 --image には http(s) リンク、data: URI、またはローカルファイルパスを指定できます。複数の画像を添付する場合は、両方のフラグを対応する順番で繰り返します。モデルが URL に直接アクセスできない場合は、--convertHttpImage2Base64 true を追加します。@midscene/[email protected]+ が必要です。
npx -y @midscene/android@1 assert \
--prompt "the visible app icon matches the supplied reference image" \
--image "https://github.githubassets.com/assets/GitHub-Mark-ea2971cee799.png" \
--image-name "icon" \
--convertHttpImage2Base64 true
# or with a local file
npx -y @midscene/android@1 assert \
--prompt "the header on screen matches the local screenshot" \
--image "./fixtures/header.png" \
--image-name "header"
# multiple reference images — pair --image and --image-name by order
npx -y @midscene/android@1 assert \
--prompt "the screen shows both the app icon and the header" \
--image "./fixtures/icon.png" --image-name "icon" \
--image "./fixtures/header.png" --image-name "header"
一時的な UI を記録して検証する
トースト、読み込みバナー、アニメーション、トランジションなど、現在の画面に対するアサーションを実行する前に消える可能性がある状態を検証する場合は、記録を使用します。
# Terminal 1: keep this foreground command running
npx -y @midscene/android@1 record start \
--device-id emulator-5554 --use-scrcpy \
--output ./submission-observation.json
# Terminal 2, while Terminal 1 records
npx -y @midscene/android@1 act --device-id emulator-5554 \
--prompt "tap the Submit button"
# Send Ctrl+C to Terminal 1 and wait for the saved-path message, then assert
npx -y @midscene/android@1 assert --device-id emulator-5554 \
--record ./submission-observation.json \
--prompt "a success toast appeared during submission"
record start にターゲットフラグ、キャプチャフラグ、--output を渡してから、Recording. Press Ctrl+C to stop and save. が表示されるまで待ちます。レコーダーは専用ターミナルでフォアグラウンドプロセスとして実行し、シェルの & は絶対に追加しないでください。操作は手動で行うか、2 つ目のターミナルから実行し、レコーダーに Ctrl+C を送信して、保存されたパスが表示されるまで待ってからアサーションを実行します。--use-scrcpy を指定すると、より高速な連続フレームソースを使用します。指定しない場合、記録は定期的なスクリーンショットにフォールバックします。任意のキャプチャフラグは --interval-ms、--max-frames、--watchdog-ms です。--max-frames はサンプリングするフレーム数の上限を設定します。マニフェストには、代表となる最後のフレームが追加で 1 枚含まれる場合があります。デフォルトでは、ウォッチドッグにより 5 分後に記録が確定して保存されます。--watchdog-ms 0 を指定すると、この安全制限が無効になります。出力は JSON マニフェストと、隣接する <name>.frames 画像ディレクトリであり、エンコードされた動画やアーカイブではありません。マニフェストには相対 JPEG/PNG パスが含まれ、base64 の画像データ本体は含まれません。JSON ファイルと画像ディレクトリは一緒に保管または移動し、JSON のパスを assert --record に渡します。現在の画面だけを確認する場合は、--record を付けずに通常の assert を使用します。
正確なターゲット指定に参照画像を使用する
ユーザーがスクリーンショット、アイコン、ロゴ、参照画像を提供し、視覚的に正確な一致を求めている場合は、一般的な act --prompt ではなく、tap --locate を優先します。--locate は JSON として渡します。prompt でターゲットを説明し、images で名前付き参照画像を指定します。画像 URL にモデルが直接アクセスできない可能性がある場合は、convertHttpImage2Base64: true が便利です。
npx -y @midscene/android@1 tap --locate '{
"prompt": "tap the area contains the image",
"images": [
{
"name": "target image",
"url": "https://github.githubassets.com/assets/GitHub-Mark-ea2971cee799.png"
}
],
"convertHttpImage2Base64": true
}'
同じ locate の JSON 形式は、locate パラメーターを受け取る他のコマンドでも使用できます。
切断
npx -y @midscene/android@1 disconnect
レポートファイルを利用する
生成された HTML レポートは、まず人が読む場合におすすめです。各操作の段階的な実行詳細と再生動画が含まれているため、何が起きたかを理解し、問題をトラブルシューティングするのがはるかに簡単になります。
別のスキルやツールでレポートを利用する必要がある場合は、まず同じプラットフォーム CLI パッケージの report-tool で変換します。LLM ベースのワークフローでは Markdown を優先してください。レポートをプログラムで処理する必要がある場合は JSON を使用します。
npx -y @midscene/android@1 report-tool --action to-markdown --htmlPath ./midscene_run/report/.../index.html --outputDir ./output-markdown
npx -y @midscene/android@1 report-tool --action split --htmlPath ./midscene_run/report/.../index.html --outputDir ./output-data
ワークフローパターン
CLI コマンドは呼び出し間で状態を保持しないため、次のパターンに従ってください。
- 接続してセッションを確立します
- 対象アプリを起動してスクリーンショットを撮影し、現在の状態を確認します。アプリが起動しており、画面上に表示されていることを確認してください。
actを使って目的の操作または対象に基づく指示を実行します。結果の画面状態にはassertを使うか、一時的な状態を扱うワークフローでは専用のターミナルでrecord start --output ...を実行したままにし、Ctrl+C で停止してからassert --recordを使います。- 完了したら切断します
- 結果を報告します — 実行した内容を要約し、タスク中に得られた主な知見やデータを提示し、生成されたファイル(スクリーンショット、ログなど)があればパスとともに列挙します
ベストプラクティス
- このスキルを使う前に対象アプリを前面に表示してください:効率を高めるには、midscene コマンドを実行する前に、ADB(例:
adb shell am start -n <package/activity>)を使ってアプリを起動してください。その後、スクリーンショットを撮影し、アプリが実際に前面に表示されていることを確認します。視覚的に確認してから、このスキルを使った UI 自動化を進めてください。ADB コマンドは、midscene を使ってアプリに移動して開くより大幅に高速です。 - UI 要素を具体的に指定してください:曖昧な説明ではなく、明確で具体的な詳細を示します。「トグル」ではなく、「右側にある Wi-Fi の切り替えスイッチ」のように指定してください。
- 可能な場合は位置を説明してください:位置を説明して対象要素を特定しやすくします(例:「右上にある検索アイコン」、「リストの3番目の項目」)。
- バックグラウンドで実行しないでください:すべての midscene コマンドは同期的に実行する必要があります。バックグラウンドでの実行は、スクリーンショットの撮影、分析、操作のループを妨げます。
- 関連する操作は1つの
actコマンドにまとめてください:同じアプリ内で連続した操作を行う場合は、複数のコマンドに分けず、1つのactプロンプトにまとめます。たとえば、「設定を開き、Wi-Fi をタップしてオンにする」は、3回ではなく1回のact呼び出しで実行してください。これにより、コマンドの往復や不要なスクリーンショット撮影・分析のサイクルを減らし、大幅に高速化できます。 - スクリーンショットの撮影を高速化する必要がある場合は scrcpy を使用してください:通常の Android スクリーンショットの撮影が遅い、不安定、または環境によってブロックされる場合は、該当する各コマンドに
--use-scrcpyを追加します。 - 適切な検証タイミングを選んでください:現在の画面には
assert --prompt "..."を使用します。トースト、バナー、アニメーション、または画面遷移の場合は、専用のターミナルでrecord start --output ...を実行し、操作を行ってから Ctrl+C で録画を停止します。保存先のメッセージが表示されるのを待ち、その後、成果物をassert --recordに渡します。 - 完了後は必ず結果を報告してください:自動化タスクの終了後、ユーザーから尋ねられるのを待たずに、結果を必ず自発的に提示してください。これには、(1)ユーザーの元の質問への回答または依頼されたタスクの結果、(2)実行中に得られた、または確認された主なデータ、(3)スクリーンショットやその他の生成ファイルとそのパス、(4)実施した手順の簡単な要約が含まれます。最後の自動化コマンドの後に、結果を報告せずに終了しないでください。ユーザーは1回のやり取りで完全な結果を受け取ることを期待しています。
- 参照画像が提供されている場合は
tap --locateを優先してください:ユーザーがスクリーンショット、アイコン、またはロゴを共有し、その画像と完全に一致する対象を指定している場合は、act --promptだけに頼らず、{ "prompt": "...", "images": [...] }のようなマルチモーダルなlocateJSON オブジェクトとともにtap --locateを使用してください。
例 — ポップアップメニューの操作:
npx -y @midscene/android@1 act --prompt "long press the message bubble and tap Delete in the popup menu"
npx -y @midscene/android@1 take_screenshot
例 — フォームの操作:
npx -y @midscene/android@1 act --prompt "fill in the username field with 'testuser' and the password field with 'pass123', then tap the Login button"
npx -y @midscene/android@1 take_screenshot
精度の向上(Deep Locate / Deep Think)
Midscene でタスクの実行が難しい場合に役立つ、任意のグローバルフラグが 2 つあります。コマンド内のどこに置いてもかまいません(サブコマンドの前後どちらでも可)。一度設定すると、該当する操作でデフォルトとして使用されるため、呼び出しごとにパラメーターを渡す必要はありません。
--deep-locate— 追加の視覚的推論を行い、対象要素の位置を正確に特定します。アクションが誤った位置を操作する場合(位置のずれ/オフセット)に使用してください。tap --locateやact内で行われる位置特定など、要素の位置を特定するすべての操作に適用されます。--deep-think— より深い推論(豊富なコンテキストとサブゴールへの分解)を用いてactの計画を立てます。複雑で複数の手順があるactの指示に使用してください。計画にのみ影響します。
どちらも速度を少し犠牲にして結果を向上させます。また、組み合わせて使用できます。
# more accurate element location (helps act's internal locating too)
npx -y @midscene/android@1 act --deep-locate --prompt "tap the small overflow (⋮) icon in the top-right corner"
# deeper planning for a complex, multi-step act
npx -y @midscene/android@1 act --deep-think --prompt "open Settings, go to Wi-Fi, and connect to the network named Office"
# combine both
npx -y @midscene/android@1 act --deep-locate --deep-think --prompt "fill in the signup form and tap Submit"
トラブルシューティング
| 問題 | 解決策 |
|---|---|
| ADB が見つからない | Android SDK Platform Tools をインストールしてください:brew install android-platform-tools(macOS の場合)、または developer.android.com からダウンロードしてください。 |
| デバイスが一覧に表示されない | USB 接続を確認し、開発者向けオプションで USB デバッグが有効になっていることを確認してから、adb devices を実行してください。 |
| デバイスに「unauthorized」と表示される | デバイスのロックを解除し、USB デバッグの認証プロンプトを承認してください。その後、もう一度 adb devices を実行してください。 |
| デバイスに「offline」と表示される | USB ケーブルを取り外して、再接続してください。adb kill-server && adb start-server を実行してください。 |
| コマンドがタイムアウトする | デバイスの画面がオフまたはロックされている可能性があります。adb shell input keyevent KEYCODE_WAKEUP でデバイスを起動し、ロックを解除してください。 |
| API キーのエラー | .env ファイルに MIDSCENE_MODEL_API_KEY=<your-key> が含まれていることを確認してください。モデルの設定を参照してください。 |
@midscene/* の依存関係のバージョンが古い | npm ls @midscene/android @midscene/core @midscene/shared(または pnpm why @midscene/android)でローカルのバージョンを確認してください。npm view @midscene/android version、npm view @midscene/core version、npm view @midscene/shared version を使って最新バージョンと比較してください。必要に応じてアップグレードしてください(npm i @midscene/android@latest @midscene/core@latest @midscene/shared@latest)。 |
| 対象デバイスが違う | 複数のデバイスが接続されている場合は、--device-id <id> フラグを使用してください。 |
| スクリーンショットの取得が遅い、または不安定 | Android Midscene コマンドに --use-scrcpy を追加すると、scrcpy による高速なスクリーンショット取得を有効にできます。 |