LangGraph on Android: phone tools for your graph.
LangGraph agents can automate Android apps through Mobilebox. langchain-mcp-adapters turns the Mobilebox MCP server into LangChain tools, create_agent builds a LangGraph graph around them, and your agent reads a cloud phone’s screen, then taps, types and installs apps.
Python, 28 lines, the hosted MCP server and its 13 tools. 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 LangGraph
pip install langgraph langchain langchain-mcp-adapters langchain-openai - 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
create_agent returns a compiled LangGraph graph: run it on its own, or add it as a node in your own graph.
# LangGraph + Mobilebox: a LangGraph agent drives a cloud Android phone over MCP.
# pip install langgraph langchain langchain-mcp-adapters langchain-openai
# MOBILESANDBOX_API_KEY=... OPENAI_API_KEY=... python agent.py
import asyncio, json, os, urllib.request
from langchain.agents import create_agent
from langchain_mcp_adapters.client import MultiServerMCPClient
API = "https://mobilebox.dev"
AUTH = {"Authorization": f"Bearer {os.environ['MOBILESANDBOX_API_KEY']}"}
MODEL = os.environ.get("MODEL", "openai:gpt-5.4-mini") # any LangChain chat model
def phones(method, path=""): # your code owns the phone: create it, and always delete it
req = urllib.request.Request(f"{API}/v1/phones{path}", method=method, headers=AUTH)
with urllib.request.urlopen(req) as res:
return json.loads(res.read() or "null")
async def main():
phone = phones("POST", "?wait=ready")["id"]
try:
client = MultiServerMCPClient({"mobilebox": {"transport": "streamable_http", "url": f"{API}/mcp", "headers": AUTH}})
agent = create_agent( # a compiled LangGraph graph: use it alone or as a node in yours
MODEL,
tools=await client.get_tools(),
system_prompt=f"You operate the Android phone {phone} with the Mobilebox tools. "
"Observe, act, and check each result on the returned screen. Don't create or delete phones.",
)
state = await agent.ainvoke({"messages": [("user", "Open Settings > Display and tell me the brightness level.")]})
print(state["messages"][-1].content)
finally:
phones("DELETE", f"/{phone}")
asyncio.run(main())
Ran once against production on 5 November 2026: the agent answered “Brightness level: 83%” in 31 s, and the phone was deleted. Run log
Questions
Before you wire LangGraph to a phone.
Can I use the phone tools inside my own graph?
Yes. client.get_tools() returns ordinary LangChain tools: bind them to a model, put them in a ToolNode or hand them to a subgraph. Keep the phone id in state so every node drives the same phone.
Which models can drive the phone?
Any LangChain chat model that calls tools. MODEL takes a provider:model id, for example openai:gpt-5.4-mini.
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
A successful tap is not a successful task
Design Android agent checks around outcomes, screen evidence, failure traces, and safe cleanup.
Screenshot or accessibility tree? Choose the evidence your agent needs
Choose structured Android observations for labels and state, screenshots for pixels, and synchronized evidence when both matter.
Using another framework? OpenAI Agents SDK, CrewAI, browser-use, Mastra, Vercel AI SDK, Claude Agent SDK.
All integrations