mobile-debug-mcp 0.24.3 → 0.24.4

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.
@@ -344,6 +344,7 @@ Capabilities:
344
344
  Constraints:
345
345
  - Does not verify correctness of the resulting state
346
346
  - Must not be used alone to confirm action success when an applicable expect_* tool exists
347
+ - Use classify_action_outcome + get_network_activity when the expected outcome is backend/API activity without a visible UI change
347
348
 
348
349
  Recommended Usage:
349
350
  1. Capture or define the expected outcome
@@ -835,6 +836,8 @@ Failure Handling:
835
836
  description: `Classify the outcome of the most recent action into exactly one of: success, no_op, backend_failure, ui_failure, unknown.
836
837
 
837
838
  MUST be called after every action (tap, swipe, type_text, press_back, start_app, etc). Never skip.
839
+ Use this with get_network_activity when the expected outcome is backend/API activity without a visible UI change.
840
+ For backend/API activity, compare get_screen_fingerprint before and after the action and call get_network_activity immediately after the action instead of waiting for wait_for_screen_change.
838
841
 
839
842
  HOW TO GATHER INPUTS before calling:
840
843
  1. Call wait_for_screen_change or compare get_screen_fingerprint before/after — set uiChanged accordingly.
@@ -868,7 +871,7 @@ BEHAVIOUR after outcome:
868
871
  },
869
872
  networkRequests: {
870
873
  type: 'array',
871
- description: 'Pass this only after calling get_network_activity as instructed by nextAction. Map each request to endpoint + status.',
874
+ description: 'Pass this only after calling get_network_activity as instructed by nextAction. Also use it when the expected outcome is backend/API activity without a visible UI change.',
872
875
  items: {
873
876
  type: 'object',
874
877
  properties: {
@@ -890,7 +893,7 @@ BEHAVIOUR after outcome:
890
893
  name: 'get_network_activity',
891
894
  description: `Returns structured network events captured from platform logs since the last action.
892
895
 
893
- Call this only when classify_action_outcome returns nextAction="call_get_network_activity".
896
+ Call this when classify_action_outcome returns nextAction="call_get_network_activity" or immediately after an action whose expected outcome is backend/API activity without a visible UI change.
894
897
  Do not call more than once per action.
895
898
 
896
899
  Events are filtered to significant (non-background) requests only.
package/docs/CHANGELOG.md CHANGED
@@ -2,6 +2,9 @@
2
2
 
3
3
  All notable changes to the **Mobile Debug MCP** project will be documented in this file.
4
4
 
5
+ ## [0.24.4]
6
+ - Moving agents away from `wait_for_screen_change`
7
+
5
8
  ## [0.24.3]
6
9
  - Improved output consistency
7
10
 
@@ -36,6 +36,14 @@ It does not apply to:
36
36
  - observation-only flows
37
37
  - non-verifiable or exploratory actions
38
38
 
39
+ Outcome-specific guidance:
40
+
41
+ - visible navigation expected -> `wait_for_screen_change` (optional) -> `expect_screen`
42
+ - local UI change expected -> `wait_for_ui` (optional) -> `expect_element_visible`
43
+ - backend/API activity expected without a visible UI change -> compare `get_screen_fingerprint` before/after, then call `get_network_activity` immediately after the action and `classify_action_outcome` with the observed requests
44
+
45
+ For backend/API activity, `wait_for_screen_change` is not the right verification tool unless a visible transition is also expected.
46
+
39
47
  ## 4. Action Tools
40
48
 
41
49
  ### 4.1 Definition
@@ -211,6 +219,7 @@ Rules:
211
219
  - MUST be deterministic
212
220
  - MUST NOT replace `expect_*` tools
213
221
  - MUST be treated as a supplementary signal only
222
+ - SHOULD be used with `get_network_activity` when the expected outcome is backend/API activity without a visible UI change
214
223
 
215
224
  It is not a verification mechanism.
216
225
 
@@ -53,6 +53,10 @@ Preferred verification:
53
53
 
54
54
  - navigation outcome known -> `expect_screen`
55
55
  - local UI change known -> `expect_element_visible`
56
+ - backend/API activity expected -> `classify_action_outcome` + `get_network_activity`
57
+
58
+ Use `wait_for_screen_change` only when a visible transition is the expected outcome. If a button should trigger an API request but the screen should stay the same, rely on network activity and classification instead.
59
+ For backend-only actions, prefer comparing `get_screen_fingerprint` before/after and call `get_network_activity` immediately after the action; do not wait on `wait_for_screen_change` if no visible transition is expected.
56
60
 
57
61
  ---
58
62
 
@@ -139,6 +143,7 @@ Notes:
139
143
  - Treats `null` fingerprints as transient and keeps polling.
140
144
  - Adds a stability confirmation before returning success to avoid transient animation frames.
141
145
  - Follow with `expect_screen` when the expected destination is known.
146
+ - Do not use this as the main success check for backend/API activity that does not change the visible UI.
142
147
 
143
148
  ---
144
149
 
@@ -451,3 +456,22 @@ Notes:
451
456
  - The tool resolves the selector internally when needed.
452
457
  - On failure, `reason` and `observed` tell you whether the selector was missing entirely or present but not yet visible.
453
458
  - Use when the screen should remain on the same destination but a specific element should appear or become visible.
