mobridge-mcp 0.8.5 → 0.8.7

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/AI-USAGE.md CHANGED
@@ -1,63 +1,177 @@
1
- # MoBridge 0.7 — hướng dẫn cho AI
2
-
3
- MoBridge dùng một daemon dùng chung (`mobd`). CLI và MCP đi qua cùng daemon, vì vậy không mở
4
- WebSocket riêng và không gọi ADB trực tiếp.
5
-
6
- ## Cài đặt
7
-
8
- Chạy `npx -y mobridge-mcp install --yes` để tự cấu hình các agent đã phát hiện. Installer backup
9
- config cũ, gỡ registration MoBridge cũ, cài launcher `~/.mobridge/bin/mobridge`, trích companion
10
- APK và ghi tài liệu này vào `~/.mobridge/AI-USAGE.md`. Sau đó restart agent.
11
-
12
- ## Chọn CLI hay MCP
13
-
14
- - Có shell: dùng CLI cho discovery, health/preflight, chẩn đoán, workflow JSONL, output file và
15
- chuỗi lệnh nhiều bước. Lệnh chính: `mobridge devices`, `connect`, `health`, `observe`, `find`,
16
- `run`, `trace`.
17
- - Chỉ có MCP: dùng đúng 5 tool `mobile.device.connect`, `mobile.screen.observe`,
18
- `mobile.screen.act`, `mobile.screen.capture`, `mobile.run`.
19
- - MCP dùng cho semantic action và ảnh inline; CLI dùng cho batch/run, stream, diagnostics và file.
20
-
21
- ## Khởi động phiên
22
-
23
- 1. Gọi `mobile.device.connect` hoặc `mobridge connect -d ANDROID:<serial>` một lần.
24
- 2. Luôn đọc `deviceId`, `supportedCapabilities` và trạng thái provision.
25
- 3. Khi có nhiều thiết bị, luôn truyền `deviceId`/`-d`.
26
- 4. Với CLI, preflight là `mobridge health --preflight <package>`.
27
- 5. Mọi response live phải có `backend: "device"`. Nếu thấy `backend: "simulated"`, dừng và không coi kết quả là thao tác trên máy thật. Backend thật là mặc định; fixture chỉ bật tường minh bằng `--simulated` hoặc `MOBRIDGE_BACKEND=sim` cho test.
28
-
29
- ## Quy tắc thao tác nhanh
30
-
31
- - Kết nối một lần. Nếu đã biết query, gọi thẳng `mobile.screen.act` với `query`; không observe/find riêng.
32
- - Từ hai bước trở lên dùng `mobile.run`/`mobridge run`; daemon giữ dataflow và session nóng.
33
- - Chỉ observe khi chưa biết màn hình, sau navigation, khi ambiguous hoặc khi action lỗi.
34
- - Mỗi MCP act chỉ một verb. Mutation phải có verify; `DISPATCHED` không đồng nghĩa `VERIFIED`.
35
- - NodeRef phải giữ `snapshotId` và `generation`; NodeRef thuần stale thì dừng, chỉ query gốc mới được resolve lại.
36
- - `mobile.run` không observe cuối mặc định; dùng `returnState:true` hoặc `mobridge run --return-state` khi cần.
37
- - Evidence lớn nằm trong trace; response thường chỉ có verdict, state gọn và traceId.
38
- - Dùng `mobile.run`/`mobridge run` cho dataflow; `$name` chỉ được resolve ở host.
39
- - Không retry mutation sau transport drop hoặc `RESULT_UNKNOWN`; đọc có thể recovery/retry một lần.
40
- - Mỗi mutation đơn cần `operationId`; workflow cần `workflowId` và `stepId` ổn định. Khi đổi MCP↔CLI,
41
- tra operation/workflow status bằng ID gốc trước khi quyết định tiếp. `requestId` chỉ nhận diện một lần gọi.
42
- - JSONL workflow có checkpoint bền: dùng `mobridge run --status --workflow-id <id>` hoặc `mobile.run`
43
- với plan `{"control":"status"}`; chỉ resume cùng plan/device bằng token hiện tại.
44
- - WAL giữ operation tombstone sau 5 phút; unresolved cũ thành `EXPIRED_UNKNOWN`, không trở thành mutation mới.
45
- Checkpoint workflow tồn tại 24 giờ, chỉ lưu HMAC plan hash và verdict/step IDs, không lưu plan/secret; sau daemon restart hãy status rồi resume bằng token mới.
46
- - Không gọi `adb`, `uiautomator`, tọa độ hoặc `adb shell input` trong luồng semantic.
47
- - App control không có authorize/allowlist/denylist theo package. Device identity tường minh, fixed argv,
48
- safety confirmation và runtime-permission policy vẫn áp dụng; `mobridge app authorize` không tồn tại.
49
- - Response dùng `transport: "accessibility"` cho semantic/gesture và `transport: "adb"` cho fallback/app step. Gesture tọa độ luôn `verification.level: "unverified"`.
50
- - Nếu response có `state.interactionBlocked:true` và `state.loadingLikely:true`, UI đang kẹt ở màn hình loading sparse. `mobridge run` sẽ giới hạn wait của bước đó tối đa 2 giây và trả `APP_LOADING_STUCK`; không retry vòng lặp, hãy `capture`/kiểm tra dialog, quyền hoặc mạng rồi observe lại.
51
- - Secret ưu tiên `valueRef`/secret broker được người dùng cho phép; CLI có thể đọc stdin. Không truyền secret trong argv,
52
- không dùng environment làm mặc định, không lưu plaintext trong checkpoint, trace hoặc audit.
53
- - Ad fast path dùng BACK nhưng chỉ xác nhận thành công khi foreground Activity rời ad; nếu chưa rời thì dùng assisted capture/vision.
54
-
55
- ## Ví dụ
56
-
57
- ```bash
1
+ # MoBridge — guide for AI agents (Android only)
2
+
3
+ MoBridge uses one shared daemon (mobd). The CLI and MCP go through the same daemon, so there is no separate
4
+ WebSocket and you never call ADB directly.
5
+
6
+ ## Install
7
+
8
+ Run npx -y mobridge-mcp install --yes to configure the agents it detects. The installer backs up old
9
+ configs, removes legacy MoBridge registrations, installs the ~/.mobridge/bin/mobridge launcher, extracts the
10
+ companion APK and writes this document to ~/.mobridge/AI-USAGE.md. Restart the agent afterwards.
11
+
12
+ ## CLI or MCP
13
+
14
+ - With a shell: use the CLI for discovery, health/preflight, diagnostics, JSONL workflows, file output and
15
+ multi-step chains. Main commands: mobridge devices, connect, health, observe, find, run, trace.
16
+ - MCP only: use exactly the 5 tools mobile.device.connect, mobile.screen.observe, mobile.screen.act,
17
+ mobile.screen.capture, mobile.run.
18
+ - MCP is for semantic actions and inline images; the CLI is for batch/run, streams, diagnostics and files.
19
+
20
+ ## Starting a session
21
+
22
+ 1. Call mobile.device.connect, or run mobridge connect -d ANDROID:<serial>, once.
23
+ 2. Always read deviceId, supportedCapabilities and the provision status. The connect result also carries
24
+ `usage`, the onboarding steps to follow before acting.
25
+ 3. With several devices always pass deviceId/-d.
26
+ 4. With the CLI the preflight is mobridge health --preflight <package>.
27
+ 5. Every live response must carry backend: "device". If you see backend: "simulated", stop and do not treat the result as an action on a real phone. The real backend is the default; fixtures are enabled only explicitly with --simulated or MOBRIDGE_BACKEND=sim, for tests.
28
+
29
+ ## Connection and failures (follow in order)
30
+
31
+ One connect call handles installation: it installs the companion APK if missing, upgrades it when its version differs from the host,
32
+ enables Accessibility over adb, creates the adb forward and then performs the handshake. You do not run adb or install the APK by hand.
33
+ After an install/update, connect waits for the companion to become ready (a few seconds at most), so no immediate second call is needed.
34
+
35
+ 1. mobridge devices (or mobile.device.connect) to get the deviceId; with several devices always pass deviceId.
36
+ 2. mobile.device.connect / mobridge connect -d ANDROID:<serial>. Read ready, blockers, warnings, provision.companionInstalled
37
+ (ALREADY | INSTALLED | UPDATED) and health.accessibility.
38
+ 3. On failure read error.code and do exactly the matching step; do not try things at random:
39
+
40
+ | error.code | Cause | Level | What to do |
41
+ |---|---|---|---|
42
+ | ADB_NOT_FOUND | `adb` is not installed or not on PATH. | needs action | Tell the user to install Android Platform Tools, then run `mobridge connect`. User: Install Android Platform Tools (https://developer.android.com/tools/releases/platform-tools) and add its folder to PATH. |
43
+ | ADB_SERVER_UNRESPONSIVE | The adb server does not answer. | self-heals / retry | Retry `mobridge connect`; if it repeats ask the user to approve `mobridge doctor --restart-adb`. |
44
+ | DEVICE_NOT_FOUND | The device that was named is not attached. | needs action | Run `mobridge devices`, pick an attached serial, never substitute another phone. User: Connect the phone by USB (or `adb connect`) and unlock it. |
45
+ | DEVICE_OFFLINE | adb sees the device but it is offline or just reconnecting. | self-heals / retry | Wait a few seconds and retry `mobridge connect`. User: If it persists: replug the cable, unlock the phone, toggle USB debugging. |
46
+ | DEVICE_UNAUTHORIZED | The phone has not accepted this computer's USB debugging key. | needs action | Ask the user to unlock the phone and accept the dialog, then retry `mobridge connect`. User: Unlock the phone and tap Allow on the "Allow USB debugging?" dialog (tick Always allow). |
47
+ | MULTIPLE_DEVICES | More than one usable device is attached and none was chosen. | needs action | Pick one from `details.candidates` and pass it as deviceId (`-d ANDROID:<serial>`), or save it once with `mobridge device use <serial>`. |
48
+ | AMBIGUOUS_DEVICE | Several devices are connected in this daemon and the call named none. | needs action | Pass `deviceId` (from `mobridge devices`) on every call; never guess one. |
49
+ | DEVICE_BINDING_MISMATCH | The runtime socket answered for a different phone than the one named. | self-heals / retry | Run `mobridge connect -d ANDROID:<serial>` again; if it repeats run `mobridge doctor`. Nothing was driven. |
50
+ | COMPANION_MISSING | The companion app is not installed and no APK was available. | needs action | Run `npx -y mobridge-mcp@latest install`, or set MSM_COMPANION_APK to the APK of this package. |
51
+ | COMPANION_VERSION_MISMATCH | The installed companion is not the build this host expects. | self-heals / retry | Run `mobridge connect`; it updates the companion once. |
52
+ | COMPANION_INSTALL_BLOCKED | The phone refused the USB install (OEM setting or confirmation prompt). | needs action | Show the user `recovery`, then retry `mobridge connect`. User: Unlock the phone and tap Install/Allow; Xiaomi/Redmi/POCO: Developer options > Install via USB and USB debugging (Security settings); Play Protect: Install anyway. |
53
+ | COMPANION_INSTALL_FAILED | The install failed for a device reason (storage, Android version). | needs action | Show the user the message, then retry `mobridge connect`. User: Free storage, or use a device on Android 10+. |
54
+ | COMPANION_NOT_READY | The companion did not answer the handshake ("socket hang up"). | self-heals / retry | Read `diagnostics` and `recovery[0]`, apply it, then run `mobridge connect` again. User: Only if `recovery[0]` asks: open the MoBridge Runtime app once / exclude it from battery optimisation. |
55
+ | COMPANION_UNAVAILABLE | The companion process is not running. | self-heals / retry | Run `mobridge connect`; it restarts the companion. |
56
+ | ACCESSIBILITY_DISABLED | The Accessibility service is off. | self-heals / retry | Run `mobridge connect`; it enables the service over adb and reads it back. |
57
+ | ACCESSIBILITY_ENABLE_BLOCKED | The phone does not let adb enable the Accessibility service. | needs action | Show the user `userAction`, then run `mobridge connect --wait-user 120` to resume the moment it is on. User: Settings > Accessibility > MoBridge Runtime > On. Android 13+: first Settings > Apps > MoBridge Runtime > ⋮ > Allow restricted settings. Xiaomi: Developer options > USB debugging (Security settings). |
58
+ | WAITING_FOR_USER_ACCESSIBILITY | Waiting for the person to turn Accessibility on; the wait window ended. | needs action | Ask the user to finish the step, then run `mobridge connect` again (it resumes; nothing is reinstalled). User: Settings > Accessibility > MoBridge Runtime > On. |
59
+ | ACCESSIBILITY_PREEMPTED | The service is enabled but not bound; another owner took the session. | self-heals / retry | Wait a few seconds and run `mobridge connect`. |
60
+ | EXTERNAL_INSTRUMENTATION_ACTIVE | Another tool holds UiAutomation (uiautomator, a test runner, another agent). | needs action | Fail fast: ask the user to stop the other tool, then `mobridge connect`. User: Stop the other automation tool on this phone. |
61
+ | TRANSPORT_DEGRADED | The link to the phone dropped. | self-heals / retry | Retry the read; for a mutation check `mobridge operation status <operationId>` first. Prefer USB over wireless adb. |
62
+ | WS_CONNECTION_LOST | The WebSocket to the companion closed. | self-heals / retry | Reads retry by themselves; a mutation reports RESULT_UNKNOWN, so look its operation up, never resend it. |
63
+ | RESULT_UNKNOWN | A mutation was dispatched but its effect could not be confirmed. | needs action | Never repeat it. Run `mobridge operation status <operationId>` and observe the screen. |
64
+ | AMBIGUOUS_MATCH | More than one node matches the query. | needs action | Narrow the query using `candidates`; never click the first. |
65
+ | NEEDS_VISION | Semantics are not enough to decide. | needs action | Take `mobile.screen.capture`, look at the image and act with `at`. |
66
+ | UNSUPPORTED_PLATFORM | iOS was requested. | needs action | Use an Android device. |
67
+
68
+ 4. Never repeat a mutation after RESULT_UNKNOWN; connecting again is safe, acting again is not.
69
+ 5. Still failing: mobridge doctor, mobridge health, then report with details.diagnostics.
70
+
71
+ ## Rules for fast operation
72
+
73
+ - Connect once. If you already know the query, call mobile.screen.act with the query directly; do not observe/find separately.
74
+ - Two or more steps: use mobile.run/mobridge run; the daemon keeps the dataflow and a hot session.
75
+ - Observe only when the screen is unknown, after navigation, when a match is ambiguous or when an action failed.
76
+ - One verb per MCP act. A mutation must be verified; DISPATCHED does not mean VERIFIED.
77
+ - A NodeRef must keep its snapshotId and generation; a plain stale NodeRef stops, only the original query may be resolved again.
78
+ - mobile.run does not observe at the end by default; use returnState:true or mobridge run --return-state when needed.
79
+ - Large evidence lives in the trace; a normal response has only the verdict, a compact state and the traceId.
80
+ - Use mobile.run/mobridge run for dataflow; $name is resolved on the host only.
81
+ - Every single mutation needs an operationId; every workflow has a workflowId and stable stepIds. When switching MCP↔CLI,
82
+ look up mobridge operation status <operationId>, or call mobile.run with plan={"control":"status"} and the workflowId.
83
+ The CLI equivalent: mobridge run --status --workflow-id <id>; to resume use the same plan/device/workflowId and --resume-token.
84
+ - Do not retry/replay a mutation after a transport drop or RESULT_UNKNOWN. requestId only identifies a call;
85
+ operationId identifies the logical effect. The WAL keeps a tombstone for 5 minutes; an old unresolved entry becomes EXPIRED_UNKNOWN and is never turned into a new command.
86
+ - A workflow checkpoint lives at most 24 hours and stores only an HMAC plan hash and verdict/step ids, never the plan or secrets. After a daemon restart, status returns a fresh resumeToken;
87
+ resume only with the same workflowId, deviceId, plan hash and token.
88
+ - Do not call adb, uiautomator, coordinates or adb shell input in the semantic flow.
89
+ - App control has no per-package authorize/allowlist/denylist. Explicit device identity, fixed argv,
90
+ safety confirmation and the runtime-permission policy still apply; there is no app authorize command.
91
+ - Responses use transport: accessibility for semantic/gesture actions and transport: adb for fallback/app steps. A coordinate gesture always has verification.level: unverified.
92
+ - Prefer valueRef/a user-approved secret broker for secrets; the CLI can read stdin. Do not pass secrets in argv,
93
+ do not use env as the default, and never put plaintext in a workflow checkpoint, trace or audit.
94
+ - FLAG_SECURE only blocks capture/vision; if semantics still work, keep using the semantic path.
95
+ - Closing an ad: BACK is only the fast path; report success only after the foreground Activity has left the ad. If the ad is still there, use assisted capture/vision;
96
+ never click a CTA and never tap from an old screenshot.
97
+
98
+ ## Routing (the daemon picks the executor, the agent does not)
99
+
100
+ - Two separate sensors: screen observe = semantic JSON from Accessibility (no image); screen capture = real pixels (the image stays in RAM and returns a captureId). Capture only when you need to look (colour, icon, canvas, ad, missing semantics): screen capture defaults to a small preview to understand the layout; to read small text/icons use --roi x,y,w,h (native resolution, screen coordinates) instead of recapturing the whole screen; screen act is for acting, not for reading the screen. The old observe/shot/tap syntax still works but the guidance uses only screen ....
101
+ - Semantic UI (find/click/type/scroll/BACK/HOME/wait) runs through Accessibility; package/process/permission/settings/log/perf run through ADB; opening an app, permission flows, notifications and ads are hybrid; canvas/games/unlabeled icons use vision.
102
+ - With a clear goal call one act directly; find is only for checking or when ambiguous. Several steps: mobile.run/mobridge run or mobridge session --jsonl; one-shot CLI is for single operations only.
103
+ - permission respond answers the dialog that is showing (resource-id, not pm grant); permission set changes state with pm grant/revoke and reads it back to verify. The two do not replace each other.
104
+ - NEEDS_VISION: read the current capture (it has a captureId), pick a point on the image, then act CLICK {at:{captureId,x,y}} (dynamic UI such as ads/video: stalePolicy VISUAL_DYNAMIC); an old image gives STALE_CAPTURE. Never guess coordinates. Find by colour: capture {color:{hex}} → colorMatch. A control without a node: capture {scan:{}} → regionScan.regions[] (regionId, bounds, position, semanticNode, at): neutral facts that do not name the icon. Look at the image, choose a region, act CLICK {at}; if unsure it stays NEEDS_VISION, do not guess.
105
+ - Do not change executor after a dispatch that may have run (timeout/dropped connection): the result is RESULT_UNKNOWN, look up the operation status, do not resend over ADB.
106
+ - Do not use raw adb when a typed command exists. mobridge capabilities [--family F] lists each op's executor, replay class and verification.
107
+
108
+ ## Choose the tool by goal
109
+
110
+ - One known goal with visible text: one command, e.g. `mobridge screen act click --text "Login" --verify auto`.
111
+ - Several steps: `mobridge run plan.jsonl`, or chain commands with `&&`. Long chains: `mobridge session --jsonl` (input lines {"id","argv":[...]}, output lines {"id","exit","output"}) so you do not pay a process spawn per command.
112
+ - Unknown screen: `mobridge screen observe`. Look only when needed: `mobridge screen capture`.
113
+ - Stuck on an ad, canvas or unlabeled icon: `mobridge screen capture`, then `mobridge screen act at --capture <captureId> --x X --y Y`; for a full-screen ad: `mobridge ad dismiss`.
114
+ - The CLI and MCP share one daemon (no separate WebSocket), but every CLI call still pays process start-up; do not run dozens of single commands when one JSONL plan does the job.
115
+ - In `a && b || c`, `||` runs when a OR b fails, not only when a fails; use `if` to branch.
116
+
117
+ ## CLI defaults (verified)
118
+
119
+ - `--match` defaults to NORMALIZED_EXACT. When the on-screen text is longer than the query you get NODE_NOT_FOUND: use `--match CONTAINS` deliberately and accept the AMBIGUOUS_MATCH risk; do not enable it by default.
120
+ - A click by query already waits for the node up to 1500 ms (4000 ms when the foreground is SystemUI); `--wait-ms <0-10000>` waits longer, `--wait-ms 0` turns the wait off.
121
+ - `--verify auto` picks the policy from the action type. DISPATCHED is not VERIFIED.
122
+ - A node without CLICK (plain text or icon): `--allow-gesture` taps the node centre by coordinates. It requires a `--verify` policy that checks the screen changed, never DISPATCH_ONLY. Use it only when needed; an ambiguous parent is still refused.
123
+ - `screen act at`: `--stale-policy strict` is the default; use `dynamic` when the screen has video, ads or animation. `--space image|screen` selects the coordinate space (default image; the capture result carries a coordinateGuide).
124
+ - `screen capture` defaults to a small image (scale 0.5): for small text use `--mode detail` or `--roi x,y,w,h`. The file format follows the `-o` extension (.png, .jpg, .webp) or `--format png|jpeg|webp`.
125
+ - `screen observe --app-only` drops the status bar and unfocused system chrome (on by default in MCP, off by default in the CLI). Content below the status bar, such as a heads-up notification, is kept.
126
+ - `type --secret` or `--secret-env VAR` keeps passwords out of argv.
127
+ - `--nth <n>` and `--within <json>` narrow down duplicate matches.
128
+
129
+ ## Valid JSONL steps (one step per line, unique ids)
130
+
131
+ {"id":"s1","open":"com.example.app"}
132
+ {"id":"s2","tap":{"text":"Skip"}}
133
+ {"id":"s3","wait":{"condition":{"nodeExists":{"text":{"value":"Home","match":"CONTAINS"}}},"timeoutMs":3000}}
134
+ {"id":"s4","type":{"field":"com.example.app:id/email","text":"a@b.c"}}
135
+ {"id":"s5","scroll":{"query":{"text":{"value":"Settings","match":"CONTAINS"}},"direction":"FORWARD"}}
136
+ {"id":"s6","key":"BACK"}
137
+ {"id":"s7","ad":"dismiss"}
138
+
139
+ The `ad` step is VERIFIED when the ad is closed or there was no ad. If an ad is still up the plan stops PAUSED with a NEEDS_VISION yield (with a capture and closeCandidate): look at the image, close it by hand, then resume. A `wait` condition is always wrapped in nodeExists/nodeAbsent/anyOf/allOf, never a bare {"text":"Home"}.
140
+
141
+ ## Lesser-known commands
142
+
143
+ - `mobridge diff --from <snapshotId> [--to <snapshotId>]` compares two snapshots (`--from` is required); `mobridge record START|STOP|STATUS|EXTRACT_FRAMES --mp4-path f.mp4`.
144
+ - `mobridge permission respond --decision ALLOW|ALLOW_WHILE_USING|ALLOW_ONCE|DENY|DENY_DONT_ASK` answers the dialog that is showing.
145
+ - `mobridge operation status <operationId>`: look here after RESULT_UNKNOWN; never resend the mutation.
146
+ - `mobridge open <package> --action APP_BRING_TO_FRONT`; `mobridge diag LOGCAT|CRASH|PERF|APP_INFO|STARTUP|BATTERY|NETSTATS|STORAGE|BUNDLE`.
147
+
148
+ ## Connection traps
149
+
150
+ - MULTIPLE_DEVICES: with several devices pass `-d ANDROID:<serial>` or run `mobridge device use <serial>`; with exactly one device it is picked automatically and `-d` is not needed.
151
+ - EXTERNAL_INSTRUMENTATION_ACTIVE: Appium/UiAutomator holds Accessibility; stop it, then connect again.
152
+ - WAITING_FOR_USER_ACCESSIBILITY (Android 13+, Xiaomi, Oppo): Settings → Apps → MoBridge Runtime → ⋮ → Allow restricted settings, then enable Accessibility.
153
+ - Recovery: `mobridge daemon restart` (after upgrading the package), `mobridge doctor --restart-adb`.
154
+
155
+ ## Typed commands (generated from the registry)
156
+
157
+ - ad: mobridge-ad dismiss · mobridge-ad tap-close
158
+ - app: app clear · app force · open
159
+ - device: devices · health --preflight · health · doctor · doctor --restart-adb · connect · state
160
+ - diag: diag
161
+ - fallback: fallback cancel · fallback commit · fallback prepare · fallback status
162
+ - input: gesture · type · key
163
+ - operation: operation status · trace
164
+ - package: app install · app uninstall
165
+ - permission: permission set · permission set --revoke · permission respond
166
+ - run: batch · run · scenario
167
+ - screen: screen act click | type | scroll · screen act at · analyze · screen capture · diff · find · inspect · screen observe · record · screen act scroll · wait · watch
168
+
169
+ ## Examples
170
+
58
171
  mobridge devices --json
59
172
  mobridge connect -d ANDROID:<serial>
60
- mobridge tap --text Login --verify auto
173
+ mobridge screen observe
174
+ mobridge screen act click --text Login --verify auto
175
+ mobridge screen capture
61
176
  mobridge run login.jsonl -d ANDROID:<serial>
62
177
  mobridge trace <traceId>
63
- ```
package/README.md CHANGED
@@ -14,6 +14,8 @@ npx -y mobridge-mcp install --yes # wires every detected agent: Claude Code, C
14
14
 
