@metamask/device-mcp 0.1.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 (315) hide show
  1. package/CHANGELOG.md +34 -0
  2. package/README.md +266 -0
  3. package/dist/backends/adb-backend.cjs +442 -0
  4. package/dist/backends/adb-backend.cjs.map +1 -0
  5. package/dist/backends/adb-backend.d.cts +35 -0
  6. package/dist/backends/adb-backend.d.cts.map +1 -0
  7. package/dist/backends/adb-backend.d.mts +35 -0
  8. package/dist/backends/adb-backend.d.mts.map +1 -0
  9. package/dist/backends/adb-backend.mjs +436 -0
  10. package/dist/backends/adb-backend.mjs.map +1 -0
  11. package/dist/backends/appium-backend.cjs +518 -0
  12. package/dist/backends/appium-backend.cjs.map +1 -0
  13. package/dist/backends/appium-backend.d.cts +36 -0
  14. package/dist/backends/appium-backend.d.cts.map +1 -0
  15. package/dist/backends/appium-backend.d.mts +36 -0
  16. package/dist/backends/appium-backend.d.mts.map +1 -0
  17. package/dist/backends/appium-backend.mjs +512 -0
  18. package/dist/backends/appium-backend.mjs.map +1 -0
  19. package/dist/backends/idb-backend.cjs +442 -0
  20. package/dist/backends/idb-backend.cjs.map +1 -0
  21. package/dist/backends/idb-backend.d.cts +35 -0
  22. package/dist/backends/idb-backend.d.cts.map +1 -0
  23. package/dist/backends/idb-backend.d.mts +35 -0
  24. package/dist/backends/idb-backend.d.mts.map +1 -0
  25. package/dist/backends/idb-backend.mjs +436 -0
  26. package/dist/backends/idb-backend.mjs.map +1 -0
  27. package/dist/backends/index.cjs +134 -0
  28. package/dist/backends/index.cjs.map +1 -0
  29. package/dist/backends/index.d.cts +16 -0
  30. package/dist/backends/index.d.cts.map +1 -0
  31. package/dist/backends/index.d.mts +16 -0
  32. package/dist/backends/index.d.mts.map +1 -0
  33. package/dist/backends/index.mjs +126 -0
  34. package/dist/backends/index.mjs.map +1 -0
  35. package/dist/backends/session-file.cjs +62 -0
  36. package/dist/backends/session-file.cjs.map +1 -0
  37. package/dist/backends/session-file.d.cts +24 -0
  38. package/dist/backends/session-file.d.cts.map +1 -0
  39. package/dist/backends/session-file.d.mts +24 -0
  40. package/dist/backends/session-file.d.mts.map +1 -0
  41. package/dist/backends/session-file.mjs +59 -0
  42. package/dist/backends/session-file.mjs.map +1 -0
  43. package/dist/backends/types.cjs +3 -0
  44. package/dist/backends/types.cjs.map +1 -0
  45. package/dist/backends/types.d.cts +93 -0
  46. package/dist/backends/types.d.cts.map +1 -0
  47. package/dist/backends/types.d.mts +93 -0
  48. package/dist/backends/types.d.mts.map +1 -0
  49. package/dist/backends/types.mjs +2 -0
  50. package/dist/backends/types.mjs.map +1 -0
  51. package/dist/backends/webdriver-client.cjs +167 -0
  52. package/dist/backends/webdriver-client.cjs.map +1 -0
  53. package/dist/backends/webdriver-client.d.cts +55 -0
  54. package/dist/backends/webdriver-client.d.cts.map +1 -0
  55. package/dist/backends/webdriver-client.d.mts +55 -0
  56. package/dist/backends/webdriver-client.d.mts.map +1 -0
  57. package/dist/backends/webdriver-client.mjs +162 -0
  58. package/dist/backends/webdriver-client.mjs.map +1 -0
  59. package/dist/cli/device-mcp.cjs +20 -0
  60. package/dist/cli/device-mcp.cjs.map +1 -0
  61. package/dist/cli/device-mcp.d.cts +3 -0
  62. package/dist/cli/device-mcp.d.cts.map +1 -0
  63. package/dist/cli/device-mcp.d.mts +3 -0
  64. package/dist/cli/device-mcp.d.mts.map +1 -0
  65. package/dist/cli/device-mcp.mjs +18 -0
  66. package/dist/cli/device-mcp.mjs.map +1 -0
  67. package/dist/index.cjs +9 -0
  68. package/dist/index.cjs.map +1 -0
  69. package/dist/index.d.cts +5 -0
  70. package/dist/index.d.cts.map +1 -0
  71. package/dist/index.d.mts +5 -0
  72. package/dist/index.d.mts.map +1 -0
  73. package/dist/index.mjs +3 -0
  74. package/dist/index.mjs.map +1 -0
  75. package/dist/server.cjs +43 -0
  76. package/dist/server.cjs.map +1 -0
  77. package/dist/server.d.cts +4 -0
  78. package/dist/server.d.cts.map +1 -0
  79. package/dist/server.d.mts +4 -0
  80. package/dist/server.d.mts.map +1 -0
  81. package/dist/server.mjs +40 -0
  82. package/dist/server.mjs.map +1 -0
  83. package/dist/tools/alert-text.cjs +25 -0
  84. package/dist/tools/alert-text.cjs.map +1 -0
  85. package/dist/tools/alert-text.d.cts +4 -0
  86. package/dist/tools/alert-text.d.cts.map +1 -0
  87. package/dist/tools/alert-text.d.mts +4 -0
  88. package/dist/tools/alert-text.d.mts.map +1 -0
  89. package/dist/tools/alert-text.mjs +22 -0
  90. package/dist/tools/alert-text.mjs.map +1 -0
  91. package/dist/tools/app-state.cjs +40 -0
  92. package/dist/tools/app-state.cjs.map +1 -0
  93. package/dist/tools/app-state.d.cts +4 -0
  94. package/dist/tools/app-state.d.cts.map +1 -0
  95. package/dist/tools/app-state.d.mts +4 -0
  96. package/dist/tools/app-state.d.mts.map +1 -0
  97. package/dist/tools/app-state.mjs +37 -0
  98. package/dist/tools/app-state.mjs.map +1 -0
  99. package/dist/tools/clipboard.cjs +42 -0
  100. package/dist/tools/clipboard.cjs.map +1 -0
  101. package/dist/tools/clipboard.d.cts +4 -0
  102. package/dist/tools/clipboard.d.cts.map +1 -0
  103. package/dist/tools/clipboard.d.mts +4 -0
  104. package/dist/tools/clipboard.d.mts.map +1 -0
  105. package/dist/tools/clipboard.mjs +39 -0
  106. package/dist/tools/clipboard.mjs.map +1 -0
  107. package/dist/tools/close-app.cjs +25 -0
  108. package/dist/tools/close-app.cjs.map +1 -0
  109. package/dist/tools/close-app.d.cts +4 -0
  110. package/dist/tools/close-app.d.cts.map +1 -0
  111. package/dist/tools/close-app.d.mts +4 -0
  112. package/dist/tools/close-app.d.mts.map +1 -0
  113. package/dist/tools/close-app.mjs +22 -0
  114. package/dist/tools/close-app.mjs.map +1 -0
  115. package/dist/tools/context.cjs +52 -0
  116. package/dist/tools/context.cjs.map +1 -0
  117. package/dist/tools/context.d.cts +4 -0
  118. package/dist/tools/context.d.cts.map +1 -0
  119. package/dist/tools/context.d.mts +4 -0
  120. package/dist/tools/context.d.mts.map +1 -0
  121. package/dist/tools/context.mjs +49 -0
  122. package/dist/tools/context.mjs.map +1 -0
  123. package/dist/tools/device-info.cjs +34 -0
  124. package/dist/tools/device-info.cjs.map +1 -0
  125. package/dist/tools/device-info.d.cts +4 -0
  126. package/dist/tools/device-info.d.cts.map +1 -0
  127. package/dist/tools/device-info.d.mts +4 -0
  128. package/dist/tools/device-info.d.mts.map +1 -0
  129. package/dist/tools/device-info.mjs +31 -0
  130. package/dist/tools/device-info.mjs.map +1 -0
  131. package/dist/tools/dismiss-alert.cjs +34 -0
  132. package/dist/tools/dismiss-alert.cjs.map +1 -0
  133. package/dist/tools/dismiss-alert.d.cts +4 -0
  134. package/dist/tools/dismiss-alert.d.cts.map +1 -0
  135. package/dist/tools/dismiss-alert.d.mts +4 -0
  136. package/dist/tools/dismiss-alert.d.mts.map +1 -0
  137. package/dist/tools/dismiss-alert.mjs +31 -0
  138. package/dist/tools/dismiss-alert.mjs.map +1 -0
  139. package/dist/tools/dismiss-keyboard.cjs +23 -0
  140. package/dist/tools/dismiss-keyboard.cjs.map +1 -0
  141. package/dist/tools/dismiss-keyboard.d.cts +4 -0
  142. package/dist/tools/dismiss-keyboard.d.cts.map +1 -0
  143. package/dist/tools/dismiss-keyboard.d.mts +4 -0
  144. package/dist/tools/dismiss-keyboard.d.mts.map +1 -0
  145. package/dist/tools/dismiss-keyboard.mjs +20 -0
  146. package/dist/tools/dismiss-keyboard.mjs.map +1 -0
  147. package/dist/tools/generate-locators.cjs +33 -0
  148. package/dist/tools/generate-locators.cjs.map +1 -0
  149. package/dist/tools/generate-locators.d.cts +4 -0
  150. package/dist/tools/generate-locators.d.cts.map +1 -0
  151. package/dist/tools/generate-locators.d.mts +4 -0
  152. package/dist/tools/generate-locators.d.mts.map +1 -0
  153. package/dist/tools/generate-locators.mjs +30 -0
  154. package/dist/tools/generate-locators.mjs.map +1 -0
  155. package/dist/tools/index.cjs +50 -0
  156. package/dist/tools/index.cjs.map +1 -0
  157. package/dist/tools/index.d.cts +24 -0
  158. package/dist/tools/index.d.cts.map +1 -0
  159. package/dist/tools/index.d.mts +24 -0
  160. package/dist/tools/index.d.mts.map +1 -0
  161. package/dist/tools/index.mjs +24 -0
  162. package/dist/tools/index.mjs.map +1 -0
  163. package/dist/tools/logs.cjs +48 -0
  164. package/dist/tools/logs.cjs.map +1 -0
  165. package/dist/tools/logs.d.cts +4 -0
  166. package/dist/tools/logs.d.cts.map +1 -0
  167. package/dist/tools/logs.d.mts +4 -0
  168. package/dist/tools/logs.d.mts.map +1 -0
  169. package/dist/tools/logs.mjs +45 -0
  170. package/dist/tools/logs.mjs.map +1 -0
  171. package/dist/tools/long-press.cjs +38 -0
  172. package/dist/tools/long-press.cjs.map +1 -0
  173. package/dist/tools/long-press.d.cts +4 -0
  174. package/dist/tools/long-press.d.cts.map +1 -0
  175. package/dist/tools/long-press.d.mts +4 -0
  176. package/dist/tools/long-press.d.mts.map +1 -0
  177. package/dist/tools/long-press.mjs +35 -0
  178. package/dist/tools/long-press.mjs.map +1 -0
  179. package/dist/tools/open-app.cjs +26 -0
  180. package/dist/tools/open-app.cjs.map +1 -0
  181. package/dist/tools/open-app.d.cts +4 -0
  182. package/dist/tools/open-app.d.cts.map +1 -0
  183. package/dist/tools/open-app.d.mts +4 -0
  184. package/dist/tools/open-app.d.mts.map +1 -0
  185. package/dist/tools/open-app.mjs +23 -0
  186. package/dist/tools/open-app.mjs.map +1 -0
  187. package/dist/tools/press-button.cjs +30 -0
  188. package/dist/tools/press-button.cjs.map +1 -0
  189. package/dist/tools/press-button.d.cts +4 -0
  190. package/dist/tools/press-button.d.cts.map +1 -0
  191. package/dist/tools/press-button.d.mts +4 -0
  192. package/dist/tools/press-button.d.mts.map +1 -0
  193. package/dist/tools/press-button.mjs +27 -0
  194. package/dist/tools/press-button.mjs.map +1 -0
  195. package/dist/tools/screen-recording.cjs +46 -0
  196. package/dist/tools/screen-recording.cjs.map +1 -0
  197. package/dist/tools/screen-recording.d.cts +4 -0
  198. package/dist/tools/screen-recording.d.cts.map +1 -0
  199. package/dist/tools/screen-recording.d.mts +4 -0
  200. package/dist/tools/screen-recording.d.mts.map +1 -0
  201. package/dist/tools/screen-recording.mjs +43 -0
  202. package/dist/tools/screen-recording.mjs.map +1 -0
  203. package/dist/tools/screenshot.cjs +42 -0
  204. package/dist/tools/screenshot.cjs.map +1 -0
  205. package/dist/tools/screenshot.d.cts +4 -0
  206. package/dist/tools/screenshot.d.cts.map +1 -0
  207. package/dist/tools/screenshot.d.mts +4 -0
  208. package/dist/tools/screenshot.d.mts.map +1 -0
  209. package/dist/tools/screenshot.mjs +39 -0
  210. package/dist/tools/screenshot.mjs.map +1 -0
  211. package/dist/tools/scroll-to-element.cjs +56 -0
  212. package/dist/tools/scroll-to-element.cjs.map +1 -0
  213. package/dist/tools/scroll-to-element.d.cts +4 -0
  214. package/dist/tools/scroll-to-element.d.cts.map +1 -0
  215. package/dist/tools/scroll-to-element.d.mts +4 -0
  216. package/dist/tools/scroll-to-element.d.mts.map +1 -0
  217. package/dist/tools/scroll-to-element.mjs +53 -0
  218. package/dist/tools/scroll-to-element.mjs.map +1 -0
  219. package/dist/tools/shared.cjs +11 -0
  220. package/dist/tools/shared.cjs.map +1 -0
  221. package/dist/tools/shared.d.cts +8 -0
  222. package/dist/tools/shared.d.cts.map +1 -0
  223. package/dist/tools/shared.d.mts +8 -0
  224. package/dist/tools/shared.d.mts.map +1 -0
  225. package/dist/tools/shared.mjs +8 -0
  226. package/dist/tools/shared.mjs.map +1 -0
  227. package/dist/tools/snapshot.cjs +37 -0
  228. package/dist/tools/snapshot.cjs.map +1 -0
  229. package/dist/tools/snapshot.d.cts +4 -0
  230. package/dist/tools/snapshot.d.cts.map +1 -0
  231. package/dist/tools/snapshot.d.mts +4 -0
  232. package/dist/tools/snapshot.d.mts.map +1 -0
  233. package/dist/tools/snapshot.mjs +34 -0
  234. package/dist/tools/snapshot.mjs.map +1 -0
  235. package/dist/tools/swipe.cjs +39 -0
  236. package/dist/tools/swipe.cjs.map +1 -0
  237. package/dist/tools/swipe.d.cts +4 -0
  238. package/dist/tools/swipe.d.cts.map +1 -0
  239. package/dist/tools/swipe.d.mts +4 -0
  240. package/dist/tools/swipe.d.mts.map +1 -0
  241. package/dist/tools/swipe.mjs +36 -0
  242. package/dist/tools/swipe.mjs.map +1 -0
  243. package/dist/tools/tap-coordinates.cjs +27 -0
  244. package/dist/tools/tap-coordinates.cjs.map +1 -0
  245. package/dist/tools/tap-coordinates.d.cts +4 -0
  246. package/dist/tools/tap-coordinates.d.cts.map +1 -0
  247. package/dist/tools/tap-coordinates.d.mts +4 -0
  248. package/dist/tools/tap-coordinates.d.mts.map +1 -0
  249. package/dist/tools/tap-coordinates.mjs +24 -0
  250. package/dist/tools/tap-coordinates.mjs.map +1 -0
  251. package/dist/tools/tap-element.cjs +46 -0
  252. package/dist/tools/tap-element.cjs.map +1 -0
  253. package/dist/tools/tap-element.d.cts +4 -0
  254. package/dist/tools/tap-element.d.cts.map +1 -0
  255. package/dist/tools/tap-element.d.mts +4 -0
  256. package/dist/tools/tap-element.d.mts.map +1 -0
  257. package/dist/tools/tap-element.mjs +43 -0
  258. package/dist/tools/tap-element.mjs.map +1 -0
  259. package/dist/tools/type-text.cjs +32 -0
  260. package/dist/tools/type-text.cjs.map +1 -0
  261. package/dist/tools/type-text.d.cts +4 -0
  262. package/dist/tools/type-text.d.cts.map +1 -0
  263. package/dist/tools/type-text.d.mts +4 -0
  264. package/dist/tools/type-text.d.mts.map +1 -0
  265. package/dist/tools/type-text.mjs +29 -0
  266. package/dist/tools/type-text.mjs.map +1 -0
  267. package/dist/tools/wait-for.cjs +51 -0
  268. package/dist/tools/wait-for.cjs.map +1 -0
  269. package/dist/tools/wait-for.d.cts +4 -0
  270. package/dist/tools/wait-for.d.cts.map +1 -0
  271. package/dist/tools/wait-for.d.mts +4 -0
  272. package/dist/tools/wait-for.d.mts.map +1 -0
  273. package/dist/tools/wait-for.mjs +48 -0
  274. package/dist/tools/wait-for.mjs.map +1 -0
  275. package/dist/tools/window-size.cjs +29 -0
  276. package/dist/tools/window-size.cjs.map +1 -0
  277. package/dist/tools/window-size.d.cts +4 -0
  278. package/dist/tools/window-size.d.cts.map +1 -0
  279. package/dist/tools/window-size.d.mts +4 -0
  280. package/dist/tools/window-size.d.mts.map +1 -0
  281. package/dist/tools/window-size.mjs +26 -0
  282. package/dist/tools/window-size.mjs.map +1 -0
  283. package/dist/utils/alert-labels.cjs +26 -0
  284. package/dist/utils/alert-labels.cjs.map +1 -0
  285. package/dist/utils/alert-labels.d.cts +3 -0
  286. package/dist/utils/alert-labels.d.cts.map +1 -0
  287. package/dist/utils/alert-labels.d.mts +3 -0
  288. package/dist/utils/alert-labels.d.mts.map +1 -0
  289. package/dist/utils/alert-labels.mjs +23 -0
  290. package/dist/utils/alert-labels.mjs.map +1 -0
  291. package/dist/utils/element.cjs +212 -0
  292. package/dist/utils/element.cjs.map +1 -0
  293. package/dist/utils/element.d.cts +24 -0
  294. package/dist/utils/element.d.cts.map +1 -0
  295. package/dist/utils/element.d.mts +24 -0
  296. package/dist/utils/element.d.mts.map +1 -0
  297. package/dist/utils/element.mjs +203 -0
  298. package/dist/utils/element.mjs.map +1 -0
  299. package/dist/utils/exec.cjs +57 -0
  300. package/dist/utils/exec.cjs.map +1 -0
  301. package/dist/utils/exec.d.cts +23 -0
  302. package/dist/utils/exec.d.cts.map +1 -0
  303. package/dist/utils/exec.d.mts +23 -0
  304. package/dist/utils/exec.d.mts.map +1 -0
  305. package/dist/utils/exec.mjs +52 -0
  306. package/dist/utils/exec.mjs.map +1 -0
  307. package/dist/utils/platform.cjs +93 -0
  308. package/dist/utils/platform.cjs.map +1 -0
  309. package/dist/utils/platform.d.cts +8 -0
  310. package/dist/utils/platform.d.cts.map +1 -0
  311. package/dist/utils/platform.d.mts +8 -0
  312. package/dist/utils/platform.d.mts.map +1 -0
  313. package/dist/utils/platform.mjs +90 -0
  314. package/dist/utils/platform.mjs.map +1 -0
  315. package/package.json +106 -0
