Clousd Mcp

io.github.Clousd-AndroidPublished by GitHub account Clousd-Androidv1.6.0Updated Nov 4, 2026

Real Android phones in the cloud for AI agents: give phones a task in plain words and get the answer

Overview

AI-generated overview

Clousd gives an assistant real cloud Android phones: hand a phone a task in plain words, or drive its screen step by step.

What you can do
  • Check the account plan, balance, renewals and warnings
  • List, start, stop and restart the account's Android phones
  • Give phones a task in plain words, follow the run, answer its questions or cancel it
  • Inspect a phone's screen and tap, type or swipe on it directly
  • Manage the account's Library files and its own uploaded APKs, and send or install them on phones
  • List saved logins and schedule tasks to run at set times or on demand
When to use it
Useful when an assistant needs to act inside real Android apps — filling in forms, checking an app's state, running the same task across several phones — or when you want a repeatable phone workflow on a schedule instead of a local emulator.
Requirements
Either the hosted endpoint with OAuth sign-in, or the local clousd-mcp package (Python) started with the CLOUSD_API_KEY environment variable; other clients send the key in the Authorization header. A Clousd account with phones and credit is needed, and network access to the Clousd API.
Before you install
The key (CLOUSD_API_KEY or the Authorization header) is a live account credential with a read or read-write scope and a list of phones. Phones run pay as you go, so runs and scheduled tasks spend money. Tools start, stop, restart and reset phones, upload files and APKs, install apps, send files and create schedules; reset wipes apps and data. Saved login values are typed on the phone without being shown, but the account holds them.

Installation

In SourceWeft

  1. Open Clousd Mcp in the dashboard and add it to a workspace.
  2. Connect the required credentials. They are stored privately and never shown on public pages.
  3. Enable the server for the chats that should use its tools.

Web executable via Streamable HTTP. Remote servers run from the web runtime once configured in a workspace.

Use with an agent

Paste this prompt into Claude Code, Codex, Cursor or another agent — or into SourceWeft chat. The agent reads this server's install guide, shows you its publisher, endpoint and sign-in, and adds it to your client once you agree. Keys never go into a command.

Read https://sourceweft.com/mcp/io.github.Clousd-Android%2Fclousd-mcp/install.md and connect the MCP server it describes to my client. Before changing any config, show me its publisher, endpoint and sign-in method and wait for my OK. Never put an API key in a command or in a file I would commit; ask me where it should come from.

Read the install guide the agent follows

Other MCP clients

Add this to your client's mcpServers config. The client completes OAuth sign-in on first connect.

{
  "mcpServers": {
    "clousd": {
      "type": "http",
      "url": "https://api.clousd.com/mcp"
    }
  }
}

README

Clousd: real Android phones in the cloud, for AI agents

[tests] [PyPI clousd] [PyPI clousd-mcp] [MCP registry] [license]

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 on the Android version you pick (12 to 17), with Google Play inside and its own network exit. Give it a task in plain words and Clousd's phone agent does the steps and answers; or drive the screen yourself, step by step. Apps see a phone, not an emulator, so your 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 skill for coding agents.

Two ways to use a phone

Give it the goal. POST /v1/runs {"task": "...", "device": "..."}, c.run(...) in Python, the run tool over MCP. Clousd's agent looks at the screen, taps and types until the goal is reached, and finishes with an answer - plus a replay of every step, and JSON in your schema when you ask for it. One call gives the same task to up to 32 phones. Saved logins are typed on the phone without your agent or the model seeing them.

Drive it yourself. observe returns a fresh screenshot with a number on every element; act taps an element, types, swipes, opens apps and links, and waits until the screen settles. Snapshots reset a phone to a saved state in seconds.

Quick start

MCP

Hosted, nothing to install: https://api.clousd.com/mcp. Apps with connectors (Claude.ai, ChatGPT…) sign in with OAuth - just add the URL. Other clients send the key in the header:

json
{  "mcpServers": {    "clousd": { "url": "https://api.clousd.com/mcp", "headers": { "Authorization": "Bearer cl_live_..." } }  }}

Local: pip install clousd-mcp, then {"command": "clousd-mcp", "env": {"CLOUSD_API_KEY": "cl_live_..."}}.

