# serve-avd The `npx serve` of Android Emulators. Host your emulator for use with Agent tools like Codex, Cursor, or Claude Desktop — locally, over your LAN, or host on a remote machine and tunnel anywhere. ```sh npx serve-avd # → Preview at http://localhost:3200 ``` https://github.com/user-attachments/assets/91ca0811-119e-46f6-8e3e-9b41bd9f9bd7 `serve-avd` captures the emulator's screen via `adb screenrecord`, exposes it as an H.264 WebCodecs stream (with an MJPEG fallback) plus a WebSocket control channel, and serves a browser preview UI on top. It works with any running Android Emulator (and most physical devices over adb) — no root, no plugin, no instrumentation in your app. It is a faithful Android port of [serve-sim](https://github.com/EvanBacon/serve-sim) by Evan Bacon: same interface, same streaming design, same wire protocol — rebuilt on what Android and adb provide. ## Features - Smooth H.264 video stream in the browser (WebCodecs), with instant paint on connect — no waiting for the next frame. - Full interaction: tap, drag, and fling with the mouse; scroll with the wheel. - Android navigation from the browser: Back, Home, Recents, power, volume, rotate, theme toggle, screenshot. - Keyboard forwarding — type into the emulator directly, Escape acts as Back, ⌘⇧H goes Home. - logcat is forwarded to the browser (and mirrored into the browser console for browser-use MCP tools to read). - Recent actions are available in the browser Tools panel and `serve-avd event-log` — and export as a replayable script (`serve-avd replay`). - UI hierarchy dumps for agents: `serve-avd ax` (uiautomator → JSON), plus semantic targeting on top: `serve-avd find "Sign in"`, `serve-avd tap --text "Sign in"`, `serve-avd wait "Welcome"`. - **Built-in MCP server** (`serve-avd mcp`) — one config line hands the emulator to Claude Desktop, Cursor, Codex or any MCP client as tools. - **Typed client SDK** (`serve-avd/client`) for Playwright-style scripts and agent frameworks — no shelling out. - Emulator controls from the CLI, Tools panel, SDK and MCP: location (+ routes), network conditions, battery, fingerprint, calls & SMS, font scale / density / locale / TalkBack, snapshots (save/load to reset state), app install/launch/stop/clear/open-URL, and `shell`/`push`/`pull` passthrough. - Multiple emulators at once — boot and attach AVDs straight from the Devices panel. - Every command works headless (straight over adb) when no server is running, and through the server (shared event log, live viewers) when one is. ## Why? Hosted emulators can be hard to test. `serve-avd` lets you test the hosted infra locally first for faster iteration. When you're ready to host an emulator remotely, simply tunnel the served URL and users can interact with the emulator as if it were running locally on their device. It's also a great way to hand an emulator to an AI agent: everything is driveable over plain HTTP + WebSocket, screenshots and UI dumps are one command away, and the event log tells you what the agent did. ## Install Requires the Android SDK platform-tools (`adb`; the `emulator` binary is needed to boot AVDs by name) and a [maintained Node.js LTS release](https://nodejs.org/en/about/previous-releases) (Node 18.17+). serve-avd finds your SDK via `$ANDROID_HOME`, `$ANDROID_SDK_ROOT`, or the default SDK locations on macOS and Linux. The H.264 stream needs `screenrecord --output-format=h264` (present on every emulator image from the last decade). If it's unavailable, serve-avd automatically falls back to an MJPEG screenshot stream. ## CLI ``` serve-avd [device...] Start preview server (default: localhost:3200) device = adb serial or AVD name (boots it if needed) serve-avd --no-preview [device...] Stream in foreground without a preview server serve-avd mcp [--serve] [-d serial] MCP server over stdio (see Connectors) serve-avd gesture '' [-d serial] Send a touch gesture serve-avd tap [-d serial] Tap at normalized 0..1 coords serve-avd tap --text "Sign in" …or the first UI element matching --id submit | --desc Search text / resource id / description [--index n] [--exact] [--long [ms]] serve-avd find "" [--id|--desc|--class] [--json] Find UI elements: bounds, centers, normalized coords serve-avd wait "" [--timeout 10s] [--gone] Poll until an element appears/disappears (exit 2 on timeout) serve-avd swipe [--duration 300ms] serve-avd button [name] [-d serial] Send a button press (default: home) home|back|app-switch|power|lock|wake| volume-up|volume-down|mute|menu|camera| notifications|quick-settings|dpad-*|… serve-avd type [-d serial] Type text via the emulator keyboard (ASCII only; also --stdin / --file ) serve-avd rotate [-d serial] portrait | portrait_upside_down | landscape_left | landscape_right serve-avd debug