appium-mcp 1.16.1 → 1.18.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 +12 -0
- package/README.md +2 -1
- package/dist/tools/app-management/is-app-installed.d.ts +3 -0
- package/dist/tools/app-management/is-app-installed.d.ts.map +1 -0
- package/dist/tools/app-management/is-app-installed.js +65 -0
- package/dist/tools/app-management/is-app-installed.js.map +1 -0
- package/dist/tools/app-management/list-apps.d.ts.map +1 -1
- package/dist/tools/app-management/list-apps.js +21 -20
- package/dist/tools/app-management/list-apps.js.map +1 -1
- package/dist/tools/index.d.ts.map +1 -1
- package/dist/tools/index.js +2 -0
- package/dist/tools/index.js.map +1 -1
- package/package.json +3 -3
- package/server.json +2 -2
- package/src/tools/app-management/is-app-installed.ts +76 -0
- package/src/tools/app-management/list-apps.ts +34 -21
- package/src/tools/index.ts +2 -0
package/CHANGELOG.md
CHANGED
|
@@ -1,3 +1,15 @@
|
|
|
1
|
+
## [1.18.0](https://github.com/appium/appium-mcp/compare/v1.17.0...v1.18.0) (2026-02-22)
|
|
2
|
+
|
|
3
|
+
### Features
|
|
4
|
+
|
|
5
|
+
* use latest uia2/xcuitest for embedded drivers and simplify a bit ([#174](https://github.com/appium/appium-mcp/issues/174)) ([d85a5df](https://github.com/appium/appium-mcp/commit/d85a5df35bb0cf363514478faa7f90c7f6438d55))
|
|
6
|
+
|
|
7
|
+
## [1.17.0](https://github.com/appium/appium-mcp/compare/v1.16.1...v1.17.0) (2026-02-21)
|
|
8
|
+
|
|
9
|
+
### Features
|
|
10
|
+
|
|
11
|
+
* **app-management:** add is-app-installed tool and improve list-apps ([#169](https://github.com/appium/appium-mcp/issues/169)) ([625a364](https://github.com/appium/appium-mcp/commit/625a364c37d643dc007130cc1f25e45c79969126))
|
|
12
|
+
|
|
1
13
|
## [1.16.1](https://github.com/appium/appium-mcp/compare/v1.16.0...v1.16.1) (2026-02-20)
|
|
2
14
|
|
|
3
15
|
### Miscellaneous Chores
|
package/README.md
CHANGED
|
@@ -288,7 +288,8 @@ MCP Appium provides a comprehensive set of tools organized into the following ca
|
|
|
288
288
|
| `appium_installApp` | Install an app on the device from a file path |
|
|
289
289
|
| `appium_uninstallApp` | Uninstall an app from the device by bundle ID |
|
|
290
290
|
| `appium_terminateApp` | Terminate (close) a specified app |
|
|
291
|
-
| `appium_list_apps` | List all installed apps on the device (Android
|
|
291
|
+
| `appium_list_apps` | List all installed apps on the device (Android and iOS) |
|
|
292
|
+
| `appium_is_app_installed` | Check whether an app is installed. Package name for Android, bundle ID for iOS. |
|
|
292
293
|
|
|
293
294
|
### Test Generation & Documentation
|
|
294
295
|
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"is-app-installed.d.ts","sourceRoot":"","sources":["../../../src/tools/app-management/is-app-installed.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,SAAS,CAAC;AAclC,MAAM,CAAC,OAAO,UAAU,cAAc,CAAC,MAAM,EAAE,OAAO,GAAG,IAAI,CA6D5D"}
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
import { z } from 'zod';
|
|
2
|
+
import { getDriver, getPlatformName, isRemoteDriverSession, isAndroidUiautomator2DriverSession, isXCUITestDriverSession, PLATFORM, } from '../../session-store.js';
|
|
3
|
+
import { execute } from '../../command.js';
|
|
4
|
+
export default function isAppInstalled(server) {
|
|
5
|
+
const schema = z.object({
|
|
6
|
+
id: z
|
|
7
|
+
.string()
|
|
8
|
+
.describe('App identifier (package name for Android, bundle ID for iOS)'),
|
|
9
|
+
});
|
|
10
|
+
server.addTool({
|
|
11
|
+
name: 'appium_is_app_installed',
|
|
12
|
+
description: 'Check whether an app is installed. Package name for Android, bundle ID for iOS.',
|
|
13
|
+
parameters: schema,
|
|
14
|
+
annotations: {
|
|
15
|
+
readOnlyHint: true,
|
|
16
|
+
openWorldHint: false,
|
|
17
|
+
},
|
|
18
|
+
execute: async (args) => {
|
|
19
|
+
const { id } = args;
|
|
20
|
+
const driver = await getDriver();
|
|
21
|
+
if (!driver) {
|
|
22
|
+
throw new Error('No driver found');
|
|
23
|
+
}
|
|
24
|
+
try {
|
|
25
|
+
let result;
|
|
26
|
+
if (isRemoteDriverSession(driver)) {
|
|
27
|
+
const platform = getPlatformName(driver);
|
|
28
|
+
const params = platform === PLATFORM.android ? { appId: id } : { bundleId: id };
|
|
29
|
+
const raw = await execute(driver, 'mobile: isAppInstalled', params);
|
|
30
|
+
result = Boolean(raw);
|
|
31
|
+
}
|
|
32
|
+
else if (isXCUITestDriverSession(driver)) {
|
|
33
|
+
result = await driver.isAppInstalled(id);
|
|
34
|
+
}
|
|
35
|
+
else if (isAndroidUiautomator2DriverSession(driver)) {
|
|
36
|
+
result = await driver.adb.isAppInstalled(id);
|
|
37
|
+
}
|
|
38
|
+
else {
|
|
39
|
+
throw new Error('Unsupported driver for isAppInstalled');
|
|
40
|
+
}
|
|
41
|
+
return {
|
|
42
|
+
content: [
|
|
43
|
+
{
|
|
44
|
+
type: 'text',
|
|
45
|
+
text: result
|
|
46
|
+
? `App "${id}" is installed.`
|
|
47
|
+
: `App "${id}" is not installed.`,
|
|
48
|
+
},
|
|
49
|
+
],
|
|
50
|
+
};
|
|
51
|
+
}
|
|
52
|
+
catch (err) {
|
|
53
|
+
return {
|
|
54
|
+
content: [
|
|
55
|
+
{
|
|
56
|
+
type: 'text',
|
|
57
|
+
text: `Failed to check if app is installed. err: ${err.toString()}`,
|
|
58
|
+
},
|
|
59
|
+
],
|
|
60
|
+
};
|
|
61
|
+
}
|
|
62
|
+
},
|
|
63
|
+
});
|
|
64
|
+
}
|
|
65
|
+
//# sourceMappingURL=is-app-installed.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"is-app-installed.js","sourceRoot":"","sources":["../../../src/tools/app-management/is-app-installed.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AACxB,OAAO,EACL,SAAS,EACT,eAAe,EACf,qBAAqB,EACrB,kCAAkC,EAClC,uBAAuB,EACvB,QAAQ,GACT,MAAM,wBAAwB,CAAC;AAChC,OAAO,EAAE,OAAO,EAAE,MAAM,kBAAkB,CAAC;AAI3C,MAAM,CAAC,OAAO,UAAU,cAAc,CAAC,MAAe;IACpD,MAAM,MAAM,GAAG,CAAC,CAAC,MAAM,CAAC;QACtB,EAAE,EAAE,CAAC;aACF,MAAM,EAAE;aACR,QAAQ,CAAC,8DAA8D,CAAC;KAC5E,CAAC,CAAC;IAEH,MAAM,CAAC,OAAO,CAAC;QACb,IAAI,EAAE,yBAAyB;QAC/B,WAAW,EACT,iFAAiF;QACnF,UAAU,EAAE,MAAM;QAClB,WAAW,EAAE;YACX,YAAY,EAAE,IAAI;YAClB,aAAa,EAAE,KAAK;SACrB;QACD,OAAO,EAAE,KAAK,EAAE,IAA4B,EAAE,EAAE;YAC9C,MAAM,EAAE,EAAE,EAAE,GAAG,IAAI,CAAC;YACpB,MAAM,MAAM,GAAG,MAAM,SAAS,EAAE,CAAC;YACjC,IAAI,CAAC,MAAM,EAAE,CAAC;gBACZ,MAAM,IAAI,KAAK,CAAC,iBAAiB,CAAC,CAAC;YACrC,CAAC;YACD,IAAI,CAAC;gBACH,IAAI,MAAe,CAAC;gBACpB,IAAI,qBAAqB,CAAC,MAAM,CAAC,EAAE,CAAC;oBAClC,MAAM,QAAQ,GAAG,eAAe,CAAC,MAAM,CAAC,CAAC;oBACzC,MAAM,MAAM,GACV,QAAQ,KAAK,QAAQ,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,KAAK,EAAE,EAAE,EAAE,CAAC,CAAC,CAAC,EAAE,QAAQ,EAAE,EAAE,EAAE,CAAC;oBACnE,MAAM,GAAG,GAAG,MAAM,OAAO,CAAC,MAAM,EAAE,wBAAwB,EAAE,MAAM,CAAC,CAAC;oBACpE,MAAM,GAAG,OAAO,CAAC,GAAG,CAAC,CAAC;gBACxB,CAAC;qBAAM,IAAI,uBAAuB,CAAC,MAAM,CAAC,EAAE,CAAC;oBAC3C,MAAM,GAAG,MAAO,MAAyB,CAAC,cAAc,CAAC,EAAE,CAAC,CAAC;gBAC/D,CAAC;qBAAM,IAAI,kCAAkC,CAAC,MAAM,CAAC,EAAE,CAAC;oBACtD,MAAM,GAAG,MACP,MACD,CAAC,GAAG,CAAC,cAAc,CAAC,EAAE,CAAC,CAAC;gBAC3B,CAAC;qBAAM,CAAC;oBACN,MAAM,IAAI,KAAK,CAAC,uCAAuC,CAAC,CAAC;gBAC3D,CAAC;gBACD,OAAO;oBACL,OAAO,EAAE;wBACP;4BACE,IAAI,EAAE,MAAM;4BACZ,IAAI,EAAE,MAAM;gCACV,CAAC,CAAC,QAAQ,EAAE,iBAAiB;gCAC7B,CAAC,CAAC,QAAQ,EAAE,qBAAqB;yBACpC;qBACF;iBACF,CAAC;YACJ,CAAC;YAAC,OAAO,GAAQ,EAAE,CAAC;gBAClB,OAAO;oBACL,OAAO,EAAE;wBACP;4BACE,IAAI,EAAE,MAAM;4BACZ,IAAI,EAAE,6CAA6C,GAAG,CAAC,QAAQ,EAAE,EAAE;yBACpE;qBACF;iBACF,CAAC;YACJ,CAAC;QACH,CAAC;KACF,CAAC,CAAC;AACL,CAAC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"list-apps.d.ts","sourceRoot":"","sources":["../../../src/tools/app-management/list-apps.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,SAAS,CAAC;
|
|
1
|
+
{"version":3,"file":"list-apps.d.ts","sourceRoot":"","sources":["../../../src/tools/app-management/list-apps.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,SAAS,CAAC;AA6DlC,MAAM,CAAC,OAAO,UAAU,QAAQ,CAAC,MAAM,EAAE,OAAO,GAAG,IAAI,CAsCtD"}
|
|
@@ -1,6 +1,15 @@
|
|
|
1
1
|
import { z } from 'zod';
|
|
2
|
-
import { getDriver, getPlatformName, isRemoteDriverSession, } from '../../session-store.js';
|
|
2
|
+
import { getDriver, getPlatformName, isRemoteDriverSession, isAndroidUiautomator2DriverSession, isXCUITestDriverSession, PLATFORM, } from '../../session-store.js';
|
|
3
3
|
import { createUIResource, createAppListUI, addUIResourceToResponse, } from '../../ui/mcp-ui-utils.js';
|
|
4
|
+
function normalizeListAppsResult(result) {
|
|
5
|
+
return Object.entries(result).map(([id, attrs]) => ({
|
|
6
|
+
packageName: id,
|
|
7
|
+
appName: (attrs?.CFBundleDisplayName ||
|
|
8
|
+
attrs?.CFBundleName ||
|
|
9
|
+
attrs?.name ||
|
|
10
|
+
''),
|
|
11
|
+
}));
|
|
12
|
+
}
|
|
4
13
|
async function listAppsFromDevice() {
|
|
5
14
|
const driver = await getDriver();
|
|
6
15
|
if (!driver) {
|
|
@@ -10,30 +19,23 @@ async function listAppsFromDevice() {
|
|
|
10
19
|
throw new Error('listApps is not yet implemented for the remote driver');
|
|
11
20
|
}
|
|
12
21
|
const platform = getPlatformName(driver);
|
|
13
|
-
if (platform ===
|
|
14
|
-
|
|
22
|
+
if (platform === PLATFORM.ios && isXCUITestDriverSession(driver)) {
|
|
23
|
+
const result = await driver.mobileListApps();
|
|
24
|
+
return normalizeListAppsResult(result || {});
|
|
15
25
|
}
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
const apps = appPackages
|
|
24
|
-
.split('package:')
|
|
25
|
-
.filter((s) => s.trim())
|
|
26
|
-
.map((s) => ({
|
|
27
|
-
packageName: s.trim(),
|
|
28
|
-
appName: '',
|
|
29
|
-
}));
|
|
30
|
-
return apps;
|
|
26
|
+
if (platform === PLATFORM.android &&
|
|
27
|
+
isAndroidUiautomator2DriverSession(driver)) {
|
|
28
|
+
const result = await driver.mobileListApps();
|
|
29
|
+
const ids = Object.keys(result || {});
|
|
30
|
+
return ids.map((packageName) => ({ packageName, appName: packageName }));
|
|
31
|
+
}
|
|
32
|
+
throw new Error(`listApps is not implemented for platform: ${platform}`);
|
|
31
33
|
}
|
|
32
34
|
export default function listApps(server) {
|
|
33
35
|
const schema = z.object({});
|
|
34
36
|
server.addTool({
|
|
35
37
|
name: 'appium_list_apps',
|
|
36
|
-
description: 'List all installed apps on the device.',
|
|
38
|
+
description: 'List all installed apps on the device. On Android, only package IDs are returned (no display names); on iOS, bundle IDs and display names are returned.',
|
|
37
39
|
parameters: schema,
|
|
38
40
|
execute: async () => {
|
|
39
41
|
try {
|
|
@@ -46,7 +48,6 @@ export default function listApps(server) {
|
|
|
46
48
|
},
|
|
47
49
|
],
|
|
48
50
|
};
|
|
49
|
-
// Add interactive app list UI
|
|
50
51
|
const uiResource = createUIResource(`ui://appium-mcp/app-list/${Date.now()}`, createAppListUI(apps));
|
|
51
52
|
return addUIResourceToResponse(textResponse, uiResource);
|
|
52
53
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"list-apps.js","sourceRoot":"","sources":["../../../src/tools/app-management/list-apps.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AACxB,OAAO,EACL,SAAS,EACT,eAAe,EACf,qBAAqB,
|
|
1
|
+
{"version":3,"file":"list-apps.js","sourceRoot":"","sources":["../../../src/tools/app-management/list-apps.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;AAmClC,MAAM,CAAC,OAAO,UAAU,aAAa,CAAC,MAAM,EAAE,OAAO,GAAG,IAAI,CAqH3D"}
|
package/dist/tools/index.js
CHANGED
|
@@ -28,6 +28,7 @@ import installApp from './app-management/install-app.js';
|
|
|
28
28
|
import uninstallApp from './app-management/uninstall-app.js';
|
|
29
29
|
import terminateApp from './app-management/terminate-app.js';
|
|
30
30
|
import listApps from './app-management/list-apps.js';
|
|
31
|
+
import isAppInstalled from './app-management/is-app-installed.js';
|
|
31
32
|
import getContexts from './context/get-contexts.js';
|
|
32
33
|
import switchContext from './context/switch-context.js';
|
|
33
34
|
export default function registerTools(server) {
|
|
@@ -125,6 +126,7 @@ export default function registerTools(server) {
|
|
|
125
126
|
uninstallApp(server);
|
|
126
127
|
terminateApp(server);
|
|
127
128
|
listApps(server);
|
|
129
|
+
isAppInstalled(server);
|
|
128
130
|
// Context Management
|
|
129
131
|
getContexts(server);
|
|
130
132
|
switchContext(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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"}
|
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
|
+
"version": "1.18.0",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"repository": {
|
|
7
7
|
"type": "git",
|
|
@@ -51,8 +51,8 @@
|
|
|
51
51
|
"@xmldom/xmldom": "^0.9.8",
|
|
52
52
|
"appium-adb": "^14.1.8",
|
|
53
53
|
"appium-ios-device": "^3.1.0",
|
|
54
|
-
"appium-uiautomator2-driver": "^
|
|
55
|
-
"appium-xcuitest-driver": "^10.
|
|
54
|
+
"appium-uiautomator2-driver": "^7.0.0",
|
|
55
|
+
"appium-xcuitest-driver": "^10.23.1",
|
|
56
56
|
"axios": "^1.7.9",
|
|
57
57
|
"fast-xml-parser": "^5.2.3",
|
|
58
58
|
"fastmcp": "^3.23.1",
|
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.18.0",
|
|
7
7
|
"packages": [
|
|
8
8
|
{
|
|
9
9
|
"registryType": "npm",
|
|
10
10
|
"identifier": "appium-mcp",
|
|
11
|
-
"version": "1.
|
|
11
|
+
"version": "1.18.0",
|
|
12
12
|
"transport": {
|
|
13
13
|
"type": "stdio"
|
|
14
14
|
}
|
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
import { FastMCP } from 'fastmcp';
|
|
2
|
+
import { z } from 'zod';
|
|
3
|
+
import {
|
|
4
|
+
getDriver,
|
|
5
|
+
getPlatformName,
|
|
6
|
+
isRemoteDriverSession,
|
|
7
|
+
isAndroidUiautomator2DriverSession,
|
|
8
|
+
isXCUITestDriverSession,
|
|
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
|
+
export default function isAppInstalled(server: FastMCP): void {
|
|
16
|
+
const schema = z.object({
|
|
17
|
+
id: z
|
|
18
|
+
.string()
|
|
19
|
+
.describe('App identifier (package name for Android, bundle ID for iOS)'),
|
|
20
|
+
});
|
|
21
|
+
|
|
22
|
+
server.addTool({
|
|
23
|
+
name: 'appium_is_app_installed',
|
|
24
|
+
description:
|
|
25
|
+
'Check whether an app is installed. Package name for Android, bundle ID for iOS.',
|
|
26
|
+
parameters: schema,
|
|
27
|
+
annotations: {
|
|
28
|
+
readOnlyHint: true,
|
|
29
|
+
openWorldHint: false,
|
|
30
|
+
},
|
|
31
|
+
execute: async (args: z.infer<typeof schema>) => {
|
|
32
|
+
const { id } = args;
|
|
33
|
+
const driver = await getDriver();
|
|
34
|
+
if (!driver) {
|
|
35
|
+
throw new Error('No driver found');
|
|
36
|
+
}
|
|
37
|
+
try {
|
|
38
|
+
let result: boolean;
|
|
39
|
+
if (isRemoteDriverSession(driver)) {
|
|
40
|
+
const platform = getPlatformName(driver);
|
|
41
|
+
const params =
|
|
42
|
+
platform === PLATFORM.android ? { appId: id } : { bundleId: id };
|
|
43
|
+
const raw = await execute(driver, 'mobile: isAppInstalled', params);
|
|
44
|
+
result = Boolean(raw);
|
|
45
|
+
} else if (isXCUITestDriverSession(driver)) {
|
|
46
|
+
result = await (driver as XCUITestDriver).isAppInstalled(id);
|
|
47
|
+
} else if (isAndroidUiautomator2DriverSession(driver)) {
|
|
48
|
+
result = await (
|
|
49
|
+
driver as AndroidUiautomator2Driver
|
|
50
|
+
).adb.isAppInstalled(id);
|
|
51
|
+
} else {
|
|
52
|
+
throw new Error('Unsupported driver for isAppInstalled');
|
|
53
|
+
}
|
|
54
|
+
return {
|
|
55
|
+
content: [
|
|
56
|
+
{
|
|
57
|
+
type: 'text',
|
|
58
|
+
text: result
|
|
59
|
+
? `App "${id}" is installed.`
|
|
60
|
+
: `App "${id}" is not installed.`,
|
|
61
|
+
},
|
|
62
|
+
],
|
|
63
|
+
};
|
|
64
|
+
} catch (err: any) {
|
|
65
|
+
return {
|
|
66
|
+
content: [
|
|
67
|
+
{
|
|
68
|
+
type: 'text',
|
|
69
|
+
text: `Failed to check if app is installed. err: ${err.toString()}`,
|
|
70
|
+
},
|
|
71
|
+
],
|
|
72
|
+
};
|
|
73
|
+
}
|
|
74
|
+
},
|
|
75
|
+
});
|
|
76
|
+
}
|
|
@@ -4,6 +4,9 @@ import {
|
|
|
4
4
|
getDriver,
|
|
5
5
|
getPlatformName,
|
|
6
6
|
isRemoteDriverSession,
|
|
7
|
+
isAndroidUiautomator2DriverSession,
|
|
8
|
+
isXCUITestDriverSession,
|
|
9
|
+
PLATFORM,
|
|
7
10
|
} from '../../session-store.js';
|
|
8
11
|
import {
|
|
9
12
|
createUIResource,
|
|
@@ -11,8 +14,23 @@ import {
|
|
|
11
14
|
addUIResourceToResponse,
|
|
12
15
|
} from '../../ui/mcp-ui-utils.js';
|
|
13
16
|
import type { AndroidUiautomator2Driver } from 'appium-uiautomator2-driver';
|
|
17
|
+
import type { XCUITestDriver } from 'appium-xcuitest-driver';
|
|
14
18
|
|
|
15
|
-
|
|
19
|
+
function normalizeListAppsResult(
|
|
20
|
+
result: Record<string, Record<string, unknown> | undefined>
|
|
21
|
+
): { packageName: string; appName: string }[] {
|
|
22
|
+
return Object.entries(result).map(([id, attrs]) => ({
|
|
23
|
+
packageName: id,
|
|
24
|
+
appName: (attrs?.CFBundleDisplayName ||
|
|
25
|
+
attrs?.CFBundleName ||
|
|
26
|
+
(attrs as any)?.name ||
|
|
27
|
+
'') as string,
|
|
28
|
+
}));
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
async function listAppsFromDevice(): Promise<
|
|
32
|
+
{ packageName: string; appName: string }[]
|
|
33
|
+
> {
|
|
16
34
|
const driver = await getDriver();
|
|
17
35
|
if (!driver) {
|
|
18
36
|
throw new Error('No driver found');
|
|
@@ -23,27 +41,22 @@ async function listAppsFromDevice(): Promise<any[]> {
|
|
|
23
41
|
}
|
|
24
42
|
|
|
25
43
|
const platform = getPlatformName(driver);
|
|
26
|
-
if (platform === 'iOS') {
|
|
27
|
-
throw new Error('listApps is not yet implemented for iOS');
|
|
28
|
-
}
|
|
29
44
|
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
'list',
|
|
35
|
-
'packages',
|
|
36
|
-
]);
|
|
45
|
+
if (platform === PLATFORM.ios && isXCUITestDriverSession(driver)) {
|
|
46
|
+
const result = await (driver as XCUITestDriver).mobileListApps();
|
|
47
|
+
return normalizeListAppsResult(result || {});
|
|
48
|
+
}
|
|
37
49
|
|
|
38
|
-
|
|
39
|
-
.
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
}));
|
|
50
|
+
if (
|
|
51
|
+
platform === PLATFORM.android &&
|
|
52
|
+
isAndroidUiautomator2DriverSession(driver)
|
|
53
|
+
) {
|
|
54
|
+
const result = await (driver as AndroidUiautomator2Driver).mobileListApps();
|
|
55
|
+
const ids = Object.keys(result || {});
|
|
56
|
+
return ids.map((packageName) => ({ packageName, appName: packageName }));
|
|
57
|
+
}
|
|
45
58
|
|
|
46
|
-
|
|
59
|
+
throw new Error(`listApps is not implemented for platform: ${platform}`);
|
|
47
60
|
}
|
|
48
61
|
|
|
49
62
|
export default function listApps(server: FastMCP): void {
|
|
@@ -51,7 +64,8 @@ export default function listApps(server: FastMCP): void {
|
|
|
51
64
|
|
|
52
65
|
server.addTool({
|
|
53
66
|
name: 'appium_list_apps',
|
|
54
|
-
description:
|
|
67
|
+
description:
|
|
68
|
+
'List all installed apps on the device. On Android, only package IDs are returned (no display names); on iOS, bundle IDs and display names are returned.',
|
|
55
69
|
parameters: schema,
|
|
56
70
|
execute: async () => {
|
|
57
71
|
try {
|
|
@@ -65,7 +79,6 @@ export default function listApps(server: FastMCP): void {
|
|
|
65
79
|
],
|
|
66
80
|
};
|
|
67
81
|
|
|
68
|
-
// Add interactive app list UI
|
|
69
82
|
const uiResource = createUIResource(
|
|
70
83
|
`ui://appium-mcp/app-list/${Date.now()}`,
|
|
71
84
|
createAppListUI(apps)
|
package/src/tools/index.ts
CHANGED
|
@@ -43,6 +43,7 @@ import installApp from './app-management/install-app.js';
|
|
|
43
43
|
import uninstallApp from './app-management/uninstall-app.js';
|
|
44
44
|
import terminateApp from './app-management/terminate-app.js';
|
|
45
45
|
import listApps from './app-management/list-apps.js';
|
|
46
|
+
import isAppInstalled from './app-management/is-app-installed.js';
|
|
46
47
|
import getContexts from './context/get-contexts.js';
|
|
47
48
|
import switchContext from './context/switch-context.js';
|
|
48
49
|
|
|
@@ -150,6 +151,7 @@ export default function registerTools(server: FastMCP): void {
|
|
|
150
151
|
uninstallApp(server);
|
|
151
152
|
terminateApp(server);
|
|
152
153
|
listApps(server);
|
|
154
|
+
isAppInstalled(server);
|
|
153
155
|
|
|
154
156
|
// Context Management
|
|
155
157
|
getContexts(server);
|