Tools: account, devices, run, run_status, answer, observe, act, credentials, schedules (mcp/).

Coding agents learn the workflow from the skill:

bash
npx skills add https://github.com/Clousd-Android/clousd-sdk --skill clousd

Python

bash
pip install clousdexport CLOUSD_API_KEY=cl_live_...
python
from clousd import Clousd
c = Clousd()run = c.run("Open Settings and tell me the Android version", device="dev_04f2", wait=True)print(run.status, run.answer)                     # completed  Android 15
phone = c.device("dev_04f2")                      # or step by stepphone.open_app("com.android.chrome")phone.tap_text("Search")phone.type("weather in Berlin")phone.key("enter")phone.wait_text("Berlin", timeout=30)

More in python/.

Plain HTTPS

bash
curl -H "Authorization: Bearer cl_live_..." https://api.clousd.com/v1/devicescurl -H "Authorization: Bearer cl_live_..." -H "Content-Type: application/json" \     -d '{"task":"Open Settings and tell me the Android version","device":"dev_04f2"}' https://api.clousd.com/v1/runscurl -N -H "Authorization: Bearer cl_live_..." https://api.clousd.com/v1/runs/r_8f2c/events      # live steps (SSE)curl -H "Authorization: Bearer cl_live_..." "https://api.clousd.com/v1/devices/dev_04f2/observe?w=540"

API in one table

RoutePurpose
POST /runsa task in plain words on device or devices[] (up to 32): {task, device, credentials:[{package,name}], options:{output_schema, mode, max_steps, timeout}}; Idempotency-Key header
GET /runs, GET /runs/{id}runs of the key; status, answer, structured_output, the card it waits on
GET /runs/{id}/eventslive events (Server-Sent Events): status, step, plan, card, answer, end
GET /runs/{id}/trajectory, /steps/{n}.jpgevery step with its screen
POST /runs/{id}/answer, /message, /cancelanswer a question or permission, talk to the running agent, stop it
GET/POST /schedules, POST /schedules/{id}/toggle, /deletetasks at a time on days of the week
GET/POST /credentials, POST /credentials/{id}/fields, DELETE …saved logins; values are never returned
GET/POST /webhooks, …/{id}/rotate, /toggle, /test, GET …/deliveriesevents to your server, signed with your secret
GET /android, GET /devices, GET /devices/{name}, POST /devices {android}, start/stop/restart/resetphones of the key and their lifecycle; a phone is created by Android version; reset wipes apps and data
DELETE /devices/{name} (?forever=1), GET /trash, POST /trash/{name}/restoredelete moves the phone to Trash for 14 days (stopped, not billed, restorable); forever=1 wipes it at once
GET /devices/{name}/observe, POST /devices/{name}/act, /screenshot, /screenrecordthe screen, step by step
GET/POST /devices/{name}/network, GET/POST /proxiesthe phone's network exit
GET/POST/DELETE /devices/{name}/adbADB over a relay: one-time code, IP allow-list, expiry
GET /balanceplan, phones, money left and warnings to show the user

Keys have a scope (read or read & write) and an explicit list of phones; keys travel only in the Authorization header. Limits: 120 requests a minute per key and device, 600 a minute per key across devices, 60 a minute for everything else; 429 comes with Retry-After. Errors are JSON: {"error": "short_code", "message": "what happened"}. Full description: openapi.yaml; reference: clousd.com/docs/reference.

What is in this repository

