clousd-mcp
Provides tools for controlling and automating real Android phones in the cloud, including observing the screen, acting on UI elements, inspecting app state, using ADB, managing snapshots, and running recipes.
Android phones include Google Play and Play services inside, enabling automation of apps that require Google Play services.
Provides built-in recipes and app packs for Instagram, enabling flows such as login, warm-up, publish, and other account actions on Instagram.
Provides Android phones built as real Motorola models, enabling automation and testing on Motorola devices.
Provides Android phones built as real OnePlus models, enabling automation and testing on OnePlus devices.
Provides Android phones built as real OPPO models, enabling automation and testing on OPPO devices.
Provides Android phones built as real Sony models, enabling automation and testing on Sony devices.
Provides Android phones built as real vivo models, enabling automation and testing on vivo devices.
Provides Android phones built as real Xiaomi models, enabling automation and testing on Xiaomi devices.
Clousd: real Android phones in the cloud, for AI agents and automation
The pitch, in one breath
Every agent framework can tap a phone. Almost none has a phone worth tapping.
Clousd is the phone. Each device is a full Android system built as a specific real model, Pixel to Galaxy to Xiaomi, with the hardware identity, Google Play, cameras, sensors and network of the handset in a user's pocket. Your agent, your script or your test suite drives it over HTTPS: look at the screen, act on it, check the result, reset to a saved state, clone it a hundred times. Apps see a phone, not an emulator, so the agent sees the screens a person sees.
This repository is the public side of it: the OpenAPI description, the Python client, the MCP server and the agent loop. Early access: keys on request at clousd.com/agents.
Related MCP server: apk-preview-mcp
Mix and match
Pick one from each column. They all compose.
Pick a phone | Pick a brain | Pick a driver |
Pixel 6 to 11, Android 12 to 17 | Any MCP client: Cursor, Windsurf, Zed, desktop assistants, agent frameworks | MCP server |
Galaxy S, A, M, Z series | Any OpenAI-compatible model: hosted APIs, OpenRouter, Ollama, vLLM on your GPU | Python client |
Xiaomi, Redmi, POCO, Motorola, OnePlus, realme, OPPO, vivo, Sony, TECNO, Infinix and more, 150+ models | No model at all: recipes replay a recorded flow in seconds | CLI |
Network exit in the country you choose: residential, mobile, ISP, datacenter | A person in the browser: the dashboard streams the screen live | REST API ( |
The phone stays the same whatever you plug in. A new model release is a free upgrade to your phone agent.
What it does
The phone taps what you'd tap
observe: a fresh screenshot with every element numbered, the app in front, and the UI tree with text, ids and boundsact: tap by element number or point, long press, swipe, scroll, type in any language, keys, open apps and links, intents, settings pages, clipboard, notification shade; the server waits until the screen settles and refuses an action taken on a stale screen (409 stale)inspect: notifications, clipboard, app versions, crashes and ANRs from the log, health, without touching the screenADB over a relay when a check has to go deeper than the screen: one-time code, IP allow-list, expiry
A phone that apps believe
Built from a snapshot of the real handset: build fingerprint, properties, sensors, cameras, codecs, GPU strings, audio, screen; Google Play and Play services inside
Its own network exit, SIM profile, time zone and locale that follow the exit; a kill-switch below Android so nothing leaves the phone outside that exit
Snapshots: save a prepared state, restore it before every run in seconds, clone it into ten or a hundred phones with their own identities
Teach it once, replay for free
Recipes: scripted flows per app (login, warm-up, publish, delete) that wait for the right screen at each step and deal with popups; built-in recipes for the big social apps, yours in JSON
Record a recipe from what is done on the phone (through the API or by a person in the live view), then replay it on any number of phones without a model
App packs: named elements with a selector chain per app version, popups handled once per app
Scale the fleet
Start with one phone, run hundreds; stopped phones cost nothing
One call runs a recipe or a chain of steps on up to 32 phones in parallel (
POST /groups,c.run_recipe(...), MCPfleet), each phone with its own login or caption, starts spread so the phones do not act in lockstepGroups and schedules in the dashboard, jobs and webhooks in the API
Benchmark harness: run AndroidWorld-style task sets on real device models with any model behind the loop
Why it is built this way
Emulators are the first thing an app checks for. Goldfish hardware, emulator builds, no SIM, a datacenter IP: the "unusual activity" path starts before your agent has tapped anything. A phone built as a real model with a real-looking network takes the same code path a user takes.
Every episode should start from the same state. Evaluation, training and testing are only comparable when run N starts exactly where run 1 did. Snapshots restore in seconds; clones give parallel episodes without copying a phone by hand.
Thinking costs tokens, replaying costs nothing. Use a model for the unknown task; once a flow works, record it and replay it as a recipe. The same phone runs both.
Your keys, your phones. API keys carry a scope (read or control) and an explicit list of phones. A read key
can observe and inspect but never acts. Over HTTP the key travels with every request; the hosted MCP server keeps
nothing between requests.
Quick start
MCP (any client)
pip install clousd-mcp{
"mcpServers": {
"clousd": { "command": "clousd-mcp", "env": { "CLOUSD_API_KEY": "cl_live_..." } }
}
}Or no install at all, the hosted server:
{
"mcpServers": {
"clousd": { "url": "https://api.clousd.com/mcp", "headers": { "Authorization": "Bearer cl_live_..." } }
}
}Python
pip install clousd
export CLOUSD_API_KEY=cl_live_...from clousd import Clousd
c = Clousd()
phone = c.device("dev_04f2")
snap = next(s for s in phone.snapshots() if s["restorable"])
phone.restore(snap["id"]) # every run starts from the same state
phone.open_app("com.android.chrome")
phone.tap_text("Search")
phone.type("weather in Berlin")
phone.key("enter")
phone.wait_text("Berlin", timeout=30)
obs = phone.observe(width=540) # screenshot + UI tree + seq
phone.act("tap", seq=obs["seq"], x=540, y=1200, settle=True)A task with a model
clousd run "Open Settings and tell me the Android version" --device dev_04f2 \
--model-url http://127.0.0.1:8080/v1 --model qwen # any OpenAI-compatible endpoint
clousd run "Find the cheapest flight to Lisbon next Friday" --device dev_04f2 --save-recipe flights.json
clousd recipe flights.json --device dev_04f2 # replay without a model
clousd bench --device dev_04f2 --model-url ... # the built-in task set, scored
clousd explore com.android.settings --device dev_04f2 # map the screens of an app, draft an app packMany phones at once
An agent that taps every phone step by step through observe/act is slow and burns model calls. For app tasks use a
recipe, and for many phones one call:
from clousd import Clousd
c = Clousd()
phones = [d for d in c.devices() if d.state == "running"] # 10 phones, any servers
for r in c.recipes("instagram"): # what can run without a model
print(r["action"], "-", r["about"], [i["name"] for i in r["inputs"]])
# sign every phone into its own account: one call, the phones work in parallel
accounts = {"dev_01": {"login": "anna.k", "password": "..."}, "dev_02": {"login": "mark_t", "password": "..."}}
job = c.run_recipe(list(accounts), "com.instagram.android", "login", vars_by_device=accounts)
print(job.failed) # [] - or the devices to look at
# warm all ten up for 15 minutes, starts spread over 20-90 s so they do not move in lockstep
job = c.run_recipe(phones, "com.instagram.android", "warm",
{"seconds": 900, "comment_chance": 0.1, "comments": "Love this|So good|Wow"}, stagger=[20, 90])
for name, r in job.results.items():
print(name, r["state"], r["steps"][-1]["output"])Accounts, proxies and media come from the account too, so a whole morning is a few calls:
p = c.add_proxy("res.example.net:9000:user:pass", ip_type="residential", rotate_url="https://example.net/rotate?key=...")
c.bind_proxy(p["proxy"]["id"], phones) # exit, time zone, SIM follow the proxy
ids = c.add_accounts([{"platform": "com.instagram.android", "login": "anna.k", "password": "...", "device": "dev_01"}])
c.run(phones, [{"op": "login", "package": "com.instagram.android", "account": "linked"}]) # passwords stay on the server
m = c.upload_media("beach.jpg")
c.run(phones, [{"op": "publish", "package": "com.instagram.android", "text": "post", "media_id": m["id"], "caption": "Sunday"}])Over MCP the same is the fleet tool: fleet op=recipes app=instagram, then fleet op=run devices=all package=com.instagram.android action=warm vars={"seconds":"900"} stagger=20,90, then fleet op=status job=... until
it is done. Over HTTPS it is GET /v1/recipes and POST /v1/groups (below).
Plain HTTPS
curl -H "Authorization: Bearer cl_live_..." https://api.clousd.com/v1/devices
curl -H "Authorization: Bearer cl_live_..." "https://api.clousd.com/v1/devices/dev_04f2/observe?w=540"
curl -H "Authorization: Bearer cl_live_..." -H "Content-Type: application/json" \
-d '{"op":"tap_text","text":"Search","settle":true}' https://api.clousd.com/v1/devices/dev_04f2/act
curl -H "Authorization: Bearer cl_live_..." https://api.clousd.com/v1/recipes
curl -H "Authorization: Bearer cl_live_..." -H "Content-Type: application/json" \
-d '{"phones":["dev_01","dev_02"],"stagger":[20,90],
"steps":[{"op":"recipe","package":"com.instagram.android","action":"warm","vars":{"seconds":"900"}}]}' \
https://api.clousd.com/v1/groups # -> 202 {"job":{"id":...}}; GET /v1/jobs/{id} for progressWhat a session looks like
observe dev_04f2 -> screenshot, "On screen: com.android.chrome", elements 1..34
act dev_04f2 tap element=12 -> "ok" (settled in 0.6 s)
act dev_04f2 type text="weather in Berlin"
act dev_04f2 key text=enter
act dev_04f2 wait_text text=Berlin -> "found after 1.9 s"
inspect dev_04f2 crashes -> []
snapshots dev_04f2 restore snapshot_id=snap_7f3 -> "restored" (next episode starts clean)observe with the UI tree takes about 1 to 3 seconds, act with settle 0.3 to 1 second; a full agent step with the
model is typically 5 to 10 seconds.
What is in this repository
Part | What it is |
OpenAPI 3.1 description of the public API v1 ( | |
| |
| |
How an agent drives a phone: the observe → act → verify loop, and the mistakes that cost the most time | |
Registry metadata: MCP registry entry |
API in one table
Route | Purpose |
| phones the key can use: state, network, |
| name a phone; tools and the SDK find phones by name or number too ( |
| create a phone: model, Android version, network type and country, plan ( |
| lifecycle; long operations answer |
| PNG, or JPEG when a width is given |
| screenshot plus the UI tree (texts, ids, bounds, clickable), with a sequence number |
|
|
| mp4 of the screen, 1 to 60 seconds (control keys) |
| run an app recipe: built-in ( |
| record a recipe from what is done on the phone: |
| built-in app recipes: package, action, what it does, its inputs, |
| the same steps on up to 32 phones in parallel: |
| which exit the phone uses; switch country or type; new IP |
| ADB over a relay: one-time code, IP allow-list, expiry |
| saved states: reset between runs, or clone a phone from a state |
| the account's proxies: add your own or a Clousd exit, put devices on it, new IP |
| saved app accounts (never with passwords); Facebook / Threads through an Instagram account; a group signs in with |
| captions and comments, the photo and video library; a group publishes with |
| the account's money: balance, spend per day (phones + proxy traffic), hours left, renewals, warnings to show the user |
| progress of long operations (for a group: |
Keys have a scope (read or control). Limits: 120 requests a minute per key and device, 600 a minute per key across
devices, 60 a minute for everything else; the server answers 429 with Retry-After and the Python client waits and
retries. Errors are JSON: {"error": "short_code", "message": "what happened"}. Full description with every field:
openapi.yaml; human-readable reference: clousd.com/docs/reference.
What teams use it for
Agent evaluation and training: restore a snapshot, run the agent for N steps, check the screen, repeat. One phone, hundreds of identical episodes;
clousd benchscores a task set,python/examples/episode.pyis the minimal loop.App testing on real models: the same test on a Galaxy A35, a Pixel 9 and a moto g05, Android 14 to 16, without a device farm; crashes, ANRs and the log one call away.
Account and content operations: each phone keeps its own identity, network and app state; clone a prepared phone instead of setting up the next one by hand; recipes replay a flow on many phones on a schedule.
Research and demos: a real phone in a specific country, reset to a known state for every run.
Platform
Android versions | 12, 13, 14, 15, 16, 17 |
Models | 150+ real models: Google, Samsung, Xiaomi, Redmi, POCO, Motorola, OnePlus, realme, OPPO, vivo, Sony, TECNO, Infinix, Nothing and more (catalog) |
Google Play | Play Store and Play services on every phone |
Network | residential, mobile, ISP or datacenter exit by country; or your own proxy; SIM, time zone and locale follow the exit (networks) |
State | snapshots and clones in seconds (snapshots) |
Screen | live WebRTC stream in the dashboard; screenshots, UI tree and mp4 recordings in the API |
Access | REST API, MCP (local or hosted), Python client and CLI, ADB relay, dashboard |
Billing | per minute while a phone runs or monthly; traffic by the gigabyte; stopped phones cost nothing (pricing) |
Requirements
An API key from the dashboard (early access: clousd.com/agents)
Python 3.9+ for the client and CLI, 3.10+ for the MCP server; or nothing at all with the hosted MCP endpoint
A model for
clousd runandclousd bench: any OpenAI-compatible endpoint; recipes and the API need none
FAQ
Is this an emulator? No. Each phone is a full Android system built as a specific real model; apps read the same hardware identity the real handset reports. Emulator detection does not trigger.
Which MCP clients work? Anything that speaks MCP over stdio or streamable HTTP. Six tools, each with parameter descriptions, a result schema and read-only/destructive hints.
Which models work? For MCP, whatever your client runs. For clousd run, any OpenAI-compatible chat endpoint with
tool calling; vision is used when the model has it and the loop falls back to the numbered element list when it does
not.
Can I run flows without a model? Yes. Record once (clousd record, clousd run --save-recipe, or the dashboard)
and replay with clousd recipe or the recipe tool on any number of phones.
Can several agents share a phone? One recipe at a time per phone; seq in observe/act makes concurrent actors
safe: an action taken on a screen that has since changed is refused, not guessed.
Where does my data go? The phone runs on Clousd servers; its traffic leaves only through the exit you chose. Keys are per account, per scope, per phone list, and revocable at any time.
Building from this repository
pip install -e python
pip install -e mcp
python -m unittest discover -s python/tests # offline: a fake server and a scripted model, no key neededReleases go to PyPI as clousd and clousd-mcp
and to the MCP registry automatically.
Links
Phones for AI agents, early access: https://clousd.com/agents/
Docs: https://clousd.com/docs/ · API reference: https://clousd.com/docs/reference/
Device catalog (150+ real models, Android 12 to 17): https://clousd.com/devices/
Networks (residential, mobile, ISP, datacenter exits): https://clousd.com/network/
Snapshots and clones: https://clousd.com/snapshots/
Pricing: https://clousd.com/pricing/
Packages: https://pypi.org/project/clousd/ · https://pypi.org/project/clousd-mcp/
MCP registry entry:
io.github.Clousd-Android/clousd-mcp· hosted MCP endpoint:https://api.clousd.com/mcp
License
MIT. See LICENSE.
This server cannot be deployed
Maintenance
Related MCP Connectors
Cloud Android phones for AI agents: create a phone, read the screen, tap, type, install APKs, park.
- LimrunOAuthcom.limrun
Cloud iOS simulators and Android emulators your agent can create, drive, and throw away.
Disposable cloud Android emulators for coding agents: run an APK or PR build, tap, type, screenshot.
Control real Android and iOS devices with LLM agents — tap, swipe, type, automate flows.
Related MCP Servers
- FlicenseNot gradedqualityCmaintenanceAn MCP server that lets AI agents drive real mobile-app automation on connected devices, enabling natural-language test tasks, test case generation, and app/build management for Android and iOS.-
- FlicenseAqualityCmaintenanceEnables installing, launching, and inspecting Android APKs on a dedicated emulator, with screen capture, UI tree inspection, and touch/navigation control via MCP tools.10-
- AlicenseNot gradedqualityBmaintenanceGives AI agents uniform perception and control over Android, iOS, and mock mobile devices through MCP, including taps, typing, app navigation, deep links, SMS/OTP retrieval, and human-in-the-loop approvals.Apache 2.0
- AlicenseNot gradedqualityCmaintenanceEnables Claude or any MCP agent to see and operate a real Android phone over adb, with fast screen reads, tap/type/swipe actions, app launching, deep links, and brand-aware setup guidance, all without admin rights or an Android SDK.MIT