15
15
  Drop `--yes` for a wizard. The installer backs up each agent config, removes older MoBridge registrations, extracts the signed companion APK, installs a user-owned launcher at `~/.mobridge/bin/mobridge` (add it to `PATH` to use the CLI), writes the agent guide to `~/.mobridge/AI-USAGE.md` and registers `mobridge mcp`. Restart your agent afterwards. `mobridge install --dry-run` previews; `mobridge remove` undoes it.
16
16
 
17
+ The skill template ships with the package (staged at `~/.mobridge/skills/mobridge/SKILL.md`) but is never written into an agent's folders by default. `mobridge skill status` shows where it is installed; `mobridge skill install --agent <claude-code|codex|cursor|antigravity|all> [--dry-run]` installs or updates it, and `mobridge skill remove --agent …` deletes only a skill MoBridge wrote. A foreign `SKILL.md` of the same name is never overwritten, and an agent without a verified skill folder is reported `unsupported`. The result describes files on disk; it does not prove the agent loaded the skill. MCP works without it: tool descriptions, rejection messages and the `usage` field of `mobile.device.connect` carry the same guidance. `mobridge guide --short` prints the quickstart.
18
+
17
19
  First connect is automatic: `mobile.device.connect` installs the companion app on the phone, enables its accessibility service through ADB and opens the channel. Nothing else to tap.