PartWhat it is
openapi.yamlOpenAPI 3.1 description of the public API v1 (https://api.clousd.com/v1)
python/clousd: Python client (runs, schedules, logins, webhooks, devices, observe/act, reset), clousd.agent (a step-by-step loop on your own model), clousd.bench, the clousd CLI
mcp/clousd-mcp: the MCP server, local or hosted
skills/clousdskill for coding agents: how to work with Clousd phones
docs/agent-loop.mddriving a phone yourself: the observe → act → verify loop
server.json, smithery.yamlregistry metadata

Upgrading from 1.5

1.6 adds your apps. An app is an APK you upload once and install by id on any of your phones; there is no catalog of other people's apps (Google Play apps are installed in the Play Store on the phone). GET /v1/apps lists your APKs (id, name, size, package, version), POST /v1/apps uploads one as a file up to 300 MB, POST /v1/apps/{id}/install {devices} installs it, DELETE /v1/apps/{id} removes it from storage. POST /v1/media also takes a multipart file now (photo 25 MB, video 200 MB, document 50 MB, apk 300 MB). Every APK is checked on upload and before each install - a real Android app, 64-bit ARM native code when it has any, not a root or system-modification tool - and refused with 422 apk_rejected and the reason otherwise. SDK: c.apps(), c.upload_app(path), c.install_app(id, devices), c.delete_app(id); c.upload_media(path) sends the file as a file. MCP: the apps tool.

Upgrading from 1.4

1.5 creates phones by Android version only. POST /v1/devices {android: "14"} (versions: GET /v1/android); the phone model is picked by the service. GET /v1/models answers 410, and devices no longer carry a model field. A phone not renamed is called Phone #N. An old body with profile still works and keeps only that model's Android version. Python: c.create_device(android="14"), c.android_versions(); c.models() is deprecated.

Upgrading from 1.2

1.3 adds the Library: GET /v1/media lists the account's files (photos, videos, documents, apks) with ids and folders, POST /v1/media uploads one, POST /v1/media/send copies files to phones. Pass ids to POST /v1/runs as files and they are placed on the phone before the first step (photos and videos in the gallery, documents in Downloads, apks installed). SDK: c.run(task, files=[...]), c.media(), c.upload_media(), c.send_media(); MCP: the library tool and files on run. Creating a device no longer takes plan: phones run pay as you go, a plan's minutes are used first.

Upgrading from 1.1

1.2 removes saved device states. /v1/devices/{name}/snapshots, /profiles and /worlds answer 410; to start from a clean phone call POST /v1/devices/{name}/reset (apps and data are wiped, the Android version stays the same). Python: device.reset() replaces snapshots(), save_snapshot(), restore() and clone().

Upgrading from 0.3

1.0 gives phones goals instead of scripts. /v1/recipes, /v1/groups, /v1/accounts, /v1/texts and the device recipe / record routes answer 410 with where to go instead: tasks are POST /v1/runs, logins are /v1/credentials. MCP: run / run_status / answer / credentials / schedules replace fleet, recipe, resources, network, snapshots and inspect. Keys in the URL are no longer accepted.

Building from this repository

bash
pip install -e pythonpip install -e mcppython -m unittest discover -s python/tests     # offline: a fake server and a scripted model, no key needed

Links

License

MIT. See LICENSE.

Source: README.md at commit 35ef0b4

Tools

11

account

Account

The account: plan and phones, money left, what is about to renew, and warnings. Check it before starting phones or long work, and tell the user every warning in plain words with the top_up link.

Takes no parameters.

devices

Devices

Phones this key can use. op=list: name, label (the name people see in the dashboard, e.g. "Phone #3"), number, state (running / stopped / starting), Android version and network exit. Every tool takes the name, the label or the number. op=start / op=stop / op=restart with device: start a stopped phone (one to three minutes until it has booted), stop one (it keeps its apps and data) or restart it. op=reset with device: back to a fresh state - apps and data wiped, same Android version; works whether the phone runs or is stopped. Ask the user before reset. op=rename with device and label: give a phone a name (empty = back to "Phone #N"). op=delete with device: the phone moves to Trash for 14 days - stopped, not billed, apps and data kept - and op=restore brings it back (stopped). forever=true deletes it with all its data at once and cannot be undone: only when the user says so. op=trash: what is in Trash (name, label, android, deleted_at, purge_at, reason). op=restore with device: back from Trash (the name or label as shown by op=trash).

Parametersoplabeldeviceforever

run

Run a task

Give phones a task. Clousd's agent looks at the screen, taps and types until the goal is reached, and finishes with an answer. Several devices = the same task on each, all at once (one run per phone under one parent). Returns the run with its status; if it is still going, follow it with run_status. A run in mode=ask may stop with waiting_for: reply with answer. Logins: never ask the user for passwords - pass credentials; their values are typed on the phone without you or the model seeing them. A task that needs a file (post this photo, fill this form from this PDF, install this app): upload it once with the library tool and pass its id in files - do not push files by hand each time.

Parametersmodetaskrequiredfilesdevicesrequiredmax_stepscredentialswait_secondsoutput_schema

library

Library

The user's Library on Clousd: every file they want on their phones lives here once (photos, videos, documents, apps) and is used by id. op=list shows it; op=upload adds a local file and returns its id; op=send copies files to phones right away (photos and videos into the gallery as if taken there, documents into Downloads, apks installed). For a task that needs a file, prefer run(files=...) - the file is placed on the phone before the first step.

Parametersopidskindpathdevices

apps

Apps

The user's own apps on Clousd: APKs they uploaded, kept in their private storage. Upload an APK once (op=upload), then install it by id on any of their phones (op=install), as often as needed. Clousd has no catalog of other people's apps - for apps from Google Play, open the Play Store on the phone. Every APK is checked on upload (a real Android app, 64-bit ARM code, no root or system tools) and refused with the reason otherwise. To have an app on the phone before a task, pass its id in run(files=...).

Parametersopapppathdevices

run_status

Run status

Follow a run. op=status: status (queued, running, paused = waits for an answer, completed, failed, cancelled), the answer or error, the last steps, per-device results for a run on several phones, and a replay link for the user. op=list: recent runs of this key. op=cancel: stop it. op=message: tell the running agent something (it reads it before its next step).

Parametersopruntextstepswait_seconds

answer

Answer a run

Reply to a run that waits for you: answer its question with text, or allow / decline the step it asks permission for. If the question is something only the user knows, ask the user first. The run goes on at once.

Parametersrunrequiredtextallow

observe

Observe the screen

Look at the phone yourself: a fresh screenshot, the app on screen and (with_text) every labelled or tappable element with a number. Act on an element by its number (act element=N); coordinates, when needed, are in this image's pixels.

Parametersdevicerequirednumberswith_text

act

Act on the phone

Do one thing on the phone yourself, then wait until the screen settles. Prefer element numbers from observe over coordinates; tap_text taps the element whose text contains `text`. Typing goes into the focused field (tap it first) and works in any language. "the screen did not change" means the action probably missed - observe again. Read without touching the screen: installed (apps), notifications (the shade), clipboard, app_info (version, installer, running), crashes (recent app crashes and ANRs), health (running, booted, network exit, last check). For a whole goal, prefer run: it does all the steps for you.

Parametersxymsx2y2textactionrequireddevicerequiredelementtimeout

credentials

Saved logins

Saved logins of the account: package, name and which fields are set (username, email, password, phone, totp...). Values are never shown. Pass one to run as "package/name"; the agent types it on the phone without seeing it. The user adds logins in the dashboard (Tasks → Sign-in) - do not ask them for passwords in the chat.

Parameterspackage

schedules

Schedules

Tasks that run by themselves. op=list: id, name, task, phones, at, days, tz, enabled and the runs it started last time. op=add: run `task` on `devices` at `at` on `days`, or every hour (every=hour), or only on demand (trigger=api); each firing starts runs like the run tool. op=run: start it now. op=toggle: pause or resume. op=delete: remove it.

Parametersatoptzdaysnametaskeverydevicestriggerschedulecredentials

Version history

9
  1. v1.6.0LatestNov 4, 2026
  2. v1.5.0Nov 3, 2026
  3. v1.4.0Nov 1, 2026
  4. v1.3.0Oct 31, 2026
  5. v1.2.0Oct 22, 2026
  6. v1.1.0Oct 21, 2026
  7. v0.3.2Oct 13, 2026
  8. v0.2.0Oct 10, 2026
  9. v0.1.2Oct 9, 2026

Score

100% of the applicable checks met

How complete this listing is, computed from the registry entry, the endpoint and public sources. Not a rating of the server and not a statement that it is safe or working today: reachability is a dated check, and no installs or reviews go into the score.

  • Reached in the last 30 daysRequired25 pts
  • Auth declaredRequired10 pts
  • Tools listed15 pts
  • DescriptionRequired15 pts
  • Logo10 pts
  • Documentation15 pts
  • License10 pts