mobile-debug-mcp 0.22.0 → 0.24.0

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/docs/CHANGELOG.md CHANGED
@@ -2,6 +2,13 @@
2
2
 
3
3
  All notable changes to the **Mobile Debug MCP** project will be documented in this file.
4
4
 
5
+ ## [0.24.0]
6
+ - Improved execution loop
7
+
8
+ ## [0.23.0]
9
+ - Added network monitoring
10
+ - Added
11
+
5
12
  ## [0.22.0]
6
13
  - Added a portable `test-authoring` skill package and documented the repository's vendor-neutral skill format
7
14
  - Added `AGENTS.md` as a top-level cold-start guide for autonomous agents entering the public repository
@@ -1,12 +1,20 @@
1
1
  # Tools index
2
2
 
3
- This repository groups tool docs into three areas aligned with the codebase: manage, observe and interact.
3
+ This repository groups the MCP tools into four areas aligned with the codebase:
4
4
 
5
- See:
5
+ - [manage](manage.md) — build, install, launch, restart, and device-management tools
6
+ - [observe](observe.md) — screenshots, logs, UI trees, fingerprints, and debug snapshots
7
+ - [interact](interact.md) — UI resolution, actions, waits, and deterministic verification
8
+ - [system](system.md) — environment and health checks
6
9
 
7
- - [mange](manage.md) — build, install and device management tools
8
- - [observe](observe.md) — logs, screenshots and UI inspection tools
9
- - [interact](interact.md) — UI interaction tools (tap, swipe, type, wait)
10
- - [system](system.md) — environment and health checks (get_system_status)
10
+ ## Agent guidance
11
11
 
12
- For per-tool deep dives, open the linked files above.
12
+ For interactive flows, the intended deterministic pattern is:
13
+
14
+ **RESOLVE -> ACT -> WAIT (if needed) -> EXPECT**
15
+
16
+ - **wait_for_\*** tools are for resolution and synchronization
17
+ - **expect_\*** tools are for final outcome verification
18
+ - observation tools are supporting context, not primary success signals
19
+
20
+ Use the linked documents below for per-tool inputs, outputs, and usage guidance.
@@ -1,108 +1,144 @@
1
- # Interact (UI actions)
1
+ # Interact (UI actions, waits, and verification)
2
2
 
3
- Tools that perform UI interactions: tap, swipe, type_text, press_back, and waiting for elements.
3
+ This document covers deterministic UI resolution, actions, waits, and outcome verification.
4
+
5
+ ## Verification pattern
6
+
7
+ For mutation actions, the intended agent loop is:
8
+
9
+ **RESOLVE -> ACT -> WAIT (if needed) -> EXPECT**
10
+
11
+ Role split:
12
+
13
+ - `wait_for_*` = resolution and synchronization
14
+ - `expect_*` = final outcome verification
15
+
16
+ Important:
17
+
18
+ - `wait_for_*` tools must not be used as the final verification of action success when an applicable `expect_*` tool exists.
19
+ - action tools report execution success, not outcome correctness.
4
20
 
5
21
  ## tap / swipe / type_text / press_back
6
22
 
7
- Tap input example:
23
+ These tools return a shared action execution envelope.
8
24
 
9
- ```
25
+ Example `tap` input:
26
+
27
+ ```json
10
28
  { "platform": "android", "deviceId": "emulator-5554", "x": 100, "y": 200 }
11
29
  ```
12
30
 
13
- Response:
31
+ Example response:
14
32
 
15
- ```
16
- { "device": { "platform": "android", "id": "emulator-5554" }, "success": true }
33
+ ```json
34
+ {
35
+ "action_id": "tap_1710000000000_1",
36
+ "timestamp": 1710000000000,
37
+ "action_type": "tap",
38
+ "target": { "selector": { "x": 100, "y": 200 }, "resolved": null },
39
+ "success": true,
40
+ "ui_fingerprint_before": "fp_before",
41
+ "ui_fingerprint_after": "fp_after"
42
+ }
17
43
  ```
