clousd-mcp
A real Android phone in the cloud for MCP agents: observe the screen, act, reset to a saved state.
사용해야 할까요
품질 및 안전성
발견 사항 (1)
- LOWobserve에서
도구 정의와 프로토콜 준수에 대한 자동 분석을 기반으로 합니다.
컨텍스트 비용
이는 서버의 도구가 모델의 컨텍스트에 로드될 때마다 소비되는 대략적인 토큰 수입니다. 수치가 높을수록 다른 작업에 사용할 수 있는 주의가 줄어듭니다.
설치
원클릭 설치
`claude_desktop_config.json` 파일에 다음을 추가하세요:
{
"mcpServers": {
"clousd-mcp": {
"command": "uvx",
"args": [
"clousd-mcp"
]
}
}
}실행 가능한 패키지
0.2.0stdio원격 엔드포인트
https://api.clousd.com/mcpstreamable-http할 수 있는 일
도구 목록
도구 (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).
입력 스키마
{
"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"
}출력 스키마
{
"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.
입력 스키마
{
"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.
입력 스키마
{
"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"
}출력 스키마
{
"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.
입력 스키마
{
"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"
}출력 스키마
{
"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.
입력 스키마
{
"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"
}출력 스키마
{
"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.
입력 스키마
{
"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"
}출력 스키마
{
"type": "object",
"properties": {
"result": {
"additionalProperties": true,
"title": "Result",
"type": "object"
}
},
"required": [
"result"
],
"title": "recipeOutput"
}커뮤니티
증거