Install any skill in seconds. Free to start, no credit card required.
Get Started Free →Control an Android phone through OpenGUI from Codex or Claude Code. Use when an agent should list online devices, run a natural-language mobile task, check execution status, pause, resume, or cancel through the local OpenGUI backend and CLI.
| Test case | Without → With | Effect | Δ tokens | Δ turns |
|---|---|---|---|---|
| case-04 | ✗→✓ | ▲ Improved | 81% | 0% |
| case-05 | ✗→✓ | ▲ Improved | 86% | 0% |
| case-06 | ✗→✓ | ▲ Improved | 62% | 0% |
| case-07 | ✗→✓ | ▲ Improved | 32% | 0% |
| case-09 | ✗→✓ | ▲ Improved | 68% | 0% |
Use this skill when Codex or Claude Code needs to operate an Android phone through OpenGUI.
The agent should not drive the phone with raw adb shell input commands. The supported path is:
textCodex / Claude Code -> server CLI or REST API -> OpenGUI backend task/execution services -> standby dispatch -> Android client -> execution socket action loop
Start this skill when the user asks for any of these:
If the user asks to install or bootstrap OpenGUI from scratch, use open-gui-bootstrap first. After backend and Android client are running, return to this skill for task execution.
cd server && pnpm opengui -- ....--json whenever the result will be parsed by Codex or Claude Code.adb shell input scripts.devices as standby presence only; execution can still fail because of model config, Android permissions, app state, or device lifecycle.OpenGUI's runnable source checkout is:
texthttps://github.com/Core-Mate/open-gui
The checkout must contain both:
server/package.jsonclient/start.shIf those paths are missing, the current directory is not the runnable OpenGUI checkout.
Before using this skill, decide where OpenGUI should run.
Use a local workspace when:
adb reverse tcp:7777 tcp:7777 should be usedUse a remote workspace only when:
Do not silently choose a remote host for phone control. USB debugging, adb reverse, Android build/install, and phone-side permissions are usually local-machine operations.
If the current directory already contains the runnable checkout, use it.
If the current directory is a wrapper directory, search one level down for the runnable checkout before cloning:
bashfind . -maxdepth 3 -type f -path '*/server/package.json' -print find . -maxdepth 3 -type f -path '*/client/start.sh' -print
If no runnable checkout exists and the user wants the agent to set it up locally, clone the public repository:
bashgit clone https://github.com/Core-Mate/open-gui.git cd open-gui
If the destination already exists, do not overwrite it. Enter the existing directory, inspect git status, and pull only when the user asked for the latest code or when the checkout is clean enough to update safely.
If the user wants a remote setup, SSH to the remote host first, then perform the same checkout detection or clone on that host. Keep the backend URL and Android connectivity explicit; a backend running on a remote host will not be reachable through local adb reverse unless the user has provided a bridge.
Before sending a task, verify these conditions:
http://localhost:7777 unless the user gave another base URLadb reverse tcp:7777 tcp:7777 has been applied for a USB-connected phoneIf the backend or client is not running, use the repository scripts:
bashcd server ./start.sh
bashcd client ./start.sh
Run commands from the server/ directory.
List online standby devices:
bashpnpm opengui -- devices --json
Create and run a new task:
bashpnpm opengui -- do "观察当前手机屏幕,简要描述你看到了什么,然后结束" --json
Run a task on a specific device:
bashpnpm opengui -- do "打开设置,检查当前网络状态" --device <deviceId> --json
Run an existing task:
bashpnpm opengui -- run <taskId> --json
Check execution status:
bashpnpm opengui -- status <executionId> --json
Pause, resume, or cancel:
bashpnpm opengui -- pause <executionId> --json pnpm opengui -- resume <executionId> "继续执行,但不要打开新的 App" --json pnpm opengui -- cancel <executionId> --json
Use a non-default backend:
bashpnpm opengui -- devices --base-url http://localhost:7777 --json
Base URL priority:
text--base-url > OPENGUI_BASE_URL > http://localhost:7777
Find or clone https://github.com/Core-Mate/open-gui.
Then work from the repository root that contains both:
server/package.jsonclient/start.shIf the current directory is a wrapper repo, find the nested runnable checkout before running commands. If no runnable checkout exists, clone it or ask for the intended repository location.
Check the backend before task dispatch:
bashcurl -fsS http://localhost:7777/docs >/dev/null
If this fails, start the backend:
bashcd server ./start.sh
If start.sh creates .env and exits, ask only for the missing model keys required for execution, then run it again.
Prefer the repo script:
bashcd client ./start.sh
If a device is already installed and connected, still make sure reverse proxy is set:
bashadb reverse tcp:7777 tcp:7777
Only interrupt the user for phone-side prompts:
Use JSON output:
bashcd server pnpm opengui -- devices --json
If no devices are returned, do not dispatch a task. Ask the user to open the Android app and complete the required permissions, then retry.
If multiple devices are returned, choose the intended one by deviceId. If the user did not specify a device and the task is low-risk, use the first online device.
For a new natural-language task:
bashpnpm opengui -- do "<task description>" --device <deviceId> --json
For an existing task:
bashpnpm opengui -- run <taskId> --device <deviceId> --json
Capture executionId from the response.
Poll until the execution reaches a terminal state:
bashpnpm opengui -- status <executionId> --json
Terminal outcomes usually include success, cancellation, or failure states in the backend execution result. If the status stays running for a long time, inspect backend logs before assuming the phone is stuck.
Cancel when the user asks to stop or the task is clearly wrong:
bashpnpm opengui -- cancel <executionId> --json
Pause when human feedback is needed:
bashpnpm opengui -- pause <executionId> --json
Resume with concise feedback:
bashpnpm opengui -- resume <executionId> "<feedback>" --json
Feedback should be specific to the current phone state, for example:
Symptom:
textfetch failed
Action:
cd server && ./start.sh--base-urlSymptom:
textNo online device. Start the Android app on the work phone first.
Action:
adb reverse tcp:7777 tcp:7777pnpm opengui -- devices --jsonSymptom:
textDevice "<deviceId>" is not online
Action:
deviceIdAction:
Action:
The CLI wraps these local backend endpoints:
textGET /api/remote-control/devices POST /api/remote-control/tasks/do POST /api/remote-control/tasks/run GET /api/remote-control/executions/:id PUT /api/remote-control/executions/:id/cancel PUT /api/remote-control/executions/:id/pause PUT /api/remote-control/executions/:id/resume
Prefer the CLI unless the user explicitly asks for direct REST usage.
Before saying the phone was controlled successfully, provide evidence:
deviceIdtaskIdexecutionIdIf the task could not be run, state the concrete blocker and the next required phone-side or config action.
Other measured skills in the registry, with their headline benchmark lift.