agent37-android template is an Android phone your code can drive: the Android 14 emulator, the SDK, ADB, and a live view of the screen in the browser, already installed and already running. It is a web app and a device, not an agent harness: there is no chat API on this instance.
It only runs as a VM instance. The emulator needs hardware virtualization (/dev/kvm), which a VM has and a sandbox does not, so a create without "type": "vm" is a 400.
Paste this into your coding agent
Create one
curl
sys.boot_completed:
curl
Drive it with ADB
ADB is already connected to the phone, so exec is all you need. Nothing has to be exposed to the internet for your code to drive the device.curl
SSH works too, and is the better way in when you want
adb pull of something big or an interactive shell: ssh root@ab12cd34ef.agent37.app.
Watch the screen
The screen is served on port6901 by noVNC, so any browser can open it with no plugin and no client. Mint a signed URL and point it at noVNC’s own page:
curl
/vnc.html:
&view_only=1 to watch without touching. The URL is a credential: anyone holding it can tap and type on the phone, so mint a short one and hand it only to the device’s owner. To embed the screen in your own app rather than open a tab, mount the noVNC client in your page and connect its WebSocket straight to the instance; Hermes with a desktop has the code, and it applies here unchanged.
noVNC is what the template ships because it needs nothing installed and rides the same authenticated edge as every other port. For a smoother picture, run ws-scrcpy on the instance and serve it on its own port: it streams H.264 over a WebSocket and the browser decodes it with WebCodecs. The native scrcpy client is better still, over an SSH tunnel to ADB (agent37 ssh ab12cd34ef -- -L 5037:localhost:5037). The emulator’s own WebRTC stream needs UDP, which the Agent37 edge does not carry.
What is on the image
google_apis carries Google Play services, so sign-in and push work, and it keeps adb root. It does not include the Play Store app: sideload with adb install, or build your own image on system-images;android-34;google_apis_playstore;x86_64 if you need the store itself. The same applies to another Android version: sdkmanager --install "system-images;android-16;google_apis;x86_64" on the instance, or bake it into your own template.
What the phone stores (apps, logins, files, the quick-boot snapshot) lives in the AVD on the instance’s persistent disk, so it survives stop, start, restart, resize and image updates. The SDK itself is in the image and costs nothing against your disk.
Environment knobs, as instance env: ANDROID_AVD_RAM_MB (default 2048), ANDROID_AVD_DATA_MB (the phone’s storage, default 6144), ANDROID_AVD_DEVICE (default pixel_6), ANDROID_SCREEN_GEOMETRY (default 560x1000x24, sized to the window the emulator draws) and ANDROID_EMULATOR_ARGS for anything else you want to pass the emulator.
Leave auto-sleep off
The emulator is the one workload that has to stay awake. It uses hardware virtualization itself, and after a wake the first call into/dev/kvm fails and takes the emulator down with it. Auto-sleep is off unless you ask for it, so there is nothing to do but leave it off; restart brings the phone back. Use stop and start to park a phone instead: that releases the compute charge and cold-boots cleanly.