devlens-mcp 0.3.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.
Files changed (175) hide show
  1. package/.claude/settings.json +12 -0
  2. package/.claude/settings.local.json +17 -0
  3. package/INSTALLATION_GUIDE.md +354 -0
  4. package/QUICK_START.md +153 -0
  5. package/README.md +354 -0
  6. package/bin/cli.ts +22 -0
  7. package/bin/register.ts +96 -0
  8. package/dist/bin/cli.d.ts +3 -0
  9. package/dist/bin/cli.d.ts.map +1 -0
  10. package/dist/bin/cli.js +20 -0
  11. package/dist/bin/cli.js.map +1 -0
  12. package/dist/bin/register.d.ts +10 -0
  13. package/dist/bin/register.d.ts.map +1 -0
  14. package/dist/bin/register.js +92 -0
  15. package/dist/bin/register.js.map +1 -0
  16. package/dist/src/config/devlens-config.d.ts +92 -0
  17. package/dist/src/config/devlens-config.d.ts.map +1 -0
  18. package/dist/src/config/devlens-config.js +70 -0
  19. package/dist/src/config/devlens-config.js.map +1 -0
  20. package/dist/src/index.d.ts +35 -0
  21. package/dist/src/index.d.ts.map +1 -0
  22. package/dist/src/index.js +8 -0
  23. package/dist/src/index.js.map +1 -0
  24. package/dist/src/metro/cdp-client.d.ts +48 -0
  25. package/dist/src/metro/cdp-client.d.ts.map +1 -0
  26. package/dist/src/metro/cdp-client.js +127 -0
  27. package/dist/src/metro/cdp-client.js.map +1 -0
  28. package/dist/src/metro/log-collector.d.ts +30 -0
  29. package/dist/src/metro/log-collector.d.ts.map +1 -0
  30. package/dist/src/metro/log-collector.js +114 -0
  31. package/dist/src/metro/log-collector.js.map +1 -0
  32. package/dist/src/metro/metro-bridge.d.ts +56 -0
  33. package/dist/src/metro/metro-bridge.d.ts.map +1 -0
  34. package/dist/src/metro/metro-bridge.js +255 -0
  35. package/dist/src/metro/metro-bridge.js.map +1 -0
  36. package/dist/src/metro/network-inspector.d.ts +34 -0
  37. package/dist/src/metro/network-inspector.d.ts.map +1 -0
  38. package/dist/src/metro/network-inspector.js +100 -0
  39. package/dist/src/metro/network-inspector.js.map +1 -0
  40. package/dist/src/platform/android/adb.d.ts +50 -0
  41. package/dist/src/platform/android/adb.d.ts.map +1 -0
  42. package/dist/src/platform/android/adb.js +137 -0
  43. package/dist/src/platform/android/adb.js.map +1 -0
  44. package/dist/src/platform/android/android-device.d.ts +21 -0
  45. package/dist/src/platform/android/android-device.d.ts.map +1 -0
  46. package/dist/src/platform/android/android-device.js +94 -0
  47. package/dist/src/platform/android/android-device.js.map +1 -0
  48. package/dist/src/platform/android/ui-automator.d.ts +17 -0
  49. package/dist/src/platform/android/ui-automator.d.ts.map +1 -0
  50. package/dist/src/platform/android/ui-automator.js +126 -0
  51. package/dist/src/platform/android/ui-automator.js.map +1 -0
  52. package/dist/src/platform/device-manager.d.ts +28 -0
  53. package/dist/src/platform/device-manager.d.ts.map +1 -0
  54. package/dist/src/platform/device-manager.js +185 -0
  55. package/dist/src/platform/device-manager.js.map +1 -0
  56. package/dist/src/platform/device.d.ts +86 -0
  57. package/dist/src/platform/device.d.ts.map +1 -0
  58. package/dist/src/platform/device.js +7 -0
  59. package/dist/src/platform/device.js.map +1 -0
  60. package/dist/src/platform/ios/accessibility.d.ts +17 -0
  61. package/dist/src/platform/ios/accessibility.d.ts.map +1 -0
  62. package/dist/src/platform/ios/accessibility.js +159 -0
  63. package/dist/src/platform/ios/accessibility.js.map +1 -0
  64. package/dist/src/platform/ios/ios-device.d.ts +22 -0
  65. package/dist/src/platform/ios/ios-device.d.ts.map +1 -0
  66. package/dist/src/platform/ios/ios-device.js +97 -0
  67. package/dist/src/platform/ios/ios-device.js.map +1 -0
  68. package/dist/src/platform/ios/simctl.d.ts +54 -0
  69. package/dist/src/platform/ios/simctl.d.ts.map +1 -0
  70. package/dist/src/platform/ios/simctl.js +192 -0
  71. package/dist/src/platform/ios/simctl.js.map +1 -0
  72. package/dist/src/server.d.ts +3 -0
  73. package/dist/src/server.d.ts.map +1 -0
  74. package/dist/src/server.js +176 -0
  75. package/dist/src/server.js.map +1 -0
  76. package/dist/src/snapshot/formatter.d.ts +18 -0
  77. package/dist/src/snapshot/formatter.d.ts.map +1 -0
  78. package/dist/src/snapshot/formatter.js +86 -0
  79. package/dist/src/snapshot/formatter.js.map +1 -0
  80. package/dist/src/snapshot/ref-registry.d.ts +67 -0
  81. package/dist/src/snapshot/ref-registry.d.ts.map +1 -0
  82. package/dist/src/snapshot/ref-registry.js +169 -0
  83. package/dist/src/snapshot/ref-registry.js.map +1 -0
  84. package/dist/src/snapshot/snapshot-differ.d.ts +57 -0
  85. package/dist/src/snapshot/snapshot-differ.d.ts.map +1 -0
  86. package/dist/src/snapshot/snapshot-differ.js +153 -0
  87. package/dist/src/snapshot/snapshot-differ.js.map +1 -0
  88. package/dist/src/tools/app-tools.d.ts +71 -0
  89. package/dist/src/tools/app-tools.d.ts.map +1 -0
  90. package/dist/src/tools/app-tools.js +97 -0
  91. package/dist/src/tools/app-tools.js.map +1 -0
  92. package/dist/src/tools/device-tools.d.ts +53 -0
  93. package/dist/src/tools/device-tools.d.ts.map +1 -0
  94. package/dist/src/tools/device-tools.js +86 -0
  95. package/dist/src/tools/device-tools.js.map +1 -0
  96. package/dist/src/tools/ds-tools.d.ts +65 -0
  97. package/dist/src/tools/ds-tools.d.ts.map +1 -0
  98. package/dist/src/tools/ds-tools.js +314 -0
  99. package/dist/src/tools/ds-tools.js.map +1 -0
  100. package/dist/src/tools/interaction-tools.d.ts +248 -0
  101. package/dist/src/tools/interaction-tools.d.ts.map +1 -0
  102. package/dist/src/tools/interaction-tools.js +391 -0
  103. package/dist/src/tools/interaction-tools.js.map +1 -0
  104. package/dist/src/tools/metro-tools.d.ts +115 -0
  105. package/dist/src/tools/metro-tools.d.ts.map +1 -0
  106. package/dist/src/tools/metro-tools.js +270 -0
  107. package/dist/src/tools/metro-tools.js.map +1 -0
  108. package/dist/src/tools/navigation-tools.d.ts +36 -0
  109. package/dist/src/tools/navigation-tools.d.ts.map +1 -0
  110. package/dist/src/tools/navigation-tools.js +60 -0
  111. package/dist/src/tools/navigation-tools.js.map +1 -0
  112. package/dist/src/tools/screenshot-tools.d.ts +298 -0
  113. package/dist/src/tools/screenshot-tools.d.ts.map +1 -0
  114. package/dist/src/tools/screenshot-tools.js +565 -0
  115. package/dist/src/tools/screenshot-tools.js.map +1 -0
  116. package/dist/src/tools/snapshot-tools.d.ts +161 -0
  117. package/dist/src/tools/snapshot-tools.d.ts.map +1 -0
  118. package/dist/src/tools/snapshot-tools.js +479 -0
  119. package/dist/src/tools/snapshot-tools.js.map +1 -0
  120. package/dist/src/utils/image-preprocess.d.ts +49 -0
  121. package/dist/src/utils/image-preprocess.d.ts.map +1 -0
  122. package/dist/src/utils/image-preprocess.js +322 -0
  123. package/dist/src/utils/image-preprocess.js.map +1 -0
  124. package/dist/src/utils/retry.d.ts +21 -0
  125. package/dist/src/utils/retry.d.ts.map +1 -0
  126. package/dist/src/utils/retry.js +33 -0
  127. package/dist/src/utils/retry.js.map +1 -0
  128. package/dist/src/visual/comparator.d.ts +51 -0
  129. package/dist/src/visual/comparator.d.ts.map +1 -0
  130. package/dist/src/visual/comparator.js +119 -0
  131. package/dist/src/visual/comparator.js.map +1 -0
  132. package/dist/src/visual/layout-analyzer.d.ts +64 -0
  133. package/dist/src/visual/layout-analyzer.d.ts.map +1 -0
  134. package/dist/src/visual/layout-analyzer.js +198 -0
  135. package/dist/src/visual/layout-analyzer.js.map +1 -0
  136. package/dist/src/visual/screenshot.d.ts +17 -0
  137. package/dist/src/visual/screenshot.d.ts.map +1 -0
  138. package/dist/src/visual/screenshot.js +39 -0
  139. package/dist/src/visual/screenshot.js.map +1 -0
  140. package/docs/figma-workflow.md +289 -0
  141. package/docs/setup-guide.md +360 -0
  142. package/docs/tool-reference.md +622 -0
  143. package/package.json +57 -0
  144. package/src/config/devlens-config.ts +76 -0
  145. package/src/index.ts +5 -0
  146. package/src/metro/cdp-client.ts +160 -0
  147. package/src/metro/log-collector.ts +137 -0
  148. package/src/metro/metro-bridge.ts +307 -0
  149. package/src/metro/network-inspector.ts +134 -0
  150. package/src/platform/android/adb.ts +200 -0
  151. package/src/platform/android/android-device.ts +116 -0
  152. package/src/platform/android/ui-automator.ts +141 -0
  153. package/src/platform/device-manager.ts +229 -0
  154. package/src/platform/device.ts +110 -0
  155. package/src/platform/ios/accessibility.ts +189 -0
  156. package/src/platform/ios/ios-device.ts +116 -0
  157. package/src/platform/ios/simctl.ts +244 -0
  158. package/src/server.ts +228 -0
  159. package/src/snapshot/formatter.ts +102 -0
  160. package/src/snapshot/ref-registry.ts +230 -0
  161. package/src/snapshot/snapshot-differ.ts +220 -0
  162. package/src/tools/app-tools.ts +111 -0
  163. package/src/tools/device-tools.ts +96 -0
  164. package/src/tools/ds-tools.ts +395 -0
  165. package/src/tools/interaction-tools.ts +467 -0
  166. package/src/tools/metro-tools.ts +320 -0
  167. package/src/tools/navigation-tools.ts +71 -0
  168. package/src/tools/screenshot-tools.ts +698 -0
  169. package/src/tools/snapshot-tools.ts +585 -0
  170. package/src/utils/image-preprocess.ts +430 -0
  171. package/src/utils/retry.ts +51 -0
  172. package/src/visual/comparator.ts +191 -0
  173. package/src/visual/layout-analyzer.ts +283 -0
  174. package/src/visual/screenshot.ts +49 -0
  175. package/tsconfig.json +20 -0
