@nbakka/mcp-appium 1.0.4 → 1.0.7
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/package.json +1 -1
- package/src/lib/server.js +38 -4
package/package.json
CHANGED
package/src/lib/server.js
CHANGED
|
@@ -5,10 +5,9 @@ import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js"
|
|
|
5
5
|
import { z } from "zod";
|
|
6
6
|
import axios from "axios";
|
|
7
7
|
|
|
8
|
-
const APPIUM_URL = "http://127.0.0.1:4723
|
|
8
|
+
const APPIUM_URL = "http://127.0.0.1:4723"; // Corrected endpoint for Appium 2.x
|
|
9
9
|
|
|
10
10
|
const server = new McpServer({ name: "MCP Appium JSONWire", version: "1.0.0" });
|
|
11
|
-
|
|
12
11
|
const state = { sessionId: null };
|
|
13
12
|
|
|
14
13
|
// Helper to extract element ID
|
|
@@ -24,18 +23,29 @@ server.tool(
|
|
|
24
23
|
capabilities: z.object({
|
|
25
24
|
platformName: z.string(),
|
|
26
25
|
udid: z.string(),
|
|
26
|
+
automationName: z.string(),
|
|
27
27
|
app: z.string().optional(),
|
|
28
|
-
automationName: z.string().optional(),
|
|
29
28
|
}),
|
|
30
29
|
},
|
|
31
30
|
async ({ capabilities }) => {
|
|
32
31
|
try {
|
|
32
|
+
// Construct capabilities strictly with prefixes
|
|
33
|
+
const alwaysMatch = {
|
|
34
|
+
platformName: capabilities.platformName,
|
|
35
|
+
"appium:udid": capabilities.udid,
|
|
36
|
+
"appium:automationName": capabilities.automationName,
|
|
37
|
+
};
|
|
38
|
+
if (capabilities.app) {
|
|
39
|
+
alwaysMatch["appium:app"] = capabilities.app;
|
|
40
|
+
}
|
|
41
|
+
|
|
33
42
|
const payload = {
|
|
34
43
|
capabilities: {
|
|
35
44
|
firstMatch: [{}],
|
|
36
|
-
alwaysMatch
|
|
45
|
+
alwaysMatch,
|
|
37
46
|
},
|
|
38
47
|
};
|
|
48
|
+
|
|
39
49
|
const response = await axios.post(`${APPIUM_URL}/session`, payload);
|
|
40
50
|
state.sessionId = response.data.sessionId;
|
|
41
51
|
return { content: [{ type: "text", text: `Session started: ${state.sessionId}` }] };
|
|
@@ -45,6 +55,7 @@ server.tool(
|
|
|
45
55
|
}
|
|
46
56
|
);
|
|
47
57
|
|
|
58
|
+
|
|
48
59
|
// Tap tool
|
|
49
60
|
server.tool(
|
|
50
61
|
"tap",
|
|
@@ -94,6 +105,29 @@ server.tool(
|
|
|
94
105
|
}
|
|
95
106
|
);
|
|
96
107
|
|
|
108
|
+
// Open Deep Link tool with package name
|
|
109
|
+
server.tool(
|
|
110
|
+
"open_deep_link",
|
|
111
|
+
"Open deep link on the device with package name",
|
|
112
|
+
{
|
|
113
|
+
deepLink: z.string(),
|
|
114
|
+
packageName: z.string(), // Add package name to be hardcoded
|
|
115
|
+
},
|
|
116
|
+
async ({ deepLink, packageName }) => {
|
|
117
|
+
if (!state.sessionId) return { content: [{ type: "text", text: "No active session" }] };
|
|
118
|
+
try {
|
|
119
|
+
// ADB command to open deep link with the provided package name
|
|
120
|
+
const adbCommand = `adb -s ${state.udid} shell am start -W -a android.intent.action.VIEW -d "${deepLink}" ${packageName}/.MainActivity`;
|
|
121
|
+
await axios.post(`${APPIUM_URL}/session/${state.sessionId}/execute`, {
|
|
122
|
+
script: adbCommand,
|
|
123
|
+
});
|
|
124
|
+
return { content: [{ type: "text", text: `Deep link opened: ${deepLink} for package: ${packageName}` }] };
|
|
125
|
+
} catch (e) {
|
|
126
|
+
return { content: [{ type: "text", text: `Error opening deep link: ${e.message}` }] };
|
|
127
|
+
}
|
|
128
|
+
}
|
|
129
|
+
);
|
|
130
|
+
|
|
97
131
|
// Close Session tool
|
|
98
132
|
server.tool(
|
|
99
133
|
"close_session",
|