clousd-mcp
A real Android phone in the cloud for MCP agents: observe the screen, act, reset to a saved state.
Sollte ich dies verwenden
Qualität und Sicherheit
Befunde (1)
- LOWin observe
Basierend auf einer automatisierten Analyse der Tool-Definitionen und der Einhaltung des Protokolls.
Kontextkosten
Dies ist die ungefähre Anzahl der Tokens, die jedes Mal verbraucht werden, wenn die Tools des Servers in den Kontext eines Modells geladen werden. Höhere Werte verringern die Aufmerksamkeit, die für andere Aufgaben verfügbar ist.
Installieren
Installation mit einem Klick
Fügen Sie dies Ihrer Datei `claude_desktop_config.json` hinzu:
{
"mcpServers": {
"clousd-mcp": {
"command": "uvx",
"args": [
"clousd-mcp"
]
}
}
}Ausführbare Pakete
0.2.0stdioRemote-Endpunkte
https://api.clousd.com/mcpstreamable-httpWas es kann
Tool-Inventar
Tools (6)
⚪devices(op, device)
Phones this API key can use. op=list: name, state (running / stopped / starting), model, Android version and network exit of each phone. 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).
Eingabe-Schema
{
"type": "object",
"properties": {
"op": {
"default": "list",
"description": "list (default) | start | stop",
"title": "Op",
"type": "string"
},
"device": {
"default": "",
"description": "device name, for start/stop",
"title": "Device",
"type": "string"
}
},
"title": "devicesArguments"
}Ausgabe-Schema
{
"type": "object",
"properties": {
"result": {
"additionalProperties": true,
"title": "Result",
"type": "object"
}
},
"required": [
"result"
],
"title": "devicesOutput"
}🟢observe(device, with_text, numbers)
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.
Eingabe-Schema
{
"type": "object",
"properties": {
"device": {
"description": "Device name from devices (op=list), e.g. dev_04f2",
"title": "Device",
"type": "string"
},
"with_text": {
"default": true,
"description": "also list the elements (numbered, centres in image pixels)",
"title": "With Text",
"type": "boolean"
},
"numbers": {
"default": true,
"description": "draw the element numbers on the screenshot",
"title": "Numbers",
"type": "boolean"
}
},
"required": [
"device"
],
"title": "observeArguments"
}🔴act(device, action, element, x, y, ...)
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.
Eingabe-Schema
{
"type": "object",
"properties": {
"device": {
"description": "Device name from devices (op=list), e.g. dev_04f2",
"title": "Device",
"type": "string"
},
"action": {
"description": "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",
"title": "Action",
"type": "string"
},
"element": {
"anyOf": [
{
"type": "integer"
},
{
"type": "null"
}
],
"default": null,
"description": "element number from the last observe (tap, long_press)",
"title": "Element"
},
"x": {
"anyOf": [
{
"type": "number"
},
{
"type": "null"
}
],
"default": null,
"description": "x in screenshot pixels (tap, long_press, swipe start)",
"title": "X"
},
"y": {
"anyOf": [
{
"type": "number"
},
{
"type": "null"
}
],
"default": null,
"description": "y in screenshot pixels",
"title": "Y"
},
"x2": {
"anyOf": [
{
"type": "number"
},
{
"type": "null"
}
],
"default": null,
"description": "swipe end x",
"title": "X2"
},
"y2": {
"anyOf": [
{
"type": "number"
},
{
"type": "null"
}
],
"default": null,
"description": "swipe end y",
"title": "Y2"
},
"text": {
"default": "",
"description": "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|sound|apps|location|about|battery|...; intent: a URI to view (geo:, tel:, https:...) or JSON {action,data,package,component,extras}; clipboard_set: the text",
"title": "Text",
"type": "string"
},
"ms": {
"default": 300,
"description": "swipe / long_press duration in ms",
"title": "Ms",
"type": "integer"
},
"timeout": {
"default": 30,
"description": "wait_text: seconds to wait, up to 120",
"title": "Timeout",
"type": "integer"
}
},
"required": [
"device",
"action"
],
"title": "actArguments"
}Ausgabe-Schema
{
"type": "object",
"properties": {
"result": {
"title": "Result",
"type": "string"
}
},
"required": [
"result"
],
"title": "actOutput"
}🟢inspect(device, what, package)
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.
Eingabe-Schema
{
"type": "object",
"properties": {
"device": {
"description": "Device name from devices (op=list), e.g. dev_04f2",
"title": "Device",
"type": "string"
},
"what": {
"description": "notifications | clipboard | app | crashes | health | installed",
"title": "What",
"type": "string"
},
"package": {
"default": "",
"description": "app: the package to describe; crashes: only this package",
"title": "Package",
"type": "string"
}
},
"required": [
"device",
"what"
],
"title": "inspectArguments"
}Ausgabe-Schema
{
"type": "object",
"properties": {
"result": {
"additionalProperties": true,
"title": "Result",
"type": "object"
}
},
"required": [
"result"
],
"title": "inspectOutput"
}🔴snapshots(device, op, snapshot_id, new_name)
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.
Eingabe-Schema
{
"type": "object",
"properties": {
"device": {
"description": "Device name from devices (op=list), e.g. dev_04f2",
"title": "Device",
"type": "string"
},
"op": {
"default": "list",
"description": "list (default) | save | restore | clone",
"title": "Op",
"type": "string"
},
"snapshot_id": {
"default": "",
"description": "restore / clone: id from op=list",
"title": "Snapshot Id",
"type": "string"
},
"new_name": {
"default": "",
"description": "clone: name of the new phone (letters and digits, up to 16)",
"title": "New Name",
"type": "string"
}
},
"required": [
"device"
],
"title": "snapshotsArguments"
}Ausgabe-Schema
{
"type": "object",
"properties": {
"result": {
"additionalProperties": true,
"title": "Result",
"type": "object"
}
},
"required": [
"result"
],
"title": "snapshotsOutput"
}🔴recipe(device, op, package, action, steps, ...)
App recipes: 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) or your own JSON and returns when it is finished. 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.
Eingabe-Schema
{
"type": "object",
"properties": {
"device": {
"description": "Device name from devices (op=list), e.g. dev_04f2",
"title": "Device",
"type": "string"
},
"op": {
"description": "run | record_start | record_status | record_stop",
"title": "Op",
"type": "string"
},
"package": {
"default": "",
"description": "run: app package of a built-in recipe (e.g. com.instagram.android)",
"title": "Package",
"type": "string"
},
"action": {
"default": "",
"description": "run: built-in recipe name (e.g. warm, login, publish_post)",
"title": "Action",
"type": "string"
},
"steps": {
"default": "",
"description": "run: your own recipe as JSON {app, steps:[...]} (e.g. a recorded draft)",
"title": "Steps",
"type": "string"
},
"vars": {
"default": "",
"description": "run: variables as JSON, e.g. {\"seconds\": \"300\"}",
"title": "Vars",
"type": "string"
}
},
"required": [
"device",
"op"
],
"title": "recipeArguments"
}Ausgabe-Schema
{
"type": "object",
"properties": {
"result": {
"additionalProperties": true,
"title": "Result",
"type": "object"
}
},
"required": [
"result"
],
"title": "recipeOutput"
}Community
Nachweis