@@ -0,0 +1,622 @@
1
+ # DevLens Tool Reference
2
+
3
+ Complete reference for all **33** DevLens MCP tools, organized by category.
4
+
5
+ > **Tip:** Use `devlens_metro_status` at the start of every session to verify Metro is healthy before invoking Metro-dependent tools.
6
+
7
+ ---
8
+
9
+ ## Device Management (3)
10
+
11
+ ### devlens_list_devices
12
+ List all running iOS Simulators and Android Emulators.
13
+
14
+ **Parameters:** None
15
+
16
+ **Returns:** Device IDs, names, platforms, OS versions, and boot status.
17
+
18
+ **Example response:**
19
+ ```
20
+ Found 2 device(s):
21
+
22
+ ● Pixel 7 (android, 14) — id: emulator-5554
23
+ ● iPhone 16 (ios, 18.0) — id: ABCD-1234-EFGH
24
+ ```
25
+
26
+ ---
27
+
28
+ ### devlens_device_info
29
+ Get detailed information about a device.
30
+
31
+ | Param | Type | Required | Description |
32
+ |-------|------|----------|-------------|
33
+ | `deviceId` | string | No | Device ID. Uses first available if omitted. |
34
+
35
+ **Example response:**
36
+ ```
37
+ Device: Pixel 7
38
+ Platform: android
39
+ OS Version: 14
40
+ Screen: 1080x2400
41
+ Orientation: portrait
42
+ ID: emulator-5554
43
+ ```
44
+
45
+ ---
46
+
47
+ ### devlens_set_orientation
48
+ Set device orientation.
49
+
50
+ | Param | Type | Required | Description |
51
+ |-------|------|----------|-------------|
52
+ | `orientation` | "portrait" \| "landscape" | Yes | Target orientation |
53
+
54
+ ---
55
+
56
+ ## App Management (4)
57
+
58
+ ### devlens_launch_app
59
+ Launch an installed app.
60
+
61
+ | Param | Type | Required | Description |
62
+ |-------|------|----------|-------------|
63
+ | `appId` | string | Yes | Bundle ID (iOS) or package name (Android) |
64
+
65
+ **Example:** `devlens_launch_app(appId: "com.example.myapp")`
66
+
67
+ ---
68
+
69
+ ### devlens_terminate_app
70
+ Force stop a running app.
71
+
72
+ | Param | Type | Required | Description |
73
+ |-------|------|----------|-------------|
74
+ | `appId` | string | Yes | Bundle ID or package name |
75
+
76
+ ---
77
+
78
+ ### devlens_install_app
79
+ Install an app from local file.
80
+
81
+ | Param | Type | Required | Description |
82
+ |-------|------|----------|-------------|
83
+ | `path` | string | Yes | Path to .apk (Android) or .app/.ipa (iOS) |
84
+
85
+ ---
86
+
87
+ ### devlens_list_apps
88
+ List all installed third-party apps.
89
+
90
+ **Parameters:** None
91
+
92
+ ---
93
+
94
+ ## Snapshot & Elements (5)
95
+
96
+ ### devlens_snapshot
97
+ **The core tool.** Captures the accessibility tree with Playwright-style ref IDs.
98
+
99
+ | Param | Type | Required | Description |
100
+ |-------|------|----------|-------------|
101
+ | `mode` | "full" \| "incremental" | No | "full" (default) returns entire tree. "incremental" returns only changes since last snapshot. |
102
+ | `validate` | boolean | No | When `true`, appends a **Validation Report** that flags zero-size elements, invisible nodes, and empty containers. Default: `false`. |
103
+
104
+ **Example response:**
105
+ ```
106
+ - FrameLayout
107
+ - LinearLayout
108
+ - ImageView "Logo" [ref=e1]
109
+ - TextView "Welcome to MyApp" [ref=e2]
110
+ - EditText "Email" [ref=e3] [focused] [id="email_input"]
111
+ - EditText "Password" [ref=e4] [id="password_input"]
112
+ - Button "Sign In" [ref=e5]
113
+ - TextView "Forgot Password?" [ref=e6]
114
+ - BottomNavigationView
115
+ - MenuItem "Home" [ref=e7]
116
+ - MenuItem "Profile" [ref=e8]
117
+
118
+ 8 elements with refs assigned.
119
+ ```
120
+
121
+ **With `validate: true`:**
122
+ ```
123
+ ...tree output...
124
+
125
+ === Validation Report ===
126
+ Total: 42 nodes | Visible: 38 | Zero-size: 4 | Interactive: 12
127
+
128
+ ⚠ Issues found:
129
+ • ImageView "BrandLogo" has zero size (0x0) — renders as invisible
130
+ • View id="divider_line" is an empty container (no children, no text)
131
+ ```
132
+
133
+ Use the `ref=eN` values with interaction tools (`devlens_tap`, `devlens_type`, etc.).
134
+
135
+ ---
136
+
137
+ ### devlens_find_element
138
+ Find elements matching text, accessibility label, or element type.
139
+
140
+ | Param | Type | Required | Description |
141
+ |-------|------|----------|-------------|
142
+ | `text` | string | No | Text content to search (partial match) |
143
+ | `label` | string | No | Accessibility label to search (partial match) |
144
+ | `type` | string | No | Element type to search (partial, case-insensitive). E.g., "Button", "ScrollView", "EditText" |
145
+
146
+ At least one of `text`, `label`, or `type` must be provided. When `type` is combined with `text`/`label`, elements must match the type AND one of text/label.
147
+
148
+ **Invisible element detection:** If no visible matches are found, DevLens also searches zero-size (invisible) nodes. If a match is found there, a warning is returned:
149
+
150
+ ```
151
+ No visible elements found for "BrandLogo", but found 1 invisible match:
152
+ ⚠ ImageView "BrandLogo" exists but has zero size (0x0) — it renders as invisible.
153
+ This usually means the image source is missing, the style sets width/height to 0,
154
+ or a parent container is collapsing.
155
+ ```
156
+
157
+ ---
158
+
159
+ ### devlens_wait_for_element
160
+ Wait for an element to appear on screen.
161
+
162
+ | Param | Type | Required | Description |
163
+ |-------|------|----------|-------------|
164
+ | `text` | string | No | Text to wait for |
165
+ | `label` | string | No | Label to wait for |
166
+ | `timeout` | number | No | Max wait in ms (default: 10000) |
167
+
168
+ ---
169
+
170
+ ### devlens_wait_for_screen
171
+ Wait for the screen to stabilize or for specific content to appear. **Replaces manual sleep+screenshot loops.**
172
+
173
+ | Param | Type | Required | Description |
174
+ |-------|------|----------|-------------|
175
+ | `text` | string | No | Wait until this text appears on screen |
176
+ | `label` | string | No | Wait until this label appears on screen |
177
+ | `stableMs` | number | No | Stability window in ms — screen must remain unchanged for this duration (default: 1000) |
178
+ | `timeoutMs` | number | No | Max wait time in ms (default: 10000) |
179
+
180
+ **Two modes:**
181
+
182
+ 1. **Content mode** (when `text` or `label` is provided): Polls every 500ms until the specified text/label appears in the snapshot.
183
+ 2. **Stability mode** (when neither is provided): Takes periodic snapshots and waits until the screen stops changing (no diff for `stableMs` milliseconds).
184
+
185
+ **Returns:** The current snapshot with ref IDs on success. Returns `isError: true` with the latest snapshot on timeout.
186
+
187
+ **Example usage:**
188
+ ```
189
+ # Wait for a specific screen after navigation
190
+ devlens_wait_for_screen(text: "Welcome Back")
191
+
192
+ # Wait for screen to stop animating/loading
193
+ devlens_wait_for_screen(stableMs: 2000)
194
+ ```
195
+
196
+ ---
197
+
198
+ ### devlens_element_info
199
+ Get detailed info about an element by ref, including **inferred layout direction**.
200
+
201
+ | Param | Type | Required | Description |
202
+ |-------|------|----------|-------------|
203
+ | `ref` | string | Yes | Element ref (e.g., "e5") |
204
+
205
+ **Response includes:**
206
+ - Element type, text, label, resource ID
207
+ - Bounds (x, y, width, height)
208
+ - Interactive status, focused status, visibility
209
+ - Children count
210
+ - **Inferred Layout** (for containers with children): `row`, `column`, `stacked`, `wrap`, or `unknown`
211
+
212
+ **Example response (container):**
213
+ ```
214
+ Element [e3]: LinearLayout
215
+ Bounds: 0,200 1080x400
216
+ Interactive: false
217
+ Children: 4
218
+ Inferred Layout: row (children arranged left-to-right)
219
+ 1. ImageView "icon" — x:12, y:210
220
+ 2. TextView "Title" — x:60, y:210
221
+ 3. TextView "Subtitle" — x:400, y:210
222
+ 4. Button "Action" — x:800, y:210
223
+ ```
224
+
225
+ ---
226
+
227
+ ## Interaction (8)
228
+
229
+ ### devlens_tap
230
+ Tap an element. Like Playwright's `browser_click`.
231
+
232
+ | Param | Type | Required | Description |
233
+ |-------|------|----------|-------------|
234
+ | `ref` | string | Yes | Element ref from devlens_snapshot |
235
+ | `element` | string | Yes | Human description (e.g., "Submit button") |
236
+
237
+ Returns updated snapshot after tap.
238
+
239
+ ---
240
+
241
+ ### devlens_type
242
+ Type text into an input.
243
+
244
+ | Param | Type | Required | Description |
245
+ |-------|------|----------|-------------|
246
+ | `ref` | string | Yes | Input element ref |
247
+ | `text` | string | Yes | Text to type |
248
+ | `submit` | boolean | No | Press Enter after typing (default: false) |
249
+
250
+ Automatically taps the element to focus it first.
251
+
252
+ ---
253
+
254
+ ### devlens_swipe
255
+ Swipe gesture.
256
+
257
+ | Param | Type | Required | Description |
258
+ |-------|------|----------|-------------|
259
+ | `direction` | "up" \| "down" \| "left" \| "right" | Yes | Direction |
260
+ | `ref` | string | No | Swipe from this element's center |
261
+ | `distance` | number | No | Distance in pixels (default: 500) |
262
+
263
+ ---
264
+
265
+ ### devlens_scroll
266
+ Scroll a scrollable container.
267
+
268
+ | Param | Type | Required | Description |
269
+ |-------|------|----------|-------------|
270
+ | `ref` | string | Yes | Scrollable container ref |
271
+ | `direction` | "up" \| "down" | Yes | Scroll direction |
272
+
273
+ ---
274
+
275
+ ### devlens_long_press
276
+ Long press an element.
277
+
278
+ | Param | Type | Required | Description |
279
+ |-------|------|----------|-------------|
280
+ | `ref` | string | Yes | Element ref |
281
+ | `duration` | number | No | Duration in ms (default: 1000) |
282
+
283
+ ---
284
+
285
+ ### devlens_press_button
286
+ Press a hardware/system button.
287
+
288
+ | Param | Type | Required | Description |
289
+ |-------|------|----------|-------------|
290
+ | `button` | "home" \| "back" \| "enter" | Yes | Button to press |
291
+
292
+ ---
293
+
294
+ ### devlens_fill_form
295
+ Fill multiple form fields at once.
296
+
297
+ | Param | Type | Required | Description |
298
+ |-------|------|----------|-------------|
299
+ | `fields` | Array<{ref, value}> | Yes | Fields to fill |
300
+
301
+ **Example:**
302
+ ```json
303
+ {
304
+ "fields": [
305
+ { "ref": "e3", "value": "user@example.com" },
306
+ { "ref": "e4", "value": "password123" }
307
+ ]
308
+ }
309
+ ```
310
+
311
+ ---
312
+
313
+ ### devlens_capture_flow
314
+ Execute a sequence of actions and capture labeled screenshots. Batch-verify multiple screens in a single call.
315
+
316
+ | Param | Type | Required | Description |
317
+ |-------|------|----------|-------------|
318
+ | `steps` | Array | Yes | Sequence of step objects |
319
+
320
+ **Step object:**
321
+
322
+ | Field | Type | Required | Description |
323
+ |-------|------|----------|-------------|
324
+ | `action` | "tap" \| "screenshot" \| "go_back" \| "swipe" \| "wait" \| "press_button" | Yes | Action to perform |
325
+ | `ref` | string | No | Element ref for tap/swipe |
326
+ | `element` | string | No | Human description for tap |
327
+ | `label` | string | No | Label for screenshot steps |
328
+ | `direction` | "up" \| "down" \| "left" \| "right" | No | Direction for swipe |
329
+ | `button` | "home" \| "back" \| "enter" | No | Button for press_button |
330
+ | `ms` | number | No | Wait duration in ms (default: 1000) |
331
+
332
+ **Example — verify 3 tabs:**
333
+ ```json
334
+ {
335
+ "steps": [
336
+ { "action": "tap", "ref": "e5", "element": "Chats tab" },
337
+ { "action": "screenshot", "label": "chats-screen" },
338
+ { "action": "tap", "ref": "e6", "element": "Tools tab" },
339
+ { "action": "screenshot", "label": "tools-screen" },
340
+ { "action": "tap", "ref": "e7", "element": "Media tab" },
341
+ { "action": "screenshot", "label": "media-screen" }
342
+ ]
343
+ }
344
+ ```
345
+
346
+ Returns all labeled screenshots + a final snapshot with refs.
347
+
348
+ ---
349
+
350
+ ## Screenshots & Visual Comparison (5)
351
+
352
+ ### devlens_screenshot
353
+ Take a screenshot of the current screen.
354
+
355
+ | Param | Type | Required | Description |
356
+ |-------|------|----------|-------------|
357
+ | `filename` | string | No | Save path (defaults to /tmp/devlens-screenshot-{timestamp}.png) |
358
+
359
+ Returns base64-encoded image + saved file path.
360
+
361
+ ---
362
+
363
+ ### devlens_compare_screenshot
364
+ Compare current screen against a reference image from a file path, HTTP URL, or base64 data. Supports region cropping.
365
+
366
+ | Param | Type | Required | Description |
367
+ |-------|------|----------|-------------|
368
+ | `referenceImagePath` | string | No | Path to reference PNG, or an HTTP/HTTPS URL to fetch it from |
369
+ | `referenceImageBase64` | string | No | Base64-encoded PNG data (without `data:` prefix) |
370
+ | `threshold` | number | No | Color threshold 0-1 (default: 0.1, lower = stricter) |
371
+ | `resizeStrategy` | "fit" \| "scale" \| "crop" | No | How to handle dimension mismatches (default: "fit") |
372
+ | `cropRef` | string | No | Crop device screenshot to this element's bounds before comparing |
373
+ | `region` | {x, y, width, height} | No | Crop device screenshot to this pixel region before comparing |
374
+
375
+ > At least one of `referenceImagePath` or `referenceImageBase64` must be provided.
376
+
377
+ **Resize strategies:**
378
+ - **`fit`** (default) — Resize both images to the smaller dimensions. Best for general comparison.
379
+ - **`scale`** — Resize the smaller image up to match the larger. Use when the reference is lower resolution.
380
+ - **`crop`** — Extract the overlapping region from both images. Use when comparing a section of the screen.
381
+
382
+ **Returns:**
383
+ - `similarity`: 0.0 to 1.0 (percentage match)
384
+ - `diffPixels`: Number of different pixels
385
+ - `diffImagePath`: Path to diff image (red highlights = differences)
386
+ - `summary`: Human-readable assessment
387
+ - Both the current screenshot and diff image as base64
388
+
389
+ **Example — compare just a component:**
390
+ ```
391
+ devlens_snapshot() # get refs
392
+ devlens_compare_screenshot(
393
+ referenceImagePath: "./design-refs/header.png",
394
+ cropRef: "e3" # only compare the header element
395
+ )
396
+ ```
397
+
398
+ ---
399
+
400
+ ### devlens_element_screenshot
401
+ Screenshot a specific element.
402
+
403
+ | Param | Type | Required | Description |
404
+ |-------|------|----------|-------------|
405
+ | `ref` | string | Yes | Element ref |
406
+ | `filename` | string | No | Save path |
407
+
408
+ ---
409
+
410
+ ### devlens_compare_images
411
+ Compare two saved images (A/B comparison). Useful for before/after screenshots.
412
+
413
+ | Param | Type | Required | Description |
414
+ |-------|------|----------|-------------|
415
+ | `imageA` | string | Yes | Path or HTTP URL of the first image |
416
+ | `imageB` | string | Yes | Path or HTTP URL of the second image |
417
+ | `threshold` | number | No | Color threshold 0-1 (default: 0.1) |
418
+ | `resizeStrategy` | "fit" \| "scale" \| "crop" | No | Dimension mismatch handling (default: "fit") |
419
+
420
+ Returns similarity score, diff pixel count, and diff image (same format as `devlens_compare_screenshot`).
421
+
422
+ ---
423
+
424
+ ### devlens_compare_with_figma
425
+ **The Figma verification tool.** Compare the device screen directly against a Figma design. Fetches the Figma frame via REST API and runs pixel comparison. Requires `FIGMA_TOKEN` environment variable.
426
+
427
+ | Param | Type | Required | Description |
428
+ |-------|------|----------|-------------|
429
+ | `figmaUrl` | string | No | Full Figma URL (e.g., `https://figma.com/design/ABC/MyApp?node-id=10-200`) |
430
+ | `fileKey` | string | No | Figma file key (alternative to figmaUrl) |
431
+ | `nodeId` | string | No | Figma node ID e.g., "10:200" (use with fileKey) |
432
+ | `scale` | number | No | Export scale (default: 2) |
433
+ | `threshold` | number | No | Color threshold 0-1 (default: 0.1) |
434
+ | `resizeStrategy` | "fit" \| "scale" \| "crop" | No | Dimension mismatch handling (default: "fit") |
435
+ | `cropRef` | string | No | Crop device screenshot to element bounds |
436
+ | `region` | {x, y, width, height} | No | Crop device screenshot to pixel region |
437
+
438
+ > Provide either `figmaUrl`, or both `fileKey` and `nodeId`.
439
+
440
+ **Example:**
441
+ ```
442
+ devlens_compare_with_figma(
443
+ figmaUrl: "https://figma.com/design/ABC123/MyApp?node-id=10-200"
444
+ )
445
+ → Similarity: 94.2%
446
+ → Diff image highlighting mismatches
447
+ ```
448
+
449
+ ---
450
+
451
+ ## React Native / Metro (6)
452
+
453
+ ### devlens_metro_status
454
+ **Health check tool.** Check if the Metro bundler is running and healthy. Call this at the start of every session and before any Metro-dependent operation.
455
+
456
+ **Parameters:** None
457
+
458
+ **Returns:** Metro health report including running status, port, packager status, and CDP connection state.
459
+
460
+ **Example responses:**
461
+
462
+ When Metro is running:
463
+ ```
464
+ Metro Bundler Status:
465
+ Running: true
466
+ Port: 8081
467
+ Packager: packager-status:running
468
+ CDP Connected: false
469
+
470
+ Metro is healthy. You can use hot reload and other Metro tools.
471
+ ```
472
+
473
+ When Metro is down:
474
+ ```
475
+ Metro Bundler Status:
476
+ Running: false
477
+ Port: 8081
478
+ Packager: —
479
+ CDP Connected: false
480
+ Error: Cannot reach Metro on port 8081: fetch failed
481
+
482
+ Metro is NOT running. Start it with:
483
+ cd your-project && npx react-native start
484
+ ```
485
+
486
+ ---
487
+
488
+ ### devlens_metro_logs
489
+ Get console output from the React Native app.
490
+
491
+ | Param | Type | Required | Description |
492
+ |-------|------|----------|-------------|
493
+ | `level` | "error" \| "warn" \| "info" \| "debug" | No | Minimum log level |
494
+ | `since` | string | No | ISO timestamp — only show logs after this time |
495
+
496
+ **Example response:**
497
+ ```
498
+ Metro logs (5 entries):
499
+
500
+ [14:32:01.123] LOG User navigated to HomeScreen
501
+ [14:32:02.456] LOG API call: GET /api/products
502
+ [14:32:03.789] WARN Image component has no alt text
503
+ [14:32:04.012] ERROR Network request failed: timeout
504
+ [14:32:05.345] LOG Rendered 24 products
505
+ ```
506
+
507
+ ---
508
+
509
+ ### devlens_component_tree
510
+ Get the React component hierarchy.
511
+
512
+ | Param | Type | Required | Description |
513
+ |-------|------|----------|-------------|
514
+ | `depth` | number | No | Max tree depth (default: 10) |
515
+
516
+ Shows component names, props, and nesting. Requires `__DEV__` mode.
517
+
518
+ ---
519
+
520
+ ### devlens_hot_reload
521
+ Trigger a hot reload / fast refresh.
522
+
523
+ **Parameters:** None
524
+
525
+ Call this after modifying React Native source files. Waits 1.5s for the reload to take effect.
526
+
527
+ ---
528
+
529
+ ### devlens_network_requests
530
+ List network requests made by the app.
531
+
532
+ | Param | Type | Required | Description |
533
+ |-------|------|----------|-------------|
534
+ | `urlPattern` | string | No | Filter by URL substring |
535
+
536
+ **Example response:**
537
+ ```
538
+ Network requests (3 total):
539
+
540
+ GET 200 145ms 12.3KB https://api.example.com/products
541
+ POST 201 89ms 0.5KB https://api.example.com/cart
542
+ GET 404 23ms 0.1KB https://api.example.com/user/avatar
543
+ ```
544
+
545
+ ---
546
+
547
+ ### devlens_dismiss_overlays
548
+ Dismiss React Native debug overlays (LogBox warnings, dev menu banners) that interfere with screenshots.
549
+
550
+ | Param | Type | Required | Description |
551
+ |-------|------|----------|-------------|
552
+ | `suppressLogBox` | boolean | No | Suppress LogBox via JavaScript injection (default: true) |
553
+ | `pressBack` | boolean | No | Press Back button to close modal overlays (default: false) |
554
+
555
+ **Example:**
556
+ ```
557
+ devlens_dismiss_overlays()
558
+ → LogBox suppressed; LogBox uninstalled
559
+
560
+ devlens_dismiss_overlays(pressBack: true)
561
+ → LogBox suppressed; Back button pressed (dismiss modal overlay)
562
+ ```
563
+
564
+ ---
565
+
566
+ ## Navigation (2)
567
+
568
+ ### devlens_open_url
569
+ Open a URL or deep link.
570
+
571
+ | Param | Type | Required | Description |
572
+ |-------|------|----------|-------------|
573
+ | `url` | string | Yes | URL or deep link (e.g., "myapp://profile") |
574
+
575
+ ---
576
+
577
+ ### devlens_go_back
578
+ Navigate back.
579
+
580
+ **Parameters:** None
581
+
582
+ On Android: presses system Back button. On iOS: performs back swipe.
583
+
584
+ ---
585
+
586
+ ## Quick Reference Table
587
+
588
+ | # | Tool | Category | Key Params |
589
+ |---|------|----------|------------|
590
+ | 1 | `devlens_list_devices` | Device | — |
591
+ | 2 | `devlens_device_info` | Device | deviceId? |
592
+ | 3 | `devlens_set_orientation` | Device | orientation |
593
+ | 4 | `devlens_launch_app` | App | appId |
594
+ | 5 | `devlens_terminate_app` | App | appId |
595
+ | 6 | `devlens_install_app` | App | path |
596
+ | 7 | `devlens_list_apps` | App | — |
597
+ | 8 | `devlens_snapshot` | Snapshot | mode?, validate? |
598
+ | 9 | `devlens_find_element` | Snapshot | text?, label?, type? |
599
+ | 10 | `devlens_wait_for_element` | Snapshot | text?, label?, timeout? |
600
+ | 11 | `devlens_wait_for_screen` | Snapshot | text?, label?, stableMs?, timeoutMs? |
601
+ | 12 | `devlens_element_info` | Snapshot | ref |
602
+ | 13 | `devlens_tap` | Interaction | ref, element |
603
+ | 14 | `devlens_type` | Interaction | ref, text, submit? |
604
+ | 15 | `devlens_swipe` | Interaction | direction, ref?, distance? |
605
+ | 16 | `devlens_scroll` | Interaction | ref, direction |
606
+ | 17 | `devlens_long_press` | Interaction | ref, duration? |
607
+ | 18 | `devlens_press_button` | Interaction | button |
608
+ | 19 | `devlens_fill_form` | Interaction | fields |
609
+ | 20 | `devlens_capture_flow` | Interaction | steps |
610
+ | 21 | `devlens_screenshot` | Visual | filename? |
611
+ | 22 | `devlens_compare_screenshot` | Visual | referenceImagePath?, referenceImageBase64?, cropRef?, region? |
612
+ | 23 | `devlens_element_screenshot` | Visual | ref, filename? |
613
+ | 24 | `devlens_compare_images` | Visual | imageA, imageB, threshold?, resizeStrategy? |
614
+ | 25 | `devlens_compare_with_figma` | Visual | figmaUrl?, fileKey?, nodeId?, cropRef?, region? |
615
+ | 26 | `devlens_metro_status` | Metro | — |
616
+ | 27 | `devlens_metro_logs` | Metro | level?, since? |
617
+ | 28 | `devlens_component_tree` | Metro | depth? |
618
+ | 29 | `devlens_hot_reload` | Metro | — |
619
+ | 30 | `devlens_network_requests` | Metro | urlPattern? |
620
+ | 31 | `devlens_dismiss_overlays` | Metro | suppressLogBox?, pressBack? |
621
+ | 32 | `devlens_open_url` | Navigation | url |
622
+ | 33 | `devlens_go_back` | Navigation | — |
package/package.json ADDED
@@ -0,0 +1,57 @@
1
+ {
2
+ "name": "devlens-mcp",
3
+ "version": "0.3.0",
4
+ "description": "DevLens — Playwright-style MCP server for mobile development. Take screenshots, compare with Figma designs, interact with iOS Simulators & Android Emulators, and access Metro bundler logs.",
5
+ "main": "dist/index.js",
6
+ "types": "dist/index.d.ts",
7
+ "bin": {
8
+ "devlens-mcp": "dist/bin/cli.js"
9
+ },
10
+ "scripts": {
11
+ "build": "tsc",
12
+ "postbuild": "node dist/bin/register.js",
13
+ "dev": "tsc --watch",
14
+ "start": "node dist/bin/cli.js",
15
+ "register": "node dist/bin/register.js --register",
16
+ "test": "vitest run",
17
+ "test:watch": "vitest",
18
+ "lint": "eslint src/",
19
+ "prepublishOnly": "npm run build"
20
+ },
21
+ "keywords": [
22
+ "mcp",
23
+ "mobile",
24
+ "react-native",
25
+ "playwright",
26
+ "automation",
27
+ "ios",
28
+ "android",
29
+ "emulator",
30
+ "simulator",
31
+ "figma",
32
+ "devtools",
33
+ "testing"
34
+ ],
35
+ "author": "",
36
+ "license": "MIT",
37
+ "engines": {
38
+ "node": ">=18.0.0"
39
+ },
40
+ "dependencies": {
41
+ "@modelcontextprotocol/sdk": "^1.12.0",
42
+ "fast-xml-parser": "^4.5.0",
43
+ "pixelmatch": "^5.3.0",
44
+ "pngjs": "^7.0.0",
45
+ "sharp": "^0.33.0",
46
+ "ws": "^8.18.0",
47
+ "zod": "^3.23.0"
48
+ },
49
+ "devDependencies": {
50
+ "@types/node": "^20.0.0",
51
+ "@types/pixelmatch": "^5.2.6",
52
+ "@types/pngjs": "^6.0.5",
53
+ "@types/ws": "^8.5.0",
54
+ "typescript": "^5.5.0",
55
+ "vitest": "^2.0.0"
56
+ }
57
+ }