appium-mcp 1.19.1 → 1.20.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 +8 -0
- package/dist/command.d.ts +2 -1
- package/dist/command.d.ts.map +1 -1
- package/dist/command.js +10 -0
- package/dist/command.js.map +1 -1
- package/dist/tools/index.d.ts.map +1 -1
- package/dist/tools/index.js +8 -0
- package/dist/tools/index.js.map +1 -1
- package/dist/tools/interactions/active-element.d.ts +3 -0
- package/dist/tools/interactions/active-element.d.ts.map +1 -0
- package/dist/tools/interactions/active-element.js +45 -0
- package/dist/tools/interactions/active-element.js.map +1 -0
- package/dist/tools/interactions/find.js +2 -2
- package/dist/tools/interactions/find.js.map +1 -1
- package/dist/tools/interactions/press-key.d.ts +3 -0
- package/dist/tools/interactions/press-key.d.ts.map +1 -0
- package/dist/tools/interactions/press-key.js +136 -0
- package/dist/tools/interactions/press-key.js.map +1 -0
- package/dist/tools/interactions/screenshot.d.ts +1 -0
- package/dist/tools/interactions/screenshot.d.ts.map +1 -1
- package/dist/tools/interactions/screenshot.js +30 -4
- package/dist/tools/interactions/screenshot.js.map +1 -1
- package/dist/tools/test-generation/locators.js +1 -1
- package/dist/tools/test-generation/locators.js.map +1 -1
- package/package.json +1 -1
- package/server.json +2 -2
- package/src/command.ts +13 -1
- package/src/tools/README.md +20 -0
- package/src/tools/index.ts +8 -0
- package/src/tools/interactions/active-element.ts +52 -0
- package/src/tools/interactions/find.ts +2 -2
- package/src/tools/interactions/press-key.ts +180 -0
- package/src/tools/interactions/screenshot.ts +37 -4
- package/src/tools/test-generation/locators.ts +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -1,3 +1,11 @@
|
|
|
1
|
+
## [1.20.0](https://github.com/appium/appium-mcp/compare/v1.19.1...v1.20.0) (2026-02-25)
|
|
2
|
+
|
|
3
|
+
### Features
|
|
4
|
+
|
|
5
|
+
* add get active element ([#176](https://github.com/appium/appium-mcp/issues/176)) ([248b71c](https://github.com/appium/appium-mcp/commit/248b71c8205f146e834891a2cb065088d14ac018))
|
|
6
|
+
* **interactions:** add press-key tool ([#178](https://github.com/appium/appium-mcp/issues/178)) ([67db0da](https://github.com/appium/appium-mcp/commit/67db0da7a5f789047ad007e6c735d87b6213ff3d))
|
|
7
|
+
* **screenshot:** add optional maxWidth parameter for image resizing ([#180](https://github.com/appium/appium-mcp/issues/180)) ([03b1c99](https://github.com/appium/appium-mcp/commit/03b1c99934631050697f6a69031c0544f83f6acd)), closes [#56](https://github.com/appium/appium-mcp/issues/56)
|
|
8
|
+
|
|
1
9
|
## [1.19.1](https://github.com/appium/appium-mcp/compare/v1.19.0...v1.19.1) (2026-02-23)
|
|
2
10
|
|
|
3
11
|
### Miscellaneous Chores
|
package/dist/command.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import type { DriverInstance } from './session-store.js';
|
|
2
|
-
import { StringRecord } from '@appium/types';
|
|
2
|
+
import type { StringRecord, Element as AppiumElement } from '@appium/types';
|
|
3
3
|
/**
|
|
4
4
|
* Execute a driver command.
|
|
5
5
|
*
|
|
@@ -104,6 +104,7 @@ export declare function getScreenshot(driver: DriverInstance, elementId?: string
|
|
|
104
104
|
* @returns The element's text content.
|
|
105
105
|
*/
|
|
106
106
|
export declare function getElementText(driver: DriverInstance, elementUUID: string): Promise<string>;
|
|
107
|
+
export declare function getActiveElement(driver: DriverInstance): Promise<AppiumElement>;
|
|
107
108
|
/**
|
|
108
109
|
* Get the current device/screen orientation.
|
|
109
110
|
*
|
package/dist/command.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"command.d.ts","sourceRoot":"","sources":["../src/command.ts"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,oBAAoB,CAAC;AACzD,OAAO,EAAE,YAAY,EAAE,MAAM,eAAe,CAAC;
|
|
1
|
+
{"version":3,"file":"command.d.ts","sourceRoot":"","sources":["../src/command.ts"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,oBAAoB,CAAC;AACzD,OAAO,KAAK,EAAE,YAAY,EAAE,OAAO,IAAI,aAAa,EAAE,MAAM,eAAe,CAAC;AAE5E;;;;;;;;;;;GAWG;AACH,wBAAsB,OAAO,CAC3B,MAAM,EAAE,cAAc,EACtB,GAAG,EAAE,MAAM,EACX,MAAM,EAAE,GAAG,GACV,OAAO,CAAC,GAAG,CAAC,CAQd;AAED;;;;;;;;GAQG;AACH,wBAAsB,WAAW,CAC/B,MAAM,EAAE,cAAc,EACtB,KAAK,EAAE,MAAM,GACZ,OAAO,CAAC,IAAI,CAAC,CAOf;AAED;;;;;GAKG;AACH,wBAAsB,iBAAiB,CACrC,MAAM,EAAE,cAAc,GACrB,OAAO,CAAC,MAAM,CAAC,CAOjB;AAED;;;;;GAKG;AACH,wBAAsB,WAAW,CAAC,MAAM,EAAE,cAAc,GAAG,OAAO,CAAC,MAAM,EAAE,CAAC,CAO3E;AAED;;;;;GAKG;AACH,wBAAsB,UAAU,CAC9B,MAAM,EAAE,cAAc,EACtB,IAAI,CAAC,EAAE,MAAM,GACZ,OAAO,CAAC,IAAI,CAAC,CAOf;AAED;;;;;;;GAOG;AACH,wBAAsB,QAAQ,CAC5B,MAAM,EAAE,cAAc,EACtB,WAAW,EAAE,MAAM,EACnB,IAAI,EAAE,MAAM,iBAQb;AAED;;;;;GAKG;AACH,wBAAsB,YAAY,CAChC,MAAM,EAAE,cAAc,EACtB,WAAW,EAAE,MAAM,GAClB,OAAO,CAAC,IAAI,CAAC,CAOf;AAED;;;;;;GAMG;AACH,wBAAsB,cAAc,CAClC,MAAM,EAAE,cAAc,EACtB,WAAW,EAAE,MAAM,GAClB,OAAO,CAAC,OAAO,eAAe,EAAE,IAAI,CAAC,CAOvC;AAED;;;;;GAKG;AACH,wBAAsB,aAAa,CACjC,MAAM,EAAE,cAAc,GACrB,OAAO,CAAC,OAAO,eAAe,EAAE,IAAI,CAAC,CAOvC;AAED;;;;;GAKG;AACH,wBAAsB,cAAc,CAClC,MAAM,EAAE,cAAc,EACtB,SAAS,EAAE,YAAY,CAAC,GAAG,CAAC,EAAE,GAAG,OAAO,eAAe,EAAE,cAAc,EAAE,GACxE,OAAO,CAAC,IAAI,CAAC,CASf;AAED;;;;;GAKG;AACH,wBAAsB,aAAa,CAAC,MAAM,EAAE,cAAc,GAAG,OAAO,CAAC,MAAM,CAAC,CAO3E;AAED;;;;;GAKG;AACH,wBAAsB,aAAa,CACjC,MAAM,EAAE,cAAc,EACtB,SAAS,CAAC,EAAE,MAAM,GACjB,OAAO,CAAC,MAAM,CAAC,CAgBjB;AAED;;;;;;GAMG;AACH,wBAAsB,cAAc,CAClC,MAAM,EAAE,cAAc,EACtB,WAAW,EAAE,MAAM,GAClB,OAAO,CAAC,MAAM,CAAC,CAOjB;AAED,wBAAsB,gBAAgB,CACpC,MAAM,EAAE,cAAc,GACrB,OAAO,CAAC,aAAa,CAAC,CAQxB;AAED;;;;;GAKG;AACH,wBAAsB,cAAc,CAClC,MAAM,EAAE,cAAc,GACrB,OAAO,CAAC,WAAW,GAAG,UAAU,CAAC,CASnC;AAED;;;;;GAKG;AACH,wBAAsB,cAAc,CAClC,MAAM,EAAE,cAAc,EACtB,WAAW,EAAE,WAAW,GAAG,UAAU,GACpC,OAAO,CAAC,IAAI,CAAC,CAOf"}
|
package/dist/command.js
CHANGED
|
@@ -218,6 +218,16 @@ export async function getElementText(driver, elementUUID) {
|
|
|
218
218
|
}
|
|
219
219
|
return await driver.getElementText(elementUUID);
|
|
220
220
|
}
|
|
221
|
+
export async function getActiveElement(driver) {
|
|
222
|
+
if (isAndroidUiautomator2DriverSession(driver)) {
|
|
223
|
+
return await driver.active();
|
|
224
|
+
}
|
|
225
|
+
else if (isXCUITestDriverSession(driver)) {
|
|
226
|
+
return await driver.active();
|
|
227
|
+
}
|
|
228
|
+
const result = await driver.getActiveElement();
|
|
229
|
+
return result;
|
|
230
|
+
}
|
|
221
231
|
/**
|
|
222
232
|
* Get the current device/screen orientation.
|
|
223
233
|
*
|
package/dist/command.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"command.js","sourceRoot":"","sources":["../src/command.ts"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"command.js","sourceRoot":"","sources":["../src/command.ts"],"names":[],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/tools/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AACH,OAAO,EAAE,OAAO,EAAE,MAAM,SAAS,CAAC;
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/tools/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AACH,OAAO,EAAE,OAAO,EAAE,MAAM,SAAS,CAAC;AAsClC,MAAM,CAAC,OAAO,UAAU,aAAa,CAAC,MAAM,EAAE,OAAO,GAAG,IAAI,CA4H3D"}
|
package/dist/tools/index.js
CHANGED
|
@@ -17,8 +17,10 @@ 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
19
|
import dragAndDrop from './interactions/drag-and-drop.js';
|
|
20
|
+
import pressKey from './interactions/press-key.js';
|
|
20
21
|
import setValue from './interactions/set-value.js';
|
|
21
22
|
import getText from './interactions/get-text.js';
|
|
23
|
+
import getActiveElement from './interactions/active-element.js';
|
|
22
24
|
import getPageSource from './interactions/get-page-source.js';
|
|
23
25
|
import { getOrientation, setOrientation } from './interactions/orientation.js';
|
|
24
26
|
import handleAlert from './interactions/handle-alert.js';
|
|
@@ -108,13 +110,19 @@ export default function registerTools(server) {
|
|
|
108
110
|
scrollToElement(server);
|
|
109
111
|
swipe(server);
|
|
110
112
|
// Element Interactions
|
|
113
|
+
// PRIORITY ORDER FOR ELEMENT SEARCH:
|
|
114
|
+
// 1. getActiveElement - Get currently focused element (efficient, instant)
|
|
115
|
+
// 2. findElement - Find specific element by strategy/selector
|
|
116
|
+
// 3. generateLocators - Generate all locators (heavyweight, for debugging only)
|
|
111
117
|
findElement(server);
|
|
112
118
|
clickElement(server);
|
|
113
119
|
doubleTap(server);
|
|
114
120
|
longPress(server);
|
|
115
121
|
dragAndDrop(server);
|
|
122
|
+
pressKey(server);
|
|
116
123
|
setValue(server);
|
|
117
124
|
getText(server);
|
|
125
|
+
getActiveElement(server);
|
|
118
126
|
getPageSource(server);
|
|
119
127
|
getOrientation(server);
|
|
120
128
|
setOrientation(server);
|
package/dist/tools/index.js.map
CHANGED
|
@@ -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 @@
|
|
|
1
|
+
{"version":3,"file":"active-element.d.ts","sourceRoot":"","sources":["../../../src/tools/interactions/active-element.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAiB,OAAO,EAAE,MAAM,SAAS,CAAC;AAItD,MAAM,CAAC,OAAO,UAAU,gBAAgB,CAAC,MAAM,EAAE,OAAO,GAAG,IAAI,CA+C9D"}
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
import { getDriver } from '../../session-store.js';
|
|
2
|
+
import { getActiveElement as _getActiveElement } from '../../command.js';
|
|
3
|
+
export default function getActiveElement(server) {
|
|
4
|
+
server.addTool({
|
|
5
|
+
name: 'appium_get_active_element',
|
|
6
|
+
description: 'Get the currently active/focused element and return its UUID for follow-up interactions. [PRIORITY 1: Use this first when you need to find what element currently has focus]',
|
|
7
|
+
annotations: {
|
|
8
|
+
readOnlyHint: true,
|
|
9
|
+
openWorldHint: false,
|
|
10
|
+
},
|
|
11
|
+
execute: async () => {
|
|
12
|
+
const driver = getDriver();
|
|
13
|
+
if (!driver) {
|
|
14
|
+
throw new Error('No driver found');
|
|
15
|
+
}
|
|
16
|
+
try {
|
|
17
|
+
const element = await _getActiveElement(driver);
|
|
18
|
+
const elementId = element['element-6066-11e4-a52e-4f735466cecf'] ??
|
|
19
|
+
element.ELEMENT;
|
|
20
|
+
if (!elementId) {
|
|
21
|
+
throw new Error('Active element was returned without a valid element ID');
|
|
22
|
+
}
|
|
23
|
+
return {
|
|
24
|
+
content: [
|
|
25
|
+
{
|
|
26
|
+
type: 'text',
|
|
27
|
+
text: `Successfully found an active element. Element id: ${elementId}`,
|
|
28
|
+
},
|
|
29
|
+
],
|
|
30
|
+
};
|
|
31
|
+
}
|
|
32
|
+
catch (err) {
|
|
33
|
+
return {
|
|
34
|
+
content: [
|
|
35
|
+
{
|
|
36
|
+
type: 'text',
|
|
37
|
+
text: `Failed to find an active element. err: ${err.toString()}`,
|
|
38
|
+
},
|
|
39
|
+
],
|
|
40
|
+
};
|
|
41
|
+
}
|
|
42
|
+
},
|
|
43
|
+
});
|
|
44
|
+
}
|
|
45
|
+
//# sourceMappingURL=active-element.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"active-element.js","sourceRoot":"","sources":["../../../src/tools/interactions/active-element.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,SAAS,EAAE,MAAM,wBAAwB,CAAC;AACnD,OAAO,EAAE,gBAAgB,IAAI,iBAAiB,EAAE,MAAM,kBAAkB,CAAC;AAEzE,MAAM,CAAC,OAAO,UAAU,gBAAgB,CAAC,MAAe;IACtD,MAAM,CAAC,OAAO,CAAC;QACb,IAAI,EAAE,2BAA2B;QACjC,WAAW,EACT,8KAA8K;QAChL,WAAW,EAAE;YACX,YAAY,EAAE,IAAI;YAClB,aAAa,EAAE,KAAK;SACrB;QACD,OAAO,EAAE,KAAK,IAA4B,EAAE;YAC1C,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,OAAO,GAAG,MAAM,iBAAiB,CAAC,MAAM,CAAC,CAAC;gBAChD,MAAM,SAAS,GACb,OAAO,CAAC,qCAAqC,CAAC;oBAC7C,OAA2C,CAAC,OAAO,CAAC;gBAEvD,IAAI,CAAC,SAAS,EAAE,CAAC;oBACf,MAAM,IAAI,KAAK,CACb,wDAAwD,CACzD,CAAC;gBACJ,CAAC;gBAED,OAAO;oBACL,OAAO,EAAE;wBACP;4BACE,IAAI,EAAE,MAAM;4BACZ,IAAI,EAAE,qDAAqD,SAAS,EAAE;yBACvE;qBACF;iBACF,CAAC;YACJ,CAAC;YAAC,OAAO,GAAQ,EAAE,CAAC;gBAClB,OAAO;oBACL,OAAO,EAAE;wBACP;4BACE,IAAI,EAAE,MAAM;4BACZ,IAAI,EAAE,0CAA0C,GAAG,CAAC,QAAQ,EAAE,EAAE;yBACjE;qBACF;iBACF,CAAC;YACJ,CAAC;QACH,CAAC;KACF,CAAC,CAAC;AACL,CAAC"}
|
|
@@ -17,10 +17,10 @@ export const findElementSchema = z.object({
|
|
|
17
17
|
export default function findElement(server) {
|
|
18
18
|
server.addTool({
|
|
19
19
|
name: 'appium_find_element',
|
|
20
|
-
description: 'Find
|
|
20
|
+
description: 'Find a specific element by strategy and selector which will return a uuid that can be used for interactions. [PRIORITY 2: Use this to search for a target element by xpath, id, accessibility id, etc.]',
|
|
21
21
|
parameters: findElementSchema,
|
|
22
22
|
annotations: {
|
|
23
|
-
readOnlyHint:
|
|
23
|
+
readOnlyHint: true,
|
|
24
24
|
openWorldHint: false,
|
|
25
25
|
},
|
|
26
26
|
execute: async (args, _context) => {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"find.js","sourceRoot":"","sources":["../../../src/tools/interactions/find.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AACxB,OAAO,EAAE,SAAS,EAAE,MAAM,wBAAwB,CAAC;AAEnD,MAAM,CAAC,MAAM,iBAAiB,GAAG,CAAC,CAAC,MAAM,CAAC;IACxC,QAAQ,EAAE,CAAC,CAAC,IAAI,CAAC;QACf,OAAO;QACP,IAAI;QACJ,MAAM;QACN,YAAY;QACZ,kBAAkB;QAClB,cAAc;QACd,sBAAsB;QACtB,uBAAuB;QACvB,kBAAkB;KACnB,CAAC;IACF,QAAQ,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,CAAC,kCAAkC,CAAC;CAClE,CAAC,CAAC;AAEH,MAAM,CAAC,OAAO,UAAU,WAAW,CAAC,MAAe;IACjD,MAAM,CAAC,OAAO,CAAC;QACb,IAAI,EAAE,qBAAqB;QAC3B,WAAW,EACT,
|
|
1
|
+
{"version":3,"file":"find.js","sourceRoot":"","sources":["../../../src/tools/interactions/find.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AACxB,OAAO,EAAE,SAAS,EAAE,MAAM,wBAAwB,CAAC;AAEnD,MAAM,CAAC,MAAM,iBAAiB,GAAG,CAAC,CAAC,MAAM,CAAC;IACxC,QAAQ,EAAE,CAAC,CAAC,IAAI,CAAC;QACf,OAAO;QACP,IAAI;QACJ,MAAM;QACN,YAAY;QACZ,kBAAkB;QAClB,cAAc;QACd,sBAAsB;QACtB,uBAAuB;QACvB,kBAAkB;KACnB,CAAC;IACF,QAAQ,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,CAAC,kCAAkC,CAAC;CAClE,CAAC,CAAC;AAEH,MAAM,CAAC,OAAO,UAAU,WAAW,CAAC,MAAe;IACjD,MAAM,CAAC,OAAO,CAAC;QACb,IAAI,EAAE,qBAAqB;QAC3B,WAAW,EACT,yMAAyM;QAC3M,UAAU,EAAE,iBAAiB;QAC7B,WAAW,EAAE;YACX,YAAY,EAAE,IAAI;YAClB,aAAa,EAAE,KAAK;SACrB;QACD,OAAO,EAAE,KAAK,EACZ,IAAuC,EACvC,QAA6C,EACrB,EAAE;YAC1B,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,OAAO,GAAG,MAAM,MAAM,CAAC,WAAW,CAAC,IAAI,CAAC,QAAQ,EAAE,IAAI,CAAC,QAAQ,CAAC,CAAC;gBACvE,OAAO;oBACL,OAAO,EAAE;wBACP;4BACE,IAAI,EAAE,MAAM;4BACZ,IAAI,EAAE,8BAA8B,IAAI,CAAC,QAAQ,kBAAkB,IAAI,CAAC,QAAQ,gBAAgB,OAAO,CAAC,qCAAqC,CAAC,EAAE;yBACjJ;qBACF;iBACF,CAAC;YACJ,CAAC;YAAC,OAAO,GAAQ,EAAE,CAAC;gBAClB,OAAO;oBACL,OAAO,EAAE;wBACP;4BACE,IAAI,EAAE,MAAM;4BACZ,IAAI,EAAE,0BAA0B,IAAI,CAAC,QAAQ,kBAAkB,IAAI,CAAC,QAAQ,UAAU,GAAG,CAAC,QAAQ,EAAE,EAAE;yBACvG;qBACF;iBACF,CAAC;YACJ,CAAC;QACH,CAAC;KACF,CAAC,CAAC;AACL,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"press-key.d.ts","sourceRoot":"","sources":["../../../src/tools/interactions/press-key.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAiB,OAAO,EAAE,MAAM,SAAS,CAAC;AAmCtD,MAAM,CAAC,OAAO,UAAU,QAAQ,CAAC,MAAM,EAAE,OAAO,GAAG,IAAI,CAgJtD"}
|
|
@@ -0,0 +1,136 @@
|
|
|
1
|
+
import { z } from 'zod';
|
|
2
|
+
import { getDriver, getPlatformName, isAndroidUiautomator2DriverSession, isXCUITestDriverSession, isRemoteDriverSession, PLATFORM, } from '../../session-store.js';
|
|
3
|
+
import { execute } from '../../command.js';
|
|
4
|
+
const ANDROID_KEYCODE_MAP = {
|
|
5
|
+
BACK: 4,
|
|
6
|
+
HOME: 3,
|
|
7
|
+
APP_SWITCH: 187,
|
|
8
|
+
};
|
|
9
|
+
const ANDROID_KEYS_DESCRIPTION = Object.keys(ANDROID_KEYCODE_MAP).join(', ');
|
|
10
|
+
const IOS_BUTTON_MAP = {
|
|
11
|
+
HOME: 'home',
|
|
12
|
+
VOLUME_UP: 'volumeup',
|
|
13
|
+
VOLUME_DOWN: 'volumedown',
|
|
14
|
+
UP: 'up',
|
|
15
|
+
DOWN: 'down',
|
|
16
|
+
LEFT: 'left',
|
|
17
|
+
RIGHT: 'right',
|
|
18
|
+
MENU: 'menu',
|
|
19
|
+
PLAY_PAUSE: 'playpause',
|
|
20
|
+
SELECT: 'select',
|
|
21
|
+
};
|
|
22
|
+
const IOS_BUTTONS_DESCRIPTION = Object.keys(IOS_BUTTON_MAP).join(', ');
|
|
23
|
+
export default function pressKey(server) {
|
|
24
|
+
const pressKeySchema = z
|
|
25
|
+
.object({
|
|
26
|
+
key: z
|
|
27
|
+
.enum([
|
|
28
|
+
'BACK',
|
|
29
|
+
'HOME',
|
|
30
|
+
'APP_SWITCH',
|
|
31
|
+
'VOLUME_UP',
|
|
32
|
+
'VOLUME_DOWN',
|
|
33
|
+
'UP',
|
|
34
|
+
'DOWN',
|
|
35
|
+
'LEFT',
|
|
36
|
+
'RIGHT',
|
|
37
|
+
'MENU',
|
|
38
|
+
'PLAY_PAUSE',
|
|
39
|
+
'SELECT',
|
|
40
|
+
])
|
|
41
|
+
.optional()
|
|
42
|
+
.describe(`Logical key/button to press. On Android: ${ANDROID_KEYS_DESCRIPTION}. On iOS/tvOS: ${IOS_BUTTONS_DESCRIPTION}.`),
|
|
43
|
+
keyCode: z
|
|
44
|
+
.number()
|
|
45
|
+
.int()
|
|
46
|
+
.optional()
|
|
47
|
+
.describe('Android keycode to press. If provided, takes precedence over key for Android.'),
|
|
48
|
+
isLongPress: z
|
|
49
|
+
.boolean()
|
|
50
|
+
.optional()
|
|
51
|
+
.describe('Android only. Whether to perform a long press. Defaults to false.'),
|
|
52
|
+
})
|
|
53
|
+
.refine((value) => value.key !== undefined || value.keyCode !== undefined, {
|
|
54
|
+
message: 'Either key or keyCode must be provided',
|
|
55
|
+
path: ['key'],
|
|
56
|
+
});
|
|
57
|
+
server.addTool({
|
|
58
|
+
name: 'appium_mobile_press_key',
|
|
59
|
+
description: 'Press navigation keys (BACK, HOME, APP_SWITCH) on Android or physical buttons (HOME, volume, etc.) on iOS/tvOS.',
|
|
60
|
+
parameters: pressKeySchema,
|
|
61
|
+
annotations: {
|
|
62
|
+
readOnlyHint: false,
|
|
63
|
+
openWorldHint: false,
|
|
64
|
+
},
|
|
65
|
+
execute: async (args, _context) => {
|
|
66
|
+
const driver = getDriver();
|
|
67
|
+
if (!driver) {
|
|
68
|
+
throw new Error('No driver found');
|
|
69
|
+
}
|
|
70
|
+
const platform = getPlatformName(driver);
|
|
71
|
+
const { key, keyCode, isLongPress } = args;
|
|
72
|
+
try {
|
|
73
|
+
if (platform === PLATFORM.android) {
|
|
74
|
+
const resolvedKeyCode = keyCode ?? (key && ANDROID_KEYCODE_MAP[key]) ?? undefined;
|
|
75
|
+
if (resolvedKeyCode == null) {
|
|
76
|
+
throw new Error(`For Android, provide either keyCode or key in [${ANDROID_KEYS_DESCRIPTION}].`);
|
|
77
|
+
}
|
|
78
|
+
if (isAndroidUiautomator2DriverSession(driver)) {
|
|
79
|
+
await driver.mobilePressKey(resolvedKeyCode, undefined, undefined, isLongPress ?? false);
|
|
80
|
+
}
|
|
81
|
+
else if (isRemoteDriverSession(driver)) {
|
|
82
|
+
await execute(driver, 'mobile: pressKey', {
|
|
83
|
+
keycode: resolvedKeyCode,
|
|
84
|
+
isLongPress: isLongPress ?? false,
|
|
85
|
+
});
|
|
86
|
+
}
|
|
87
|
+
else {
|
|
88
|
+
throw new Error('Unsupported Android driver for press_key');
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
else if (platform === PLATFORM.ios) {
|
|
92
|
+
const logicalKey = key ?? 'HOME';
|
|
93
|
+
const buttonName = IOS_BUTTON_MAP[logicalKey];
|
|
94
|
+
if (!buttonName) {
|
|
95
|
+
throw new Error(`For iOS/tvOS, key must be one of ${IOS_BUTTONS_DESCRIPTION}.`);
|
|
96
|
+
}
|
|
97
|
+
if (isXCUITestDriverSession(driver)) {
|
|
98
|
+
await driver.mobilePressButton(buttonName);
|
|
99
|
+
}
|
|
100
|
+
else if (isRemoteDriverSession(driver)) {
|
|
101
|
+
await execute(driver, 'mobile: pressButton', {
|
|
102
|
+
name: buttonName,
|
|
103
|
+
});
|
|
104
|
+
}
|
|
105
|
+
else {
|
|
106
|
+
throw new Error('Unsupported iOS/tvOS driver for press_key');
|
|
107
|
+
}
|
|
108
|
+
}
|
|
109
|
+
else {
|
|
110
|
+
throw new Error(`Unsupported platform: ${platform}. Only Android and iOS are supported.`);
|
|
111
|
+
}
|
|
112
|
+
return {
|
|
113
|
+
content: [
|
|
114
|
+
{
|
|
115
|
+
type: 'text',
|
|
116
|
+
text: platform === PLATFORM.android
|
|
117
|
+
? `Successfully pressed key${key ? ` "${key}"` : ''} on Android.`
|
|
118
|
+
: `Successfully pressed key${key ? ` "${key}"` : ''} on iOS/tvOS.`,
|
|
119
|
+
},
|
|
120
|
+
],
|
|
121
|
+
};
|
|
122
|
+
}
|
|
123
|
+
catch (err) {
|
|
124
|
+
return {
|
|
125
|
+
content: [
|
|
126
|
+
{
|
|
127
|
+
type: 'text',
|
|
128
|
+
text: `Failed to press key${key ? ` "${key}"` : ''}. err: ${err.toString()}`,
|
|
129
|
+
},
|
|
130
|
+
],
|
|
131
|
+
};
|
|
132
|
+
}
|
|
133
|
+
},
|
|
134
|
+
});
|
|
135
|
+
}
|
|
136
|
+
//# sourceMappingURL=press-key.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"press-key.js","sourceRoot":"","sources":["../../../src/tools/interactions/press-key.ts"],"names":[],"mappings":"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"}
|
|
@@ -18,6 +18,7 @@ export interface ScreenshotDeps {
|
|
|
18
18
|
export declare function executeScreenshot(opts: {
|
|
19
19
|
deps?: ScreenshotDeps;
|
|
20
20
|
elementId?: any;
|
|
21
|
+
maxWidth?: number;
|
|
21
22
|
}): Promise<any>;
|
|
22
23
|
export declare function screenshot(server: FastMCP): void;
|
|
23
24
|
export declare function elementScreenshot(server: FastMCP): void;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"screenshot.d.ts","sourceRoot":"","sources":["../../../src/tools/interactions/screenshot.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,SAAS,CAAC;AAGlC,OAAO,KAAK,EAAE,sBAAsB,EAAE,MAAM,wBAAwB,CAAC;AACrE,OAAO,EAAE,SAAS,EAAE,KAAK,EAAE,MAAM,kBAAkB,CAAC;
|
|
1
|
+
{"version":3,"file":"screenshot.d.ts","sourceRoot":"","sources":["../../../src/tools/interactions/screenshot.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,SAAS,CAAC;AAGlC,OAAO,KAAK,EAAE,sBAAsB,EAAE,MAAM,wBAAwB,CAAC;AACrE,OAAO,EAAE,SAAS,EAAE,KAAK,EAAE,MAAM,kBAAkB,CAAC;AAYpD;;;;;GAKG;AACH,wBAAgB,oBAAoB,IAAI,MAAM,CAY7C;AAED,MAAM,WAAW,cAAc;IAC7B,SAAS,EAAE,MAAM,sBAAsB,CAAC;IACxC,SAAS,EAAE,OAAO,SAAS,CAAC;IAC5B,KAAK,EAAE,OAAO,KAAK,CAAC;IACpB,oBAAoB,EAAE,OAAO,oBAAoB,CAAC;IAClD,OAAO,EAAE,MAAM,MAAM,CAAC;CACvB;AAUD,wBAAsB,iBAAiB,CAAC,IAAI,EAAE;IAC5C,IAAI,CAAC,EAAE,cAAc,CAAC;IACtB,SAAS,CAAC,MAAC;IACX,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB,GAAG,OAAO,CAAC,GAAG,CAAC,CAqEf;AASD,wBAAgB,UAAU,CAAC,MAAM,EAAE,OAAO,GAAG,IAAI,CAiBhD;AAED,wBAAgB,iBAAiB,CAAC,MAAM,EAAE,OAAO,GAAG,IAAI,CAqBvD"}
|
|
@@ -6,6 +6,7 @@ import * as os from 'node:os';
|
|
|
6
6
|
import { createUIResource, createScreenshotViewerUI, addUIResourceToResponse, } from '../../ui/mcp-ui-utils.js';
|
|
7
7
|
import { getScreenshot } from '../../command.js';
|
|
8
8
|
import z from 'zod';
|
|
9
|
+
import { imageUtil } from '@appium/support';
|
|
9
10
|
/**
|
|
10
11
|
* Resolves the screenshot directory path.
|
|
11
12
|
* - If SCREENSHOTS_DIR is not set, returns process.cwd()
|
|
@@ -30,7 +31,7 @@ const defaultDeps = {
|
|
|
30
31
|
dateNow: () => Date.now(),
|
|
31
32
|
};
|
|
32
33
|
export async function executeScreenshot(opts) {
|
|
33
|
-
const { deps = defaultDeps, elementId } = opts;
|
|
34
|
+
const { deps = defaultDeps, elementId, maxWidth } = opts;
|
|
34
35
|
const driver = deps.getDriver();
|
|
35
36
|
if (!driver) {
|
|
36
37
|
throw new Error('No driver found');
|
|
@@ -38,7 +39,22 @@ export async function executeScreenshot(opts) {
|
|
|
38
39
|
try {
|
|
39
40
|
const screenshotBase64 = await getScreenshot(driver, elementId);
|
|
40
41
|
// Convert base64 to buffer
|
|
41
|
-
const
|
|
42
|
+
const originalBuffer = Buffer.from(screenshotBase64, 'base64');
|
|
43
|
+
// Resize if maxWidth is provided and image is wider
|
|
44
|
+
let screenshotBuffer = originalBuffer;
|
|
45
|
+
let displayBase64 = screenshotBase64;
|
|
46
|
+
if (maxWidth !== undefined) {
|
|
47
|
+
const sharp = imageUtil.requireSharp();
|
|
48
|
+
const metadata = await sharp(originalBuffer).metadata();
|
|
49
|
+
if (metadata.width !== undefined && metadata.width > maxWidth) {
|
|
50
|
+
const resizedBuffer = await sharp(originalBuffer)
|
|
51
|
+
.resize({ width: maxWidth })
|
|
52
|
+
.png()
|
|
53
|
+
.toBuffer();
|
|
54
|
+
screenshotBuffer = Buffer.from(resizedBuffer);
|
|
55
|
+
displayBase64 = screenshotBuffer.toString('base64');
|
|
56
|
+
}
|
|
57
|
+
}
|
|
42
58
|
// Generate filename with timestamp
|
|
43
59
|
const timestamp = deps.dateNow();
|
|
44
60
|
const filename = `screenshot_${timestamp}.png`;
|
|
@@ -57,7 +73,7 @@ export async function executeScreenshot(opts) {
|
|
|
57
73
|
],
|
|
58
74
|
};
|
|
59
75
|
// Add interactive screenshot viewer UI
|
|
60
|
-
const uiResource = createUIResource(`ui://appium-mcp/screenshot-viewer/${Date.now()}`, createScreenshotViewerUI(
|
|
76
|
+
const uiResource = createUIResource(`ui://appium-mcp/screenshot-viewer/${Date.now()}`, createScreenshotViewerUI(displayBase64, filepath));
|
|
61
77
|
return addUIResourceToResponse(textResponse, uiResource);
|
|
62
78
|
}
|
|
63
79
|
catch (err) {
|
|
@@ -71,20 +87,29 @@ export async function executeScreenshot(opts) {
|
|
|
71
87
|
};
|
|
72
88
|
}
|
|
73
89
|
}
|
|
90
|
+
const maxWidthSchema = z
|
|
91
|
+
.number()
|
|
92
|
+
.optional()
|
|
93
|
+
.describe('Optional maximum width in pixels to resize the screenshot. The aspect ratio is preserved. Useful for reducing token usage when sending screenshots to LLMs.');
|
|
74
94
|
export function screenshot(server) {
|
|
95
|
+
const screenshotSchema = z.object({
|
|
96
|
+
maxWidth: maxWidthSchema,
|
|
97
|
+
});
|
|
75
98
|
server.addTool({
|
|
76
99
|
name: 'appium_screenshot',
|
|
77
100
|
description: 'Take a screenshot of the current screen and return as PNG image',
|
|
101
|
+
parameters: screenshotSchema,
|
|
78
102
|
annotations: {
|
|
79
103
|
readOnlyHint: false,
|
|
80
104
|
openWorldHint: false,
|
|
81
105
|
},
|
|
82
|
-
execute: async () => executeScreenshot({}),
|
|
106
|
+
execute: async (args, _context) => executeScreenshot({ maxWidth: args.maxWidth }),
|
|
83
107
|
});
|
|
84
108
|
}
|
|
85
109
|
export function elementScreenshot(server) {
|
|
86
110
|
const elementScreenshotSchema = z.object({
|
|
87
111
|
elementUUID: elementUUIDScheme,
|
|
112
|
+
maxWidth: maxWidthSchema,
|
|
88
113
|
});
|
|
89
114
|
server.addTool({
|
|
90
115
|
name: 'appium_element_screenshot',
|
|
@@ -96,6 +121,7 @@ export function elementScreenshot(server) {
|
|
|
96
121
|
},
|
|
97
122
|
execute: async (args, _context) => executeScreenshot({
|
|
98
123
|
elementId: args.elementUUID,
|
|
124
|
+
maxWidth: args.maxWidth,
|
|
99
125
|
}),
|
|
100
126
|
});
|
|
101
127
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"screenshot.js","sourceRoot":"","sources":["../../../src/tools/interactions/screenshot.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,SAAS,EAAE,MAAM,wBAAwB,CAAC;AACnD,OAAO,EAAE,iBAAiB,EAAE,MAAM,iBAAiB,CAAC;AAEpD,OAAO,EAAE,SAAS,EAAE,KAAK,EAAE,MAAM,kBAAkB,CAAC;AACpD,OAAO,EAAE,IAAI,EAAE,UAAU,EAAE,MAAM,WAAW,CAAC;AAC7C,OAAO,KAAK,EAAE,MAAM,SAAS,CAAC;AAC9B,OAAO,EACL,gBAAgB,EAChB,wBAAwB,EACxB,uBAAuB,GACxB,MAAM,0BAA0B,CAAC;AAClC,OAAO,EAAE,aAAa,EAAE,MAAM,kBAAkB,CAAC;AACjD,OAAO,CAAC,MAAM,KAAK,CAAC;
|
|
1
|
+
{"version":3,"file":"screenshot.js","sourceRoot":"","sources":["../../../src/tools/interactions/screenshot.ts"],"names":[],"mappings":"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"}
|
|
@@ -17,7 +17,7 @@ import { getPageSource } from '../../command.js';
|
|
|
17
17
|
export default function generateLocators(server) {
|
|
18
18
|
server.addTool({
|
|
19
19
|
name: 'generate_locators',
|
|
20
|
-
description: `Generate locators for the current page
|
|
20
|
+
description: `Generate locators for all interactable elements on the current page. [PRIORITY 3: Use this for debugging/inspection or when you need comprehensive element info with locator suggestions]`,
|
|
21
21
|
parameters: z.object({}),
|
|
22
22
|
annotations: {
|
|
23
23
|
readOnlyHint: true,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"locators.js","sourceRoot":"","sources":["../../../src/tools/test-generation/locators.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AACH,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AACxB,OAAO,EACL,SAAS,EACT,kCAAkC,EAClC,uBAAuB,GACxB,MAAM,wBAAwB,CAAC;AAChC,OAAO,EAAE,0BAA0B,EAAE,MAAM,yCAAyC,CAAC;AACrF,OAAO,EACL,gBAAgB,EAChB,wBAAwB,EACxB,uBAAuB,GACxB,MAAM,0BAA0B,CAAC;AAClC,OAAO,EAAE,aAAa,EAAE,MAAM,kBAAkB,CAAC;AAEjD,MAAM,CAAC,OAAO,UAAU,gBAAgB,CAAC,MAAW;IAClD,MAAM,CAAC,OAAO,CAAC;QACb,IAAI,EAAE,mBAAmB;QACzB,WAAW,EAAE,
|
|
1
|
+
{"version":3,"file":"locators.js","sourceRoot":"","sources":["../../../src/tools/test-generation/locators.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
package/server.json
CHANGED
|
@@ -3,12 +3,12 @@
|
|
|
3
3
|
"name": "io.github.appium/appium-mcp",
|
|
4
4
|
"title": "MCP Appium - Mobile Development and Automation Server",
|
|
5
5
|
"description": "MCP server for Appium mobile automation on iOS and Android devices with test creation tools.",
|
|
6
|
-
"version": "1.
|
|
6
|
+
"version": "1.20.0",
|
|
7
7
|
"packages": [
|
|
8
8
|
{
|
|
9
9
|
"registryType": "npm",
|
|
10
10
|
"identifier": "appium-mcp",
|
|
11
|
-
"version": "1.
|
|
11
|
+
"version": "1.20.0",
|
|
12
12
|
"transport": {
|
|
13
13
|
"type": "stdio"
|
|
14
14
|
}
|
package/src/command.ts
CHANGED
|
@@ -4,7 +4,7 @@ import {
|
|
|
4
4
|
isXCUITestDriverSession,
|
|
5
5
|
} from './session-store.js';
|
|
6
6
|
import type { DriverInstance } from './session-store.js';
|
|
7
|
-
import { StringRecord } from '@appium/types';
|
|
7
|
+
import type { StringRecord, Element as AppiumElement } from '@appium/types';
|
|
8
8
|
|
|
9
9
|
/**
|
|
10
10
|
* Execute a driver command.
|
|
@@ -259,6 +259,18 @@ export async function getElementText(
|
|
|
259
259
|
return await driver.getElementText(elementUUID);
|
|
260
260
|
}
|
|
261
261
|
|
|
262
|
+
export async function getActiveElement(
|
|
263
|
+
driver: DriverInstance
|
|
264
|
+
): Promise<AppiumElement> {
|
|
265
|
+
if (isAndroidUiautomator2DriverSession(driver)) {
|
|
266
|
+
return await driver.active();
|
|
267
|
+
} else if (isXCUITestDriverSession(driver)) {
|
|
268
|
+
return await driver.active();
|
|
269
|
+
}
|
|
270
|
+
const result = await driver.getActiveElement();
|
|
271
|
+
return result as unknown as AppiumElement;
|
|
272
|
+
}
|
|
273
|
+
|
|
262
274
|
/**
|
|
263
275
|
* Get the current device/screen orientation.
|
|
264
276
|
*
|
package/src/tools/README.md
CHANGED
|
@@ -30,11 +30,31 @@ This directory contains all MCP tools available in MCP Appium.
|
|
|
30
30
|
- `double-tap.ts` - Double tap elements
|
|
31
31
|
- `long-press.ts` - Long press (press and hold) elements
|
|
32
32
|
- `drag-and-drop.ts` - Drag and drop elements or coordinates
|
|
33
|
+
- `press-key.ts` - Press navigation keys or physical buttons
|
|
33
34
|
- `set-value.ts` - Enter text
|
|
34
35
|
- `get-text.ts` - Get element text
|
|
35
36
|
- `get-page-source.ts` - Get page source (XML) from current screen
|
|
36
37
|
- `screenshot.ts` - Capture screenshots
|
|
37
38
|
|
|
39
|
+
#### Element Search Priority Order
|
|
40
|
+
|
|
41
|
+
When searching for elements, follow this priority order for efficiency:
|
|
42
|
+
|
|
43
|
+
1. **`appium_get_active_element`** (PRIORITY 1) - Use this first to get the currently focused element
|
|
44
|
+
- Lightweight and instant
|
|
45
|
+
- Returns single element UUID
|
|
46
|
+
- Best for: Finding what element currently has focus
|
|
47
|
+
|
|
48
|
+
2. **`appium_find_element`** (PRIORITY 2) - Use this to search for a specific target element
|
|
49
|
+
- Specify strategy (xpath, id, accessibility id, etc.) and selector
|
|
50
|
+
- Returns specific element UUID
|
|
51
|
+
- Best for: Targeting a known element
|
|
52
|
+
|
|
53
|
+
3. **`generate_locators`** (PRIORITY 3) - Use this for debugging/inspection only
|
|
54
|
+
- Parses entire page source
|
|
55
|
+
- Returns locators for all interactable elements
|
|
56
|
+
- Best for: Understanding page structure, debugging, generating test code
|
|
57
|
+
|
|
38
58
|
### App Management (`app-management/`)
|
|
39
59
|
|
|
40
60
|
- `activate-app.ts` - Activate apps
|
package/src/tools/index.ts
CHANGED
|
@@ -32,8 +32,10 @@ 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
34
|
import dragAndDrop from './interactions/drag-and-drop.js';
|
|
35
|
+
import pressKey from './interactions/press-key.js';
|
|
35
36
|
import setValue from './interactions/set-value.js';
|
|
36
37
|
import getText from './interactions/get-text.js';
|
|
38
|
+
import getActiveElement from './interactions/active-element.js';
|
|
37
39
|
import getPageSource from './interactions/get-page-source.js';
|
|
38
40
|
import { getOrientation, setOrientation } from './interactions/orientation.js';
|
|
39
41
|
import handleAlert from './interactions/handle-alert.js';
|
|
@@ -132,13 +134,19 @@ export default function registerTools(server: FastMCP): void {
|
|
|
132
134
|
swipe(server);
|
|
133
135
|
|
|
134
136
|
// Element Interactions
|
|
137
|
+
// PRIORITY ORDER FOR ELEMENT SEARCH:
|
|
138
|
+
// 1. getActiveElement - Get currently focused element (efficient, instant)
|
|
139
|
+
// 2. findElement - Find specific element by strategy/selector
|
|
140
|
+
// 3. generateLocators - Generate all locators (heavyweight, for debugging only)
|
|
135
141
|
findElement(server);
|
|
136
142
|
clickElement(server);
|
|
137
143
|
doubleTap(server);
|
|
138
144
|
longPress(server);
|
|
139
145
|
dragAndDrop(server);
|
|
146
|
+
pressKey(server);
|
|
140
147
|
setValue(server);
|
|
141
148
|
getText(server);
|
|
149
|
+
getActiveElement(server);
|
|
142
150
|
getPageSource(server);
|
|
143
151
|
getOrientation(server);
|
|
144
152
|
setOrientation(server);
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
import type { ContentResult, FastMCP } from 'fastmcp';
|
|
2
|
+
import { getDriver } from '../../session-store.js';
|
|
3
|
+
import { getActiveElement as _getActiveElement } from '../../command.js';
|
|
4
|
+
|
|
5
|
+
export default function getActiveElement(server: FastMCP): void {
|
|
6
|
+
server.addTool({
|
|
7
|
+
name: 'appium_get_active_element',
|
|
8
|
+
description:
|
|
9
|
+
'Get the currently active/focused element and return its UUID for follow-up interactions. [PRIORITY 1: Use this first when you need to find what element currently has focus]',
|
|
10
|
+
annotations: {
|
|
11
|
+
readOnlyHint: true,
|
|
12
|
+
openWorldHint: false,
|
|
13
|
+
},
|
|
14
|
+
execute: async (): Promise<ContentResult> => {
|
|
15
|
+
const driver = getDriver();
|
|
16
|
+
if (!driver) {
|
|
17
|
+
throw new Error('No driver found');
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
try {
|
|
21
|
+
const element = await _getActiveElement(driver);
|
|
22
|
+
const elementId =
|
|
23
|
+
element['element-6066-11e4-a52e-4f735466cecf'] ??
|
|
24
|
+
(element as unknown as { ELEMENT?: string }).ELEMENT;
|
|
25
|
+
|
|
26
|
+
if (!elementId) {
|
|
27
|
+
throw new Error(
|
|
28
|
+
'Active element was returned without a valid element ID'
|
|
29
|
+
);
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
return {
|
|
33
|
+
content: [
|
|
34
|
+
{
|
|
35
|
+
type: 'text',
|
|
36
|
+
text: `Successfully found an active element. Element id: ${elementId}`,
|
|
37
|
+
},
|
|
38
|
+
],
|
|
39
|
+
};
|
|
40
|
+
} catch (err: any) {
|
|
41
|
+
return {
|
|
42
|
+
content: [
|
|
43
|
+
{
|
|
44
|
+
type: 'text',
|
|
45
|
+
text: `Failed to find an active element. err: ${err.toString()}`,
|
|
46
|
+
},
|
|
47
|
+
],
|
|
48
|
+
};
|
|
49
|
+
}
|
|
50
|
+
},
|
|
51
|
+
});
|
|
52
|
+
}
|
|
@@ -21,10 +21,10 @@ export default function findElement(server: FastMCP): void {
|
|
|
21
21
|
server.addTool({
|
|
22
22
|
name: 'appium_find_element',
|
|
23
23
|
description:
|
|
24
|
-
'Find
|
|
24
|
+
'Find a specific element by strategy and selector which will return a uuid that can be used for interactions. [PRIORITY 2: Use this to search for a target element by xpath, id, accessibility id, etc.]',
|
|
25
25
|
parameters: findElementSchema,
|
|
26
26
|
annotations: {
|
|
27
|
-
readOnlyHint:
|
|
27
|
+
readOnlyHint: true,
|
|
28
28
|
openWorldHint: false,
|
|
29
29
|
},
|
|
30
30
|
execute: async (
|
|
@@ -0,0 +1,180 @@
|
|
|
1
|
+
import type { ContentResult, FastMCP } from 'fastmcp';
|
|
2
|
+
import { z } from 'zod';
|
|
3
|
+
import {
|
|
4
|
+
getDriver,
|
|
5
|
+
getPlatformName,
|
|
6
|
+
isAndroidUiautomator2DriverSession,
|
|
7
|
+
isXCUITestDriverSession,
|
|
8
|
+
isRemoteDriverSession,
|
|
9
|
+
PLATFORM,
|
|
10
|
+
} from '../../session-store.js';
|
|
11
|
+
import { execute } from '../../command.js';
|
|
12
|
+
import type { AndroidUiautomator2Driver } from 'appium-uiautomator2-driver';
|
|
13
|
+
import type { XCUITestDriver } from 'appium-xcuitest-driver';
|
|
14
|
+
|
|
15
|
+
const ANDROID_KEYCODE_MAP: Record<string, number> = {
|
|
16
|
+
BACK: 4,
|
|
17
|
+
HOME: 3,
|
|
18
|
+
APP_SWITCH: 187,
|
|
19
|
+
};
|
|
20
|
+
const ANDROID_KEYS_DESCRIPTION = Object.keys(ANDROID_KEYCODE_MAP).join(', ');
|
|
21
|
+
|
|
22
|
+
const IOS_BUTTON_MAP: Record<string, string> = {
|
|
23
|
+
HOME: 'home',
|
|
24
|
+
VOLUME_UP: 'volumeup',
|
|
25
|
+
VOLUME_DOWN: 'volumedown',
|
|
26
|
+
UP: 'up',
|
|
27
|
+
DOWN: 'down',
|
|
28
|
+
LEFT: 'left',
|
|
29
|
+
RIGHT: 'right',
|
|
30
|
+
MENU: 'menu',
|
|
31
|
+
PLAY_PAUSE: 'playpause',
|
|
32
|
+
SELECT: 'select',
|
|
33
|
+
};
|
|
34
|
+
const IOS_BUTTONS_DESCRIPTION = Object.keys(IOS_BUTTON_MAP).join(', ');
|
|
35
|
+
|
|
36
|
+
export default function pressKey(server: FastMCP): void {
|
|
37
|
+
const pressKeySchema = z
|
|
38
|
+
.object({
|
|
39
|
+
key: z
|
|
40
|
+
.enum([
|
|
41
|
+
'BACK',
|
|
42
|
+
'HOME',
|
|
43
|
+
'APP_SWITCH',
|
|
44
|
+
'VOLUME_UP',
|
|
45
|
+
'VOLUME_DOWN',
|
|
46
|
+
'UP',
|
|
47
|
+
'DOWN',
|
|
48
|
+
'LEFT',
|
|
49
|
+
'RIGHT',
|
|
50
|
+
'MENU',
|
|
51
|
+
'PLAY_PAUSE',
|
|
52
|
+
'SELECT',
|
|
53
|
+
])
|
|
54
|
+
.optional()
|
|
55
|
+
.describe(
|
|
56
|
+
`Logical key/button to press. On Android: ${ANDROID_KEYS_DESCRIPTION}. On iOS/tvOS: ${IOS_BUTTONS_DESCRIPTION}.`
|
|
57
|
+
),
|
|
58
|
+
keyCode: z
|
|
59
|
+
.number()
|
|
60
|
+
.int()
|
|
61
|
+
.optional()
|
|
62
|
+
.describe(
|
|
63
|
+
'Android keycode to press. If provided, takes precedence over key for Android.'
|
|
64
|
+
),
|
|
65
|
+
isLongPress: z
|
|
66
|
+
.boolean()
|
|
67
|
+
.optional()
|
|
68
|
+
.describe(
|
|
69
|
+
'Android only. Whether to perform a long press. Defaults to false.'
|
|
70
|
+
),
|
|
71
|
+
})
|
|
72
|
+
.refine((value) => value.key !== undefined || value.keyCode !== undefined, {
|
|
73
|
+
message: 'Either key or keyCode must be provided',
|
|
74
|
+
path: ['key'],
|
|
75
|
+
});
|
|
76
|
+
|
|
77
|
+
server.addTool({
|
|
78
|
+
name: 'appium_mobile_press_key',
|
|
79
|
+
description:
|
|
80
|
+
'Press navigation keys (BACK, HOME, APP_SWITCH) on Android or physical buttons (HOME, volume, etc.) on iOS/tvOS.',
|
|
81
|
+
parameters: pressKeySchema,
|
|
82
|
+
annotations: {
|
|
83
|
+
readOnlyHint: false,
|
|
84
|
+
openWorldHint: false,
|
|
85
|
+
},
|
|
86
|
+
execute: async (
|
|
87
|
+
args: z.infer<typeof pressKeySchema>,
|
|
88
|
+
_context: Record<string, unknown> | undefined
|
|
89
|
+
): Promise<ContentResult> => {
|
|
90
|
+
const driver = getDriver();
|
|
91
|
+
if (!driver) {
|
|
92
|
+
throw new Error('No driver found');
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
const platform = getPlatformName(driver);
|
|
96
|
+
const { key, keyCode, isLongPress } = args;
|
|
97
|
+
|
|
98
|
+
try {
|
|
99
|
+
if (platform === PLATFORM.android) {
|
|
100
|
+
const resolvedKeyCode =
|
|
101
|
+
keyCode ?? (key && ANDROID_KEYCODE_MAP[key]) ?? undefined;
|
|
102
|
+
|
|
103
|
+
if (resolvedKeyCode == null) {
|
|
104
|
+
throw new Error(
|
|
105
|
+
`For Android, provide either keyCode or key in [${ANDROID_KEYS_DESCRIPTION}].`
|
|
106
|
+
);
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
if (isAndroidUiautomator2DriverSession(driver)) {
|
|
110
|
+
await (driver as AndroidUiautomator2Driver).mobilePressKey(
|
|
111
|
+
resolvedKeyCode,
|
|
112
|
+
undefined,
|
|
113
|
+
undefined,
|
|
114
|
+
isLongPress ?? false
|
|
115
|
+
);
|
|
116
|
+
} else if (isRemoteDriverSession(driver)) {
|
|
117
|
+
await execute(driver, 'mobile: pressKey', {
|
|
118
|
+
keycode: resolvedKeyCode,
|
|
119
|
+
isLongPress: isLongPress ?? false,
|
|
120
|
+
});
|
|
121
|
+
} else {
|
|
122
|
+
throw new Error('Unsupported Android driver for press_key');
|
|
123
|
+
}
|
|
124
|
+
} else if (platform === PLATFORM.ios) {
|
|
125
|
+
const logicalKey = key ?? 'HOME';
|
|
126
|
+
const buttonName = IOS_BUTTON_MAP[logicalKey];
|
|
127
|
+
|
|
128
|
+
if (!buttonName) {
|
|
129
|
+
throw new Error(
|
|
130
|
+
`For iOS/tvOS, key must be one of ${IOS_BUTTONS_DESCRIPTION}.`
|
|
131
|
+
);
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
if (isXCUITestDriverSession(driver)) {
|
|
135
|
+
await (driver as XCUITestDriver).mobilePressButton(
|
|
136
|
+
buttonName as any
|
|
137
|
+
);
|
|
138
|
+
} else if (isRemoteDriverSession(driver)) {
|
|
139
|
+
await execute(driver, 'mobile: pressButton', {
|
|
140
|
+
name: buttonName,
|
|
141
|
+
});
|
|
142
|
+
} else {
|
|
143
|
+
throw new Error('Unsupported iOS/tvOS driver for press_key');
|
|
144
|
+
}
|
|
145
|
+
} else {
|
|
146
|
+
throw new Error(
|
|
147
|
+
`Unsupported platform: ${platform}. Only Android and iOS are supported.`
|
|
148
|
+
);
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
return {
|
|
152
|
+
content: [
|
|
153
|
+
{
|
|
154
|
+
type: 'text',
|
|
155
|
+
text:
|
|
156
|
+
platform === PLATFORM.android
|
|
157
|
+
? `Successfully pressed key${
|
|
158
|
+
key ? ` "${key}"` : ''
|
|
159
|
+
} on Android.`
|
|
160
|
+
: `Successfully pressed key${
|
|
161
|
+
key ? ` "${key}"` : ''
|
|
162
|
+
} on iOS/tvOS.`,
|
|
163
|
+
},
|
|
164
|
+
],
|
|
165
|
+
};
|
|
166
|
+
} catch (err: any) {
|
|
167
|
+
return {
|
|
168
|
+
content: [
|
|
169
|
+
{
|
|
170
|
+
type: 'text',
|
|
171
|
+
text: `Failed to press key${
|
|
172
|
+
key ? ` "${key}"` : ''
|
|
173
|
+
}. err: ${err.toString()}`,
|
|
174
|
+
},
|
|
175
|
+
],
|
|
176
|
+
};
|
|
177
|
+
}
|
|
178
|
+
},
|
|
179
|
+
});
|
|
180
|
+
}
|
|
@@ -12,6 +12,7 @@ import {
|
|
|
12
12
|
} from '../../ui/mcp-ui-utils.js';
|
|
13
13
|
import { getScreenshot } from '../../command.js';
|
|
14
14
|
import z from 'zod';
|
|
15
|
+
import { imageUtil } from '@appium/support';
|
|
15
16
|
|
|
16
17
|
/**
|
|
17
18
|
* Resolves the screenshot directory path.
|
|
@@ -52,8 +53,9 @@ const defaultDeps: ScreenshotDeps = {
|
|
|
52
53
|
export async function executeScreenshot(opts: {
|
|
53
54
|
deps?: ScreenshotDeps;
|
|
54
55
|
elementId?;
|
|
56
|
+
maxWidth?: number;
|
|
55
57
|
}): Promise<any> {
|
|
56
|
-
const { deps = defaultDeps, elementId } = opts;
|
|
58
|
+
const { deps = defaultDeps, elementId, maxWidth } = opts;
|
|
57
59
|
|
|
58
60
|
const driver = deps.getDriver();
|
|
59
61
|
if (!driver) {
|
|
@@ -64,7 +66,23 @@ export async function executeScreenshot(opts: {
|
|
|
64
66
|
const screenshotBase64 = await getScreenshot(driver, elementId);
|
|
65
67
|
|
|
66
68
|
// Convert base64 to buffer
|
|
67
|
-
const
|
|
69
|
+
const originalBuffer = Buffer.from(screenshotBase64, 'base64');
|
|
70
|
+
|
|
71
|
+
// Resize if maxWidth is provided and image is wider
|
|
72
|
+
let screenshotBuffer: Buffer = originalBuffer;
|
|
73
|
+
let displayBase64 = screenshotBase64;
|
|
74
|
+
if (maxWidth !== undefined) {
|
|
75
|
+
const sharp = imageUtil.requireSharp();
|
|
76
|
+
const metadata = await sharp(originalBuffer).metadata();
|
|
77
|
+
if (metadata.width !== undefined && metadata.width > maxWidth) {
|
|
78
|
+
const resizedBuffer = await sharp(originalBuffer)
|
|
79
|
+
.resize({ width: maxWidth })
|
|
80
|
+
.png()
|
|
81
|
+
.toBuffer();
|
|
82
|
+
screenshotBuffer = Buffer.from(resizedBuffer);
|
|
83
|
+
displayBase64 = screenshotBuffer.toString('base64');
|
|
84
|
+
}
|
|
85
|
+
}
|
|
68
86
|
|
|
69
87
|
// Generate filename with timestamp
|
|
70
88
|
const timestamp = deps.dateNow();
|
|
@@ -91,7 +109,7 @@ export async function executeScreenshot(opts: {
|
|
|
91
109
|
// Add interactive screenshot viewer UI
|
|
92
110
|
const uiResource = createUIResource(
|
|
93
111
|
`ui://appium-mcp/screenshot-viewer/${Date.now()}`,
|
|
94
|
-
createScreenshotViewerUI(
|
|
112
|
+
createScreenshotViewerUI(displayBase64, filepath)
|
|
95
113
|
);
|
|
96
114
|
|
|
97
115
|
return addUIResourceToResponse(textResponse, uiResource);
|
|
@@ -107,22 +125,36 @@ export async function executeScreenshot(opts: {
|
|
|
107
125
|
}
|
|
108
126
|
}
|
|
109
127
|
|
|
128
|
+
const maxWidthSchema = z
|
|
129
|
+
.number()
|
|
130
|
+
.optional()
|
|
131
|
+
.describe(
|
|
132
|
+
'Optional maximum width in pixels to resize the screenshot. The aspect ratio is preserved. Useful for reducing token usage when sending screenshots to LLMs.'
|
|
133
|
+
);
|
|
134
|
+
|
|
110
135
|
export function screenshot(server: FastMCP): void {
|
|
136
|
+
const screenshotSchema = z.object({
|
|
137
|
+
maxWidth: maxWidthSchema,
|
|
138
|
+
});
|
|
139
|
+
|
|
111
140
|
server.addTool({
|
|
112
141
|
name: 'appium_screenshot',
|
|
113
142
|
description:
|
|
114
143
|
'Take a screenshot of the current screen and return as PNG image',
|
|
144
|
+
parameters: screenshotSchema,
|
|
115
145
|
annotations: {
|
|
116
146
|
readOnlyHint: false,
|
|
117
147
|
openWorldHint: false,
|
|
118
148
|
},
|
|
119
|
-
execute: async (): Promise<any> =>
|
|
149
|
+
execute: async (args: any, _context: any): Promise<any> =>
|
|
150
|
+
executeScreenshot({ maxWidth: args.maxWidth }),
|
|
120
151
|
});
|
|
121
152
|
}
|
|
122
153
|
|
|
123
154
|
export function elementScreenshot(server: FastMCP): void {
|
|
124
155
|
const elementScreenshotSchema = z.object({
|
|
125
156
|
elementUUID: elementUUIDScheme,
|
|
157
|
+
maxWidth: maxWidthSchema,
|
|
126
158
|
});
|
|
127
159
|
|
|
128
160
|
server.addTool({
|
|
@@ -137,6 +169,7 @@ export function elementScreenshot(server: FastMCP): void {
|
|
|
137
169
|
execute: async (args: any, _context: any): Promise<any> =>
|
|
138
170
|
executeScreenshot({
|
|
139
171
|
elementId: args.elementUUID,
|
|
172
|
+
maxWidth: args.maxWidth,
|
|
140
173
|
}),
|
|
141
174
|
});
|
|
142
175
|
}
|
|
@@ -26,7 +26,7 @@ import { getPageSource } from '../../command.js';
|
|
|
26
26
|
export default function generateLocators(server: any): void {
|
|
27
27
|
server.addTool({
|
|
28
28
|
name: 'generate_locators',
|
|
29
|
-
description: `Generate locators for the current page
|
|
29
|
+
description: `Generate locators for all interactable elements on the current page. [PRIORITY 3: Use this for debugging/inspection or when you need comprehensive element info with locator suggestions]`,
|
|
30
30
|
parameters: z.object({}),
|
|
31
31
|
annotations: {
|
|
32
32
|
readOnlyHint: true,
|