@nbakka/mcp-appium 2.0.0 → 2.0.2
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/lib/server.js +83 -2
- package/package.json +2 -2
package/lib/server.js
CHANGED
|
@@ -14,6 +14,7 @@ const getAgentVersion = () => {
|
|
|
14
14
|
const json = require("../package.json");
|
|
15
15
|
return json.version;
|
|
16
16
|
};
|
|
17
|
+
|
|
17
18
|
const getLatestAgentVersion = async () => {
|
|
18
19
|
const response = await fetch("https://api.github.com/repos/mobile-next/mobile-mcp/tags?per_page=1");
|
|
19
20
|
const json = await response.json();
|
|
@@ -146,11 +147,10 @@ tool("mobile_click_on_element_by_text", "Click on the screen element identified
|
|
|
146
147
|
}, async ({ text }) => {
|
|
147
148
|
requireRobot();
|
|
148
149
|
const xpath = `//*[@text="${text}"]`;
|
|
149
|
-
const element = await robot.
|
|
150
|
+
const element = await robot.clickByXPath(xpath);
|
|
150
151
|
if (!element) {
|
|
151
152
|
throw new Error(`Element with text "${text}" not found`);
|
|
152
153
|
}
|
|
153
|
-
await element.click();
|
|
154
154
|
// Wait for 2 seconds after click
|
|
155
155
|
await new Promise(resolve => setTimeout(resolve, 2000));
|
|
156
156
|
return `Clicked on element with text: "${text}"`;
|
|
@@ -219,8 +219,89 @@ await new Promise(resolve => setTimeout(resolve, 5000));
|
|
|
219
219
|
const orientation = await robot.getOrientation();
|
|
220
220
|
return `Current device orientation is ${orientation}`;
|
|
221
221
|
});
|
|
222
|
+
tool(
|
|
223
|
+
"mobile_create_session",
|
|
224
|
+
"create a mobile session once so that session id can be used in other tools where it is needed",
|
|
225
|
+
{},
|
|
226
|
+
async () => {
|
|
227
|
+
const capabilities = {
|
|
228
|
+
platformName: "Android",
|
|
229
|
+
"appium:udid": "emulator-5554",
|
|
230
|
+
"appium:automationName": "UiAutomator2",
|
|
231
|
+
"appium:noReset": true,
|
|
232
|
+
"appium:appPackage": "com.locon.housing",
|
|
233
|
+
"appium:appActivity": "com.locon.housing.presentation.MainActivity",
|
|
234
|
+
};
|
|
235
|
+
|
|
236
|
+
const payload = {
|
|
237
|
+
capabilities: {
|
|
238
|
+
firstMatch: [{}],
|
|
239
|
+
alwaysMatch: capabilities,
|
|
240
|
+
},
|
|
241
|
+
};
|
|
242
|
+
|
|
243
|
+
const response = await fetch("http://localhost:4723/session", {
|
|
244
|
+
method: "POST",
|
|
245
|
+
headers: { "Content-Type": "application/json" },
|
|
246
|
+
body: JSON.stringify(payload),
|
|
247
|
+
});
|
|
248
|
+
|
|
249
|
+
if (!response.ok) {
|
|
250
|
+
throw new Error(`Failed to create session: ${response.statusText}`);
|
|
251
|
+
}
|
|
252
|
+
|
|
253
|
+
const json = await response.json();
|
|
254
|
+
return `Session created with sessionId: ${json.sessionId}`;
|
|
255
|
+
}
|
|
256
|
+
);
|
|
257
|
+
|
|
258
|
+
|
|
259
|
+
tool(
|
|
260
|
+
"mobile_click_using_xpath",
|
|
261
|
+
"Click an element identified by text using path",
|
|
262
|
+
{
|
|
263
|
+
sessionId: zod_1.z.string().describe("Appium session ID"),
|
|
264
|
+
text: zod_1.z.string().describe("Visible text of the element to click"),
|
|
265
|
+
},
|
|
266
|
+
async ({ sessionId, text }) => {
|
|
267
|
+
const xpath = `//*[@text="${text}"]`;
|
|
268
|
+
const clickUrl = `http://localhost:4723/session/${sessionId}/element`;
|
|
269
|
+
|
|
270
|
+
// Find element
|
|
271
|
+
const findResponse = await fetch(clickUrl, {
|
|
272
|
+
method: "POST",
|
|
273
|
+
headers: { "Content-Type": "application/json" },
|
|
274
|
+
body: JSON.stringify({ using: "xpath", value: xpath }),
|
|
275
|
+
});
|
|
276
|
+
|
|
277
|
+
if (!findResponse.ok) {
|
|
278
|
+
throw new Error(`Failed to find element: ${findResponse.statusText}`);
|
|
279
|
+
}
|
|
280
|
+
|
|
281
|
+
const findJson = await findResponse.json();
|
|
282
|
+
if (!findJson.value || !findJson.value.elementId) {
|
|
283
|
+
throw new Error(`Element with text "${text}" not found`);
|
|
284
|
+
}
|
|
285
|
+
|
|
286
|
+
const elementId = findJson.value.elementId;
|
|
287
|
+
|
|
288
|
+
// Click element
|
|
289
|
+
const clickElementUrl = `http://localhost:4723/session/${sessionId}/element/${elementId}/click`;
|
|
290
|
+
const clickResponse = await fetch(clickElementUrl, { method: "POST" });
|
|
291
|
+
|
|
292
|
+
if (!clickResponse.ok) {
|
|
293
|
+
throw new Error(`Failed to click element: ${clickResponse.statusText}`);
|
|
294
|
+
}
|
|
295
|
+
|
|
296
|
+
// Optional wait after click
|
|
297
|
+
await new Promise((resolve) => setTimeout(resolve, 2000));
|
|
298
|
+
|
|
299
|
+
return `Clicked on element with text: "${text}" in session: ${sessionId}`;
|
|
300
|
+
}
|
|
301
|
+
);
|
|
222
302
|
// async check for latest agent version
|
|
223
303
|
checkForLatestAgentVersion().then();
|
|
224
304
|
return server;
|
|
225
305
|
};
|
|
306
|
+
|
|
226
307
|
exports.createMcpServer = createMcpServer;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@nbakka/mcp-appium",
|
|
3
|
-
"version": "2.0.
|
|
3
|
+
"version": "2.0.2",
|
|
4
4
|
"description": "Appium MCP",
|
|
5
5
|
"engines": {
|
|
6
6
|
"node": ">=18"
|
|
@@ -43,7 +43,7 @@
|
|
|
43
43
|
},
|
|
44
44
|
"main": "index.js",
|
|
45
45
|
"bin": {
|
|
46
|
-
"mcp-
|
|
46
|
+
"mcp-appium": "lib/index.js"
|
|
47
47
|
},
|
|
48
48
|
"directories": {
|
|
49
49
|
"lib": "lib"
|