browser-use with a phone: the web and Android in one agent.
browser-use drives a browser; Mobilebox adds the phone. Register two custom actions over the Mobilebox REST API, phone_screen and phone_act, and one browser-use agent reads Android apps as numbered elements and taps, types and swipes in them while it keeps browsing the web.
Python, 33 lines, the REST API. Android and iPhone over one API.
- 1
Get a key
Sign up with GitHub and create an API key in the dashboard. New accounts get $2 of credit.
- 2
Install browser-use
pip install browser-use && uvx browser-use install - 3
Run the example
python agent.pywithMOBILESANDBOX_API_KEYandOPENAI_API_KEYset. It creates a phone, gives the agent one task and deletes the phone, also when the run fails.
The whole example
browser-use connects to MCP servers it starts itself, so the hosted phone comes in as two plain actions over REST.
# browser-use + Mobilebox: one agent with a browser and a cloud Android phone (two custom actions over REST).
# pip install browser-use && uvx browser-use install
# MOBILESANDBOX_API_KEY=... OPENAI_API_KEY=... python agent.py
import asyncio, json, os, urllib.error, urllib.request
from browser_use import Agent, ChatOpenAI, Tools
API = "https://mobilebox.dev/v1/phones"
AUTH = {"Authorization": f"Bearer {os.environ['MOBILESANDBOX_API_KEY']}", "Content-Type": "application/json"}
def phones(method, path="", body=None):
req = urllib.request.Request(API + path, method=method, headers=AUTH, data=body and json.dumps(body).encode())
with urllib.request.urlopen(req) as res:
return json.loads(res.read() or "null")
phone = phones("POST", "?wait=ready")["id"] # your code owns the phone: create it, and always delete it
tools = Tools()
@tools.action('Read the phone screen as numbered elements: [ref] Type "text" (x,y)')
def phone_screen() -> str:
return phones("GET", f"/{phone}/observe")["text"]
@tools.action('Run phone actions, a JSON list such as [{"type":"open_app","package":"com.android.settings"},'
'{"type":"tap","target":{"text":"Display"}}]. Returns each result and the new screen.')
def phone_act(actions: str) -> str:
try:
done = phones("POST", f"/{phone}/actions", {"actions": json.loads(actions)})
except urllib.error.HTTPError as error:
return error.read().decode() # code, message and next: what to do instead
return json.dumps(done["results"]) + "\n" + done["screen"]["text"]
async def main():
try:
task = ("You have a cloud Android phone: drive it with phone_screen and phone_act. On it, open Settings > About phone "
"and read the Android version. Then find that version's release date on en.wikipedia.org.")
agent = Agent(task=task, llm=ChatOpenAI(model=os.environ.get("MODEL", "gpt-5.4-mini")), tools=tools)
print((await agent.run(max_steps=25)).final_result())
finally:
phones("DELETE", f"/{phone}")
asyncio.run(main())
Ran once against production on 5 November 2026: the agent answered “Android 14, released 4 October 2023” in 174 s, and the phone was deleted. Run log
Questions
Before you wire browser-use to a phone.
Why REST instead of MCP?
browser-use’s MCP client starts local servers from a command. Mobilebox’s MCP server is hosted, so two actions over the REST API are the shortest path: the same phone, the same actions, the same screen text.
What can a web-and-phone agent do?
Check one flow on both sides: read a value in an app and confirm it on the website, or sign up on the web and verify the welcome screen in the app. The example reads the Android version on the phone, then finds its release date on Wikipedia.
Can the agent install my app?
Yes. install_app takes a public APK or split-bundle URL, or your code uploads the file over REST; then the agent opens it with {"type":"open_app","package":…}. See installing APKs and split bundles.
Does it work on iPhone?
Yes. Create the phone with platform: "ios" and the agent uses the same tools. See iPhone and iPad.
What does a run like this cost?
A ready phone costs $0.01 a minute, billed per second with a one-minute minimum; boot time and parked phones are free, so a run like the one above costs about a cent. See pricing.
Read more
Does this task need a phone or a browser?
Choose the smallest runtime that can actually complete the task: HTTP, browser, or native Android.
Android, E2B, Browserbase: which sandbox fits?
Compare execution surfaces and state, rather than treating every agent sandbox as interchangeable.
Using another framework? OpenAI Agents SDK, LangGraph, CrewAI, Mastra, Vercel AI SDK, Claude Agent SDK.
All integrations