18
44
 
19
- Notes:
20
- - tap: `adb shell input tap x y` (Android) or `idb` events for iOS.
21
- - swipe: `adb shell input swipe x1 y1 x2 y2 duration`.
22
- - type_text: `adb shell input text` (spaces encoded as %s) may fail for special characters.
23
- - press_back: `adb shell input keyevent 4`.
45
+ Guidance:
46
+
47
+ - `tap` is best for coordinate-based interactions when no resolved element is available.
48
+ - `swipe` is execution-only; use `wait_for_*` and `expect_*` to verify its effect when the expected outcome is known.
49
+ - `type_text` reports whether text entry was dispatched, not whether the intended field state is correct.
50
+ - `press_back` reports whether the back action was dispatched, not whether the intended destination screen was reached.
51
+
52
+ Preferred verification:
53
+
54
+ - navigation outcome known -> `expect_screen`
55
+ - local UI change known -> `expect_element_visible`
24
56
 
25
57
  ---
26
58
 
27
59
  ## scroll_to_element
28
60
 
29
- Description:
30
- - Scrolls the UI until an element matching the provided selector becomes visible, or until a maximum number of scroll attempts is reached.
31
- - Delegates platform behaviour to Android and iOS implementations for reliable swipes and UI-tree checks.
61
+ Scroll until an element matching the provided selector becomes visible, or until the tool reaches a stopping condition.
32
62
 
33
63
  Input example:
34
- ```
64
+
65
+ ```json
35
66
  { "platform": "android", "selector": { "text": "Offscreen Test Element" }, "direction": "down", "maxScrolls": 10, "scrollAmount": 0.7, "deviceId": "emulator-5554" }
36
67
  ```
37
68
 
38
69
  Response example (found):
39
- ```
40
- { "success": true, "reason": "element_found", "element": { /* element metadata */ }, "scrollsPerformed": 2 }
70
+
71
+ ```json
72
+ { "success": true, "reason": "element_found", "element": { "text": "Offscreen Test Element" }, "scrollsPerformed": 2 }
41
73
  ```
42
74
 
43
75
  Response example (failure - unchanged UI):
44
- ```
76
+
77
+ ```json
45
78
  { "success": false, "reason": "ui_unchanged_after_scroll", "scrollsPerformed": 3 }
46
79
  ```
47
80
 
48
81
  Notes:
49
- - Matching is exact on provided selector fields (text, resourceId, contentDesc, className).
50
- - Visibility check uses element.bounds intersecting the device resolution when available; falls back to the element.visible flag if bounds/resolution are missing.
51
- - The tool fingerprints the visible UI between scrolls; if the fingerprint doesn't change after a swipe the tool stops early assuming end-of-list.
52
- - Android swipe uses `adb shell input swipe` with screen percentage coordinates. iOS swipe uses `idb ui swipe` command; note `idb` swipe does not accept a duration argument.
53
- - Unit tests are located at `test/unit/observe/scroll_to_element.test.ts`, automated device smoke checks under `test/device/automated/...`, and manual device runners under `test/device/manual/...`.
82
+
83
+ - Matching is exact on provided selector fields (`text`, `resourceId`, `contentDesc`, `className`).
84
+ - The tool fingerprints the visible UI between scrolls and can stop early if the UI does not change after a swipe.
85
+ - `scroll_to_element` can return success when it finds the element, but use `expect_element_visible` when you want explicit final verification of the expected visible result.
54
86
 
55
87
  ---
56
88
 
57
89
  ## wait_for_screen_change
58
90
 
59
- Description:
60
- - Waits until the current screen fingerprint differs from the provided `previousFingerprint`. Useful after taps, navigation, or other interactions that should change the visible UI.
91
+ Purpose:
92
+
93
+ - detect that a screen transition has occurred by waiting for the current fingerprint to differ from a previous fingerprint
94
+
95
+ Capabilities:
96
+
97
+ - synchronization when transition timing is uncertain
98
+ - detection that something changed on screen
99
+
100
+ Constraints:
101
+
102
+ - does not verify correctness of the resulting state
103
+ - must not be used alone to confirm action success when an applicable `expect_*` tool exists
61
104
 
62
105
  Input example:
63
- ```
106
+
107
+ ```json
64
108
  { "platform": "android", "previousFingerprint": "<hex-fingerprint>", "timeoutMs": 5000, "pollIntervalMs": 300, "deviceId": "emulator-5554" }
65
109
  ```