@@ -0,0 +1 @@
1
+ {"version":3,"file":"screenshot.d.mts","sourceRoot":"","sources":["../../src/tools/screenshot.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,gDAAgD;AAIzE,OAAO,KAAK,EAAE,aAAa,EAAE,8BAA6B;AAE1D,wBAAgB,sBAAsB,CACpC,MAAM,EAAE,SAAS,EACjB,OAAO,EAAE,aAAa,GACrB,IAAI,CAuCN"}
@@ -0,0 +1,39 @@
1
+ import { z } from "zod";
2
+ import { errorResult } from "./shared.mjs";
3
+ export function registerScreenshotTool(server, backend) {
4
+ server.registerTool('device_screenshot', {
5
+ title: 'Screenshot',
6
+ description: 'Capture a screenshot of the current device screen. ' +
7
+ 'Returns base64-encoded PNG data. Optionally saves to a file path.',
8
+ inputSchema: {
9
+ outputPath: z
10
+ .string()
11
+ .optional()
12
+ .describe('File path to save the screenshot (optional)'),
13
+ },
14
+ annotations: { readOnlyHint: true },
15
+ }, async ({ outputPath }) => {
16
+ try {
17
+ const result = await backend.screenshot(outputPath);
18
+ return {
19
+ content: [
20
+ {
21
+ type: 'image',
22
+ data: result.data,
23
+ mimeType: `image/${result.format}`,
24
+ },
25
+ {
26
+ type: 'text',
27
+ text: result.path
28
+ ? `Screenshot saved to ${result.path}`
29
+ : 'Screenshot captured',
30
+ },
31
+ ],
32
+ };
33
+ }
34
+ catch (error) {
35
+ return errorResult(error);
36
+ }
37
+ });
38
+ }
39
+ //# sourceMappingURL=screenshot.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"screenshot.mjs","sourceRoot":"","sources":["../../src/tools/screenshot.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,CAAC,EAAE,YAAY;AAExB,OAAO,EAAE,WAAW,EAAE,qBAAoB;AAG1C,MAAM,UAAU,sBAAsB,CACpC,MAAiB,EACjB,OAAsB;IAEtB,MAAM,CAAC,YAAY,CACjB,mBAAmB,EACnB;QACE,KAAK,EAAE,YAAY;QACnB,WAAW,EACT,qDAAqD;YACrD,mEAAmE;QACrE,WAAW,EAAE;YACX,UAAU,EAAE,CAAC;iBACV,MAAM,EAAE;iBACR,QAAQ,EAAE;iBACV,QAAQ,CAAC,6CAA6C,CAAC;SAC3D;QACD,WAAW,EAAE,EAAE,YAAY,EAAE,IAAI,EAAE;KACpC,EACD,KAAK,EAAE,EAAE,UAAU,EAAE,EAAE,EAAE;QACvB,IAAI,CAAC;YACH,MAAM,MAAM,GAAG,MAAM,OAAO,CAAC,UAAU,CAAC,UAAU,CAAC,CAAC;YACpD,OAAO;gBACL,OAAO,EAAE;oBACP;wBACE,IAAI,EAAE,OAAgB;wBACtB,IAAI,EAAE,MAAM,CAAC,IAAI;wBACjB,QAAQ,EAAE,SAAS,MAAM,CAAC,MAAM,EAAE;qBACnC;oBACD;wBACE,IAAI,EAAE,MAAe;wBACrB,IAAI,EAAE,MAAM,CAAC,IAAI;4BACf,CAAC,CAAC,uBAAuB,MAAM,CAAC,IAAI,EAAE;4BACtC,CAAC,CAAC,qBAAqB;qBAC1B;iBACF;aACF,CAAC;QACJ,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,OAAO,WAAW,CAAC,KAAK,CAAC,CAAC;QAC5B,CAAC;IACH,CAAC,CACF,CAAC;AACJ,CAAC","sourcesContent":["import type { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';\nimport { z } from 'zod';\n\nimport { errorResult } from './shared.js';\nimport type { DeviceBackend } from '../backends/types.js';\n\nexport function registerScreenshotTool(\n server: McpServer,\n backend: DeviceBackend,\n): void {\n server.registerTool(\n 'device_screenshot',\n {\n title: 'Screenshot',\n description:\n 'Capture a screenshot of the current device screen. ' +\n 'Returns base64-encoded PNG data. Optionally saves to a file path.',\n inputSchema: {\n outputPath: z\n .string()\n .optional()\n .describe('File path to save the screenshot (optional)'),\n },\n annotations: { readOnlyHint: true },\n },\n async ({ outputPath }) => {\n try {\n const result = await backend.screenshot(outputPath);\n return {\n content: [\n {\n type: 'image' as const,\n data: result.data,\n mimeType: `image/${result.format}`,\n },\n {\n type: 'text' as const,\n text: result.path\n ? `Screenshot saved to ${result.path}`\n : 'Screenshot captured',\n },\n ],\n };\n } catch (error) {\n return errorResult(error);\n }\n },\n );\n}\n"]}
@@ -0,0 +1,56 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.registerScrollToElementTool = registerScrollToElementTool;
4
+ const zod_1 = require("zod");
5
+ const shared_js_1 = require("./shared.cjs");
6
+ function registerScrollToElementTool(server, backend) {
7
+ server.registerTool('device_scroll_to_element', {
8
+ title: 'Scroll To Element',
9
+ description: 'Scroll the screen until an element matching the query becomes visible. ' +
10
+ 'Combines scrolling and element search into one atomic operation. ' +
11
+ 'Specify at least one of: label, identifier, text, type.',
12
+ inputSchema: {
13
+ label: zod_1.z.string().optional().describe('Accessibility label to match'),
14
+ identifier: zod_1.z
15
+ .string()
16
+ .optional()
17
+ .describe('Identifier/resource-id to match'),
18
+ text: zod_1.z.string().optional().describe('Text content to match'),
19
+ type: zod_1.z.string().optional().describe('Element type to match'),
20
+ direction: zod_1.z
21
+ .enum(['up', 'down'])
22
+ .optional()
23
+ .describe('Scroll direction (default: down)'),
24
+ maxAttempts: zod_1.z
25
+ .number()
26
+ .optional()
27
+ .describe('Maximum scroll attempts (default: 10)'),
28
+ },
29
+ }, async ({ label, identifier, text, type, direction, maxAttempts }) => {
30
+ try {
31
+ const element = await backend.scrollToElement({ label, identifier, text, type }, direction, maxAttempts);
32
+ return {
33
+ content: [
34
+ {
35
+ type: 'text',
36
+ text: [
37
+ `Found element after scrolling:`,
38
+ ` type: ${element.type}`,
39
+ element.label ? ` label: "${element.label}"` : null,
40
+ element.identifier ? ` id: "${element.identifier}"` : null,
41
+ element.value ? ` value: "${element.value}"` : null,
42
+ ` frame: (${element.frame.x}, ${element.frame.y}) ${element.frame.width}x${element.frame.height}`,
43
+ ` enabled: ${element.enabled}`,
44
+ ]
45
+ .filter(Boolean)
46
+ .join('\n'),
47
+ },
48
+ ],
49
+ };
50
+ }
51
+ catch (error) {
52
+ return (0, shared_js_1.errorResult)(error);
53
+ }
54
+ });
55
+ }
56
+ //# sourceMappingURL=scroll-to-element.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"scroll-to-element.cjs","sourceRoot":"","sources":["../../src/tools/scroll-to-element.ts"],"names":[],"mappings":";;AAMA,kEA4DC;AAjED,6BAAwB;AAExB,4CAA0C;AAG1C,SAAgB,2BAA2B,CACzC,MAAiB,EACjB,OAAsB;IAEtB,MAAM,CAAC,YAAY,CACjB,0BAA0B,EAC1B;QACE,KAAK,EAAE,mBAAmB;QAC1B,WAAW,EACT,yEAAyE;YACzE,mEAAmE;YACnE,yDAAyD;QAC3D,WAAW,EAAE;YACX,KAAK,EAAE,OAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE,CAAC,QAAQ,CAAC,8BAA8B,CAAC;YACrE,UAAU,EAAE,OAAC;iBACV,MAAM,EAAE;iBACR,QAAQ,EAAE;iBACV,QAAQ,CAAC,iCAAiC,CAAC;YAC9C,IAAI,EAAE,OAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE,CAAC,QAAQ,CAAC,uBAAuB,CAAC;YAC7D,IAAI,EAAE,OAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE,CAAC,QAAQ,CAAC,uBAAuB,CAAC;YAC7D,SAAS,EAAE,OAAC;iBACT,IAAI,CAAC,CAAC,IAAI,EAAE,MAAM,CAAC,CAAC;iBACpB,QAAQ,EAAE;iBACV,QAAQ,CAAC,kCAAkC,CAAC;YAC/C,WAAW,EAAE,OAAC;iBACX,MAAM,EAAE;iBACR,QAAQ,EAAE;iBACV,QAAQ,CAAC,uCAAuC,CAAC;SACrD;KACF,EACD,KAAK,EAAE,EAAE,KAAK,EAAE,UAAU,EAAE,IAAI,EAAE,IAAI,EAAE,SAAS,EAAE,WAAW,EAAE,EAAE,EAAE;QAClE,IAAI,CAAC;YACH,MAAM,OAAO,GAAG,MAAM,OAAO,CAAC,eAAe,CAC3C,EAAE,KAAK,EAAE,UAAU,EAAE,IAAI,EAAE,IAAI,EAAE,EACjC,SAAS,EACT,WAAW,CACZ,CAAC;YACF,OAAO;gBACL,OAAO,EAAE;oBACP;wBACE,IAAI,EAAE,MAAe;wBACrB,IAAI,EAAE;4BACJ,gCAAgC;4BAChC,WAAW,OAAO,CAAC,IAAI,EAAE;4BACzB,OAAO,CAAC,KAAK,CAAC,CAAC,CAAC,aAAa,OAAO,CAAC,KAAK,GAAG,CAAC,CAAC,CAAC,IAAI;4BACpD,OAAO,CAAC,UAAU,CAAC,CAAC,CAAC,UAAU,OAAO,CAAC,UAAU,GAAG,CAAC,CAAC,CAAC,IAAI;4BAC3D,OAAO,CAAC,KAAK,CAAC,CAAC,CAAC,aAAa,OAAO,CAAC,KAAK,GAAG,CAAC,CAAC,CAAC,IAAI;4BACpD,aAAa,OAAO,CAAC,KAAK,CAAC,CAAC,KAAK,OAAO,CAAC,KAAK,CAAC,CAAC,KAAK,OAAO,CAAC,KAAK,CAAC,KAAK,IAAI,OAAO,CAAC,KAAK,CAAC,MAAM,EAAE;4BAClG,cAAc,OAAO,CAAC,OAAO,EAAE;yBAChC;6BACE,MAAM,CAAC,OAAO,CAAC;6BACf,IAAI,CAAC,IAAI,CAAC;qBACd;iBACF;aACF,CAAC;QACJ,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,OAAO,IAAA,uBAAW,EAAC,KAAK,CAAC,CAAC;QAC5B,CAAC;IACH,CAAC,CACF,CAAC;AACJ,CAAC","sourcesContent":["import type { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';\nimport { z } from 'zod';\n\nimport { errorResult } from './shared.js';\nimport type { DeviceBackend } from '../backends/types.js';\n\nexport function registerScrollToElementTool(\n server: McpServer,\n backend: DeviceBackend,\n): void {\n server.registerTool(\n 'device_scroll_to_element',\n {\n title: 'Scroll To Element',\n description:\n 'Scroll the screen until an element matching the query becomes visible. ' +\n 'Combines scrolling and element search into one atomic operation. ' +\n 'Specify at least one of: label, identifier, text, type.',\n inputSchema: {\n label: z.string().optional().describe('Accessibility label to match'),\n identifier: z\n .string()\n .optional()\n .describe('Identifier/resource-id to match'),\n text: z.string().optional().describe('Text content to match'),\n type: z.string().optional().describe('Element type to match'),\n direction: z\n .enum(['up', 'down'])\n .optional()\n .describe('Scroll direction (default: down)'),\n maxAttempts: z\n .number()\n .optional()\n .describe('Maximum scroll attempts (default: 10)'),\n },\n },\n async ({ label, identifier, text, type, direction, maxAttempts }) => {\n try {\n const element = await backend.scrollToElement(\n { label, identifier, text, type },\n direction,\n maxAttempts,\n );\n return {\n content: [\n {\n type: 'text' as const,\n text: [\n `Found element after scrolling:`,\n ` type: ${element.type}`,\n element.label ? ` label: \"${element.label}\"` : null,\n element.identifier ? ` id: \"${element.identifier}\"` : null,\n element.value ? ` value: \"${element.value}\"` : null,\n ` frame: (${element.frame.x}, ${element.frame.y}) ${element.frame.width}x${element.frame.height}`,\n ` enabled: ${element.enabled}`,\n ]\n .filter(Boolean)\n .join('\\n'),\n },\n ],\n };\n } catch (error) {\n return errorResult(error);\n }\n },\n );\n}\n"]}
@@ -0,0 +1,4 @@
1
+ import type { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
2
+ import type { DeviceBackend } from "../backends/types.cjs";
3
+ export declare function registerScrollToElementTool(server: McpServer, backend: DeviceBackend): void;
4
+ //# sourceMappingURL=scroll-to-element.d.cts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"scroll-to-element.d.cts","sourceRoot":"","sources":["../../src/tools/scroll-to-element.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,gDAAgD;AAIzE,OAAO,KAAK,EAAE,aAAa,EAAE,8BAA6B;AAE1D,wBAAgB,2BAA2B,CACzC,MAAM,EAAE,SAAS,EACjB,OAAO,EAAE,aAAa,GACrB,IAAI,CAyDN"}
@@ -0,0 +1,4 @@
1
+ import type { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
2
+ import type { DeviceBackend } from "../backends/types.mjs";
3
+ export declare function registerScrollToElementTool(server: McpServer, backend: DeviceBackend): void;
4
+ //# sourceMappingURL=scroll-to-element.d.mts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"scroll-to-element.d.mts","sourceRoot":"","sources":["../../src/tools/scroll-to-element.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,gDAAgD;AAIzE,OAAO,KAAK,EAAE,aAAa,EAAE,8BAA6B;AAE1D,wBAAgB,2BAA2B,CACzC,MAAM,EAAE,SAAS,EACjB,OAAO,EAAE,aAAa,GACrB,IAAI,CAyDN"}
@@ -0,0 +1,53 @@
1
+ import { z } from "zod";
2
+ import { errorResult } from "./shared.mjs";
3
+ export function registerScrollToElementTool(server, backend) {
4
+ server.registerTool('device_scroll_to_element', {
5
+ title: 'Scroll To Element',
6
+ description: 'Scroll the screen until an element matching the query becomes visible. ' +
7
+ 'Combines scrolling and element search into one atomic operation. ' +
8
+ 'Specify at least one of: label, identifier, text, type.',
9
+ inputSchema: {
10
+ label: z.string().optional().describe('Accessibility label to match'),
11
+ identifier: z
12
+ .string()
13
+ .optional()
14
+ .describe('Identifier/resource-id to match'),
15
+ text: z.string().optional().describe('Text content to match'),
16
+ type: z.string().optional().describe('Element type to match'),
17
+ direction: z
18
+ .enum(['up', 'down'])
19
+ .optional()
20
+ .describe('Scroll direction (default: down)'),
21
+ maxAttempts: z
22
+ .number()
23
+ .optional()
24
+ .describe('Maximum scroll attempts (default: 10)'),
25
+ },
26
+ }, async ({ label, identifier, text, type, direction, maxAttempts }) => {
27
+ try {
28
+ const element = await backend.scrollToElement({ label, identifier, text, type }, direction, maxAttempts);
29
+ return {
30
+ content: [
31
+ {
32
+ type: 'text',
33
+ text: [
34
+ `Found element after scrolling:`,
35
+ ` type: ${element.type}`,
36
+ element.label ? ` label: "${element.label}"` : null,
37
+ element.identifier ? ` id: "${element.identifier}"` : null,
38
+ element.value ? ` value: "${element.value}"` : null,
39
+ ` frame: (${element.frame.x}, ${element.frame.y}) ${element.frame.width}x${element.frame.height}`,
40
+ ` enabled: ${element.enabled}`,
41
+ ]
42
+ .filter(Boolean)
43
+ .join('\n'),
44
+ },
45
+ ],
46
+ };
47
+ }
48
+ catch (error) {
49
+ return errorResult(error);
50
+ }
51
+ });
52
+ }
53
+ //# sourceMappingURL=scroll-to-element.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"scroll-to-element.mjs","sourceRoot":"","sources":["../../src/tools/scroll-to-element.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,CAAC,EAAE,YAAY;AAExB,OAAO,EAAE,WAAW,EAAE,qBAAoB;AAG1C,MAAM,UAAU,2BAA2B,CACzC,MAAiB,EACjB,OAAsB;IAEtB,MAAM,CAAC,YAAY,CACjB,0BAA0B,EAC1B;QACE,KAAK,EAAE,mBAAmB;QAC1B,WAAW,EACT,yEAAyE;YACzE,mEAAmE;YACnE,yDAAyD;QAC3D,WAAW,EAAE;YACX,KAAK,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE,CAAC,QAAQ,CAAC,8BAA8B,CAAC;YACrE,UAAU,EAAE,CAAC;iBACV,MAAM,EAAE;iBACR,QAAQ,EAAE;iBACV,QAAQ,CAAC,iCAAiC,CAAC;YAC9C,IAAI,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE,CAAC,QAAQ,CAAC,uBAAuB,CAAC;YAC7D,IAAI,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE,CAAC,QAAQ,CAAC,uBAAuB,CAAC;YAC7D,SAAS,EAAE,CAAC;iBACT,IAAI,CAAC,CAAC,IAAI,EAAE,MAAM,CAAC,CAAC;iBACpB,QAAQ,EAAE;iBACV,QAAQ,CAAC,kCAAkC,CAAC;YAC/C,WAAW,EAAE,CAAC;iBACX,MAAM,EAAE;iBACR,QAAQ,EAAE;iBACV,QAAQ,CAAC,uCAAuC,CAAC;SACrD;KACF,EACD,KAAK,EAAE,EAAE,KAAK,EAAE,UAAU,EAAE,IAAI,EAAE,IAAI,EAAE,SAAS,EAAE,WAAW,EAAE,EAAE,EAAE;QAClE,IAAI,CAAC;YACH,MAAM,OAAO,GAAG,MAAM,OAAO,CAAC,eAAe,CAC3C,EAAE,KAAK,EAAE,UAAU,EAAE,IAAI,EAAE,IAAI,EAAE,EACjC,SAAS,EACT,WAAW,CACZ,CAAC;YACF,OAAO;gBACL,OAAO,EAAE;oBACP;wBACE,IAAI,EAAE,MAAe;wBACrB,IAAI,EAAE;4BACJ,gCAAgC;4BAChC,WAAW,OAAO,CAAC,IAAI,EAAE;4BACzB,OAAO,CAAC,KAAK,CAAC,CAAC,CAAC,aAAa,OAAO,CAAC,KAAK,GAAG,CAAC,CAAC,CAAC,IAAI;4BACpD,OAAO,CAAC,UAAU,CAAC,CAAC,CAAC,UAAU,OAAO,CAAC,UAAU,GAAG,CAAC,CAAC,CAAC,IAAI;4BAC3D,OAAO,CAAC,KAAK,CAAC,CAAC,CAAC,aAAa,OAAO,CAAC,KAAK,GAAG,CAAC,CAAC,CAAC,IAAI;4BACpD,aAAa,OAAO,CAAC,KAAK,CAAC,CAAC,KAAK,OAAO,CAAC,KAAK,CAAC,CAAC,KAAK,OAAO,CAAC,KAAK,CAAC,KAAK,IAAI,OAAO,CAAC,KAAK,CAAC,MAAM,EAAE;4BAClG,cAAc,OAAO,CAAC,OAAO,EAAE;yBAChC;6BACE,MAAM,CAAC,OAAO,CAAC;6BACf,IAAI,CAAC,IAAI,CAAC;qBACd;iBACF;aACF,CAAC;QACJ,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,OAAO,WAAW,CAAC,KAAK,CAAC,CAAC;QAC5B,CAAC;IACH,CAAC,CACF,CAAC;AACJ,CAAC","sourcesContent":["import type { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';\nimport { z } from 'zod';\n\nimport { errorResult } from './shared.js';\nimport type { DeviceBackend } from '../backends/types.js';\n\nexport function registerScrollToElementTool(\n server: McpServer,\n backend: DeviceBackend,\n): void {\n server.registerTool(\n 'device_scroll_to_element',\n {\n title: 'Scroll To Element',\n description:\n 'Scroll the screen until an element matching the query becomes visible. ' +\n 'Combines scrolling and element search into one atomic operation. ' +\n 'Specify at least one of: label, identifier, text, type.',\n inputSchema: {\n label: z.string().optional().describe('Accessibility label to match'),\n identifier: z\n .string()\n .optional()\n .describe('Identifier/resource-id to match'),\n text: z.string().optional().describe('Text content to match'),\n type: z.string().optional().describe('Element type to match'),\n direction: z\n .enum(['up', 'down'])\n .optional()\n .describe('Scroll direction (default: down)'),\n maxAttempts: z\n .number()\n .optional()\n .describe('Maximum scroll attempts (default: 10)'),\n },\n },\n async ({ label, identifier, text, type, direction, maxAttempts }) => {\n try {\n const element = await backend.scrollToElement(\n { label, identifier, text, type },\n direction,\n maxAttempts,\n );\n return {\n content: [\n {\n type: 'text' as const,\n text: [\n `Found element after scrolling:`,\n ` type: ${element.type}`,\n element.label ? ` label: \"${element.label}\"` : null,\n element.identifier ? ` id: \"${element.identifier}\"` : null,\n element.value ? ` value: \"${element.value}\"` : null,\n ` frame: (${element.frame.x}, ${element.frame.y}) ${element.frame.width}x${element.frame.height}`,\n ` enabled: ${element.enabled}`,\n ]\n .filter(Boolean)\n .join('\\n'),\n },\n ],\n };\n } catch (error) {\n return errorResult(error);\n }\n },\n );\n}\n"]}
@@ -0,0 +1,11 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.errorResult = errorResult;
4
+ function errorResult(error) {
5
+ const message = error instanceof Error ? error.message : String(error);
6
+ return {
7
+ content: [{ type: 'text', text: message }],
8
+ isError: true,
9
+ };
10
+ }
11
+ //# sourceMappingURL=shared.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"shared.cjs","sourceRoot":"","sources":["../../src/tools/shared.ts"],"names":[],"mappings":";;AAAA,kCASC;AATD,SAAgB,WAAW,CAAC,KAAc;IAIxC,MAAM,OAAO,GAAG,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;IACvE,OAAO;QACL,OAAO,EAAE,CAAC,EAAE,IAAI,EAAE,MAAe,EAAE,IAAI,EAAE,OAAO,EAAE,CAAC;QACnD,OAAO,EAAE,IAAI;KACd,CAAC;AACJ,CAAC","sourcesContent":["export function errorResult(error: unknown): {\n content: { type: 'text'; text: string }[];\n isError: true;\n} {\n const message = error instanceof Error ? error.message : String(error);\n return {\n content: [{ type: 'text' as const, text: message }],\n isError: true,\n };\n}\n"]}
@@ -0,0 +1,8 @@
1
+ export declare function errorResult(error: unknown): {
2
+ content: {
3
+ type: 'text';
4
+ text: string;
5
+ }[];
6
+ isError: true;
7
+ };
8
+ //# sourceMappingURL=shared.d.cts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"shared.d.cts","sourceRoot":"","sources":["../../src/tools/shared.ts"],"names":[],"mappings":"AAAA,wBAAgB,WAAW,CAAC,KAAK,EAAE,OAAO,GAAG;IAC3C,OAAO,EAAE;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAA;KAAE,EAAE,CAAC;IAC1C,OAAO,EAAE,IAAI,CAAC;CACf,CAMA"}
@@ -0,0 +1,8 @@
1
+ export declare function errorResult(error: unknown): {
2
+ content: {
3
+ type: 'text';
4
+ text: string;
5
+ }[];
6
+ isError: true;
7
+ };
8
+ //# sourceMappingURL=shared.d.mts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"shared.d.mts","sourceRoot":"","sources":["../../src/tools/shared.ts"],"names":[],"mappings":"AAAA,wBAAgB,WAAW,CAAC,KAAK,EAAE,OAAO,GAAG;IAC3C,OAAO,EAAE;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAA;KAAE,EAAE,CAAC;IAC1C,OAAO,EAAE,IAAI,CAAC;CACf,CAMA"}
@@ -0,0 +1,8 @@
1
+ export function errorResult(error) {
2
+ const message = error instanceof Error ? error.message : String(error);
3
+ return {
4
+ content: [{ type: 'text', text: message }],
5
+ isError: true,
6
+ };
7
+ }
8
+ //# sourceMappingURL=shared.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"shared.mjs","sourceRoot":"","sources":["../../src/tools/shared.ts"],"names":[],"mappings":"AAAA,MAAM,UAAU,WAAW,CAAC,KAAc;IAIxC,MAAM,OAAO,GAAG,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;IACvE,OAAO;QACL,OAAO,EAAE,CAAC,EAAE,IAAI,EAAE,MAAe,EAAE,IAAI,EAAE,OAAO,EAAE,CAAC;QACnD,OAAO,EAAE,IAAI;KACd,CAAC;AACJ,CAAC","sourcesContent":["export function errorResult(error: unknown): {\n content: { type: 'text'; text: string }[];\n isError: true;\n} {\n const message = error instanceof Error ? error.message : String(error);\n return {\n content: [{ type: 'text' as const, text: message }],\n isError: true,\n };\n}\n"]}
@@ -0,0 +1,37 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.registerSnapshotTool = registerSnapshotTool;
4
+ const shared_js_1 = require("./shared.cjs");
5
+ const element_js_1 = require("../utils/element.cjs");
6
+ function registerSnapshotTool(server, backend) {
7
+ server.registerTool('device_snapshot', {
8
+ title: 'Device Snapshot',
9
+ description: 'Capture the current UI hierarchy from the device. Returns all visible elements ' +
10
+ 'with their types, labels, identifiers, values, frames, and enabled state. ' +
11
+ 'Call this FIRST to see what is on screen before interacting.',
12
+ inputSchema: {},
13
+ annotations: { readOnlyHint: true },
14
+ }, async () => {
15
+ try {
16
+ const result = await backend.snapshot();
17
+ const formatted = (0, element_js_1.formatHierarchy)(result.hierarchy, 0);
18
+ return {
19
+ content: [
20
+ {
21
+ type: 'text',
22
+ text: [
23
+ `Platform: ${result.platform}`,
24
+ `Timestamp: ${new Date(result.timestamp).toISOString()}`,
25
+ `Elements:`,
26
+ formatted,
27
+ ].join('\n'),
28
+ },
29
+ ],
30
+ };
31
+ }
32
+ catch (error) {
33
+ return (0, shared_js_1.errorResult)(error);
34
+ }
35
+ });
36
+ }
37
+ //# sourceMappingURL=snapshot.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"snapshot.cjs","sourceRoot":"","sources":["../../src/tools/snapshot.ts"],"names":[],"mappings":";;AAMA,oDAqCC;AAzCD,4CAA0C;AAE1C,qDAAsD;AAEtD,SAAgB,oBAAoB,CAClC,MAAiB,EACjB,OAAsB;IAEtB,MAAM,CAAC,YAAY,CACjB,iBAAiB,EACjB;QACE,KAAK,EAAE,iBAAiB;QACxB,WAAW,EACT,iFAAiF;YACjF,4EAA4E;YAC5E,8DAA8D;QAChE,WAAW,EAAE,EAAE;QACf,WAAW,EAAE,EAAE,YAAY,EAAE,IAAI,EAAE;KACpC,EACD,KAAK,IAAI,EAAE;QACT,IAAI,CAAC;YACH,MAAM,MAAM,GAAG,MAAM,OAAO,CAAC,QAAQ,EAAE,CAAC;YACxC,MAAM,SAAS,GAAG,IAAA,4BAAe,EAAC,MAAM,CAAC,SAAS,EAAE,CAAC,CAAC,CAAC;YACvD,OAAO;gBACL,OAAO,EAAE;oBACP;wBACE,IAAI,EAAE,MAAe;wBACrB,IAAI,EAAE;4BACJ,aAAa,MAAM,CAAC,QAAQ,EAAE;4BAC9B,cAAc,IAAI,IAAI,CAAC,MAAM,CAAC,SAAS,CAAC,CAAC,WAAW,EAAE,EAAE;4BACxD,WAAW;4BACX,SAAS;yBACV,CAAC,IAAI,CAAC,IAAI,CAAC;qBACb;iBACF;aACF,CAAC;QACJ,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,OAAO,IAAA,uBAAW,EAAC,KAAK,CAAC,CAAC;QAC5B,CAAC;IACH,CAAC,CACF,CAAC;AACJ,CAAC","sourcesContent":["import type { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';\n\nimport { errorResult } from './shared.js';\nimport type { DeviceBackend } from '../backends/types.js';\nimport { formatHierarchy } from '../utils/element.js';\n\nexport function registerSnapshotTool(\n server: McpServer,\n backend: DeviceBackend,\n): void {\n server.registerTool(\n 'device_snapshot',\n {\n title: 'Device Snapshot',\n description:\n 'Capture the current UI hierarchy from the device. Returns all visible elements ' +\n 'with their types, labels, identifiers, values, frames, and enabled state. ' +\n 'Call this FIRST to see what is on screen before interacting.',\n inputSchema: {},\n annotations: { readOnlyHint: true },\n },\n async () => {\n try {\n const result = await backend.snapshot();\n const formatted = formatHierarchy(result.hierarchy, 0);\n return {\n content: [\n {\n type: 'text' as const,\n text: [\n `Platform: ${result.platform}`,\n `Timestamp: ${new Date(result.timestamp).toISOString()}`,\n `Elements:`,\n formatted,\n ].join('\\n'),\n },\n ],\n };\n } catch (error) {\n return errorResult(error);\n }\n },\n );\n}\n"]}
@@ -0,0 +1,4 @@
1
+ import type { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
2
+ import type { DeviceBackend } from "../backends/types.cjs";
3
+ export declare function registerSnapshotTool(server: McpServer, backend: DeviceBackend): void;
4
+ //# sourceMappingURL=snapshot.d.cts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"snapshot.d.cts","sourceRoot":"","sources":["../../src/tools/snapshot.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,gDAAgD;AAGzE,OAAO,KAAK,EAAE,aAAa,EAAE,8BAA6B;AAG1D,wBAAgB,oBAAoB,CAClC,MAAM,EAAE,SAAS,EACjB,OAAO,EAAE,aAAa,GACrB,IAAI,CAkCN"}
@@ -0,0 +1,4 @@
1
+ import type { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
2
+ import type { DeviceBackend } from "../backends/types.mjs";
3
+ export declare function registerSnapshotTool(server: McpServer, backend: DeviceBackend): void;
4
+ //# sourceMappingURL=snapshot.d.mts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"snapshot.d.mts","sourceRoot":"","sources":["../../src/tools/snapshot.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,gDAAgD;AAGzE,OAAO,KAAK,EAAE,aAAa,EAAE,8BAA6B;AAG1D,wBAAgB,oBAAoB,CAClC,MAAM,EAAE,SAAS,EACjB,OAAO,EAAE,aAAa,GACrB,IAAI,CAkCN"}
@@ -0,0 +1,34 @@
1
+ import { errorResult } from "./shared.mjs";
2
+ import { formatHierarchy } from "../utils/element.mjs";
3
+ export function registerSnapshotTool(server, backend) {
4
+ server.registerTool('device_snapshot', {
5
+ title: 'Device Snapshot',
6
+ description: 'Capture the current UI hierarchy from the device. Returns all visible elements ' +
7
+ 'with their types, labels, identifiers, values, frames, and enabled state. ' +
8
+ 'Call this FIRST to see what is on screen before interacting.',
9
+ inputSchema: {},
10
+ annotations: { readOnlyHint: true },
11
+ }, async () => {
12
+ try {
13
+ const result = await backend.snapshot();
14
+ const formatted = formatHierarchy(result.hierarchy, 0);
15
+ return {
16
+ content: [
17
+ {
18
+ type: 'text',
19
+ text: [
20
+ `Platform: ${result.platform}`,
21
+ `Timestamp: ${new Date(result.timestamp).toISOString()}`,
22
+ `Elements:`,
23
+ formatted,
24
+ ].join('\n'),
25
+ },
26
+ ],
27
+ };
28
+ }
29
+ catch (error) {
30
+ return errorResult(error);
31
+ }
32
+ });
33
+ }
34
+ //# sourceMappingURL=snapshot.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"snapshot.mjs","sourceRoot":"","sources":["../../src/tools/snapshot.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,WAAW,EAAE,qBAAoB;AAE1C,OAAO,EAAE,eAAe,EAAE,6BAA4B;AAEtD,MAAM,UAAU,oBAAoB,CAClC,MAAiB,EACjB,OAAsB;IAEtB,MAAM,CAAC,YAAY,CACjB,iBAAiB,EACjB;QACE,KAAK,EAAE,iBAAiB;QACxB,WAAW,EACT,iFAAiF;YACjF,4EAA4E;YAC5E,8DAA8D;QAChE,WAAW,EAAE,EAAE;QACf,WAAW,EAAE,EAAE,YAAY,EAAE,IAAI,EAAE;KACpC,EACD,KAAK,IAAI,EAAE;QACT,IAAI,CAAC;YACH,MAAM,MAAM,GAAG,MAAM,OAAO,CAAC,QAAQ,EAAE,CAAC;YACxC,MAAM,SAAS,GAAG,eAAe,CAAC,MAAM,CAAC,SAAS,EAAE,CAAC,CAAC,CAAC;YACvD,OAAO;gBACL,OAAO,EAAE;oBACP;wBACE,IAAI,EAAE,MAAe;wBACrB,IAAI,EAAE;4BACJ,aAAa,MAAM,CAAC,QAAQ,EAAE;4BAC9B,cAAc,IAAI,IAAI,CAAC,MAAM,CAAC,SAAS,CAAC,CAAC,WAAW,EAAE,EAAE;4BACxD,WAAW;4BACX,SAAS;yBACV,CAAC,IAAI,CAAC,IAAI,CAAC;qBACb;iBACF;aACF,CAAC;QACJ,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,OAAO,WAAW,CAAC,KAAK,CAAC,CAAC;QAC5B,CAAC;IACH,CAAC,CACF,CAAC;AACJ,CAAC","sourcesContent":["import type { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';\n\nimport { errorResult } from './shared.js';\nimport type { DeviceBackend } from '../backends/types.js';\nimport { formatHierarchy } from '../utils/element.js';\n\nexport function registerSnapshotTool(\n server: McpServer,\n backend: DeviceBackend,\n): void {\n server.registerTool(\n 'device_snapshot',\n {\n title: 'Device Snapshot',\n description:\n 'Capture the current UI hierarchy from the device. Returns all visible elements ' +\n 'with their types, labels, identifiers, values, frames, and enabled state. ' +\n 'Call this FIRST to see what is on screen before interacting.',\n inputSchema: {},\n annotations: { readOnlyHint: true },\n },\n async () => {\n try {\n const result = await backend.snapshot();\n const formatted = formatHierarchy(result.hierarchy, 0);\n return {\n content: [\n {\n type: 'text' as const,\n text: [\n `Platform: ${result.platform}`,\n `Timestamp: ${new Date(result.timestamp).toISOString()}`,\n `Elements:`,\n formatted,\n ].join('\\n'),\n },\n ],\n };\n } catch (error) {\n return errorResult(error);\n }\n },\n );\n}\n"]}
@@ -0,0 +1,39 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.registerSwipeTool = registerSwipeTool;
4
+ const zod_1 = require("zod");
5
+ const shared_js_1 = require("./shared.cjs");
6
+ function registerSwipeTool(server, backend) {
7
+ server.registerTool('device_swipe', {
8
+ title: 'Swipe',
9
+ description: 'Swipe on the device screen. Use natural scrolling: swipe "up" to scroll down. ' +
10
+ 'Optionally specify start coordinates and distance.',
11
+ inputSchema: {
12
+ direction: zod_1.z
13
+ .enum(['up', 'down', 'left', 'right'])
14
+ .describe('Swipe direction'),
15
+ startX: zod_1.z.number().optional().describe('Start X coordinate'),
16
+ startY: zod_1.z.number().optional().describe('Start Y coordinate'),
17
+ distance: zod_1.z
18
+ .number()
19
+ .optional()
20
+ .describe('Swipe distance in pixels (default: 500)'),
21
+ },
22
+ }, async ({ direction, startX, startY, distance }) => {
23
+ try {
24
+ await backend.swipe(direction, startX, startY, distance);
25
+ return {
26
+ content: [
27
+ {
28
+ type: 'text',
29
+ text: `Swiped ${direction}${startX === undefined ? '' : ` from (${startX}, ${startY})`}${distance === undefined ? '' : ` distance=${distance}px`}`,
30
+ },
31
+ ],
32
+ };
33
+ }
34
+ catch (error) {
35
+ return (0, shared_js_1.errorResult)(error);
36
+ }
37
+ });
38
+ }
39
+ //# sourceMappingURL=swipe.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"swipe.cjs","sourceRoot":"","sources":["../../src/tools/swipe.ts"],"names":[],"mappings":";;AAMA,8CAuCC;AA5CD,6BAAwB;AAExB,4CAA0C;AAG1C,SAAgB,iBAAiB,CAC/B,MAAiB,EACjB,OAAsB;IAEtB,MAAM,CAAC,YAAY,CACjB,cAAc,EACd;QACE,KAAK,EAAE,OAAO;QACd,WAAW,EACT,gFAAgF;YAChF,oDAAoD;QACtD,WAAW,EAAE;YACX,SAAS,EAAE,OAAC;iBACT,IAAI,CAAC,CAAC,IAAI,EAAE,MAAM,EAAE,MAAM,EAAE,OAAO,CAAC,CAAC;iBACrC,QAAQ,CAAC,iBAAiB,CAAC;YAC9B,MAAM,EAAE,OAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE,CAAC,QAAQ,CAAC,oBAAoB,CAAC;YAC5D,MAAM,EAAE,OAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE,CAAC,QAAQ,CAAC,oBAAoB,CAAC;YAC5D,QAAQ,EAAE,OAAC;iBACR,MAAM,EAAE;iBACR,QAAQ,EAAE;iBACV,QAAQ,CAAC,yCAAyC,CAAC;SACvD;KACF,EACD,KAAK,EAAE,EAAE,SAAS,EAAE,MAAM,EAAE,MAAM,EAAE,QAAQ,EAAE,EAAE,EAAE;QAChD,IAAI,CAAC;YACH,MAAM,OAAO,CAAC,KAAK,CAAC,SAAS,EAAE,MAAM,EAAE,MAAM,EAAE,QAAQ,CAAC,CAAC;YACzD,OAAO;gBACL,OAAO,EAAE;oBACP;wBACE,IAAI,EAAE,MAAe;wBACrB,IAAI,EAAE,UAAU,SAAS,GAAG,MAAM,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,UAAU,MAAM,KAAK,MAAM,GAAG,GAAG,QAAQ,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,aAAa,QAAQ,IAAI,EAAE;qBACnJ;iBACF;aACF,CAAC;QACJ,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,OAAO,IAAA,uBAAW,EAAC,KAAK,CAAC,CAAC;QAC5B,CAAC;IACH,CAAC,CACF,CAAC;AACJ,CAAC","sourcesContent":["import type { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';\nimport { z } from 'zod';\n\nimport { errorResult } from './shared.js';\nimport type { DeviceBackend } from '../backends/types.js';\n\nexport function registerSwipeTool(\n server: McpServer,\n backend: DeviceBackend,\n): void {\n server.registerTool(\n 'device_swipe',\n {\n title: 'Swipe',\n description:\n 'Swipe on the device screen. Use natural scrolling: swipe \"up\" to scroll down. ' +\n 'Optionally specify start coordinates and distance.',\n inputSchema: {\n direction: z\n .enum(['up', 'down', 'left', 'right'])\n .describe('Swipe direction'),\n startX: z.number().optional().describe('Start X coordinate'),\n startY: z.number().optional().describe('Start Y coordinate'),\n distance: z\n .number()\n .optional()\n .describe('Swipe distance in pixels (default: 500)'),\n },\n },\n async ({ direction, startX, startY, distance }) => {\n try {\n await backend.swipe(direction, startX, startY, distance);\n return {\n content: [\n {\n type: 'text' as const,\n text: `Swiped ${direction}${startX === undefined ? '' : ` from (${startX}, ${startY})`}${distance === undefined ? '' : ` distance=${distance}px`}`,\n },\n ],\n };\n } catch (error) {\n return errorResult(error);\n }\n },\n );\n}\n"]}
@@ -0,0 +1,4 @@
1
+ import type { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
2
+ import type { DeviceBackend } from "../backends/types.cjs";
3
+ export declare function registerSwipeTool(server: McpServer, backend: DeviceBackend): void;
4
+ //# sourceMappingURL=swipe.d.cts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"swipe.d.cts","sourceRoot":"","sources":["../../src/tools/swipe.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,gDAAgD;AAIzE,OAAO,KAAK,EAAE,aAAa,EAAE,8BAA6B;AAE1D,wBAAgB,iBAAiB,CAC/B,MAAM,EAAE,SAAS,EACjB,OAAO,EAAE,aAAa,GACrB,IAAI,CAoCN"}
@@ -0,0 +1,4 @@
1
+ import type { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
2
+ import type { DeviceBackend } from "../backends/types.mjs";
3
+ export declare function registerSwipeTool(server: McpServer, backend: DeviceBackend): void;
4
+ //# sourceMappingURL=swipe.d.mts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"swipe.d.mts","sourceRoot":"","sources":["../../src/tools/swipe.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,gDAAgD;AAIzE,OAAO,KAAK,EAAE,aAAa,EAAE,8BAA6B;AAE1D,wBAAgB,iBAAiB,CAC/B,MAAM,EAAE,SAAS,EACjB,OAAO,EAAE,aAAa,GACrB,IAAI,CAoCN"}
@@ -0,0 +1,36 @@
1
+ import { z } from "zod";
2
+ import { errorResult } from "./shared.mjs";
3
+ export function registerSwipeTool(server, backend) {
4
+ server.registerTool('device_swipe', {
5
+ title: 'Swipe',
6
+ description: 'Swipe on the device screen. Use natural scrolling: swipe "up" to scroll down. ' +
7
+ 'Optionally specify start coordinates and distance.',
8
+ inputSchema: {
9
+ direction: z
10
+ .enum(['up', 'down', 'left', 'right'])
11
+ .describe('Swipe direction'),
12
+ startX: z.number().optional().describe('Start X coordinate'),
13
+ startY: z.number().optional().describe('Start Y coordinate'),
14
+ distance: z
15
+ .number()
16
+ .optional()
17
+ .describe('Swipe distance in pixels (default: 500)'),
18
+ },
19
+ }, async ({ direction, startX, startY, distance }) => {
20
+ try {
21
+ await backend.swipe(direction, startX, startY, distance);
22
+ return {
23
+ content: [
24
+ {
25
+ type: 'text',
26
+ text: `Swiped ${direction}${startX === undefined ? '' : ` from (${startX}, ${startY})`}${distance === undefined ? '' : ` distance=${distance}px`}`,
27
+ },
28
+ ],
29
+ };
30
+ }
31
+ catch (error) {
32
+ return errorResult(error);
33
+ }
34
+ });
35
+ }
36
+ //# sourceMappingURL=swipe.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"swipe.mjs","sourceRoot":"","sources":["../../src/tools/swipe.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,CAAC,EAAE,YAAY;AAExB,OAAO,EAAE,WAAW,EAAE,qBAAoB;AAG1C,MAAM,UAAU,iBAAiB,CAC/B,MAAiB,EACjB,OAAsB;IAEtB,MAAM,CAAC,YAAY,CACjB,cAAc,EACd;QACE,KAAK,EAAE,OAAO;QACd,WAAW,EACT,gFAAgF;YAChF,oDAAoD;QACtD,WAAW,EAAE;YACX,SAAS,EAAE,CAAC;iBACT,IAAI,CAAC,CAAC,IAAI,EAAE,MAAM,EAAE,MAAM,EAAE,OAAO,CAAC,CAAC;iBACrC,QAAQ,CAAC,iBAAiB,CAAC;YAC9B,MAAM,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE,CAAC,QAAQ,CAAC,oBAAoB,CAAC;YAC5D,MAAM,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE,CAAC,QAAQ,CAAC,oBAAoB,CAAC;YAC5D,QAAQ,EAAE,CAAC;iBACR,MAAM,EAAE;iBACR,QAAQ,EAAE;iBACV,QAAQ,CAAC,yCAAyC,CAAC;SACvD;KACF,EACD,KAAK,EAAE,EAAE,SAAS,EAAE,MAAM,EAAE,MAAM,EAAE,QAAQ,EAAE,EAAE,EAAE;QAChD,IAAI,CAAC;YACH,MAAM,OAAO,CAAC,KAAK,CAAC,SAAS,EAAE,MAAM,EAAE,MAAM,EAAE,QAAQ,CAAC,CAAC;YACzD,OAAO;gBACL,OAAO,EAAE;oBACP;wBACE,IAAI,EAAE,MAAe;wBACrB,IAAI,EAAE,UAAU,SAAS,GAAG,MAAM,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,UAAU,MAAM,KAAK,MAAM,GAAG,GAAG,QAAQ,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,aAAa,QAAQ,IAAI,EAAE;qBACnJ;iBACF;aACF,CAAC;QACJ,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,OAAO,WAAW,CAAC,KAAK,CAAC,CAAC;QAC5B,CAAC;IACH,CAAC,CACF,CAAC;AACJ,CAAC","sourcesContent":["import type { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';\nimport { z } from 'zod';\n\nimport { errorResult } from './shared.js';\nimport type { DeviceBackend } from '../backends/types.js';\n\nexport function registerSwipeTool(\n server: McpServer,\n backend: DeviceBackend,\n): void {\n server.registerTool(\n 'device_swipe',\n {\n title: 'Swipe',\n description:\n 'Swipe on the device screen. Use natural scrolling: swipe \"up\" to scroll down. ' +\n 'Optionally specify start coordinates and distance.',\n inputSchema: {\n direction: z\n .enum(['up', 'down', 'left', 'right'])\n .describe('Swipe direction'),\n startX: z.number().optional().describe('Start X coordinate'),\n startY: z.number().optional().describe('Start Y coordinate'),\n distance: z\n .number()\n .optional()\n .describe('Swipe distance in pixels (default: 500)'),\n },\n },\n async ({ direction, startX, startY, distance }) => {\n try {\n await backend.swipe(direction, startX, startY, distance);\n return {\n content: [\n {\n type: 'text' as const,\n text: `Swiped ${direction}${startX === undefined ? '' : ` from (${startX}, ${startY})`}${distance === undefined ? '' : ` distance=${distance}px`}`,\n },\n ],\n };\n } catch (error) {\n return errorResult(error);\n }\n },\n );\n}\n"]}
@@ -0,0 +1,27 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.registerTapCoordinatesTool = registerTapCoordinatesTool;
4
+ const zod_1 = require("zod");
5
+ const shared_js_1 = require("./shared.cjs");
6
+ function registerTapCoordinatesTool(server, backend) {
7
+ server.registerTool('device_tap_coordinates', {
8
+ title: 'Tap Coordinates',
9
+ description: 'Tap at exact screen coordinates. Use as a last resort when an element ' +
10
+ 'cannot be found by label/identifier/text. Get coordinates from device_snapshot frame data.',
11
+ inputSchema: {
12
+ x: zod_1.z.number().describe('X coordinate in pixels'),
13
+ y: zod_1.z.number().describe('Y coordinate in pixels'),
14
+ },
15
+ }, async ({ x, y }) => {
16
+ try {
17
+ await backend.tapCoordinates(x, y);
18
+ return {
19
+ content: [{ type: 'text', text: `Tapped at (${x}, ${y})` }],
20
+ };
21
+ }
22
+ catch (error) {
23
+ return (0, shared_js_1.errorResult)(error);
24
+ }
25
+ });
26
+ }
27
+ //# sourceMappingURL=tap-coordinates.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"tap-coordinates.cjs","sourceRoot":"","sources":["../../src/tools/tap-coordinates.ts"],"names":[],"mappings":";;AAMA,gEA2BC;AAhCD,6BAAwB;AAExB,4CAA0C;AAG1C,SAAgB,0BAA0B,CACxC,MAAiB,EACjB,OAAsB;IAEtB,MAAM,CAAC,YAAY,CACjB,wBAAwB,EACxB;QACE,KAAK,EAAE,iBAAiB;QACxB,WAAW,EACT,wEAAwE;YACxE,4FAA4F;QAC9F,WAAW,EAAE;YACX,CAAC,EAAE,OAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,CAAC,wBAAwB,CAAC;YAChD,CAAC,EAAE,OAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,CAAC,wBAAwB,CAAC;SACjD;KACF,EACD,KAAK,EAAE,EAAE,CAAC,EAAE,CAAC,EAAE,EAAE,EAAE;QACjB,IAAI,CAAC;YACH,MAAM,OAAO,CAAC,cAAc,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC;YACnC,OAAO;gBACL,OAAO,EAAE,CAAC,EAAE,IAAI,EAAE,MAAe,EAAE,IAAI,EAAE,cAAc,CAAC,KAAK,CAAC,GAAG,EAAE,CAAC;aACrE,CAAC;QACJ,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,OAAO,IAAA,uBAAW,EAAC,KAAK,CAAC,CAAC;QAC5B,CAAC;IACH,CAAC,CACF,CAAC;AACJ,CAAC","sourcesContent":["import type { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';\nimport { z } from 'zod';\n\nimport { errorResult } from './shared.js';\nimport type { DeviceBackend } from '../backends/types.js';\n\nexport function registerTapCoordinatesTool(\n server: McpServer,\n backend: DeviceBackend,\n): void {\n server.registerTool(\n 'device_tap_coordinates',\n {\n title: 'Tap Coordinates',\n description:\n 'Tap at exact screen coordinates. Use as a last resort when an element ' +\n 'cannot be found by label/identifier/text. Get coordinates from device_snapshot frame data.',\n inputSchema: {\n x: z.number().describe('X coordinate in pixels'),\n y: z.number().describe('Y coordinate in pixels'),\n },\n },\n async ({ x, y }) => {\n try {\n await backend.tapCoordinates(x, y);\n return {\n content: [{ type: 'text' as const, text: `Tapped at (${x}, ${y})` }],\n };\n } catch (error) {\n return errorResult(error);\n }\n },\n );\n}\n"]}
@@ -0,0 +1,4 @@
1
+ import type { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
2
+ import type { DeviceBackend } from "../backends/types.cjs";
3
+ export declare function registerTapCoordinatesTool(server: McpServer, backend: DeviceBackend): void;
4
+ //# sourceMappingURL=tap-coordinates.d.cts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"tap-coordinates.d.cts","sourceRoot":"","sources":["../../src/tools/tap-coordinates.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,gDAAgD;AAIzE,OAAO,KAAK,EAAE,aAAa,EAAE,8BAA6B;AAE1D,wBAAgB,0BAA0B,CACxC,MAAM,EAAE,SAAS,EACjB,OAAO,EAAE,aAAa,GACrB,IAAI,CAwBN"}
@@ -0,0 +1,4 @@
1
+ import type { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
2
+ import type { DeviceBackend } from "../backends/types.mjs";
3
+ export declare function registerTapCoordinatesTool(server: McpServer, backend: DeviceBackend): void;
4
+ //# sourceMappingURL=tap-coordinates.d.mts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"tap-coordinates.d.mts","sourceRoot":"","sources":["../../src/tools/tap-coordinates.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,gDAAgD;AAIzE,OAAO,KAAK,EAAE,aAAa,EAAE,8BAA6B;AAE1D,wBAAgB,0BAA0B,CACxC,MAAM,EAAE,SAAS,EACjB,OAAO,EAAE,aAAa,GACrB,IAAI,CAwBN"}
@@ -0,0 +1,24 @@
1
+ import { z } from "zod";
2
+ import { errorResult } from "./shared.mjs";
3
+ export function registerTapCoordinatesTool(server, backend) {
4
+ server.registerTool('device_tap_coordinates', {
5
+ title: 'Tap Coordinates',
6
+ description: 'Tap at exact screen coordinates. Use as a last resort when an element ' +
7
+ 'cannot be found by label/identifier/text. Get coordinates from device_snapshot frame data.',
8
+ inputSchema: {
9
+ x: z.number().describe('X coordinate in pixels'),
10
+ y: z.number().describe('Y coordinate in pixels'),
11
+ },
12
+ }, async ({ x, y }) => {
13
+ try {
14
+ await backend.tapCoordinates(x, y);
15
+ return {
16
+ content: [{ type: 'text', text: `Tapped at (${x}, ${y})` }],
17
+ };
18
+ }
19
+ catch (error) {
20
+ return errorResult(error);
21
+ }
22
+ });
23
+ }
24
+ //# sourceMappingURL=tap-coordinates.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"tap-coordinates.mjs","sourceRoot":"","sources":["../../src/tools/tap-coordinates.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,CAAC,EAAE,YAAY;AAExB,OAAO,EAAE,WAAW,EAAE,qBAAoB;AAG1C,MAAM,UAAU,0BAA0B,CACxC,MAAiB,EACjB,OAAsB;IAEtB,MAAM,CAAC,YAAY,CACjB,wBAAwB,EACxB;QACE,KAAK,EAAE,iBAAiB;QACxB,WAAW,EACT,wEAAwE;YACxE,4FAA4F;QAC9F,WAAW,EAAE;YACX,CAAC,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,CAAC,wBAAwB,CAAC;YAChD,CAAC,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,CAAC,wBAAwB,CAAC;SACjD;KACF,EACD,KAAK,EAAE,EAAE,CAAC,EAAE,CAAC,EAAE,EAAE,EAAE;QACjB,IAAI,CAAC;YACH,MAAM,OAAO,CAAC,cAAc,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC;YACnC,OAAO;gBACL,OAAO,EAAE,CAAC,EAAE,IAAI,EAAE,MAAe,EAAE,IAAI,EAAE,cAAc,CAAC,KAAK,CAAC,GAAG,EAAE,CAAC;aACrE,CAAC;QACJ,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,OAAO,WAAW,CAAC,KAAK,CAAC,CAAC;QAC5B,CAAC;IACH,CAAC,CACF,CAAC;AACJ,CAAC","sourcesContent":["import type { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';\nimport { z } from 'zod';\n\nimport { errorResult } from './shared.js';\nimport type { DeviceBackend } from '../backends/types.js';\n\nexport function registerTapCoordinatesTool(\n server: McpServer,\n backend: DeviceBackend,\n): void {\n server.registerTool(\n 'device_tap_coordinates',\n {\n title: 'Tap Coordinates',\n description:\n 'Tap at exact screen coordinates. Use as a last resort when an element ' +\n 'cannot be found by label/identifier/text. Get coordinates from device_snapshot frame data.',\n inputSchema: {\n x: z.number().describe('X coordinate in pixels'),\n y: z.number().describe('Y coordinate in pixels'),\n },\n },\n async ({ x, y }) => {\n try {\n await backend.tapCoordinates(x, y);\n return {\n content: [{ type: 'text' as const, text: `Tapped at (${x}, ${y})` }],\n };\n } catch (error) {\n return errorResult(error);\n }\n },\n );\n}\n"]}