appium-mcp 1.7.5 → 1.8.1
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/.github/workflows/ci.yml +3 -0
- package/CHANGELOG.md +22 -0
- package/dist/devicemanager/adb-manager.d.ts +1 -0
- package/dist/devicemanager/adb-manager.d.ts.map +1 -0
- package/dist/devicemanager/adb-manager.js +5 -5
- package/dist/devicemanager/adb-manager.js.map +1 -1
- package/dist/devicemanager/ios-manager.d.ts +1 -0
- package/dist/devicemanager/ios-manager.d.ts.map +1 -0
- package/dist/devicemanager/ios-manager.js +2 -0
- package/dist/devicemanager/ios-manager.js.map +1 -1
- package/dist/index.d.ts +1 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/locators/element-filter.d.ts +1 -0
- package/dist/locators/element-filter.d.ts.map +1 -0
- package/dist/locators/generate-all-locators.d.ts +1 -0
- package/dist/locators/generate-all-locators.d.ts.map +1 -0
- package/dist/locators/locator-generation.d.ts +1 -0
- package/dist/locators/locator-generation.d.ts.map +1 -0
- package/dist/locators/source-parsing.d.ts +1 -0
- package/dist/locators/source-parsing.d.ts.map +1 -0
- package/dist/logger.d.ts +2 -1
- package/dist/logger.d.ts.map +1 -0
- package/dist/resources/index.d.ts +1 -0
- package/dist/resources/index.d.ts.map +1 -0
- package/dist/resources/java/template.d.ts +1 -0
- package/dist/resources/java/template.d.ts.map +1 -0
- package/dist/schema.d.ts +1 -0
- package/dist/schema.d.ts.map +1 -0
- package/dist/scripts/simple-index-documentation.d.ts +1 -0
- package/dist/scripts/simple-index-documentation.d.ts.map +1 -0
- package/dist/scripts/simple-query-documentation.d.ts +1 -0
- package/dist/scripts/simple-query-documentation.d.ts.map +1 -0
- package/dist/server.d.ts +1 -0
- package/dist/server.d.ts.map +1 -0
- package/dist/session-store.d.ts +16 -2
- package/dist/session-store.d.ts.map +1 -0
- package/dist/session-store.js +21 -0
- package/dist/session-store.js.map +1 -1
- package/dist/tests/__mocks__/@appium/support.d.ts +1 -0
- package/dist/tests/__mocks__/@appium/support.d.ts.map +1 -0
- package/dist/tests/generate-all-locators.test.d.ts +1 -0
- package/dist/tests/generate-all-locators.test.d.ts.map +1 -0
- package/dist/tests/screenshot.test.d.ts +1 -0
- package/dist/tests/screenshot.test.d.ts.map +1 -0
- package/dist/tests/screenshot.test.js +6 -5
- package/dist/tests/screenshot.test.js.map +1 -1
- package/dist/tests/test-setup-wda.d.ts +1 -0
- package/dist/tests/test-setup-wda.d.ts.map +1 -0
- package/dist/tests/test-setup-wda.js +1 -3
- package/dist/tests/test-setup-wda.js.map +1 -1
- package/dist/tools/app-management/activate-app.d.ts +2 -1
- package/dist/tools/app-management/activate-app.d.ts.map +1 -0
- package/dist/tools/app-management/activate-app.js.map +1 -1
- package/dist/tools/app-management/install-app.d.ts +2 -1
- package/dist/tools/app-management/install-app.d.ts.map +1 -0
- package/dist/tools/app-management/install-app.js +6 -2
- package/dist/tools/app-management/install-app.js.map +1 -1
- package/dist/tools/app-management/list-apps.d.ts +2 -1
- package/dist/tools/app-management/list-apps.d.ts.map +1 -0
- package/dist/tools/app-management/list-apps.js +4 -1
- package/dist/tools/app-management/list-apps.js.map +1 -1
- package/dist/tools/app-management/terminate-app.d.ts +2 -1
- package/dist/tools/app-management/terminate-app.d.ts.map +1 -0
- package/dist/tools/app-management/terminate-app.js +6 -2
- package/dist/tools/app-management/terminate-app.js.map +1 -1
- package/dist/tools/app-management/uninstall-app.d.ts +2 -1
- package/dist/tools/app-management/uninstall-app.d.ts.map +1 -0
- package/dist/tools/app-management/uninstall-app.js +6 -2
- package/dist/tools/app-management/uninstall-app.js.map +1 -1
- package/dist/tools/context/get-contexts.d.ts +2 -1
- package/dist/tools/context/get-contexts.d.ts.map +1 -0
- package/dist/tools/context/get-contexts.js +4 -1
- package/dist/tools/context/get-contexts.js.map +1 -1
- package/dist/tools/context/switch-context.d.ts +2 -1
- package/dist/tools/context/switch-context.d.ts.map +1 -0
- package/dist/tools/context/switch-context.js +4 -1
- package/dist/tools/context/switch-context.js.map +1 -1
- package/dist/tools/documentation/answer-appium.d.ts +1 -0
- package/dist/tools/documentation/answer-appium.d.ts.map +1 -0
- package/dist/tools/documentation/index.d.ts +1 -0
- package/dist/tools/documentation/index.d.ts.map +1 -0
- package/dist/tools/documentation/reasoning-rag.d.ts +1 -0
- package/dist/tools/documentation/reasoning-rag.d.ts.map +1 -0
- package/dist/tools/documentation/reasoning-rag.js +3 -3
- package/dist/tools/documentation/reasoning-rag.js.map +1 -1
- package/dist/tools/documentation/sentence-transformers-embeddings.d.ts +1 -0
- package/dist/tools/documentation/sentence-transformers-embeddings.d.ts.map +1 -0
- package/dist/tools/documentation/sentence-transformers-embeddings.js +4 -3
- package/dist/tools/documentation/sentence-transformers-embeddings.js.map +1 -1
- package/dist/tools/documentation/simple-pdf-indexer.d.ts +1 -0
- package/dist/tools/documentation/simple-pdf-indexer.d.ts.map +1 -0
- package/dist/tools/index.d.ts +2 -1
- package/dist/tools/index.d.ts.map +1 -0
- package/dist/tools/interactions/click.d.ts +2 -1
- package/dist/tools/interactions/click.d.ts.map +1 -0
- package/dist/tools/interactions/click.js +4 -2
- package/dist/tools/interactions/click.js.map +1 -1
- package/dist/tools/interactions/double-tap.d.ts +2 -1
- package/dist/tools/interactions/double-tap.d.ts.map +1 -0
- package/dist/tools/interactions/double-tap.js +8 -4
- package/dist/tools/interactions/double-tap.js.map +1 -1
- package/dist/tools/interactions/drag-and-drop.d.ts +2 -1
- package/dist/tools/interactions/drag-and-drop.d.ts.map +1 -0
- package/dist/tools/interactions/drag-and-drop.js +4 -4
- package/dist/tools/interactions/drag-and-drop.js.map +1 -1
- package/dist/tools/interactions/find.d.ts +2 -1
- package/dist/tools/interactions/find.d.ts.map +1 -0
- package/dist/tools/interactions/find.js.map +1 -1
- package/dist/tools/interactions/get-page-source.d.ts +2 -1
- package/dist/tools/interactions/get-page-source.d.ts.map +1 -0
- package/dist/tools/interactions/get-page-source.js.map +1 -1
- package/dist/tools/interactions/get-text.d.ts +2 -1
- package/dist/tools/interactions/get-text.d.ts.map +1 -0
- package/dist/tools/interactions/get-text.js +4 -2
- package/dist/tools/interactions/get-text.js.map +1 -1
- package/dist/tools/interactions/long-press.d.ts +2 -1
- package/dist/tools/interactions/long-press.d.ts.map +1 -0
- package/dist/tools/interactions/long-press.js +12 -5
- package/dist/tools/interactions/long-press.js.map +1 -1
- package/dist/tools/interactions/screenshot.d.ts +6 -4
- package/dist/tools/interactions/screenshot.d.ts.map +1 -0
- package/dist/tools/interactions/screenshot.js +6 -3
- package/dist/tools/interactions/screenshot.js.map +1 -1
- package/dist/tools/interactions/set-value.d.ts +2 -1
- package/dist/tools/interactions/set-value.d.ts.map +1 -0
- package/dist/tools/interactions/set-value.js +4 -2
- package/dist/tools/interactions/set-value.js.map +1 -1
- package/dist/tools/ios/boot-simulator.d.ts +1 -0
- package/dist/tools/ios/boot-simulator.d.ts.map +1 -0
- package/dist/tools/ios/install-wda.d.ts +1 -0
- package/dist/tools/ios/install-wda.d.ts.map +1 -0
- package/dist/tools/ios/setup-wda.d.ts +1 -0
- package/dist/tools/ios/setup-wda.d.ts.map +1 -0
- package/dist/tools/navigations/scroll-to-element.d.ts +1 -0
- package/dist/tools/navigations/scroll-to-element.d.ts.map +1 -0
- package/dist/tools/navigations/scroll-to-element.js +2 -2
- package/dist/tools/navigations/scroll-to-element.js.map +1 -1
- package/dist/tools/navigations/scroll.d.ts +1 -0
- package/dist/tools/navigations/scroll.d.ts.map +1 -0
- package/dist/tools/navigations/scroll.js +19 -9
- package/dist/tools/navigations/scroll.js.map +1 -1
- package/dist/tools/navigations/swipe.d.ts +1 -0
- package/dist/tools/navigations/swipe.d.ts.map +1 -0
- package/dist/tools/navigations/swipe.js +11 -5
- package/dist/tools/navigations/swipe.js.map +1 -1
- package/dist/tools/session/create-session.d.ts +31 -0
- package/dist/tools/session/create-session.d.ts.map +1 -0
- package/dist/tools/session/create-session.js +88 -21
- package/dist/tools/session/create-session.js.map +1 -1
- package/dist/tools/session/delete-session.d.ts +1 -0
- package/dist/tools/session/delete-session.d.ts.map +1 -0
- package/dist/tools/session/delete-session.js +10 -1
- package/dist/tools/session/delete-session.js.map +1 -1
- package/dist/tools/session/select-device.d.ts +1 -0
- package/dist/tools/session/select-device.d.ts.map +1 -0
- package/dist/tools/session/select-device.js +11 -4
- package/dist/tools/session/select-device.js.map +1 -1
- package/dist/tools/session/select-platform.d.ts +1 -0
- package/dist/tools/session/select-platform.d.ts.map +1 -0
- package/dist/tools/session/select-platform.js +12 -5
- package/dist/tools/session/select-platform.js.map +1 -1
- package/dist/tools/test-generation/generate-tests.d.ts +2 -1
- package/dist/tools/test-generation/generate-tests.d.ts.map +1 -0
- package/dist/tools/test-generation/locators.d.ts +1 -0
- package/dist/tools/test-generation/locators.d.ts.map +1 -0
- package/dist/tools/test-generation/locators.js +4 -2
- package/dist/tools/test-generation/locators.js.map +1 -1
- package/dist/ui/mcp-ui-utils.d.ts +1 -0
- package/dist/ui/mcp-ui-utils.d.ts.map +1 -0
- package/package.json +6 -6
- package/server.json +2 -2
- package/src/session-store.ts +34 -2
- package/src/tests/screenshot.test.ts +6 -5
- package/src/tools/app-management/activate-app.ts +2 -2
- package/src/tools/app-management/install-app.ts +12 -3
- package/src/tools/app-management/list-apps.ts +12 -3
- package/src/tools/app-management/terminate-app.ts +12 -3
- package/src/tools/app-management/uninstall-app.ts +12 -3
- package/src/tools/context/get-contexts.ts +10 -4
- package/src/tools/context/switch-context.ts +17 -6
- package/src/tools/index.ts +1 -1
- package/src/tools/interactions/click.ts +6 -3
- package/src/tools/interactions/double-tap.ts +19 -7
- package/src/tools/interactions/drag-and-drop.ts +16 -7
- package/src/tools/interactions/find.ts +5 -2
- package/src/tools/interactions/get-page-source.ts +2 -2
- package/src/tools/interactions/get-text.ts +6 -3
- package/src/tools/interactions/long-press.ts +22 -10
- package/src/tools/interactions/screenshot.ts +11 -5
- package/src/tools/interactions/set-value.ts +9 -3
- package/src/tools/navigations/scroll-to-element.ts +4 -4
- package/src/tools/navigations/scroll.ts +25 -10
- package/src/tools/navigations/swipe.ts +17 -6
- package/src/tools/session/create-session.ts +108 -27
- package/src/tools/session/delete-session.ts +10 -1
- package/src/tools/session/select-device.ts +11 -4
- package/src/tools/session/select-platform.ts +12 -5
- package/src/tools/test-generation/generate-tests.ts +1 -1
- package/src/tools/test-generation/locators.ts +8 -3
- package/tsconfig.json +7 -15
- package/tsconfig.tsbuildinfo +1 -0
|
@@ -2,8 +2,9 @@
|
|
|
2
2
|
* Tool to create a new mobile session (Android or iOS)
|
|
3
3
|
*/
|
|
4
4
|
import { z } from 'zod';
|
|
5
|
-
import { access, readFile } from 'fs/promises';
|
|
6
|
-
import { constants } from 'fs';
|
|
5
|
+
import { access, readFile } from 'node:fs/promises';
|
|
6
|
+
import { constants } from 'node:fs';
|
|
7
|
+
import { URL } from 'node:url';
|
|
7
8
|
import { AndroidUiautomator2Driver } from 'appium-uiautomator2-driver';
|
|
8
9
|
import { XCUITestDriver } from 'appium-xcuitest-driver';
|
|
9
10
|
import {
|
|
@@ -24,6 +25,7 @@ import {
|
|
|
24
25
|
createSessionDashboardUI,
|
|
25
26
|
addUIResourceToResponse,
|
|
26
27
|
} from '../../ui/mcp-ui-utils.js';
|
|
28
|
+
import WebDriver from 'webdriver';
|
|
27
29
|
|
|
28
30
|
// Define capabilities type
|
|
29
31
|
interface Capabilities {
|
|
@@ -76,7 +78,8 @@ function filterEmptyCapabilities(capabilities: Capabilities): Capabilities {
|
|
|
76
78
|
*/
|
|
77
79
|
function buildAndroidCapabilities(
|
|
78
80
|
configCaps: Record<string, any>,
|
|
79
|
-
customCaps: Record<string, any> | undefined
|
|
81
|
+
customCaps: Record<string, any> | undefined,
|
|
82
|
+
isRemoteServer: boolean
|
|
80
83
|
): Capabilities {
|
|
81
84
|
const defaultCaps: Capabilities = {
|
|
82
85
|
platformName: 'Android',
|
|
@@ -84,7 +87,7 @@ function buildAndroidCapabilities(
|
|
|
84
87
|
'appium:deviceName': 'Android Device',
|
|
85
88
|
};
|
|
86
89
|
|
|
87
|
-
const selectedDeviceUdid = getSelectedDevice();
|
|
90
|
+
const selectedDeviceUdid = isRemoteServer ? undefined : getSelectedDevice();
|
|
88
91
|
|
|
89
92
|
const capabilities = {
|
|
90
93
|
...defaultCaps,
|
|
@@ -128,9 +131,10 @@ async function validateIOSDeviceSelection(
|
|
|
128
131
|
*/
|
|
129
132
|
async function buildIOSCapabilities(
|
|
130
133
|
configCaps: Record<string, any>,
|
|
131
|
-
customCaps: Record<string, any> | undefined
|
|
134
|
+
customCaps: Record<string, any> | undefined,
|
|
135
|
+
isRemoteServer: boolean
|
|
132
136
|
): Promise<Capabilities> {
|
|
133
|
-
const deviceType = getSelectedDeviceType();
|
|
137
|
+
const deviceType = isRemoteServer ? null : getSelectedDeviceType();
|
|
134
138
|
await validateIOSDeviceSelection(deviceType);
|
|
135
139
|
|
|
136
140
|
const defaultCaps: Capabilities = {
|
|
@@ -139,8 +143,10 @@ async function buildIOSCapabilities(
|
|
|
139
143
|
'appium:deviceName': 'iPhone Simulator',
|
|
140
144
|
};
|
|
141
145
|
|
|
142
|
-
const selectedDeviceUdid = getSelectedDevice();
|
|
143
|
-
const selectedDeviceInfo =
|
|
146
|
+
const selectedDeviceUdid = isRemoteServer ? undefined : getSelectedDevice();
|
|
147
|
+
const selectedDeviceInfo = isRemoteServer
|
|
148
|
+
? undefined
|
|
149
|
+
: getSelectedDeviceInfo();
|
|
144
150
|
|
|
145
151
|
log.debug('Selected device info:', selectedDeviceInfo);
|
|
146
152
|
|
|
@@ -202,22 +208,69 @@ async function createDriverSession(
|
|
|
202
208
|
return sessionId;
|
|
203
209
|
}
|
|
204
210
|
|
|
211
|
+
/**
|
|
212
|
+
* Registers a tool for creating a new mobile session with Android or iOS devices.
|
|
213
|
+
*
|
|
214
|
+
* This function adds a 'create_session' tool to the provided server that handles
|
|
215
|
+
* mobile session creation with support for both local and remote Appium servers.
|
|
216
|
+
*
|
|
217
|
+
* @param server - The server instance to which the create_session tool will be added
|
|
218
|
+
*
|
|
219
|
+
* @tool create_session
|
|
220
|
+
* @description Creates a new mobile session with Android or iOS device. Requires prior
|
|
221
|
+
* platform selection via the select_platform tool. Supports both local and remote
|
|
222
|
+
* Appium server connections.
|
|
223
|
+
*
|
|
224
|
+
* @param {Object} args - Tool execution arguments
|
|
225
|
+
* @param {'ios' | 'android'} args.platform - REQUIRED. The target platform, must match
|
|
226
|
+
* the platform explicitly selected via select_platform tool
|
|
227
|
+
* @param {Object} [args.capabilities] - Optional custom W3C format capabilities
|
|
228
|
+
* @param {string} [args.remoteServerUrl] - Optional remote Appium server URL
|
|
229
|
+
* (e.g., http://localhost:4723). If not provided, uses local Appium server
|
|
230
|
+
*
|
|
231
|
+
* @returns {Promise<Object>} Response object containing:
|
|
232
|
+
* - text: Success message with session ID and device details
|
|
233
|
+
* - ui: Interactive session dashboard UI component
|
|
234
|
+
*
|
|
235
|
+
* @throws {Error} If session creation fails or platform capabilities cannot be loaded
|
|
236
|
+
*
|
|
237
|
+
* @example
|
|
238
|
+
* // Register the tool
|
|
239
|
+
* createSession(server);
|
|
240
|
+
*/
|
|
205
241
|
export default function createSession(server: any): void {
|
|
206
242
|
server.addTool({
|
|
207
243
|
name: 'create_session',
|
|
208
244
|
description: `Create a new mobile session with Android or iOS device.
|
|
209
|
-
|
|
210
|
-
|
|
245
|
+
WORKFLOW FOR LOCAL SERVERS (no remoteServerUrl):
|
|
246
|
+
- Use select_platform tool FIRST to ask the user which platform they want
|
|
247
|
+
- Then optionally use select_device tool if multiple devices are available
|
|
248
|
+
- Finally call create_session with the selected platform and device
|
|
249
|
+
- DO NOT assume or default to any platform
|
|
250
|
+
WORKFLOW FOR REMOTE SERVERS (remoteServerUrl provided):
|
|
251
|
+
- SKIP select_platform tool entirely
|
|
252
|
+
- Infer the platform from the user's request (e.g., 'ios', 'android')
|
|
253
|
+
- Infer device type from context when possible (e.g., 'simulator', 'real device')
|
|
254
|
+
- Call create_session directly with platform, remoteServerUrl, and any other capabilities from the user's request
|
|
255
|
+
- Example: User says 'start session with http://localhost:4723 for ios with iphone 17' → infer platform='ios' and call create_session with remoteServerUrl and platform parameters
|
|
211
256
|
`,
|
|
212
257
|
parameters: z.object({
|
|
213
258
|
platform: z.enum(['ios', 'android']).describe(
|
|
214
|
-
`REQUIRED:
|
|
215
|
-
|
|
259
|
+
`REQUIRED: Platform to use. For local servers, this must match the platform the user explicitly selected via the select_platform tool.
|
|
260
|
+
If remoteServerUrl is provided, the assistant should ask the user to confirm or infer the platform from the conversation; do not assume a default.`
|
|
216
261
|
),
|
|
217
262
|
capabilities: z
|
|
218
263
|
.object({})
|
|
219
264
|
.optional()
|
|
220
|
-
.describe(
|
|
265
|
+
.describe(
|
|
266
|
+
'Optional custom W3C format capabilities for the session. Common options include appium:app (app path), appium:deviceName, appium:platformVersion, appium:bundleId, appium:autoGrantPermissions, etc. Custom capabilities override default and config file settings.'
|
|
267
|
+
),
|
|
268
|
+
remoteServerUrl: z
|
|
269
|
+
.string()
|
|
270
|
+
.optional()
|
|
271
|
+
.describe(
|
|
272
|
+
'Remote Appium server URL (e.g., http://localhost:4723 or http://192.168.1.100:4723). If not provided, uses local Appium server.'
|
|
273
|
+
),
|
|
221
274
|
}),
|
|
222
275
|
annotations: {
|
|
223
276
|
readOnlyHint: false,
|
|
@@ -229,31 +282,59 @@ export default function createSession(server: any): void {
|
|
|
229
282
|
log.info(
|
|
230
283
|
'Existing session detected, cleaning up before creating new session...'
|
|
231
284
|
);
|
|
232
|
-
|
|
285
|
+
try {
|
|
286
|
+
await safeDeleteSession();
|
|
287
|
+
} catch {
|
|
288
|
+
// ok to ignore
|
|
289
|
+
}
|
|
233
290
|
}
|
|
234
291
|
|
|
235
|
-
const {
|
|
292
|
+
const {
|
|
293
|
+
platform,
|
|
294
|
+
capabilities: customCapabilities,
|
|
295
|
+
remoteServerUrl,
|
|
296
|
+
} = args;
|
|
236
297
|
|
|
237
298
|
const configCapabilities = await loadCapabilitiesConfig();
|
|
238
299
|
const platformCaps =
|
|
239
300
|
platform === 'android'
|
|
240
301
|
? configCapabilities.android
|
|
241
302
|
: configCapabilities.ios;
|
|
242
|
-
|
|
243
303
|
const finalCapabilities =
|
|
244
304
|
platform === 'android'
|
|
245
|
-
? buildAndroidCapabilities(
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
305
|
+
? buildAndroidCapabilities(
|
|
306
|
+
platformCaps,
|
|
307
|
+
customCapabilities,
|
|
308
|
+
!!remoteServerUrl
|
|
309
|
+
)
|
|
310
|
+
: await buildIOSCapabilities(
|
|
311
|
+
platformCaps,
|
|
312
|
+
customCapabilities,
|
|
313
|
+
!!remoteServerUrl
|
|
314
|
+
);
|
|
315
|
+
|
|
316
|
+
let sessionId;
|
|
317
|
+
if (remoteServerUrl) {
|
|
318
|
+
const remoteUrl = new URL(remoteServerUrl);
|
|
319
|
+
const client = await WebDriver.newSession({
|
|
320
|
+
protocol: remoteUrl.protocol.replace(':', ''),
|
|
321
|
+
hostname: remoteUrl.hostname,
|
|
322
|
+
port: parseInt(remoteUrl.port, 10),
|
|
323
|
+
path: remoteUrl.pathname,
|
|
324
|
+
capabilities: finalCapabilities,
|
|
325
|
+
});
|
|
326
|
+
sessionId = client.sessionId;
|
|
327
|
+
setSession(client, client.sessionId);
|
|
328
|
+
} else {
|
|
329
|
+
log.info(
|
|
330
|
+
`Creating new ${platform.toUpperCase()} session with capabilities:`,
|
|
331
|
+
JSON.stringify(finalCapabilities, null, 2)
|
|
332
|
+
);
|
|
254
333
|
|
|
255
|
-
|
|
256
|
-
|
|
334
|
+
const driver = createDriverForPlatform(platform);
|
|
335
|
+
sessionId = await createDriverSession(driver, finalCapabilities);
|
|
336
|
+
setSession(driver, sessionId);
|
|
337
|
+
}
|
|
257
338
|
|
|
258
339
|
// Safely convert sessionId to string for display
|
|
259
340
|
const sessionIdStr =
|
|
@@ -40,7 +40,16 @@ export default function deleteSession(server: any): void {
|
|
|
40
40
|
}
|
|
41
41
|
} catch (error: any) {
|
|
42
42
|
log.error(`Error deleting session`, error);
|
|
43
|
-
|
|
43
|
+
// don't need to raise an error since session end means anyway we should create a new session
|
|
44
|
+
// to proceed further requests.
|
|
45
|
+
return {
|
|
46
|
+
content: [
|
|
47
|
+
{
|
|
48
|
+
type: 'text',
|
|
49
|
+
text: `Session delete might fail as error ${error}`,
|
|
50
|
+
},
|
|
51
|
+
],
|
|
52
|
+
};
|
|
44
53
|
}
|
|
45
54
|
},
|
|
46
55
|
});
|
|
@@ -269,10 +269,17 @@ async function handleIOSDeviceSelection(
|
|
|
269
269
|
export default function selectDevice(server: any): void {
|
|
270
270
|
server.addTool({
|
|
271
271
|
name: 'select_device',
|
|
272
|
-
description: `
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
272
|
+
description: `Select a specific device from available LOCAL devices. For LOCAL Appium servers ONLY.
|
|
273
|
+
DO NOT use this tool for REMOTE Appium servers - remoteServerUrl indicates a remote server.
|
|
274
|
+
WORKFLOW FOR LOCAL SERVERS:
|
|
275
|
+
- Use this tool ONLY when select_platform returns multiple devices
|
|
276
|
+
- For Android: Use before calling create_session if multiple devices are found
|
|
277
|
+
- For iOS: Use before calling boot_simulator or create_session if multiple simulators/devices are found
|
|
278
|
+
- Ask the user which device they want to use from the list provided
|
|
279
|
+
WORKFLOW FOR REMOTE SERVERS:
|
|
280
|
+
- SKIP this tool entirely
|
|
281
|
+
- Device selection should be handled via capabilities in create_session (e.g., appium:deviceName, appium:udid)
|
|
282
|
+
- The remote Appium server is already configured for specific device(s)
|
|
276
283
|
`,
|
|
277
284
|
parameters: z.object({
|
|
278
285
|
platform: z
|
|
@@ -195,10 +195,17 @@ async function handleIOSPlatformSelection(
|
|
|
195
195
|
export default function selectPlatform(server: any): void {
|
|
196
196
|
server.addTool({
|
|
197
197
|
name: 'select_platform',
|
|
198
|
-
description: `
|
|
199
|
-
DO NOT
|
|
200
|
-
|
|
201
|
-
|
|
198
|
+
description: `Select the mobile platform for LOCAL Appium servers ONLY.
|
|
199
|
+
DO NOT use this tool if the user mentions a REMOTE Appium server URL (e.g., http://localhost:4723, http://192.168.1.100:4723, or any other server address).
|
|
200
|
+
WORKFLOW FOR LOCAL SERVERS:
|
|
201
|
+
1. First, ASK THE USER which mobile platform they want to use (Android or iOS)
|
|
202
|
+
2. You MUST explicitly prompt the user to choose between Android or iOS
|
|
203
|
+
3. DO NOT assume or default to any platform
|
|
204
|
+
4. After platform selection, available devices will be listed
|
|
205
|
+
5. If multiple devices are available, use select_device to let the user choose
|
|
206
|
+
6. After device selection, proceed to create_session
|
|
207
|
+
WORKFLOW FOR REMOTE SERVERS:
|
|
208
|
+
If user provides a remote server URL, SKIP this tool entirely. Instead, infer the platform and device type from the user's request (e.g., 'ios xcuitest driver with iphone 17 simulator' means platform='ios') and call create_session directly with the remoteServerUrl parameter.
|
|
202
209
|
`,
|
|
203
210
|
parameters: z.object({
|
|
204
211
|
platform: z
|
|
@@ -210,7 +217,7 @@ export default function selectPlatform(server: any): void {
|
|
|
210
217
|
.enum(['simulator', 'real'])
|
|
211
218
|
.optional()
|
|
212
219
|
.describe(
|
|
213
|
-
"For iOS only: Specify whether to use 'simulator' or 'real' device. REQUIRED when platform is 'ios'."
|
|
220
|
+
"For iOS only: Specify whether to use 'simulator' (iOS Simulator on macOS) or 'real' (physical iOS device). REQUIRED when platform is 'ios'."
|
|
214
221
|
),
|
|
215
222
|
}),
|
|
216
223
|
annotations: {
|
|
@@ -10,7 +10,7 @@
|
|
|
10
10
|
* For detailed documentation on adding tools, see docs/CONTRIBUTING.md
|
|
11
11
|
*/
|
|
12
12
|
import { z } from 'zod';
|
|
13
|
-
import { getDriver } from '../../session-store.js';
|
|
13
|
+
import { getDriver, isRemoteDriverSession } from '../../session-store.js';
|
|
14
14
|
import { generateAllElementLocators } from '../../locators/generate-all-locators.js';
|
|
15
15
|
import log from '../../logger.js';
|
|
16
16
|
import {
|
|
@@ -18,6 +18,7 @@ import {
|
|
|
18
18
|
createLocatorGeneratorUI,
|
|
19
19
|
addUIResourceToResponse,
|
|
20
20
|
} from '../../ui/mcp-ui-utils.js';
|
|
21
|
+
import type { Client } from 'webdriver';
|
|
21
22
|
|
|
22
23
|
export default function generateLocators(server: any): void {
|
|
23
24
|
server.addTool({
|
|
@@ -42,8 +43,12 @@ export default function generateLocators(server: any): void {
|
|
|
42
43
|
|
|
43
44
|
try {
|
|
44
45
|
// Get the page source from the driver
|
|
45
|
-
const pageSource = await driver.getPageSource();
|
|
46
|
-
const driverName = (
|
|
46
|
+
const pageSource = await (driver as any).getPageSource();
|
|
47
|
+
const driverName = isRemoteDriverSession(driver)
|
|
48
|
+
? (driver as Client).capabilities[
|
|
49
|
+
'appium:automationName'
|
|
50
|
+
]?.toLowerCase()
|
|
51
|
+
: (await (driver as any).caps.automationName).toLowerCase();
|
|
47
52
|
if (!pageSource) {
|
|
48
53
|
throw new Error('Page source is empty or null');
|
|
49
54
|
}
|
package/tsconfig.json
CHANGED
|
@@ -1,23 +1,15 @@
|
|
|
1
1
|
{
|
|
2
|
+
"$schema": "https://json.schemastore.org/tsconfig",
|
|
3
|
+
"extends": "@appium/tsconfig/tsconfig.json",
|
|
2
4
|
"compilerOptions": {
|
|
3
|
-
"target": "ES2020",
|
|
4
|
-
"module": "NodeNext",
|
|
5
|
-
"moduleResolution": "NodeNext",
|
|
6
|
-
"esModuleInterop": true,
|
|
7
|
-
"resolveJsonModule": true,
|
|
8
|
-
"strict": true,
|
|
9
|
-
"skipLibCheck": true,
|
|
10
5
|
"outDir": "dist",
|
|
11
6
|
"sourceMap": true,
|
|
12
7
|
"declaration": true,
|
|
13
|
-
"
|
|
14
|
-
"
|
|
15
|
-
"
|
|
16
|
-
"
|
|
17
|
-
"paths": {
|
|
18
|
-
"*": ["node_modules/*"]
|
|
19
|
-
}
|
|
8
|
+
"resolveJsonModule": true,
|
|
9
|
+
"rootDir": "src",
|
|
10
|
+
"module": "NodeNext",
|
|
11
|
+
"moduleResolution": "NodeNext"
|
|
20
12
|
},
|
|
21
13
|
"include": ["src/**/*"],
|
|
22
14
|
"exclude": ["node_modules", "dist"]
|
|
23
|
-
}
|
|
15
|
+
}
|