66
110
 
67
111
  Success response example:
68
- ```
112
+
113
+ ```json
69
114
  { "success": true, "newFingerprint": "<hex-fingerprint>", "elapsedMs": 420 }
70
115
  ```
71
116
 
72
117
  Failure (timeout) example:
73
- ```
118
+
119
+ ```json
74
120
  { "success": false, "reason": "timeout", "lastFingerprint": "<hex-fingerprint>", "elapsedMs": 5000 }
75
121
  ```
76
122
 
77
123
  Notes:
78
- - Always compares to the original `previousFingerprint` (baseline is not updated during polling).
79
- - Treats `null` fingerprints as transient; continues polling rather than returning success.
80
- - Includes a stability confirmation: after detecting a different fingerprint it waits one additional poll interval and confirms the fingerprint is stable before returning success to avoid reacting to transient flickers or animation frames.
81
- - Default `timeoutMs` is 5000ms and default `pollIntervalMs` is 300ms; callers may override these.
82
- - Implemented as an interact-level tool and delegates platform-specific fingerprint calculation to the observe layer (`get_screen_fingerprint`).
124
+
125
+ - Always compares to the original `previousFingerprint`.
126
+ - Treats `null` fingerprints as transient and keeps polling.
127
+ - Adds a stability confirmation before returning success to avoid transient animation frames.
128
+ - Follow with `expect_screen` when the expected destination is known.
83
129
 
84
130
  ---
85
131
 
86
132
  ## find_element
87
133
 
88
- Purpose:
89
-
90
- Locate a UI element on the current screen using semantic matching and return an actionable element descriptor (including tap coordinates) and confidence telemetry.
134
+ Locate a UI element on the current screen using semantic matching and return an actionable element descriptor.
91
135
 
92
136
  Input:
93
137
 
94
138
  ```json
95
- { "query": "string", "exact": false, "timeoutMs": 3000, "platform": "android|ios", "deviceId": "optional device id" }
139
+ { "query": "Login", "exact": false, "timeoutMs": 3000, "platform": "android", "deviceId": "emulator-5554" }
96
140
  ```
97
141
 
98
- Behaviour:
99
-
100
- - Fetches the current UI tree (get_ui_tree) and scores visible elements using: text, content description, resource-id, and class name.
101
- - Normalises strings (lowercase, trimmed). If exact=true require exact match; otherwise allow partial matches (contains) and resource-id/class matches.
102
- - Considers element bounds and visibility; scores non-interactable children as matches and attempts to resolve a clickable ancestor (parent index or containing clickable element) to produce an actionable element.
103
- - Retries until timeoutMs; stops early for high-confidence matches.
104
- - Does not block on long operations and returns partial results where appropriate.
105
-
106
142
  Output:
107
143
 
