mcpField
A
android-device-automation

android-device-automation

github.com/web-infra-devエージェントワークフロー3185.8k 回インストール11 週間前に更新
リポジトリ

android-device-automation について

スクリーンショットと自然言語コマンドで Android デバイスを操作する Midscene スキルです。Android コマンドラインを使い、AI エージェントが順に画面を確認し、操作と検証を行います。

主な機能

  1. 01自然言語による UI 操作
  2. 02画面の撮影と分析
  3. 03画面状態のアサーション
  4. 04一時的な UI の記録
  5. 05ADB コマンドとレポート

活用シーン

  1. 01Android アプリで複数手順を実行
  2. 02QA で表示状態を確認
  3. 03一時的な通知や画面遷移を記録
  4. 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 デバイスの自動化

重要なルール — 違反するとワークフローが破綻します:

  1. midscene コマンドをバックグラウンドで実行しないでください。 各コマンドは同期的に実行し、次の操作を決める前に出力(特にスクリーンショット)を確認してください。バックグラウンド実行では、スクリーンショットの確認・分析・操作のループが破綻します。
  2. midscene コマンドは一度に 1 つだけ実行してください。 前のコマンドが完了するまで待ち、スクリーンショットを確認してから次の操作を決めてください。複数のコマンドを連結して実行しないでください。
  3. 各コマンドが完了するのに十分な時間を確保してください。 Midscene のコマンドでは AI による推論と画面操作が行われるため、一般的なシェルコマンドより時間がかかることがあります。通常、コマンドの実行には約 1 分かかります。複雑な act コマンドでは、さらに時間がかかる場合があります。
  4. 終了前に必ずタスクの結果を報告してください。 自動化タスクの完了後、重要なデータ、完了した操作、撮影したスクリーンショット、関連する調査結果などを含めて、ユーザーに結果を積極的に要約して伝える必要があります。最後の自動化ステップの後に何も伝えずに終了しないでください。ユーザーは 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 コマンドは呼び出し間で状態を保持しないため、次のパターンに従ってください。

  1. 接続してセッションを確立します
  2. 対象アプリを起動してスクリーンショットを撮影し、現在の状態を確認します。アプリが起動しており、画面上に表示されていることを確認してください。
  3. act を使って目的の操作または対象に基づく指示を実行します。結果の画面状態には assert を使うか、一時的な状態を扱うワークフローでは専用のターミナルで record start --output ... を実行したままにし、Ctrl+C で停止してから assert --record を使います。
  4. 完了したら切断します
  5. 結果を報告します — 実行した内容を要約し、タスク中に得られた主な知見やデータを提示し、生成されたファイル(スクリーンショット、ログなど)があればパスとともに列挙します

ベストプラクティス

  1. このスキルを使う前に対象アプリを前面に表示してください:効率を高めるには、midscene コマンドを実行する前に、ADB(例:adb shell am start -n <package/activity>)を使ってアプリを起動してください。その後、スクリーンショットを撮影し、アプリが実際に前面に表示されていることを確認します。視覚的に確認してから、このスキルを使った UI 自動化を進めてください。ADB コマンドは、midscene を使ってアプリに移動して開くより大幅に高速です。
  2. UI 要素を具体的に指定してください:曖昧な説明ではなく、明確で具体的な詳細を示します。「トグル」ではなく、「右側にある Wi-Fi の切り替えスイッチ」のように指定してください。
  3. 可能な場合は位置を説明してください:位置を説明して対象要素を特定しやすくします(例:「右上にある検索アイコン」、「リストの3番目の項目」)。
  4. バックグラウンドで実行しないでください:すべての midscene コマンドは同期的に実行する必要があります。バックグラウンドでの実行は、スクリーンショットの撮影、分析、操作のループを妨げます。
  5. 関連する操作は1つの act コマンドにまとめてください:同じアプリ内で連続した操作を行う場合は、複数のコマンドに分けず、1つの act プロンプトにまとめます。たとえば、「設定を開き、Wi-Fi をタップしてオンにする」は、3回ではなく1回の act 呼び出しで実行してください。これにより、コマンドの往復や不要なスクリーンショット撮影・分析のサイクルを減らし、大幅に高速化できます。
  6. スクリーンショットの撮影を高速化する必要がある場合は scrcpy を使用してください:通常の Android スクリーンショットの撮影が遅い、不安定、または環境によってブロックされる場合は、該当する各コマンドに --use-scrcpy を追加します。
  7. 適切な検証タイミングを選んでください:現在の画面には assert --prompt "..." を使用します。トースト、バナー、アニメーション、または画面遷移の場合は、専用のターミナルで record start --output ... を実行し、操作を行ってから Ctrl+C で録画を停止します。保存先のメッセージが表示されるのを待ち、その後、成果物を assert --record に渡します。
  8. 完了後は必ず結果を報告してください:自動化タスクの終了後、ユーザーから尋ねられるのを待たずに、結果を必ず自発的に提示してください。これには、(1)ユーザーの元の質問への回答または依頼されたタスクの結果、(2)実行中に得られた、または確認された主なデータ、(3)スクリーンショットやその他の生成ファイルとそのパス、(4)実施した手順の簡単な要約が含まれます。最後の自動化コマンドの後に、結果を報告せずに終了しないでください。ユーザーは1回のやり取りで完全な結果を受け取ることを期待しています。
  9. 参照画像が提供されている場合は tap --locate を優先してください:ユーザーがスクリーンショット、アイコン、またはロゴを共有し、その画像と完全に一致する対象を指定している場合は、act --prompt だけに頼らず、{ "prompt": "...", "images": [...] } のようなマルチモーダルな locate JSON オブジェクトとともに 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 による高速なスクリーンショット取得を有効にできます。

コメント