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 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 only) |
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,3 @@
1
+ import { FastMCP } from 'fastmcp';
2
+ export default function isAppInstalled(server: FastMCP): void;
3
+ //# sourceMappingURL=is-app-installed.d.ts.map
@@ -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;AAgDlC,MAAM,CAAC,OAAO,UAAU,QAAQ,CAAC,MAAM,EAAE,OAAO,GAAG,IAAI,CAsCtD"}
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 === 'iOS') {
14
- throw new Error('listApps is not yet implemented for iOS');
22
+ if (platform === PLATFORM.ios && isXCUITestDriverSession(driver)) {
23
+ const result = await driver.mobileListApps();
24
+ return normalizeListAppsResult(result || {});
15
25
  }
16
- const appPackages = await driver.adb.adbExec([
17
- 'shell',
18
- 'cmd',
19
- 'package',
20
- 'list',
21
- 'packages',
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,GACtB,MAAM,wBAAwB,CAAC;AAChC,OAAO,EACL,gBAAgB,EAChB,eAAe,EACf,uBAAuB,GACxB,MAAM,0BAA0B,CAAC;AAGlC,KAAK,UAAU,kBAAkB;IAC/B,MAAM,MAAM,GAAG,MAAM,SAAS,EAAE,CAAC;IACjC,IAAI,CAAC,MAAM,EAAE,CAAC;QACZ,MAAM,IAAI,KAAK,CAAC,iBAAiB,CAAC,CAAC;IACrC,CAAC;IAED,IAAI,qBAAqB,CAAC,MAAM,CAAC,EAAE,CAAC;QAClC,MAAM,IAAI,KAAK,CAAC,uDAAuD,CAAC,CAAC;IAC3E,CAAC;IAED,MAAM,QAAQ,GAAG,eAAe,CAAC,MAAM,CAAC,CAAC;IACzC,IAAI,QAAQ,KAAK,KAAK,EAAE,CAAC;QACvB,MAAM,IAAI,KAAK,CAAC,yCAAyC,CAAC,CAAC;IAC7D,CAAC;IAED,MAAM,WAAW,GAAG,MAAO,MAAoC,CAAC,GAAG,CAAC,OAAO,CAAC;QAC1E,OAAO;QACP,KAAK;QACL,SAAS;QACT,MAAM;QACN,UAAU;KACX,CAAC,CAAC;IAEH,MAAM,IAAI,GAAU,WAAW;SAC5B,KAAK,CAAC,UAAU,CAAC;SACjB,MAAM,CAAC,CAAC,CAAM,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC;SAC5B,GAAG,CAAC,CAAC,CAAM,EAAE,EAAE,CAAC,CAAC;QAChB,WAAW,EAAE,CAAC,CAAC,IAAI,EAAE;QACrB,OAAO,EAAE,EAAE;KACZ,CAAC,CAAC,CAAC;IAEN,OAAO,IAAI,CAAC;AACd,CAAC;AAED,MAAM,CAAC,OAAO,UAAU,QAAQ,CAAC,MAAe;IAC9C,MAAM,MAAM,GAAG,CAAC,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC;IAE5B,MAAM,CAAC,OAAO,CAAC;QACb,IAAI,EAAE,kBAAkB;QACxB,WAAW,EAAE,wCAAwC;QACrD,UAAU,EAAE,MAAM;QAClB,OAAO,EAAE,KAAK,IAAI,EAAE;YAClB,IAAI,CAAC;gBACH,MAAM,IAAI,GAAG,MAAM,kBAAkB,EAAE,CAAC;gBACxC,MAAM,YAAY,GAAG;oBACnB,OAAO,EAAE;wBACP;4BACE,IAAI,EAAE,MAAM;4BACZ,IAAI,EAAE,mBAAmB,IAAI,CAAC,SAAS,CAAC,IAAI,EAAE,IAAI,EAAE,CAAC,CAAC,EAAE;yBACzD;qBACF;iBACF,CAAC;gBAEF,8BAA8B;gBAC9B,MAAM,UAAU,GAAG,gBAAgB,CACjC,4BAA4B,IAAI,CAAC,GAAG,EAAE,EAAE,EACxC,eAAe,CAAC,IAAI,CAAC,CACtB,CAAC;gBAEF,OAAO,uBAAuB,CAAC,YAAY,EAAE,UAAU,CAAC,CAAC;YAC3D,CAAC;YAAC,OAAO,GAAQ,EAAE,CAAC;gBAClB,OAAO;oBACL,OAAO,EAAE;wBACP;4BACE,IAAI,EAAE,MAAM;4BACZ,IAAI,EAAE,6BAA6B,GAAG,CAAC,QAAQ,EAAE,EAAE;yBACpD;qBACF;iBACF,CAAC;YACJ,CAAC;QACH,CAAC;KACF,CAAC,CAAC;AACL,CAAC"}
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;AAkClC,MAAM,CAAC,OAAO,UAAU,aAAa,CAAC,MAAM,EAAE,OAAO,GAAG,IAAI,CAoH3D"}
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"}
@@ -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);
@@ -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.16.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": "^6.7.13",
55
- "appium-xcuitest-driver": "^10.18.2",
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.16.1",
6
+ "version": "1.18.0",
7
7
  "packages": [
8
8
  {
9
9
  "registryType": "npm",
10
10
  "identifier": "appium-mcp",
11
- "version": "1.16.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
- async function listAppsFromDevice(): Promise<any[]> {
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
- const appPackages = await (driver as AndroidUiautomator2Driver).adb.adbExec([
31
- 'shell',
32
- 'cmd',
33
- 'package',
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
- const apps: any[] = appPackages
39
- .split('package:')
40
- .filter((s: any) => s.trim())
41
- .map((s: any) => ({
42
- packageName: s.trim(),
43
- appName: '',
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
- return apps;
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: 'List all installed apps on the device.',
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)
@@ -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);