108
144
  ```json
@@ -113,10 +149,10 @@ Output:
113
149
  "resourceId": "com.example:id/login",
114
150
  "contentDesc": null,
115
151
  "class": "android.widget.Button",
116
- "bounds": { "left":0, "top":0, "right":100, "bottom":50 },
152
+ "bounds": { "left": 0, "top": 0, "right": 100, "bottom": 50 },
117
153
  "clickable": true,
118
154
  "enabled": true,
119
- "tapCoordinates": { "x":50, "y":25 },
155
+ "tapCoordinates": { "x": 50, "y": 25 },
120
156
  "telemetry": { "matchedIndex": 3, "matchedInteractable": true }
121
157
  },
122
158
  "score": 1.0,
@@ -126,99 +162,226 @@ Output:
126
162
 
127
163
  Notes:
128
164
 
129
- - `tapCoordinates` are the recommended center point to use for `tap` calls.
130
- - `confidence` mirrors the internal scoring (0..1) and is suitable for telemetry or logging to decide whether to proceed with an automated action.
131
- - The tool favours actionable (clickable/focusable) targets; when a matching node is not directly actionable, it finds the smallest containing clickable ancestor.
132
- - Unit tests for edge cases (parent-clickable child-text, resource-id matches, fuzzy matching) are under `test/unit/observe/find_element.test.ts`.
165
+ - Best used when no precise selector is available yet.
166
+ - `tapCoordinates` are suitable for `tap` calls.
167
+ - Prefer `wait_for_ui` when you already know a deterministic selector and want a stable `elementId`.
133
168
 
134
169
  ---
135
170
 
136
171
  ## wait_for_ui
137
172
 
138
173
  Purpose:
139
- - Deterministically wait for a UI selector match and return the matched element metadata.
140
174
 
141
- Input (ToolsInteract.waitForUIHandler):
142
- ```
175
+ - resolve elements and/or detect that a UI availability condition has occurred
176
+
177
+ Capabilities:
178
+
179
+ - deterministic element resolution
180
+ - synchronization when element timing or availability is uncertain
181
+
182
+ Constraints:
183
+
184
+ - does not verify correctness of the resulting state
185
+ - must not be used alone to confirm action success when an applicable `expect_*` tool exists
186
+
187
+ Input:
188
+
189
+ ```json
143
190
  {
144
- "selector": { "text": "optional", "resource_id": "optional", "accessibility_id": "optional", "contains": false },
145
- "condition": "exists|not_exists|visible|clickable",
146
- "timeout_ms": 60000,
191
+ "selector": { "text": "Generate Session", "contains": false },
192
+ "condition": "clickable",
193
+ "timeout_ms": 5000,
147
194
  "poll_interval_ms": 300,
148
195
  "match": { "index": 0 },
149
196
  "retry": { "max_attempts": 1, "backoff_ms": 0 },
150
- "platform": "android|ios",
151
- "deviceId": "optional device id"
197
+ "platform": "android",
198
+ "deviceId": "emulator-5554"
152
199
  }
153
200
  ```
154
201
 
155
- Success response highlights:
156
- - status: `success`
157
- - matched: number of matches found in the current poll
158
- - element: matched element metadata including `elementId`
159
- - metrics: latency, poll count, attempts
160
-
161
- Failure/timeout response:
162
- - status: `timeout`
163
- - error: structured error with `code` and `message`
164
- - metrics: latency, poll count, attempts
202
+ Success response:
165
203
 
166
- Notes & tips:
167
- - `wait_for_ui` is responsible for **resolution only**.
168
- - Successful responses now include an `elementId` that can be passed to `tap_element`.
169
- - This enables the deterministic loop: **observe -> act -> verify**.
204
+ ```json
205
+ {
206
+ "status": "success",
207
+ "matched": 1,
208
+ "element": {
209
+ "text": "Generate Session",
210
+ "resource_id": null,
211
+ "accessibility_id": null,
212
+ "class": "android.widget.TextView",
213
+ "bounds": [471, 1098, 809, 1158],
214
+ "index": 8,
215
+ "elementId": "el_..."
216
+ },
217
+ "metrics": { "latency_ms": 120, "poll_count": 1, "attempts": 1 }
218
+ }
219
+ ```
170
220
 
171
- Tests:
172
- - Unit: `test/unit/interact/wait_for_ui_contract.test.ts` and `test/unit/interact/wait_for_ui_selector_matching.test.ts`
173
- - Automated device checks now live under `test/device/automated/...`; manual/debug runners live under `test/device/manual/...` (requires devices/emulators and adb/xcrun in PATH)
221
+ Timeout response:
174
222
 