18
20
 
19
21
  ## How it works
@@ -122,7 +124,7 @@ Two or more steps: send a JSONL plan instead of many calls. The daemon keeps the
122
124
  | Answer a permission dialog | CLI `mobridge permission respond --decision ALLOW_WHILE_USING` (answers the dialog like a user). `permission set <pkg> CAMERA` changes the state directly via ADB and reads it back. They are not interchangeable. |
123
125
  | Close an ad | CLI `mobridge ad dismiss`. It tries BACK, then assisted capture; it never taps a call-to-action. Exit 8 = pick the close point from the returned capture, then `mobridge ad tap-close`. |
124
126
  | Install / force-stop / uninstall | CLI `mobridge app install <file.apk>` (copies it into `MSM_APK_DIR` and reads the package id with aapt2/aapt, from PATH or the Android SDK build-tools), `app install <package> --apk <name>`, `app uninstall`, `app force`; `package install|uninstall` and `process stop` are aliases. Each reads the package/process state back. |
125
- | Wait / exit codes | `mobridge wait` that runs out of time returns status `TIMEOUT` and exit 10 (never VERIFIED/0). Exit codes: 0 VERIFIED, 1 FAILED, 2 DISPATCHED, 3 RESULT_UNKNOWN, 4 needs setup, 5 ambiguous, 6 policy, 7 transport, 8/9 `ad`, 10 TIMEOUT. |
127
+ | Wait / exit codes | `mobridge wait` that runs out of time returns status `TIMEOUT` and exit 10 (never VERIFIED/0). Exit codes: 0 VERIFIED, 1 FAILED, 2 DISPATCHED, 3 RESULT_UNKNOWN, 4 needs setup, 5 ambiguous, 6 policy, 7 transport, 8/9 `ad`, 10 TIMEOUT. Exit 2 means "sent, effect unproven", so do not chain on it with `&&` without a `--verify` policy; `mobridge open <pkg>` returns 0 when the package is already in front. `mobridge daemon restart` replaces a stale daemon (use after upgrading the package). `mobridge screen act key` takes `BACK`, `HOME`, `RECENTS` or `NOTIFICATION_SHADE`, positional or `--key`. |
126
128
  | Diagnose | CLI `mobridge diag LOGCAT|CRASH|BATTERY|NETWORK|DISPLAY|POWER`. |
127
129
  | Anything missing | `mobridge capabilities [--family F]` lists every operation, its executor, replay class and verification. |
128
130