Android Viewer について
Android Viewerは、AIコーディングの作業で人とエージェントがAndroidエミュレーターを共同操作するための、ブラウザー用ライブビューアー兼MCPサーバーです。端末へのアプリ導入なしで画面を配信し、折りたたみ姿勢も扱えます。
主な機能
- 01ブラウザーでのエミュレーター画面配信
- 02タップ、スワイプ、キー、テキスト入力
- 03AVDの一覧表示と起動
- 04回転と折りたたみ姿勢の制御
- 05フル解像度のスクリーンショット
活用シーン
- 01エージェント操作中のアプリ確認
- 02回転方向ごとの画面テスト
- 03折りたたみエミュレーターの表示切替
- 04AVDの起動と選択
MCP 対応
MCPサーバーはデバイス一覧、起動、状態取得、スクリーンショット、入力操作をツールとして公開します。ビューアー起動中は、エージェントの操作がライブセッションに反映されます。
設定
ローカルサーバーの設定はどのクライアントでも共通です。コピーしてクライアントの MCP 設定ファイルに貼り付けてください。
npx -y @acertijosapps/android-viewerANDROID_VIEWER_URLViewer to show actions live (default http://localhost:8093); without it, adb is used directlyANDROID_HOMEAndroid SDK location, if adb and emulator are not found automaticallyローカルサーバーにはマシン上の実行環境(Node.js 18 以上など)が必要です。設定ファイルの場所はクライアントごとに異なります。
ツール
10掲載時のツール一覧 · 1 週間前に更新
このツールにパラメーターはありません。
詳細
@acertijosapps/android-viewer
ブラウザーで Android エミュレーターをライブ表示するビューアーと、AI エージェントが操作できる MCP サーバーです。 Claude Code などの AI コーディングツールのブラウザーペイン向けに作られており、折りたたみ式端末の姿勢も含め、あなたとエージェントが同じエミュレーターをリアルタイムで表示し、操作できます。
- ライブ動画:WebSocket 経由の
adb exec-out screenrecord(H.264)を、WebCodecs でブラウザー内でデコードします。 - 入力:クリック、ドラッグ、長押し、スクロールを
adb shell inputコマンドに変換します。 - マシン上のすべての AVD:実行中のエミュレーターを選ぶか、停止中のエミュレーターをビューアーから起動できます。
- エミュレーターのコントロール:戻る、ホーム、最近使ったアプリ、電源、音量、回転、フル解像度のスクリーンショット。
- 折りたたみ式端末:閉じる/半開き/開く/背面ディスプレイ。エミュレーターでは、エミュレーター標準のコントロールと同様にシミュレートされたヒンジを動かします。折りたたんだり回転したりすると、ストリームはアクティブなディスプレイに追従します。
- MCP サーバー:同じ操作をツールとして提供するため、エージェントのタップがビューアーにリアルタイムで表示されます。
- デバイスへのインストール不要:APK もサーバープッシュも不要で、必要なのは
adbだけです。
要件
- Node.js 18 以降。
- Android SDK Platform-Tools(
adb)。AVD の一覧表示と起動には emulator も必要です。ANDROID_HOME、ANDROID_SDK_ROOT、またはデフォルトの SDK の場所から検出します。ADBとEMULATORで上書きできます。 - WebCodecs に対応したブラウザー(Chromium ベースのブラウザー、Safari 16.4 以降、Firefox 130 以降)。
- macOS、Linux、Windows で動作します。
クイックスタート
npx @acertijosapps/android-viewer
http://localhost:8093 を開いてデバイスを選びます。ディープリンク:?avd=Pixel_10 または ?serial=emulator-5554。
android-viewer [options] Start the viewer
android-viewer mcp [options] Start the MCP server on stdio
-p, --port <port> Viewer port (default 8093, env PORT)
--host <host> Interface to bind (default 127.0.0.1, env HOST)
--viewer-url <url> Viewer the MCP talks to (default http://localhost:8093)
その他の環境変数:MAX_DIM(エンコード動画の長辺。デフォルトは 1024)、BIT_RATE(デフォルトは 6M)、SCREENSHOT_MAX(MCP スクリーンショットの長辺。デフォルトは 1024)、DEBUG=1(すべての入力コマンドをログに記録)。
AI エージェントと使用する(MCP)
Claude Code:
claude mcp add android-viewer -- npx -y @acertijosapps/android-viewer mcp
その他の MCP クライアント:
{
"mcpServers": {
"android-viewer": {
"command": "npx",
"args": ["-y", "@acertijosapps/android-viewer", "mcp"]
}
}
}
公式 MCP Registry にも io.github.acertijosapps/android-viewer として掲載されています。
エージェントの操作を確認するには、ビューアーを起動したままにしてください(npx @acertijosapps/android-viewer)。ビューアーが起動していない場合、MCP は adb を通じてデバイスを直接操作します。
| ツール | 機能 |
|---|---|
list_devices | マシン上の AVD(実行中の場合は serial と booted を含む)とその他の adb デバイスを一覧表示します |
launch_avd | 名前を指定して AVD を起動します |
get_state | ディスプレイサイズ、回転、現在の姿勢、利用可能な姿勢、ビューアーの URL を表示します |
screenshot | アクティブなディスプレイの PNG。長辺は 1024 px 以下です |
tap | input tap |
swipe | input swipe。開始点と終了点が同じで 500 ms 以上の場合は長押しになります |
press_key | back、home、recents、power、wakeup、volup、voldown、enter、delete、tab、escape |
type_text | input text(印字可能な ASCII) |
rotate | 左または右に 90°回転します(エミュレーター) |
set_posture | closed、half_opened、opened、rear_display、状態 ID、または reset を指定します。新しい状態を返します |
座標はスクリーンショット全体に対して 0–1 に正規化されるため(x = pixel_x / image_width)、どの姿勢や向きでも使用できます。接続されているデバイスが 1 台だけの場合、serial は省略できます。
Claude Code のブラウザーペインで使用する
.claude/launch.json にビューアーを追加し、preview_start android-viewer で開きます。
{
"version": "0.0.1",
"configurations": [
{
"name": "android-viewer",
"runtimeExecutable": "npx",
"runtimeArgs": ["-y", "@acertijosapps/android-viewer"],
"port": 8093,
"autoPort": false
}
]
}
HTTP API
MCP はビューアーの API を使用しており、同じ API を呼び出すこともできます。serial はクエリ文字列または本文に指定します。デバイスが 1 台の場合は省略できます。POST リクエストには content-type: application/json とローカルオリジンが必要なため、他のウェブサイトからデバイスを操作することはできません。
| エンドポイント | |
|---|---|
GET /api/devices | [{ avd, serial, booted, model }]:serial: null = 停止中、booted: null = 時間内に応答なし |
GET /api/state | ディスプレイサイズ、回転、displayId、姿勢、利用可能な姿勢 |
GET /api/screenshot?max=<px> | PNG。実際の画面サイズは X-Screen-Width / X-Screen-Height で確認できます |
POST /api/tap | { x, y } |
POST /api/swipe | { x1, y1, x2, y2, ms } |
POST /api/key | { key } |
POST /api/text | { text } |
POST /api/posture | { posture } |
POST /api/rotate | { direction: "left" | "right" } |
POST /api/launch | { avd } |
ビューアーのタブがデバイスを表示している場合、操作はそのライブセッション経由で行われます。ビューアーはすぐに更新され、ジェスチャーによってフレームが生成されない場合はウォッチドッグがストリームを再起動します。
動作の仕組み
- デバイスごとに 1 つのセッションを作成し、すべてのタブで共有します。最後のタブが閉じると停止します。
- 1 秒ごとに
dumpsys display(サイズ、回転、論理ディスプレイ 0 の背後にある物理ディスプレイ)とcmd device_state stateを読み取ります。ディスプレイが変わると、状態が安定するまで待ってから、新しいパネルの--display-idを指定してscreenrecordを再起動します。デバイスを折りたたむとパネルが切り替わります。 screenrecordは画面が変化したときにのみフレームを出力するため、ビューアーは途中参加者向けに最後の IDR 以降の GOP を保持し、動画がない間はスクリーンショットを送信します。- デバイスごとに実行する
screenrecordは 1 つだけです。2 つ実行すると、エミュレーターのソフトウェアエンコーダーが枯渇します(err=-38)。クライアントからの再起動要求にはレート制限が適用されます。 - スクリーンショットには生の
screencapを使用します(負荷が高いとき、エミュレーター内での PNG 圧縮は遅いためです)。面積平均で縮小し、ネイティブ依存関係なしでnode:zlibを使って PNG にエンコードします。
制限事項
- ドラッグはリアルタイムではなく、指を離したときに送信されます(実際の継続時間を指定した
input swipeを 1 回実行します)。 - キーボードのパススルーとオーディオにはまだ対応していません。
type_textとpress_keyを使用してください。 - scrcpy などのネイティブクライアントより遅延が大きくなります。
- 複数のエミュレーターで同時に録画すると、ソフトウェアエンコーダーの動作が遅くなります。空き RAM が少ない場合(エミュレーターがスワップにページアウトされている場合)、
adb shellの呼び出しごとに数秒かかることがあります。 - アプリが独自の姿勢を要求する場合(
DeviceStateManager.requestState)、フォアグラウンドにある間はset_postureよりもその要求が優先されます。 - 物理ディスプレイが 1 つだけの
Flip_Horizontal_Foldスタイルの AVD は、閉じると状態が変わりますが、表示される画像は変わりません。
ws-scrcpy を使わない理由
最初に ws-scrcpy を試しました。ストリーミングと入力は機能しますが、姿勢を変更すると、再読み込みするまで動画がフリーズします(scrcpy 1.19 のサーバーが以前のディスプレイにバインドされたままになるためです)。また、姿勢を制御する機能もありません。
貢献
ブランチモデル(main · beta)、Conventional Commits、リリースについては CONTRIBUTING.md に記載されています。変更内容は CHANGELOG.md に記載されています。
作者
AcertijosApps が作成しました。他のライブラリについては acertijosapps.com/librerias をご覧ください。
質問や提案:[email protected]、または issue を作成してください。
ライセンス
MIT
コメント
AI アプリケーションが外部のツールやデータソースに統一的な方法で接続するためのオープンなプロトコルです。クライアントはモデルとの対話を担い、MCP サーバーはツール・リソース・プロンプトテンプレートを提供します。標準メッセージでやり取りするため、1 つのサーバーを複数のクライアントで再利用できます。