175
- Example:
176
- ```
177
- ToolsInteract.waitForUIHandler({
178
- selector: { text: 'Generate Session' },
179
- condition: 'clickable',
180
- timeout_ms: 5000,
181
- platform: 'android'
182
- })
223
+ ```json
224
+ {
225
+ "status": "timeout",
226
+ "error": { "code": "ELEMENT_NOT_FOUND", "message": "Condition visible not satisfied within timeout" },
227
+ "metrics": { "latency_ms": 5000, "poll_count": 17, "attempts": 1 }
228
+ }
183
229
  ```
184
230
 
185
- Troubleshooting:
186
- - If `wait_for_ui` times out, confirm the selector is precise and that the current UI tree exposes the expected text, resource ID, or accessibility ID.
231
+ Notes:
232
+
233
+ - Use `wait_for_ui` to get a stable `elementId` for `tap_element`.
234
+ - Use it before an action when the target element or timing is uncertain.
235
+ - If the expected outcome is known after the action, follow with `expect_*`.
236
+
237
+ ---
187
238
 
188
239
  ## tap_element
189
240
 
190
- Purpose:
191
- - Execute a tap against a UI element that has already been resolved by `wait_for_ui`.
241
+ Tap a previously resolved UI element using its `elementId`.
192
242
 
193
243
  Input:
194
- ```
244
+
245
+ ```json
195
246
  { "elementId": "el_..." }
196
247
  ```
197
248
 
198
- Behavior:
199
- - validates that the element still exists in the current UI context
200
- - validates that the element is visible
201
- - validates that the element is enabled
202
- - performs the tap using the resolved element bounds
203
-
204
249
  Success response:
