@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.
Files changed (2) hide show
  1. package/package.json +1 -1
  2. package/src/lib/server.js +38 -4
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@nbakka/mcp-appium",
3
- "version": "1.0.4",
3
+ "version": "1.0.7",
4
4
  "description": "Selenium WebDriver MCP Server",
5
5
  "type": "module",
6
6
  "main": "src/lib/server.js",
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/wd/hub";
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: capabilities,
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",