# io.github.Clousd-Android/clousd-mcp (remote · api.clousd.com)

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

- Trust score: 36/100 (low)
- Change this week: 0
- Registry status: active
- Liveness: live
- Owner verified: no
- Last scored: 2026-11-05

> **Recent critical change**: Authorization (2026-10-16). See the changelog below before you install this server.

## Components

- remote · `api.clousd.com`: 36/100 (this document), [markdown](https://verifymcp.io/servers/clousd-android-clousd-mcp/api.md), [page](https://verifymcp.io/servers/clousd-android-clousd-mcp/api)
- pypi · `clousd-mcp`: 80/100, [markdown](https://verifymcp.io/servers/clousd-android-clousd-mcp/clousd-mcp.md), [page](https://verifymcp.io/servers/clousd-android-clousd-mcp/clousd-mcp)

## Channel facts

- Endpoint: `https://api.clousd.com/mcp`
- Transports: `streamable-http`
- Auth: `required`
- Version: `1.6.0`

## Trust breakdown

How this component scores in each security and reliability category. Every signal is checked automatically against the live server, and we only credit what we can confirm. Scores are 0–100 per category. Scoring method: https://verifymcp.io/docs/scoring (what has changed: https://verifymcp.io/docs/scoring/changelog)

Scored 2026-11-05.

- **Endpoint Security**: 89/100
  - The endpoint's TLS certificate is valid, in date, and uses a strong key.
  - The endpoint enforces authorisation, advertised via RFC 9728 protected-resource metadata.
  - HTTPS is enforced; there's no plaintext access path.
  - HSTS check failed: the Strict-Transport-Security header is absent.
  - DNSSEC check failed: this domain isn't protected by DNSSEC.
  - The authorisation server offers only Dynamic Client Registration (RFC 7591), which MCP 2026-07-28 deprecated in favour of Client ID Metadata Documents.
- **Transport & Reachability**: 0/100
  - Transport blocked by authentication: the endpoint requires auth we don't have to verify streamable-http.
- **Schema Quality & AI Usability**: 0/100
  - Schema blocked by authentication: the endpoint requires auth we don't have to read it.
- **Stability & Change Management**: 0/100
  - Stability not yet verified: not enough scan history yet (needs a 30-day window).
- **Tool Coverage**: 0/100
  - Tool coverage blocked by authentication: the endpoint requires auth we don't have to read its tools.
- **Tool Safety**: 0/100
  - Tool safety blocked by authentication: the endpoint requires auth we don't have to read its tools.
- **Capabilities**: 0/100
  - Capabilities blocked by authentication: the endpoint requires auth we don't have to read them.

**Unverified: 6 categories.** Categories scored 0 because we could not verify them: authentication we do not have, an unreachable endpoint, or not enough scan history. We only credit what we can confirm.

## Install

### How do I install the io.github.Clousd-Android/clousd-mcp server?

io.github.Clousd-Android/clousd-mcp is a hosted endpoint at https://api.clousd.com/mcp, so there is nothing to install locally. Ready-made configuration for Claude, Cursor, VS Code, Codex and 5 more is on this page, copied from each client's own documentation.

### Claude

```bash
claude mcp add --transport http clousd-android-clousd-mcp 'https://api.clousd.com/mcp'
```

### Cursor

```json
{
  "mcpServers": {
    "clousd-android-clousd-mcp": {
      "url": "https://api.clousd.com/mcp"
    }
  }
}
```

### VS Code

```json
{
  "servers": {
    "clousd-android-clousd-mcp": {
      "type": "http",
      "url": "https://api.clousd.com/mcp"
    }
  }
}
```

### Codex

```toml
[mcp_servers.clousd-android-clousd-mcp]
url = "https://api.clousd.com/mcp"
```

### opencode

```json
{
  "$schema": "https://opencode.ai/config.json",
  "mcp": {
    "clousd-android-clousd-mcp": {
      "type": "remote",
      "url": "https://api.clousd.com/mcp",
      "enabled": true
    }
  }
}
```

### OpenClaw

```bash
openclaw mcp add clousd-android-clousd-mcp --url 'https://api.clousd.com/mcp' --transport streamable-http
```

### Hermes

```yaml
mcp_servers:
  clousd-android-clousd-mcp:
    url: "https://api.clousd.com/mcp"
```

### Netclaw

```json
{
  "McpServers": {
    "clousd-android-clousd-mcp": {
      "Transport": "http",
      "Url": "https://api.clousd.com/mcp"
    }
  }
}
```

### Vellum

```bash
assistant mcp add clousd-android-clousd-mcp -t streamable-http -u 'https://api.clousd.com/mcp'
```

### Other

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

The mcpServers block is a cross-client convention. Remote transports vary, so check your client's docs.

## Changelog

Every change recorded for this component, newest first. Days that predate change tracking, or that we cannot explain, say so: "we were watching and nothing happened" and "we were not watching" are different claims.

### 2026-10-21 (score 36, −29)

- [security regression] Endpoint reachability: reachable → behind authorisation
- [security regression] Tool safety: pass → unverified
- [security regression] Stability: 0.30 → unverified
- [security regression] Transport: pass → unverified
- [security improvement] Authorization: fail → pass
- [security] First check of Authorization: partial
- [functional regression] Capabilities: pass → unverified
- [functional regression] Tool coverage: 100 → unverified
- [functional] Schema quality: Schema blocked by authentication: the endpoint requires auth we don't have to read it.

### 2026-10-19 (score 65, +1)

No change was recorded against any check on this day. Stability & Change Management went from 23 to 27. That category is still filling its 30-day observation window: 7 days of observed history at the previous scan, 8 at this one. The score rises as the window fills, whether or not the server changes.

### 2026-10-17 (score 64, +1)

No change was recorded against any check on this day. Stability & Change Management went from 17 to 20. That category is still filling its 30-day observation window: 5 days of observed history at the previous scan, 6 at this one. The score rises as the window fills, whether or not the server changes.

### 2026-10-16 (score 63, +40)

- [critical regression] Authorization: unverified → fail
- [security improvement] Injection markers: unverified → pass
- [security improvement] Transport: fail → pass
- [security] The server rewrote its instructions, which are the text every model session reads
- [security] New tool “fleet”, which the server declares destructive
- [security] New tool “network”, which the server declares destructive
- [security] Tool “devices” rewrote its description, which is the text the model reads
- [security] Tool “recipe” rewrote its description, which is the text the model reads
- [functional regression] Schema quality: 200 → 339
- [functional improvement] Endpoint reachability: not serving MCP → reachable
- [functional improvement] Tool coverage: 83% → 90%
- [functional improvement] Tool coverage: unverified → 100
- [functional improvement] Stability: unverified → 0.17
- [functional improvement] MCP protocol: unverified → pass
- [functional] New tool “account”
- [functional] New tool “resources”
- [cosmetic] “devices” added an optional parameter “label”
- [cosmetic] “observe” reworded the description of “device”
- [cosmetic] “act” reworded the description of “device”
- [cosmetic] “devices” reworded the description of “device”
- [cosmetic] “devices” reworded the description of “op”
- [cosmetic] “inspect” reworded the description of “device”
- [cosmetic] “recipe” reworded the description of “device”
- [cosmetic] “snapshots” reworded the description of “device”

### 2026-10-13 (score 23, −39)

- [security regression] Endpoint reachability: reachable → not serving MCP
- [security regression] Stability: 0.03 → unverified
- [security regression] Tool safety: pass → unverified
- [security regression] Authorization: fail → unverified
- [security regression] Transport: pass → fail
- [functional regression] Tool coverage: 100 → unverified
- [functional regression] Capabilities: pass → unverified
- [functional] First check of Schema quality: unverified

### 2026-10-12 (score 62, 0)

- [functional improvement] Stability: unverified → 0.03

### 2026-10-11 (score 62)

First indexed and scored.

## MCP tools (10)

### `devices` (~226 tokens)

Phones this API key can use.
    op=list: name, label (the name people see in the dashboard, e.g. "Anna IG" or "Pixel 7 #3"), number, state (running /
    stopped / starting), model, Android version, network exit, the app accounts linked to it and its proxy_id. Every
    tool takes the name, the label or the number. op=rename with device and label: give a phone a name (empty = back to
    "Model #N"); name phones after their accounts to keep a fleet readable.
    op=start / op=stop with `device`: start a stopped phone (waits until it has booted, one to three minutes) or stop
    one (a stopped phone keeps its state and costs nothing).

Input parameters:

- `device` (string): device (name, label or number), for start / stop / rename
- `label` (string): rename: the new name, up to 40 characters
- `op` (string): list (default) | start | stop | rename

Output parameters:

- `result` (object)

### `observe` (~136 tokens)

Look at the phone: 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.

Input parameters:

- `device` (string, required): Device from devices (op=list): its name, its label from the dashboard (e.g. "Anna IG" or "Pixel 7 #3") or its number
- `numbers` (boolean): draw the element numbers on the screenshot
- `with_text` (boolean): also list the elements (numbered, centres in image pixels)

### `act` (~367 tokens)

Do one thing on the phone, 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. Returns what happened; "the screen did not change" means the action probably
    missed - observe again.

Input parameters:

- `action` (string, required): one of: tap long_press swipe scroll tap_text wait_text type key open_app close_app open_url installed intent settings clipboard_set notifications_open notifications_close notifications_clear
- `device` (string, required): Device from devices (op=list): its name, its label from the dashboard (e.g. "Anna IG" or "Pixel 7 #3") or its number
- `element`: element number from the last observe (tap, long_press)
- `ms` (integer): swipe / long_press duration in ms
- `text` (string): type: the text; key: home|back|recents|enter|tab|del|menu; scroll: down|up; open_app/close_app: package; open_url: https://...; tap_text/wait_text: text on screen; settings: wifi|bluetooth|display|so…
- `timeout` (integer): wait_text: seconds to wait, up to 120
- `x`: x in screenshot pixels (tap, long_press, swipe start)
- `x2`: swipe end x
- `y`: y in screenshot pixels
- `y2`: swipe end y

Output parameters:

- `result` (string)

### `inspect` (~186 tokens)

Read the phone without touching the screen.
    notifications: the shade as a list (app, title, text, time). clipboard: the clipboard text.
    app: installed version, install/update time, installer, whether it runs or is on screen.
    crashes: recent app crashes, native crashes and ANRs with the first lines of the stack.
    health: running, booted, network exit and the latest automatic check of the phone.
    installed: packages of apps that can be opened.

Input parameters:

- `device` (string, required): Device from devices (op=list): its name, its label from the dashboard (e.g. "Anna IG" or "Pixel 7 #3") or its number
- `package` (string): app: the package to describe; crashes: only this package
- `what` (string, required): notifications | clipboard | app | crashes | health | installed

Output parameters:

- `result` (object)

### `snapshots` (~183 tokens)

Saved states of a phone, for starting every run from the same point.
    op=list: id, created, android, current, restorable. op=save: save the current state.
    op=restore with snapshot_id: reset the phone to that state (what happened since is lost).
    op=clone with snapshot_id and new_name: a new phone from that state.

Input parameters:

- `device` (string, required): Device from devices (op=list): its name, its label from the dashboard (e.g. "Anna IG" or "Pixel 7 #3") or its number
- `new_name` (string): clone: name of the new phone (letters and digits, up to 16)
- `op` (string): list (default) | save | restore | clone
- `snapshot_id` (string): restore / clone: id from op=list

Output parameters:

- `result` (object)

### `recipe` (~282 tokens)

App recipes on one phone: scripted flows that wait for the right screen at each step, deal with popups and report
    what they did. op=run runs a built-in recipe (package + action - the list with inputs is fleet op=recipes) or your own
    JSON and returns when it is finished; for several phones use fleet op=run instead.
    op=record_start begins recording what is done on the phone (through act, or by a person in the live view);
    record_status shows progress; record_stop returns the recorded draft recipe, ready for op=run.

Input parameters:

- `action` (string): run: built-in recipe name (e.g. warm, login, publish_post)
- `device` (string, required): Device from devices (op=list): its name, its label from the dashboard (e.g. "Anna IG" or "Pixel 7 #3") or its number
- `op` (string, required): run | record_start | record_status | record_stop
- `package` (string): run: app package of a built-in recipe (e.g. com.instagram.android)
- `steps` (string): run: your own recipe as JSON {app, steps:[...]} (e.g. a recorded draft)
- `vars` (string): run: variables as JSON, e.g. {"seconds": "300"}

Output parameters:

- `result` (object)

### `account` (~181 tokens)

The account's money - check it before starting phones, creating them or launching long runs, and tell the user
    what it says. op=balance: balance, spend_per_day (running per-minute phones + paid proxy traffic of the last 24 hours),
    runs_out_in_hours, phones running per minute with their price, monthly renewals within 7 days, prices per hour / day
    cap / month / GB by exit type, the top_up link, and warnings: show every warning to the user in plain words (e.g.
    "about 6 hours left; at zero the phones stop and go to storage", "proxy traffic cost $3.40 today") with the top_up
    link. When the balance is low, say so before spending more - do not silently start phones.

Input parameters:

- `op` (string): balance

Output parameters:

- `result` (object)

### `network` (~422 tokens)

Where phones go online. Every phone uses one proxy of the account: your own proxy, or a Clousd exit (residential,
    mobile, ISP, datacenter in a country, paid per GB); time zone, locale and SIM follow it. op=options: exit types on
    sale and countries. op=status: the exit a device uses now (IP, country, carrier). op=proxies: the account's proxies
    and which devices use each. op=add: save your proxy (it is checked at once) or a Clousd exit. op=bind: put devices on
    a proxy. op=unbind: take them off (no internet until bound again). op=rotate: new IP for every running device on the
    proxy. op=check: test your proxy. op=delete: remove an unused proxy.

Input parameters:

- `country` (string): add: two-letter country of a Clousd exit, e.g. US
- `device` (string): status: the device to look at
- `devices` (string): bind / unbind: device names, JSON list or comma-separated
- `ip_type` (string): add (own proxy): static | residential | mobile
- `name` (string): add: a name to find it by
- `op` (string, required): options | status | proxies | add | check | bind | unbind | rotate | delete
- `proxy` (string): add: your own proxy - host:port:user:pass, user:pass@host:port or socks5://user:pass@host:port
- `proxy_id` (integer): check / bind / rotate / delete: proxy id from op=proxies
- `rotate_url` (string): add (own residential/mobile proxy): the provider's link that changes the IP
- `type` (string): add: instead of your own proxy, a Clousd exit - residential | mobile | isp | datacenter (see op=options), paid per GB

Output parameters:

- `result` (object)

### `resources` (~546 tokens)

The account's resources, the same as Resources in the dashboard. accounts: saved app accounts (login, status, the
    phone it is linked to; parent_id = it signs in through that Instagram) - passwords and 2FA secrets are never shown;
    add_via_instagram (account_id = an Instagram account, platform = com.facebook.katana or com.instagram.barcelona): a
    Facebook / Threads that signs in through that Instagram, on the same phone, no password. To sign a phone in, run fleet with the step
    {"op":"login","package":...,"account":<id> or "linked"} and the server fills the password itself. add_accounts /
    link_account: save accounts and link one to a phone. texts / add_texts: captions, comments, bios, names. media /
    upload_media: the photo and video library; publish one with fleet step {"op":"publish","package":...,"text":"post",
    "media_id":<id>,"caption":...}. send_media: copy files into phones' galleries as if taken by that phone.

Input parameters:

- `account_id` (integer): link_account: account id from op=accounts; add_via_instagram: the Instagram account id
- `accounts` (string): add_accounts: JSON list of {platform, login, password, email?, email_password?, totp?, note?, device?}
- `data_b64` (string): upload_media: the file as base64 when there is no path (up to 25 MB)
- `device` (string): link_account: the phone to link it to (empty = unlink)
- `devices` (string): send_media: device names, JSON list or comma-separated
- `kind` (string): media: image | video (empty = both)
- `media_ids` (string): send_media: library ids, JSON list or comma-separated
- `name` (string): upload_media: file name with extension, e.g. beach.jpg
- `op` (string, required): accounts | add_accounts | link_account | add_via_instagram | texts | add_texts | media | upload_media | send_media
- `path` (string): upload_media: a file path on the machine running this server (local MCP only)
- `platform` (string): accounts: filter by app package, e.g. com.instagram.android; add_via_instagram: com.facebook.katana or com.instagram.barcelona
- `texts` (string): add_texts: JSON list of strings
- `type` (string): texts / add_texts: caption | comment | bio | name | username

Output parameters:

- `result` (object)

### `fleet` (~637 tokens)

Work with many phones in one call - the way to automate, instead of tapping each phone step by step.
    op=recipes lists the built-in app recipes (sign in, warm up an account, publish, delete the last post...) with their
    inputs; prefer a recipe over act whenever one fits the task. op=run starts a recipe (package + action) or your own
    steps on up to 32 phones at once (they may live on different servers) and returns a job id right away - the phones
    work in parallel, minutes to an hour for a warm-up. op=status with job shows per-phone progress: call it every
    30-60 s until state is done or failed. Steps for op=run: recipe (package, action, vars), open_app / close_app
    (package), url (url), tap_text / wait_text (text, seconds), wait (seconds, seconds_max), scroll (text=down|up),
    browse (seconds 10-600: scroll like a person), install_app (package from the catalog), key (key), screenshot,
    rotate (new IP), if_text / unless_text (text, skip), login (package, account: an id from resources op=accounts or
    "linked" for the account linked to each phone - the server fills the password), publish (package, text: post|story|reel,
    media_id from resources op=media, caption). vars_by_device gives each phone its own account or media_id too, e.g.
    {"dev_1": {"account": "12"}, "dev_2": {"account": "13"}}.

Input parameters:

- `action` (string): run: recipe action from op=recipes, e.g. warm, login, publish_post
- `app` (string): recipes: filter by app name or package, e.g. instagram
- `devices` (string): run: device names as JSON list or comma-separated, e.g. ["dev_1","dev_2"]; "all" = every running device of this key
- `job` (string): status: job id returned by op=run
- `op` (string, required): recipes | run | status
- `package` (string): run: app package of the recipe, e.g. com.instagram.android
- `stagger` (string): run: spread the starts, min,max seconds, e.g. 20,90 (phones do not act in lockstep)
- `steps` (string): run: instead of a recipe, your own steps as JSON list, e.g. [{"op":"open_app","package":"com.android.chrome"},{"op":"wait","seconds":5}]
- `vars` (string): run: variables for every device as JSON, e.g. {"seconds": "900", "comment_chance": "0.1"}
- `vars_by_device` (string): run: per-device variables as JSON, e.g. {"dev_1": {"login": "anna", "password": "..."}} (logins differ per phone)

Output parameters:

- `result` (object)

## Diagnostics

Captured diagnostic sections: TLS, DNSSEC, Authorisation, Transports. The full working is on the page: https://verifymcp.io/servers/clousd-android-clousd-mcp/api#diagnostics

## Score history

- 2026-11-05: 36
- 2026-11-04: 36
- 2026-11-03: 36
- 2026-11-02: 36
- 2026-11-01: 36
- 2026-10-31: 36
- 2026-10-30: 36
- 2026-10-29: 36
- 2026-10-28: 36
- 2026-10-27: 36
- 2026-10-26: 36
- 2026-10-25: 36
- 2026-10-24: 36
- 2026-10-23: 36
- 2026-10-22: 36
- 2026-10-21: 36
- 2026-10-20: 65
- 2026-10-19: 65
- 2026-10-18: 64
- 2026-10-17: 64
- 2026-10-16: 63
- 2026-10-15: 23
- 2026-10-14: 23
- 2026-10-13: 23
- 2026-10-12: 62
- 2026-10-11: 62

## Common questions

### What is the io.github.Clousd-Android/clousd-mcp server?

io.github.Clousd-Android/clousd-mcp is listed in the public MCP registry as io.github.Clousd-Android/clousd-mcp. Real Android phones in the cloud for AI agents: give phones a task in plain words and get the answer. This page covers its hosted endpoint (https://api.clousd.com/mcp).

### Is the io.github.Clousd-Android/clousd-mcp server safe to use?

io.github.Clousd-Android/clousd-mcp scores 36 out of 100 on VerifyMCP. That is a record of what we were able to check automatically, not an endorsement. The category breakdown on this page shows every signal behind the number, including the ones we could not confirm.

### What tools does the io.github.Clousd-Android/clousd-mcp server expose?

io.github.Clousd-Android/clousd-mcp exposes 10 tools: devices, observe, act, inspect, snapshots, and 5 more. Their descriptions and schemas cost roughly 3,166 tokens of context every time the server is loaded.

### Does the io.github.Clousd-Android/clousd-mcp server require authentication?

Yes. io.github.Clousd-Android/clousd-mcp asked us for credentials when we connected, so you will need to authorise it in your MCP client before it can do anything.

### Is the io.github.Clousd-Android/clousd-mcp server still maintained?

io.github.Clousd-Android/clousd-mcp is still listed as active in the MCP registry. We last reached this channel on 5 November 2026. Those dates come from our own scans of the registry and the channel itself, not from anything the publisher announced.

## Links

- Remote endpoint: https://api.clousd.com/mcp
- Authorisation metadata: https://api.clousd.com/.well-known/oauth-protected-resource/mcp
- Repository: https://github.com/Clousd-Android/clousd-sdk
- Website: https://clousd.com/agents/
- Changelog RSS feed: https://verifymcp.io/servers/clousd-android-clousd-mcp/api.xml
- Changelog JSON feed: https://verifymcp.io/servers/clousd-android-clousd-mcp/api.json
- HTML version of this page: https://verifymcp.io/servers/clousd-android-clousd-mcp/api