205
- ```
206
- { "success": true, "elementId": "el_123", "action": "tap" }
250
+
251
+ ```json
252
+ {
253
+ "action_id": "tap_element_1710000000000_1",
254
+ "timestamp": 1710000000000,
255
+ "action_type": "tap_element",
256
+ "target": {
257
+ "selector": { "elementId": "el_123" },
258
+ "resolved": {
259
+ "elementId": "el_123",
260
+ "text": "Play session",
261
+ "resource_id": null,
262
+ "accessibility_id": null,
263
+ "class": "android.widget.TextView",
264
+ "bounds": [519, 1770, 762, 1830],
265
+ "index": 11
266
+ }
267
+ },
268
+ "success": true,
269
+ "ui_fingerprint_before": "fp_before",
270
+ "ui_fingerprint_after": "fp_after"
271
+ }
207
272
  ```
208
273
 
209
274
  Failure response:
210
- ```
275
+
276
+ ```json
211
277
  {
278
+ "action_id": "tap_element_1710000000001_2",
279
+ "timestamp": 1710000000001,
280
+ "action_type": "tap_element",
281
+ "target": { "selector": { "elementId": "el_123" }, "resolved": null },
212
282
  "success": false,
213
- "elementId": "el_123",
214
- "action": "tap",
215
- "error": { "code": "element_not_found|element_not_visible|element_not_enabled", "message": "..." }
283
+ "failure_code": "STALE_REFERENCE",
284
+ "retryable": true,
285
+ "ui_fingerprint_before": "fp_before",
286
+ "ui_fingerprint_after": "fp_before"
287
+ }
288
+ ```
289
+
290
+ Recommended usage:
291
+
292
+ 1. resolve target with `wait_for_ui`
293
+ 2. call `tap_element`
294
+ 3. if needed, wait for transition with `wait_for_*`
295
+ 4. verify with `expect_*`
296
+
297
+ Verification guidance:
298
+
299
+ - navigation -> `expect_screen`
300
+ - local UI change -> `expect_element_visible`
301
+
302
+ Failure handling:
303
+
304
+ - `STALE_REFERENCE` -> re-resolve the element, then retry
305
+ - `ELEMENT_NOT_INTERACTABLE` -> wait or refine the target, then retry
306
+ - `UNKNOWN` -> capture a snapshot and stop
307
+
308
+ ---
309
+
310
+ ## expect_screen
311
+
312
+ Deterministically verify that the intended navigation outcome of an action has occurred.
313
+
314
+ Input:
315
+
316
+ ```json
317
+ { "platform": "android", "deviceId": "emulator-5554", "fingerprint": "<expected-fingerprint>" }
318
+ ```
319
+
320
+ or
321
+
322
+ ```json
323
+ { "platform": "android", "deviceId": "emulator-5554", "screen": "com.example.app.MainActivity" }
324
+ ```
325
+
326
+ Response:
327
+
328
+ ```json
329
+ {
330
+ "success": true,
331
+ "observed_screen": { "fingerprint": "<actual-fingerprint>", "screen": "com.example.app.MainActivity" },
332
+ "expected_screen": { "fingerprint": "<expected-fingerprint>", "screen": null },
333
+ "confidence": 1
334
+ }
335
+ ```
336
+
337
+ Notes:
338
+
339
+ - Primary and authoritative verification tool for navigation outcomes.
340
+ - Prefer fingerprints; use semantic screen identifiers as a fallback.
341
+ - Works best when the expected screen identifier is known ahead of time.
342
+ - If transition timing is uncertain, place `wait_for_screen_change` before `expect_screen`.
343
+
344
+ ---
345
+
346
+ ## expect_element_visible
347
+
348
+ Deterministically verify that the intended UI outcome of an action has occurred by confirming a target element is visible.
349
+
350
+ Input:
351
+
352
+ ```json
353
+ {
354
+ "selector": { "text": "Play session" },
355
+ "element_id": "optional-resolved-element-id",
356
+ "timeout_ms": 5000,
357
+ "poll_interval_ms": 300,
358
+ "platform": "android",
359
+ "deviceId": "emulator-5554"
360
+ }
361
+ ```
362
+
363
+ Response:
364
+
365
+ ```json
366
+ {
367
+ "success": true,
368
+ "selector": { "text": "Play session" },
369
+ "element_id": "el_123",
370
+ "element": {
371
+ "elementId": "el_123",
372
+ "text": "Play session",
373
+ "resource_id": null,
374
+ "accessibility_id": null,
375
+ "class": "android.widget.TextView",
376
+ "bounds": [519, 1770, 762, 1830],
377
+ "index": 11
378
+ }
216
379
  }
217
380
  ```
218
381
 
219
382
  Notes:
220
- - `tap_element` does **not** accept selectors.
221
- - `tap_element` does **not** perform lookup, waiting, retries, or ambiguity resolution.
222
- - Migration pattern for selector-based flows is:
223
- 1. `wait_for_ui(selector)`
224
- 2. `tap_element(elementId)`
383
+
384
+ - Primary and authoritative verification tool for expected element visibility.
385
+ - `selector` is the primary input; `element_id` is optional context only.
386
+ - The tool resolves the selector internally when needed.
387
+ - Use when the screen should remain on the same destination but a specific element should appear or become visible.
@@ -1,6 +1,16 @@
1
1
  # Manage (build & device management)
2
2
 
3
- This document covers tools that perform project builds, device selection and lifecycle operations (install/start/terminate/restart/reset).
3
+ This document covers tools that perform project builds, device selection, installation, and app lifecycle operations.
4
+
5
+ For app launch and restart flows, agents should use:
6
+
7
+ **ACT -> WAIT (if needed) -> EXPECT**
8
+
9
+ For example:
10
+
11
+ 1. `start_app` or `restart_app`
12
+ 2. optional `wait_for_screen_change`
13
+ 3. `expect_screen` when the expected landing screen is known
4
14
 
5
15
  ## list_devices
6
16
  Enumerate connected Android devices and iOS simulators.
@@ -22,58 +32,32 @@ Notes:
22
32
 