459
+
460
+ ---
461
+
462
+ ## classify_action_outcome + get_network_activity
463
+
464
+ Use this pair when the action is expected to trigger network/backend work and the screen may not visibly change.
465
+
466
+ Pattern:
467
+
468
+ 1. perform the action
469
+ 2. call `classify_action_outcome` with `uiChanged` from `wait_for_screen_change` or a screen fingerprint comparison
470
+ 3. if the classifier asks for it, call `get_network_activity`
471
+ 4. call `classify_action_outcome` again with `networkRequests`
472
+
473
+ Guidance:
474
+
475
+ - `uiChanged=true` or `expectedElementVisible=true` means the action outcome is already verified
476
+ - `nextAction="call_get_network_activity"` means the UI signal was inconclusive and the agent should inspect network activity
477
+ - if network requests succeed but the UI stays unchanged, treat the outcome as a backend/API result rather than a screen transition
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "mobile-debug-mcp",
3
- "version": "0.24.3",
3
+ "version": "0.24.4",
4
4
  "description": "MCP server for mobile app debugging (Android + iOS), with focus on security and reliability",
5
5
  "type": "module",
6
6
  "bin": {
@@ -344,6 +344,7 @@ Capabilities:
344
344
  Constraints:
345
345
  - Does not verify correctness of the resulting state
346
346
  - Must not be used alone to confirm action success when an applicable expect_* tool exists
347
+ - Use classify_action_outcome + get_network_activity when the expected outcome is backend/API activity without a visible UI change
347
348
 
348
349
  Recommended Usage:
349
350
  1. Capture or define the expected outcome
@@ -835,6 +836,8 @@ Failure Handling:
835
836
  description: `Classify the outcome of the most recent action into exactly one of: success, no_op, backend_failure, ui_failure, unknown.
836
837
 
837
838
  MUST be called after every action (tap, swipe, type_text, press_back, start_app, etc). Never skip.
839
+ Use this with get_network_activity when the expected outcome is backend/API activity without a visible UI change.
840
+ For backend/API activity, compare get_screen_fingerprint before and after the action and call get_network_activity immediately after the action instead of waiting for wait_for_screen_change.
838
841
 
839
842
  HOW TO GATHER INPUTS before calling:
840
843
  1. Call wait_for_screen_change or compare get_screen_fingerprint before/after — set uiChanged accordingly.
@@ -868,7 +871,7 @@ BEHAVIOUR after outcome:
868
871
  },
869
872
  networkRequests: {
870
873
  type: 'array',
871
- description: 'Pass this only after calling get_network_activity as instructed by nextAction. Map each request to endpoint + status.',
874
+ description: 'Pass this only after calling get_network_activity as instructed by nextAction. Also use it when the expected outcome is backend/API activity without a visible UI change.',
872
875
  items: {
873
876
  type: 'object',
874
877
  properties: {
@@ -890,7 +893,7 @@ BEHAVIOUR after outcome:
890
893
  name: 'get_network_activity',
891
894
  description: `Returns structured network events captured from platform logs since the last action.
892
895
 
893
- Call this only when classify_action_outcome returns nextAction="call_get_network_activity".
896
+ Call this when classify_action_outcome returns nextAction="call_get_network_activity" or immediately after an action whose expected outcome is backend/API activity without a visible UI change.
894
897
  Do not call more than once per action.
895
898
 
896
899
  Events are filtered to significant (non-background) requests only.
@@ -26,6 +26,7 @@ async function run() {
26
26
  assert(waitForScreenChange, 'wait_for_screen_change should be registered')
27
27
  assert.match((waitForScreenChange as any).description, /does not verify correctness of the resulting state/i)
28
28
  assert.match((waitForScreenChange as any).description, /follow with expect_screen/i)
29
+ assert.match((waitForScreenChange as any).description, /backend\/API activity without a visible UI change/i)
29
30
 
30
31
  const captureDebugSnapshot = toolDefinitions.find((tool) => tool.name === 'capture_debug_snapshot')
31
32
  assert(captureDebugSnapshot, 'capture_debug_snapshot should be registered')
@@ -60,6 +61,18 @@ async function run() {
60
61
  assert.match((expectElementVisible as any).description, /selector is the primary input/i)
61
62
  assert.match((expectElementVisible as any).description, /Returns structured binary success\/failure only/i)
62
63
 
64
+ const classifyActionOutcome = toolDefinitions.find((tool) => tool.name === 'classify_action_outcome')
65
+ assert(classifyActionOutcome, 'classify_action_outcome should be registered')
66
+ assert.match((classifyActionOutcome as any).description, /backend\/API activity without a visible UI change/i)
67
+ assert.match((classifyActionOutcome as any).description, /get_network_activity/i)
68
+ assert.match((classifyActionOutcome as any).description, /immediately after the action/i)
69
+
70
+ const getNetworkActivity = toolDefinitions.find((tool) => tool.name === 'get_network_activity')
71
+ assert(getNetworkActivity, 'get_network_activity should be registered')
72
+ assert.match((getNetworkActivity as any).description, /backend\/API activity without a visible UI change/i)
73
+ assert.doesNotMatch((getNetworkActivity as any).description, /Call this only when/i)
74
+ assert.match((getNetworkActivity as any).description, /immediately after an action/i)
75
+
63
76
  await assert.rejects(() => handleToolCall('unknown_tool'), /Unknown tool: unknown_tool/)
64
77
 
65
78
  console.log('server contract tests passed')