appium-mcp 1.4.0 → 1.5.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGELOG.md CHANGED
@@ -1,3 +1,9 @@
1
+ ## [1.5.0](https://github.com/appium/appium-mcp/compare/v1.4.0...v1.5.0) (2025-12-19)
2
+
3
+ ### Features
4
+
5
+ * **interactions:** add drag and drop tool for element and coordinate-based drag operations ([#55](https://github.com/appium/appium-mcp/issues/55)) ([571942e](https://github.com/appium/appium-mcp/commit/571942ecbd2d7ef395cc8e6a8aaf158dcf0f54fb))
6
+
1
7
  ## [1.4.0](https://github.com/appium/appium-mcp/compare/v1.3.0...v1.4.0) (2025-12-07)
2
8
 
3
9
  ### Features
package/README.md CHANGED
@@ -193,6 +193,7 @@ MCP Appium provides a comprehensive set of tools organized into the following ca
193
193
  | `appium_click` | Click on an element |
194
194
  | `appium_double_tap` | Perform double tap on an element |
195
195
  | `appium_long_press` | Perform a long press (press and hold) gesture on an element |
196
+ | `appium_drag_and_drop` | Perform a drag and drop gesture from a source location to a target location (supports element-to-element, element-to-coordinates, coordinates-to-element, and coordinates-to-coordinates) |
196
197
  | `appium_set_value` | Enter text into an input field |
197
198
  | `appium_get_text` | Get text content from an element |
198
199
 
@@ -16,6 +16,7 @@ import findElement from './interactions/find.js';
16
16
  import clickElement from './interactions/click.js';
17
17
  import doubleTap from './interactions/double-tap.js';
18
18
  import longPress from './interactions/long-press.js';
19
+ import dragAndDrop from './interactions/drag-and-drop.js';
19
20
  import setValue from './interactions/set-value.js';
20
21
  import getText from './interactions/get-text.js';
21
22
  import getPageSource from './interactions/get-page-source.js';
@@ -107,6 +108,7 @@ export default function registerTools(server) {
107
108
  clickElement(server);
108
109
  doubleTap(server);
109
110
  longPress(server);
111
+ dragAndDrop(server);
110
112
  setValue(server);
111
113
  getText(server);
112
114
  getPageSource(server);
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/tools/index.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/tools/index.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ import { FastMCP } from 'fastmcp/dist/FastMCP.js';
2
+ export default function dragAndDrop(server: FastMCP): void;
@@ -0,0 +1,173 @@
1
+ import { z } from 'zod';
2
+ import { getDriver, getPlatformName } from '../../session-store.js';
3
+ import { elementUUIDScheme } from '../../schema.js';
4
+ const DROP_PAUSE_DURATION_MS = 150;
5
+ async function performDragAndDrop(driver, startX, startY, endX, endY, duration, longPressDuration) {
6
+ await driver.performActions([
7
+ {
8
+ type: 'pointer',
9
+ id: 'finger1',
10
+ parameters: { pointerType: 'touch' },
11
+ actions: [
12
+ { type: 'pointerMove', duration: 0, x: startX, y: startY },
13
+ { type: 'pointerDown', button: 0 },
14
+ { type: 'pause', duration: longPressDuration },
15
+ { type: 'pointerMove', duration: duration, x: endX, y: endY },
16
+ { type: 'pause', duration: DROP_PAUSE_DURATION_MS },
17
+ { type: 'pointerUp', button: 0 },
18
+ ],
19
+ },
20
+ ]);
21
+ }
22
+ export default function dragAndDrop(server) {
23
+ const dragAndDropSchema = z.object({
24
+ sourceElementUUID: elementUUIDScheme
25
+ .trim()
26
+ .min(1)
27
+ .optional()
28
+ .describe('UUID of the source element to drag from. Either sourceElementUUID or sourceX/sourceY must be provided.'),
29
+ sourceX: z
30
+ .number()
31
+ .int()
32
+ .min(0)
33
+ .optional()
34
+ .describe('Starting X coordinate. Required if sourceElementUUID is not provided.'),
35
+ sourceY: z
36
+ .number()
37
+ .int()
38
+ .min(0)
39
+ .optional()
40
+ .describe('Starting Y coordinate. Required if sourceElementUUID is not provided.'),
41
+ targetElementUUID: elementUUIDScheme
42
+ .trim()
43
+ .min(1)
44
+ .optional()
45
+ .describe('UUID of the target element to drop on. Either targetElementUUID or targetX/targetY must be provided.'),
46
+ targetX: z
47
+ .number()
48
+ .int()
49
+ .min(0)
50
+ .optional()
51
+ .describe('Ending X coordinate. Required if targetElementUUID is not provided.'),
52
+ targetY: z
53
+ .number()
54
+ .int()
55
+ .min(0)
56
+ .optional()
57
+ .describe('Ending Y coordinate. Required if targetElementUUID is not provided.'),
58
+ duration: z
59
+ .number()
60
+ .int()
61
+ .min(100)
62
+ .max(5000)
63
+ .default(1200)
64
+ .optional()
65
+ .describe('Duration of the drag movement in milliseconds. Default is 1200ms.'),
66
+ longPressDuration: z
67
+ .number()
68
+ .int()
69
+ .min(400)
70
+ .max(2000)
71
+ .default(600)
72
+ .optional()
73
+ .describe('Duration of the long press before dragging in milliseconds. Default is 600ms.'),
74
+ });
75
+ server.addTool({
76
+ name: 'appium_drag_and_drop',
77
+ description: `Perform a drag and drop gesture from a source location to a target location.
78
+ The gesture includes:
79
+ 1. Long press (default 600ms, configurable) on the source to initiate drag mode
80
+ 2. While holding, drag to the target location
81
+ 3. Release at the target to complete the drop
82
+
83
+ Supports four modes:
84
+ 1. Element to Element: Drag from one element to another element
85
+ 2. Element to Coordinates: Drag from an element to specific coordinates
86
+ 3. Coordinates to Element: Drag from coordinates to an element
87
+ 4. Coordinates to Coordinates: Drag from coordinates to coordinates
88
+
89
+ This is useful for reordering lists, moving items, drag-to-delete, and other drag interactions.`,
90
+ parameters: dragAndDropSchema,
91
+ annotations: {
92
+ readOnlyHint: false,
93
+ openWorldHint: false,
94
+ },
95
+ execute: async (args, context) => {
96
+ const driver = getDriver();
97
+ if (!driver) {
98
+ throw new Error('No driver found');
99
+ }
100
+ try {
101
+ const platform = getPlatformName(driver);
102
+ const duration = args.duration || 1200;
103
+ const longPressDuration = args.longPressDuration || 600;
104
+ if (!args.sourceElementUUID &&
105
+ (args.sourceX === undefined || args.sourceY === undefined)) {
106
+ throw new Error('Either sourceElementUUID or both sourceX and sourceY must be provided.');
107
+ }
108
+ if (!args.targetElementUUID &&
109
+ (args.targetX === undefined || args.targetY === undefined)) {
110
+ throw new Error('Either targetElementUUID or both targetX and targetY must be provided.');
111
+ }
112
+ let startX, startY;
113
+ let endX, endY;
114
+ if (args.sourceElementUUID) {
115
+ const rect = await driver.getElementRect(args.sourceElementUUID);
116
+ startX = Math.floor(rect.x + rect.width / 2);
117
+ startY = Math.floor(rect.y + rect.height / 2);
118
+ }
119
+ else {
120
+ startX = args.sourceX;
121
+ startY = args.sourceY;
122
+ }
123
+ if (args.targetElementUUID) {
124
+ const rect = await driver.getElementRect(args.targetElementUUID);
125
+ endX = Math.floor(rect.x + rect.width / 2);
126
+ endY = Math.floor(rect.y + rect.height / 2);
127
+ }
128
+ else {
129
+ endX = args.targetX;
130
+ endY = args.targetY;
131
+ }
132
+ const { width, height } = await driver.getWindowSize();
133
+ if (startX < 0 || startX >= width || startY < 0 || startY >= height) {
134
+ throw new Error(`Source coordinates (${startX}, ${startY}) are out of screen bounds (${width}x${height})`);
135
+ }
136
+ if (endX < 0 || endX >= width || endY < 0 || endY >= height) {
137
+ throw new Error(`Target coordinates (${endX}, ${endY}) are out of screen bounds (${width}x${height})`);
138
+ }
139
+ if (platform === 'Android' || platform === 'iOS') {
140
+ await performDragAndDrop(driver, startX, startY, endX, endY, duration, longPressDuration);
141
+ }
142
+ else {
143
+ throw new Error(`Unsupported platform: ${platform}. Only Android and iOS are supported.`);
144
+ }
145
+ const sourceDesc = args.sourceElementUUID
146
+ ? `element ${args.sourceElementUUID}`
147
+ : `coordinates (${startX}, ${startY})`;
148
+ const targetDesc = args.targetElementUUID
149
+ ? `element ${args.targetElementUUID}`
150
+ : `coordinates (${endX}, ${endY})`;
151
+ return {
152
+ content: [
153
+ {
154
+ type: 'text',
155
+ text: `Successfully performed drag and drop from ${sourceDesc} to ${targetDesc}.`,
156
+ },
157
+ ],
158
+ };
159
+ }
160
+ catch (err) {
161
+ return {
162
+ content: [
163
+ {
164
+ type: 'text',
165
+ text: `Failed to perform drag and drop. Error: ${err.toString()}`,
166
+ },
167
+ ],
168
+ };
169
+ }
170
+ },
171
+ });
172
+ }
173
+ //# sourceMappingURL=drag-and-drop.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"drag-and-drop.js","sourceRoot":"","sources":["../../../src/tools/interactions/drag-and-drop.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AACxB,OAAO,EAAE,SAAS,EAAE,eAAe,EAAE,MAAM,wBAAwB,CAAC;AACpE,OAAO,EAAE,iBAAiB,EAAE,MAAM,iBAAiB,CAAC;AAEpD,MAAM,sBAAsB,GAAG,GAAG,CAAC;AAEnC,KAAK,UAAU,kBAAkB,CAC/B,MAAW,EACX,MAAc,EACd,MAAc,EACd,IAAY,EACZ,IAAY,EACZ,QAAgB,EAChB,iBAAyB;IAEzB,MAAM,MAAM,CAAC,cAAc,CAAC;QAC1B;YACE,IAAI,EAAE,SAAS;YACf,EAAE,EAAE,SAAS;YACb,UAAU,EAAE,EAAE,WAAW,EAAE,OAAO,EAAE;YACpC,OAAO,EAAE;gBACP,EAAE,IAAI,EAAE,aAAa,EAAE,QAAQ,EAAE,CAAC,EAAE,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,MAAM,EAAE;gBAC1D,EAAE,IAAI,EAAE,aAAa,EAAE,MAAM,EAAE,CAAC,EAAE;gBAClC,EAAE,IAAI,EAAE,OAAO,EAAE,QAAQ,EAAE,iBAAiB,EAAE;gBAC9C,EAAE,IAAI,EAAE,aAAa,EAAE,QAAQ,EAAE,QAAQ,EAAE,CAAC,EAAE,IAAI,EAAE,CAAC,EAAE,IAAI,EAAE;gBAC7D,EAAE,IAAI,EAAE,OAAO,EAAE,QAAQ,EAAE,sBAAsB,EAAE;gBACnD,EAAE,IAAI,EAAE,WAAW,EAAE,MAAM,EAAE,CAAC,EAAE;aACjC;SACF;KACF,CAAC,CAAC;AACL,CAAC;AAED,MAAM,CAAC,OAAO,UAAU,WAAW,CAAC,MAAe;IACjD,MAAM,iBAAiB,GAAG,CAAC,CAAC,MAAM,CAAC;QACjC,iBAAiB,EAAE,iBAAiB;aACjC,IAAI,EAAE;aACN,GAAG,CAAC,CAAC,CAAC;aACN,QAAQ,EAAE;aACV,QAAQ,CACP,wGAAwG,CACzG;QACH,OAAO,EAAE,CAAC;aACP,MAAM,EAAE;aACR,GAAG,EAAE;aACL,GAAG,CAAC,CAAC,CAAC;aACN,QAAQ,EAAE;aACV,QAAQ,CACP,uEAAuE,CACxE;QACH,OAAO,EAAE,CAAC;aACP,MAAM,EAAE;aACR,GAAG,EAAE;aACL,GAAG,CAAC,CAAC,CAAC;aACN,QAAQ,EAAE;aACV,QAAQ,CACP,uEAAuE,CACxE;QACH,iBAAiB,EAAE,iBAAiB;aACjC,IAAI,EAAE;aACN,GAAG,CAAC,CAAC,CAAC;aACN,QAAQ,EAAE;aACV,QAAQ,CACP,sGAAsG,CACvG;QACH,OAAO,EAAE,CAAC;aACP,MAAM,EAAE;aACR,GAAG,EAAE;aACL,GAAG,CAAC,CAAC,CAAC;aACN,QAAQ,EAAE;aACV,QAAQ,CACP,qEAAqE,CACtE;QACH,OAAO,EAAE,CAAC;aACP,MAAM,EAAE;aACR,GAAG,EAAE;aACL,GAAG,CAAC,CAAC,CAAC;aACN,QAAQ,EAAE;aACV,QAAQ,CACP,qEAAqE,CACtE;QACH,QAAQ,EAAE,CAAC;aACR,MAAM,EAAE;aACR,GAAG,EAAE;aACL,GAAG,CAAC,GAAG,CAAC;aACR,GAAG,CAAC,IAAI,CAAC;aACT,OAAO,CAAC,IAAI,CAAC;aACb,QAAQ,EAAE;aACV,QAAQ,CACP,mEAAmE,CACpE;QACH,iBAAiB,EAAE,CAAC;aACjB,MAAM,EAAE;aACR,GAAG,EAAE;aACL,GAAG,CAAC,GAAG,CAAC;aACR,GAAG,CAAC,IAAI,CAAC;aACT,OAAO,CAAC,GAAG,CAAC;aACZ,QAAQ,EAAE;aACV,QAAQ,CACP,+EAA+E,CAChF;KACJ,CAAC,CAAC;IAEH,MAAM,CAAC,OAAO,CAAC;QACb,IAAI,EAAE,sBAAsB;QAC5B,WAAW,EAAE;;;;;;;;;;;;sGAYqF;QAClG,UAAU,EAAE,iBAAiB;QAC7B,WAAW,EAAE;YACX,YAAY,EAAE,KAAK;YACnB,aAAa,EAAE,KAAK;SACrB;QACD,OAAO,EAAE,KAAK,EAAE,IAAS,EAAE,OAAY,EAAgB,EAAE;YACvD,MAAM,MAAM,GAAG,SAAS,EAAE,CAAC;YAC3B,IAAI,CAAC,MAAM,EAAE,CAAC;gBACZ,MAAM,IAAI,KAAK,CAAC,iBAAiB,CAAC,CAAC;YACrC,CAAC;YAED,IAAI,CAAC;gBACH,MAAM,QAAQ,GAAG,eAAe,CAAC,MAAM,CAAC,CAAC;gBACzC,MAAM,QAAQ,GAAG,IAAI,CAAC,QAAQ,IAAI,IAAI,CAAC;gBACvC,MAAM,iBAAiB,GAAG,IAAI,CAAC,iBAAiB,IAAI,GAAG,CAAC;gBAExD,IACE,CAAC,IAAI,CAAC,iBAAiB;oBACvB,CAAC,IAAI,CAAC,OAAO,KAAK,SAAS,IAAI,IAAI,CAAC,OAAO,KAAK,SAAS,CAAC,EAC1D,CAAC;oBACD,MAAM,IAAI,KAAK,CACb,wEAAwE,CACzE,CAAC;gBACJ,CAAC;gBAED,IACE,CAAC,IAAI,CAAC,iBAAiB;oBACvB,CAAC,IAAI,CAAC,OAAO,KAAK,SAAS,IAAI,IAAI,CAAC,OAAO,KAAK,SAAS,CAAC,EAC1D,CAAC;oBACD,MAAM,IAAI,KAAK,CACb,wEAAwE,CACzE,CAAC;gBACJ,CAAC;gBAED,IAAI,MAAc,EAAE,MAAc,CAAC;gBACnC,IAAI,IAAY,EAAE,IAAY,CAAC;gBAE/B,IAAI,IAAI,CAAC,iBAAiB,EAAE,CAAC;oBAC3B,MAAM,IAAI,GAAG,MAAM,MAAM,CAAC,cAAc,CAAC,IAAI,CAAC,iBAAiB,CAAC,CAAC;oBACjE,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,GAAG,IAAI,CAAC,KAAK,GAAG,CAAC,CAAC,CAAC;oBAC7C,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,GAAG,IAAI,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC;gBAChD,CAAC;qBAAM,CAAC;oBACN,MAAM,GAAG,IAAI,CAAC,OAAO,CAAC;oBACtB,MAAM,GAAG,IAAI,CAAC,OAAO,CAAC;gBACxB,CAAC;gBAED,IAAI,IAAI,CAAC,iBAAiB,EAAE,CAAC;oBAC3B,MAAM,IAAI,GAAG,MAAM,MAAM,CAAC,cAAc,CAAC,IAAI,CAAC,iBAAiB,CAAC,CAAC;oBACjE,IAAI,GAAG,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,GAAG,IAAI,CAAC,KAAK,GAAG,CAAC,CAAC,CAAC;oBAC3C,IAAI,GAAG,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,GAAG,IAAI,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC;gBAC9C,CAAC;qBAAM,CAAC;oBACN,IAAI,GAAG,IAAI,CAAC,OAAO,CAAC;oBACpB,IAAI,GAAG,IAAI,CAAC,OAAO,CAAC;gBACtB,CAAC;gBAED,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,GAAG,MAAM,MAAM,CAAC,aAAa,EAAE,CAAC;gBACvD,IAAI,MAAM,GAAG,CAAC,IAAI,MAAM,IAAI,KAAK,IAAI,MAAM,GAAG,CAAC,IAAI,MAAM,IAAI,MAAM,EAAE,CAAC;oBACpE,MAAM,IAAI,KAAK,CACb,uBAAuB,MAAM,KAAK,MAAM,+BAA+B,KAAK,IAAI,MAAM,GAAG,CAC1F,CAAC;gBACJ,CAAC;gBACD,IAAI,IAAI,GAAG,CAAC,IAAI,IAAI,IAAI,KAAK,IAAI,IAAI,GAAG,CAAC,IAAI,IAAI,IAAI,MAAM,EAAE,CAAC;oBAC5D,MAAM,IAAI,KAAK,CACb,uBAAuB,IAAI,KAAK,IAAI,+BAA+B,KAAK,IAAI,MAAM,GAAG,CACtF,CAAC;gBACJ,CAAC;gBAED,IAAI,QAAQ,KAAK,SAAS,IAAI,QAAQ,KAAK,KAAK,EAAE,CAAC;oBACjD,MAAM,kBAAkB,CACtB,MAAM,EACN,MAAM,EACN,MAAM,EACN,IAAI,EACJ,IAAI,EACJ,QAAQ,EACR,iBAAiB,CAClB,CAAC;gBACJ,CAAC;qBAAM,CAAC;oBACN,MAAM,IAAI,KAAK,CACb,yBAAyB,QAAQ,uCAAuC,CACzE,CAAC;gBACJ,CAAC;gBAED,MAAM,UAAU,GAAG,IAAI,CAAC,iBAAiB;oBACvC,CAAC,CAAC,WAAW,IAAI,CAAC,iBAAiB,EAAE;oBACrC,CAAC,CAAC,gBAAgB,MAAM,KAAK,MAAM,GAAG,CAAC;gBACzC,MAAM,UAAU,GAAG,IAAI,CAAC,iBAAiB;oBACvC,CAAC,CAAC,WAAW,IAAI,CAAC,iBAAiB,EAAE;oBACrC,CAAC,CAAC,gBAAgB,IAAI,KAAK,IAAI,GAAG,CAAC;gBAErC,OAAO;oBACL,OAAO,EAAE;wBACP;4BACE,IAAI,EAAE,MAAM;4BACZ,IAAI,EAAE,6CAA6C,UAAU,OAAO,UAAU,GAAG;yBAClF;qBACF;iBACF,CAAC;YACJ,CAAC;YAAC,OAAO,GAAQ,EAAE,CAAC;gBAClB,OAAO;oBACL,OAAO,EAAE;wBACP;4BACE,IAAI,EAAE,MAAM;4BACZ,IAAI,EAAE,2CAA2C,GAAG,CAAC,QAAQ,EAAE,EAAE;yBAClE;qBACF;iBACF,CAAC;YACJ,CAAC;QACH,CAAC;KACF,CAAC,CAAC;AACL,CAAC"}
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "appium-mcp",
3
3
  "mcpName": "io.github.appium/appium-mcp",
4
- "version": "1.4.0",
4
+ "version": "1.5.0",
5
5
  "type": "module",
6
6
  "repository": {
7
7
  "type": "git",
@@ -29,6 +29,7 @@ This directory contains all MCP tools available in MCP Appium.
29
29
  - `click.ts` - Click elements
30
30
  - `double-tap.ts` - Double tap elements
31
31
  - `long-press.ts` - Long press (press and hold) elements
32
+ - `drag-and-drop.ts` - Drag and drop elements or coordinates
32
33
  - `set-value.ts` - Enter text
33
34
  - `get-text.ts` - Get element text
34
35
  - `get-page-source.ts` - Get page source (XML) from current screen
@@ -31,6 +31,7 @@ import findElement from './interactions/find.js';
31
31
  import clickElement from './interactions/click.js';
32
32
  import doubleTap from './interactions/double-tap.js';
33
33
  import longPress from './interactions/long-press.js';
34
+ import dragAndDrop from './interactions/drag-and-drop.js';
34
35
  import setValue from './interactions/set-value.js';
35
36
  import getText from './interactions/get-text.js';
36
37
  import getPageSource from './interactions/get-page-source.js';
@@ -131,6 +132,7 @@ export default function registerTools(server: FastMCP): void {
131
132
  clickElement(server);
132
133
  doubleTap(server);
133
134
  longPress(server);
135
+ dragAndDrop(server);
134
136
  setValue(server);
135
137
  getText(server);
136
138
  getPageSource(server);
@@ -0,0 +1,229 @@
1
+ import { FastMCP } from 'fastmcp/dist/FastMCP.js';
2
+ import { z } from 'zod';
3
+ import { getDriver, getPlatformName } from '../../session-store.js';
4
+ import { elementUUIDScheme } from '../../schema.js';
5
+
6
+ const DROP_PAUSE_DURATION_MS = 150;
7
+
8
+ async function performDragAndDrop(
9
+ driver: any,
10
+ startX: number,
11
+ startY: number,
12
+ endX: number,
13
+ endY: number,
14
+ duration: number,
15
+ longPressDuration: number
16
+ ): Promise<void> {
17
+ await driver.performActions([
18
+ {
19
+ type: 'pointer',
20
+ id: 'finger1',
21
+ parameters: { pointerType: 'touch' },
22
+ actions: [
23
+ { type: 'pointerMove', duration: 0, x: startX, y: startY },
24
+ { type: 'pointerDown', button: 0 },
25
+ { type: 'pause', duration: longPressDuration },
26
+ { type: 'pointerMove', duration: duration, x: endX, y: endY },
27
+ { type: 'pause', duration: DROP_PAUSE_DURATION_MS },
28
+ { type: 'pointerUp', button: 0 },
29
+ ],
30
+ },
31
+ ]);
32
+ }
33
+
34
+ export default function dragAndDrop(server: FastMCP): void {
35
+ const dragAndDropSchema = z.object({
36
+ sourceElementUUID: elementUUIDScheme
37
+ .trim()
38
+ .min(1)
39
+ .optional()
40
+ .describe(
41
+ 'UUID of the source element to drag from. Either sourceElementUUID or sourceX/sourceY must be provided.'
42
+ ),
43
+ sourceX: z
44
+ .number()
45
+ .int()
46
+ .min(0)
47
+ .optional()
48
+ .describe(
49
+ 'Starting X coordinate. Required if sourceElementUUID is not provided.'
50
+ ),
51
+ sourceY: z
52
+ .number()
53
+ .int()
54
+ .min(0)
55
+ .optional()
56
+ .describe(
57
+ 'Starting Y coordinate. Required if sourceElementUUID is not provided.'
58
+ ),
59
+ targetElementUUID: elementUUIDScheme
60
+ .trim()
61
+ .min(1)
62
+ .optional()
63
+ .describe(
64
+ 'UUID of the target element to drop on. Either targetElementUUID or targetX/targetY must be provided.'
65
+ ),
66
+ targetX: z
67
+ .number()
68
+ .int()
69
+ .min(0)
70
+ .optional()
71
+ .describe(
72
+ 'Ending X coordinate. Required if targetElementUUID is not provided.'
73
+ ),
74
+ targetY: z
75
+ .number()
76
+ .int()
77
+ .min(0)
78
+ .optional()
79
+ .describe(
80
+ 'Ending Y coordinate. Required if targetElementUUID is not provided.'
81
+ ),
82
+ duration: z
83
+ .number()
84
+ .int()
85
+ .min(100)
86
+ .max(5000)
87
+ .default(1200)
88
+ .optional()
89
+ .describe(
90
+ 'Duration of the drag movement in milliseconds. Default is 1200ms.'
91
+ ),
92
+ longPressDuration: z
93
+ .number()
94
+ .int()
95
+ .min(400)
96
+ .max(2000)
97
+ .default(600)
98
+ .optional()
99
+ .describe(
100
+ 'Duration of the long press before dragging in milliseconds. Default is 600ms.'
101
+ ),
102
+ });
103
+
104
+ server.addTool({
105
+ name: 'appium_drag_and_drop',
106
+ description: `Perform a drag and drop gesture from a source location to a target location.
107
+ The gesture includes:
108
+ 1. Long press (default 600ms, configurable) on the source to initiate drag mode
109
+ 2. While holding, drag to the target location
110
+ 3. Release at the target to complete the drop
111
+
112
+ Supports four modes:
113
+ 1. Element to Element: Drag from one element to another element
114
+ 2. Element to Coordinates: Drag from an element to specific coordinates
115
+ 3. Coordinates to Element: Drag from coordinates to an element
116
+ 4. Coordinates to Coordinates: Drag from coordinates to coordinates
117
+
118
+ This is useful for reordering lists, moving items, drag-to-delete, and other drag interactions.`,
119
+ parameters: dragAndDropSchema,
120
+ annotations: {
121
+ readOnlyHint: false,
122
+ openWorldHint: false,
123
+ },
124
+ execute: async (args: any, context: any): Promise<any> => {
125
+ const driver = getDriver();
126
+ if (!driver) {
127
+ throw new Error('No driver found');
128
+ }
129
+
130
+ try {
131
+ const platform = getPlatformName(driver);
132
+ const duration = args.duration || 1200;
133
+ const longPressDuration = args.longPressDuration || 600;
134
+
135
+ if (
136
+ !args.sourceElementUUID &&
137
+ (args.sourceX === undefined || args.sourceY === undefined)
138
+ ) {
139
+ throw new Error(
140
+ 'Either sourceElementUUID or both sourceX and sourceY must be provided.'
141
+ );
142
+ }
143
+
144
+ if (
145
+ !args.targetElementUUID &&
146
+ (args.targetX === undefined || args.targetY === undefined)
147
+ ) {
148
+ throw new Error(
149
+ 'Either targetElementUUID or both targetX and targetY must be provided.'
150
+ );
151
+ }
152
+
153
+ let startX: number, startY: number;
154
+ let endX: number, endY: number;
155
+
156
+ if (args.sourceElementUUID) {
157
+ const rect = await driver.getElementRect(args.sourceElementUUID);
158
+ startX = Math.floor(rect.x + rect.width / 2);
159
+ startY = Math.floor(rect.y + rect.height / 2);
160
+ } else {
161
+ startX = args.sourceX;
162
+ startY = args.sourceY;
163
+ }
164
+
165
+ if (args.targetElementUUID) {
166
+ const rect = await driver.getElementRect(args.targetElementUUID);
167
+ endX = Math.floor(rect.x + rect.width / 2);
168
+ endY = Math.floor(rect.y + rect.height / 2);
169
+ } else {
170
+ endX = args.targetX;
171
+ endY = args.targetY;
172
+ }
173
+
174
+ const { width, height } = await driver.getWindowSize();
175
+ if (startX < 0 || startX >= width || startY < 0 || startY >= height) {
176
+ throw new Error(
177
+ `Source coordinates (${startX}, ${startY}) are out of screen bounds (${width}x${height})`
178
+ );
179
+ }
180
+ if (endX < 0 || endX >= width || endY < 0 || endY >= height) {
181
+ throw new Error(
182
+ `Target coordinates (${endX}, ${endY}) are out of screen bounds (${width}x${height})`
183
+ );
184
+ }
185
+
186
+ if (platform === 'Android' || platform === 'iOS') {
187
+ await performDragAndDrop(
188
+ driver,
189
+ startX,
190
+ startY,
191
+ endX,
192
+ endY,
193
+ duration,
194
+ longPressDuration
195
+ );
196
+ } else {
197
+ throw new Error(
198
+ `Unsupported platform: ${platform}. Only Android and iOS are supported.`
199
+ );
200
+ }
201
+
202
+ const sourceDesc = args.sourceElementUUID
203
+ ? `element ${args.sourceElementUUID}`
204
+ : `coordinates (${startX}, ${startY})`;
205
+ const targetDesc = args.targetElementUUID
206
+ ? `element ${args.targetElementUUID}`
207
+ : `coordinates (${endX}, ${endY})`;
208
+
209
+ return {
210
+ content: [
211
+ {
212
+ type: 'text',
213
+ text: `Successfully performed drag and drop from ${sourceDesc} to ${targetDesc}.`,
214
+ },
215
+ ],
216
+ };
217
+ } catch (err: any) {
218
+ return {
219
+ content: [
220
+ {
221
+ type: 'text',
222
+ text: `Failed to perform drag and drop. Error: ${err.toString()}`,
223
+ },
224
+ ],
225
+ };
226
+ }
227
+ },
228
+ });
229
+ }