appium-mcp 1.64.0 → 1.65.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 +6 -0
- package/README.md +1 -2
- package/dist/tools/session/driver-settings.d.ts.map +1 -1
- package/dist/tools/session/driver-settings.js +47 -44
- package/dist/tools/session/driver-settings.js.map +1 -1
- package/package.json +1 -1
- package/server.json +2 -2
- package/src/resources/submodules.zip +0 -0
- package/src/tools/README.md +1 -1
- package/src/tools/session/driver-settings.ts +58 -52
package/CHANGELOG.md
CHANGED
|
@@ -1,3 +1,9 @@
|
|
|
1
|
+
## [1.65.0](https://github.com/appium/appium-mcp/compare/v1.64.0...v1.65.0) (2026-04-23)
|
|
2
|
+
|
|
3
|
+
### Features
|
|
4
|
+
|
|
5
|
+
* **tools:** consolidate driver settings into appium_driver_settings ([#284](https://github.com/appium/appium-mcp/issues/284)) ([65e5dcd](https://github.com/appium/appium-mcp/commit/65e5dcd49412c73a85f5b5794ade47b84647560c))
|
|
6
|
+
|
|
1
7
|
## [1.64.0](https://github.com/appium/appium-mcp/compare/v1.63.1...v1.64.0) (2026-04-23)
|
|
2
8
|
|
|
3
9
|
### Features
|
package/README.md
CHANGED
|
@@ -318,8 +318,7 @@ MCP Appium provides a comprehensive set of tools organized into the following ca
|
|
|
318
318
|
| ---------------- | ----------------------------------------------------------------------------------------------------------- |
|
|
319
319
|
| `appium_session_management` | Unified session management. `action=create`: start a new session for Android, iOS, or `general` capabilities (see 'general' mode above); forwards capabilities to a remote server via WebDriver `newSession` when `remoteServerUrl` is provided. `action=delete`: stop and clean up a session (defaults to active). `action=list`: show all active sessions. `action=select`: switch the active session by `sessionId`. |
|
|
320
320
|
| `appium_mobile_device_control` | Control device behavior: lock/unlock the screen, shake the device, or open the notifications panel (`action`: `lock` \| `unlock` \| `shake` \| `open_notifications`). `shake` is iOS only; `open_notifications` is Android only; `seconds` is optional for timed lock. |
|
|
321
|
-
| `
|
|
322
|
-
| `appium_update_settings` | Merge key-value updates into driver session settings (driver-specific keys; use `appium_get_settings` to inspect). |
|
|
321
|
+
| `appium_driver_settings` | Read or update Appium driver session settings in one tool. `action=get` returns current settings as JSON; `action=update` merges a `settings` map (driver-specific keys; use `action=get` first to inspect). |
|
|
323
322
|
|
|
324
323
|
The remote server URL in `appium_session_management` (action=create) can be set via the `remoteServerUrl` parameter.
|
|
325
324
|
If `REMOTE_SERVER_URL_ALLOW_REGEX` is set, the URL must match the provided regex pattern for security reasons.
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"driver-settings.d.ts","sourceRoot":"","sources":["../../../src/tools/session/driver-settings.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAiB,OAAO,EAAE,MAAM,SAAS,CAAC;
|
|
1
|
+
{"version":3,"file":"driver-settings.d.ts","sourceRoot":"","sources":["../../../src/tools/session/driver-settings.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAiB,OAAO,EAAE,MAAM,SAAS,CAAC;AA6DtD,MAAM,CAAC,OAAO,UAAU,cAAc,CAAC,MAAM,EAAE,OAAO,GAAG,IAAI,CAkC5D"}
|
|
@@ -1,63 +1,66 @@
|
|
|
1
1
|
import { z } from 'zod';
|
|
2
2
|
import { getSessionDriverSettings, updateSessionDriverSettings, } from '../../command.js';
|
|
3
3
|
import { errorResult, resolveDriver, textResult, toolErrorMessage, } from '../tool-response.js';
|
|
4
|
-
const
|
|
4
|
+
const schema = z.object({
|
|
5
|
+
action: z
|
|
6
|
+
.enum(['get', 'update'])
|
|
7
|
+
.describe('get: read current Appium driver session settings (timeouts, selector waits, flags). ' +
|
|
8
|
+
'update: merge a settings map into the session (requires settings).'),
|
|
5
9
|
settings: z
|
|
6
10
|
.record(z.string(), z.any())
|
|
7
|
-
.
|
|
8
|
-
'
|
|
9
|
-
'waitForSelectorTimeout, ignoreUnimportantViews; iOS XCUITest has its own set). ' +
|
|
10
|
-
'
|
|
11
|
+
.optional()
|
|
12
|
+
.describe('Required when action is update. Driver-specific keys (e.g. Android UiAutomator2: ' +
|
|
13
|
+
'waitForIdleTimeout, waitForSelectorTimeout, ignoreUnimportantViews; iOS XCUITest has its own set). ' +
|
|
14
|
+
'Use action=get first to inspect current values.'),
|
|
15
|
+
sessionId: z
|
|
16
|
+
.string()
|
|
17
|
+
.optional()
|
|
18
|
+
.describe('Session ID to target. If omitted, uses the active session.'),
|
|
11
19
|
});
|
|
20
|
+
async function handleGet(sessionId) {
|
|
21
|
+
const resolved = resolveDriver(sessionId);
|
|
22
|
+
if (!resolved.ok) {
|
|
23
|
+
return resolved.result;
|
|
24
|
+
}
|
|
25
|
+
const { driver } = resolved;
|
|
26
|
+
const settings = await getSessionDriverSettings(driver);
|
|
27
|
+
return textResult(JSON.stringify(settings, null, 2));
|
|
28
|
+
}
|
|
29
|
+
async function handleUpdate(sessionId, settings) {
|
|
30
|
+
const resolved = resolveDriver(sessionId);
|
|
31
|
+
if (!resolved.ok) {
|
|
32
|
+
return resolved.result;
|
|
33
|
+
}
|
|
34
|
+
const { driver } = resolved;
|
|
35
|
+
await updateSessionDriverSettings(driver, settings);
|
|
36
|
+
return textResult('Successfully updated driver settings.');
|
|
37
|
+
}
|
|
12
38
|
export default function driverSettings(server) {
|
|
13
39
|
server.addTool({
|
|
14
|
-
name: '
|
|
15
|
-
description: 'Read
|
|
16
|
-
'
|
|
17
|
-
'UiAutomator2/XCUITest sessions and remote WebDriver clients that support Appium settings.',
|
|
18
|
-
parameters:
|
|
19
|
-
annotations: {
|
|
20
|
-
readOnlyHint: true,
|
|
21
|
-
openWorldHint: false,
|
|
22
|
-
},
|
|
23
|
-
execute: async (_args, _context) => {
|
|
24
|
-
const resolved = resolveDriver();
|
|
25
|
-
if (!resolved.ok) {
|
|
26
|
-
return resolved.result;
|
|
27
|
-
}
|
|
28
|
-
const { driver } = resolved;
|
|
29
|
-
try {
|
|
30
|
-
const settings = await getSessionDriverSettings(driver);
|
|
31
|
-
return textResult(JSON.stringify(settings, null, 2));
|
|
32
|
-
}
|
|
33
|
-
catch (err) {
|
|
34
|
-
return errorResult(`Failed to get driver settings. Error: ${toolErrorMessage(err)}`);
|
|
35
|
-
}
|
|
36
|
-
},
|
|
37
|
-
});
|
|
38
|
-
server.addTool({
|
|
39
|
-
name: 'appium_update_settings',
|
|
40
|
-
description: 'Update Appium driver session settings by merging the provided map into the current ' +
|
|
41
|
-
'configuration. Useful to reduce flakiness (e.g. adjust waitForIdleTimeout) or toggle ' +
|
|
42
|
-
'driver-specific behavior. Keys are driver-specific; use appium_get_settings to see ' +
|
|
43
|
-
'what is supported.',
|
|
44
|
-
parameters: updateSettingsSchema,
|
|
40
|
+
name: 'appium_driver_settings',
|
|
41
|
+
description: 'Read or update Appium driver session settings (e.g. idle timeouts, selector waits). ' +
|
|
42
|
+
'Use action=get to return JSON settings; action=update merges a map into the session. ' +
|
|
43
|
+
'Works for embedded UiAutomator2/XCUITest sessions and remote WebDriver clients that support Appium settings.',
|
|
44
|
+
parameters: schema,
|
|
45
45
|
annotations: {
|
|
46
46
|
readOnlyHint: false,
|
|
47
47
|
openWorldHint: false,
|
|
48
48
|
},
|
|
49
49
|
execute: async (args, _context) => {
|
|
50
|
-
const resolved = resolveDriver();
|
|
51
|
-
if (!resolved.ok) {
|
|
52
|
-
return resolved.result;
|
|
53
|
-
}
|
|
54
|
-
const { driver } = resolved;
|
|
55
50
|
try {
|
|
56
|
-
|
|
57
|
-
|
|
51
|
+
switch (args.action) {
|
|
52
|
+
case 'get':
|
|
53
|
+
return await handleGet(args.sessionId);
|
|
54
|
+
case 'update': {
|
|
55
|
+
if (args.settings === undefined) {
|
|
56
|
+
return errorResult('settings is required for update action');
|
|
57
|
+
}
|
|
58
|
+
return await handleUpdate(args.sessionId, args.settings);
|
|
59
|
+
}
|
|
60
|
+
}
|
|
58
61
|
}
|
|
59
62
|
catch (err) {
|
|
60
|
-
return errorResult(`Failed to
|
|
63
|
+
return errorResult(`Failed to ${args.action} driver settings. Error: ${toolErrorMessage(err)}`);
|
|
61
64
|
}
|
|
62
65
|
},
|
|
63
66
|
});
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"driver-settings.js","sourceRoot":"","sources":["../../../src/tools/session/driver-settings.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AACxB,OAAO,EACL,wBAAwB,EACxB,2BAA2B,GAC5B,MAAM,kBAAkB,CAAC;AAC1B,OAAO,EACL,WAAW,EACX,aAAa,EACb,UAAU,EACV,gBAAgB,GACjB,MAAM,qBAAqB,CAAC;AAE7B,MAAM,
|
|
1
|
+
{"version":3,"file":"driver-settings.js","sourceRoot":"","sources":["../../../src/tools/session/driver-settings.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.65.0",
|
|
7
7
|
"packages": [
|
|
8
8
|
{
|
|
9
9
|
"registryType": "npm",
|
|
10
10
|
"identifier": "appium-mcp",
|
|
11
|
-
"version": "1.
|
|
11
|
+
"version": "1.65.0",
|
|
12
12
|
"transport": {
|
|
13
13
|
"type": "stdio"
|
|
14
14
|
}
|
|
Binary file
|
package/src/tools/README.md
CHANGED
|
@@ -14,7 +14,7 @@ This directory contains all MCP tools available in MCP Appium.
|
|
|
14
14
|
- `select-device.ts` - Discover devices and select one (auto-selects if only one found)
|
|
15
15
|
- `device-control.ts` - Device controls in one tool (`appium_mobile_device_control`; `action=lock|unlock|shake|open_notifications`)
|
|
16
16
|
- `file-transfer.ts` - Push/pull files on device (`appium_mobile_file` with `action=push|pull`)
|
|
17
|
-
- `driver-settings.ts` - Read/update Appium driver session settings (`
|
|
17
|
+
- `driver-settings.ts` - Read/update Appium driver session settings (`appium_driver_settings`, `action`: `get` \| `update`)
|
|
18
18
|
|
|
19
19
|
### iOS Setup (`ios/`)
|
|
20
20
|
|
|
@@ -11,78 +11,84 @@ import {
|
|
|
11
11
|
toolErrorMessage,
|
|
12
12
|
} from '../tool-response.js';
|
|
13
13
|
|
|
14
|
-
const
|
|
14
|
+
const schema = z.object({
|
|
15
|
+
action: z
|
|
16
|
+
.enum(['get', 'update'])
|
|
17
|
+
.describe(
|
|
18
|
+
'get: read current Appium driver session settings (timeouts, selector waits, flags). ' +
|
|
19
|
+
'update: merge a settings map into the session (requires settings).'
|
|
20
|
+
),
|
|
15
21
|
settings: z
|
|
16
22
|
.record(z.string(), z.any())
|
|
23
|
+
.optional()
|
|
17
24
|
.describe(
|
|
18
|
-
'
|
|
19
|
-
'
|
|
20
|
-
'
|
|
21
|
-
'Call appium_get_settings first to inspect current values.'
|
|
25
|
+
'Required when action is update. Driver-specific keys (e.g. Android UiAutomator2: ' +
|
|
26
|
+
'waitForIdleTimeout, waitForSelectorTimeout, ignoreUnimportantViews; iOS XCUITest has its own set). ' +
|
|
27
|
+
'Use action=get first to inspect current values.'
|
|
22
28
|
),
|
|
29
|
+
sessionId: z
|
|
30
|
+
.string()
|
|
31
|
+
.optional()
|
|
32
|
+
.describe('Session ID to target. If omitted, uses the active session.'),
|
|
23
33
|
});
|
|
24
34
|
|
|
25
|
-
|
|
26
|
-
server.addTool({
|
|
27
|
-
name: 'appium_get_settings',
|
|
28
|
-
description:
|
|
29
|
-
'Read current Appium driver session settings (e.g. idle timeouts, animation flags, ' +
|
|
30
|
-
'selector waits). Use this to tune stability for agent-driven flows. Works for embedded ' +
|
|
31
|
-
'UiAutomator2/XCUITest sessions and remote WebDriver clients that support Appium settings.',
|
|
32
|
-
parameters: z.object({}),
|
|
33
|
-
annotations: {
|
|
34
|
-
readOnlyHint: true,
|
|
35
|
-
openWorldHint: false,
|
|
36
|
-
},
|
|
37
|
-
execute: async (
|
|
38
|
-
_args: Record<string, never>,
|
|
39
|
-
_context: Record<string, unknown> | undefined
|
|
40
|
-
): Promise<ContentResult> => {
|
|
41
|
-
const resolved = resolveDriver();
|
|
42
|
-
if (!resolved.ok) {
|
|
43
|
-
return resolved.result;
|
|
44
|
-
}
|
|
45
|
-
const { driver } = resolved;
|
|
35
|
+
type DriverSettingsArgs = z.infer<typeof schema>;
|
|
46
36
|
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
37
|
+
async function handleGet(sessionId?: string): Promise<ContentResult> {
|
|
38
|
+
const resolved = resolveDriver(sessionId);
|
|
39
|
+
if (!resolved.ok) {
|
|
40
|
+
return resolved.result;
|
|
41
|
+
}
|
|
42
|
+
const { driver } = resolved;
|
|
43
|
+
|
|
44
|
+
const settings = await getSessionDriverSettings(driver);
|
|
45
|
+
return textResult(JSON.stringify(settings, null, 2));
|
|
46
|
+
}
|
|
57
47
|
|
|
48
|
+
async function handleUpdate(
|
|
49
|
+
sessionId: string | undefined,
|
|
50
|
+
settings: Record<string, unknown>
|
|
51
|
+
): Promise<ContentResult> {
|
|
52
|
+
const resolved = resolveDriver(sessionId);
|
|
53
|
+
if (!resolved.ok) {
|
|
54
|
+
return resolved.result;
|
|
55
|
+
}
|
|
56
|
+
const { driver } = resolved;
|
|
57
|
+
|
|
58
|
+
await updateSessionDriverSettings(driver, settings);
|
|
59
|
+
return textResult('Successfully updated driver settings.');
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
export default function driverSettings(server: FastMCP): void {
|
|
58
63
|
server.addTool({
|
|
59
|
-
name: '
|
|
64
|
+
name: 'appium_driver_settings',
|
|
60
65
|
description:
|
|
61
|
-
'
|
|
62
|
-
'
|
|
63
|
-
'
|
|
64
|
-
|
|
65
|
-
parameters: updateSettingsSchema,
|
|
66
|
+
'Read or update Appium driver session settings (e.g. idle timeouts, selector waits). ' +
|
|
67
|
+
'Use action=get to return JSON settings; action=update merges a map into the session. ' +
|
|
68
|
+
'Works for embedded UiAutomator2/XCUITest sessions and remote WebDriver clients that support Appium settings.',
|
|
69
|
+
parameters: schema,
|
|
66
70
|
annotations: {
|
|
67
71
|
readOnlyHint: false,
|
|
68
72
|
openWorldHint: false,
|
|
69
73
|
},
|
|
70
74
|
execute: async (
|
|
71
|
-
args:
|
|
75
|
+
args: DriverSettingsArgs,
|
|
72
76
|
_context: Record<string, unknown> | undefined
|
|
73
77
|
): Promise<ContentResult> => {
|
|
74
|
-
const resolved = resolveDriver();
|
|
75
|
-
if (!resolved.ok) {
|
|
76
|
-
return resolved.result;
|
|
77
|
-
}
|
|
78
|
-
const { driver } = resolved;
|
|
79
|
-
|
|
80
78
|
try {
|
|
81
|
-
|
|
82
|
-
|
|
79
|
+
switch (args.action) {
|
|
80
|
+
case 'get':
|
|
81
|
+
return await handleGet(args.sessionId);
|
|
82
|
+
case 'update': {
|
|
83
|
+
if (args.settings === undefined) {
|
|
84
|
+
return errorResult('settings is required for update action');
|
|
85
|
+
}
|
|
86
|
+
return await handleUpdate(args.sessionId, args.settings);
|
|
87
|
+
}
|
|
88
|
+
}
|
|
83
89
|
} catch (err: unknown) {
|
|
84
90
|
return errorResult(
|
|
85
|
-
`Failed to
|
|
91
|
+
`Failed to ${args.action} driver settings. Error: ${toolErrorMessage(err)}`
|
|
86
92
|
);
|
|
87
93
|
}
|
|
88
94
|
},
|