23
33
  ---
24
34
 
25
- ## build_app / build_android / build_ios
26
- Build a project and return the path to the generated artifact (APK or .app/.ipa).
35
+ ## build_app
36
+ Build a project and return the path to the generated artifact.
27
37
 
28
- Input (examples):
29
-
30
- Android:
31
-
32
- ```json
33
- { "projectPath": "/path/to/project", "gradleTask": "assembleDebug", "maxWorkers": 4 }
34
- ```
35
-
36
- iOS:
38
+ Input:
37
39
 
38
40
  ```json
39
- { "projectPath": "/path/to/project", "scheme": "AppScheme", "derivedDataPath": "/tmp/derived", "buildJobs": 4 }
41
+ { "platform": "android", "projectType": "kmp", "projectPath": "/path/to/project", "variant": "Debug" }
40
42
  ```
41
43
 
42
44
  Response:
43
45
 
44
- ```
45
- { "artifactPath": "/path/to/build/output/app.apk" }
46
- ```
47
-
48
- Notes:
49
- - Android: honors `MCP_GRADLE_WORKERS` / `MCP_GRADLE_CACHE`; will prefer project gradlew when present.
50
- - iOS: honors `MCP_DERIVED_DATA`, `MCP_BUILD_JOBS` and `MCP_XCODE_DESTINATION_UDID`.
51
-
52
- ---
53
-
54
- ## build_flutter / build_react_native
55
- Framework-specific helpers. These are best-effort and may delegate to native subprojects when necessary.
56
-
57
- Input (flutter example):
58
-
59
46
  ```json
60
- { "projectPath": "/path/to/flutter", "platform": "android", "buildMode": "debug" }
61
- ```
62
-
63
- Response:
64
-
65
- ```
66
47
  { "artifactPath": "/path/to/build/output/app.apk" }
67
48
  ```
68
49
 
69
50
  Notes:
70
- - Flutter: prefers `FLUTTER_PATH` or `flutter` on PATH; iOS builds may require codesigning and CocoaPods.
71
- - React Native: delegates to android/ios subprojects; run `pod install` in CI before iOS builds.
51
+ - Requires `platform`, `projectType`, and `projectPath`.
52
+ - Android builds prefer the project `gradlew` when present.
53
+ - iOS builds honor environment-based Xcode destination and derived-data settings where configured.
72
54
 
73
55
  ---
74
56
 
75
57
  ## build_and_install (buildAndInstallHandler)
76
- Orchestrates build then install and returns streamed NDJSON events and a final result object.
58
+ Orchestrates build then install and returns streamed NDJSON events plus a final result object.
59
+
60
+ This is a documented repository helper, not part of the main public MCP tool list in `toolDefinitions`.
77
61
 
78
62
  Input:
79
63
 
@@ -135,6 +119,23 @@ start_app input example:
135
119
  start_app response example:
136
120
 
137
121
  ```json
138
- { "device": { "platform": "android", "id": "emulator-5554" }, "appStarted": true, "launchTimeMs": 142 }
122
+ {
123
+ "action_id": "start_app_1710000000000_1",
124
+ "timestamp": 1710000000000,
125
+ "action_type": "start_app",
126
+ "target": { "selector": { "appId": "com.example.app" }, "resolved": null },
127
+ "success": true,
128
+ "ui_fingerprint_before": "fp_before",
129
+ "ui_fingerprint_after": "fp_after"
130
+ }
139
131
  ```
140
132
 
133
+ restart_app returns the same action envelope shape with `action_type: "restart_app"`.
134
+
135
+ terminate_app and reset_app_data return operation-specific lifecycle results instead of the action envelope.
136
+
137
+ Notes:
138
+
139
+ - `start_app` and `restart_app` report execution success, not outcome correctness.
140
+ - When the landing screen is known, use `expect_screen` as the final verification step.
141
+ - If launch timing is uncertain, insert `wait_for_screen_change` before `expect_screen`.