@mobilenext/mobile-mcp 0.0.29 → 0.0.30-beta
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/mobilecli.js +53 -0
- package/lib/server.js +33 -19
- package/package.json +3 -2
package/lib/mobilecli.js
ADDED
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.getMobilecliPath = void 0;
|
|
4
|
+
const node_fs_1 = require("node:fs");
|
|
5
|
+
const node_path_1 = require("node:path");
|
|
6
|
+
const getMobilecliPath = () => {
|
|
7
|
+
if (process.env.MOBILECLI_PATH) {
|
|
8
|
+
return process.env.MOBILECLI_PATH;
|
|
9
|
+
}
|
|
10
|
+
const platform = process.platform;
|
|
11
|
+
let binaryName = "mobilecli";
|
|
12
|
+
switch (platform) {
|
|
13
|
+
case "darwin":
|
|
14
|
+
binaryName += "-darwin";
|
|
15
|
+
break;
|
|
16
|
+
case "linux":
|
|
17
|
+
const arch = process.arch;
|
|
18
|
+
if (arch === "arm64") {
|
|
19
|
+
binaryName += "-linux-arm64";
|
|
20
|
+
}
|
|
21
|
+
else {
|
|
22
|
+
binaryName += "-linux-amd64";
|
|
23
|
+
}
|
|
24
|
+
break;
|
|
25
|
+
case "win32":
|
|
26
|
+
binaryName += "-windows-amd64.exe";
|
|
27
|
+
break;
|
|
28
|
+
default:
|
|
29
|
+
throw new Error(`Unsupported platform: ${platform}`);
|
|
30
|
+
}
|
|
31
|
+
// Check if mobile-mcp is installed as a package
|
|
32
|
+
const currentPath = __filename;
|
|
33
|
+
const pathParts = currentPath.split(node_path_1.sep);
|
|
34
|
+
const lastNodeModulesIndex = pathParts.lastIndexOf("node_modules");
|
|
35
|
+
if (lastNodeModulesIndex !== -1) {
|
|
36
|
+
// We're inside node_modules, go to the last node_modules in the path
|
|
37
|
+
const nodeModulesParts = pathParts.slice(0, lastNodeModulesIndex + 1);
|
|
38
|
+
const lastNodeModulesPath = nodeModulesParts.join(node_path_1.sep);
|
|
39
|
+
const mobilecliPath = (0, node_path_1.join)(lastNodeModulesPath, "@mobilenext", "mobilecli", "bin", binaryName);
|
|
40
|
+
if ((0, node_fs_1.existsSync)(mobilecliPath)) {
|
|
41
|
+
return mobilecliPath;
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
// Not in node_modules, look one directory up from current script
|
|
45
|
+
const scriptDir = (0, node_path_1.dirname)(__filename);
|
|
46
|
+
const parentDir = (0, node_path_1.dirname)(scriptDir);
|
|
47
|
+
const mobilecliPath = (0, node_path_1.join)(parentDir, "node_modules", "@mobilenext", "mobilecli", "bin", binaryName);
|
|
48
|
+
if ((0, node_fs_1.existsSync)(mobilecliPath)) {
|
|
49
|
+
return mobilecliPath;
|
|
50
|
+
}
|
|
51
|
+
throw new Error(`Could not find mobilecli binary for platform: ${platform}`);
|
|
52
|
+
};
|
|
53
|
+
exports.getMobilecliPath = getMobilecliPath;
|
package/lib/server.js
CHANGED
|
@@ -9,6 +9,7 @@ const zod_1 = require("zod");
|
|
|
9
9
|
const node_fs_1 = __importDefault(require("node:fs"));
|
|
10
10
|
const node_os_1 = __importDefault(require("node:os"));
|
|
11
11
|
const node_crypto_1 = __importDefault(require("node:crypto"));
|
|
12
|
+
const node_child_process_1 = require("node:child_process");
|
|
12
13
|
const logger_1 = require("./logger");
|
|
13
14
|
const android_1 = require("./android");
|
|
14
15
|
const robot_1 = require("./robot");
|
|
@@ -16,28 +17,12 @@ const iphone_simulator_1 = require("./iphone-simulator");
|
|
|
16
17
|
const ios_1 = require("./ios");
|
|
17
18
|
const png_1 = require("./png");
|
|
18
19
|
const image_utils_1 = require("./image-utils");
|
|
20
|
+
const mobilecli_1 = require("./mobilecli");
|
|
19
21
|
const getAgentVersion = () => {
|
|
20
22
|
const json = require("../package.json");
|
|
21
23
|
return json.version;
|
|
22
24
|
};
|
|
23
25
|
exports.getAgentVersion = getAgentVersion;
|
|
24
|
-
const getLatestAgentVersion = async () => {
|
|
25
|
-
const response = await fetch("https://api.github.com/repos/mobile-next/mobile-mcp/tags?per_page=1");
|
|
26
|
-
const json = await response.json();
|
|
27
|
-
return json[0].name;
|
|
28
|
-
};
|
|
29
|
-
const checkForLatestAgentVersion = async () => {
|
|
30
|
-
try {
|
|
31
|
-
const latestVersion = await getLatestAgentVersion();
|
|
32
|
-
const currentVersion = (0, exports.getAgentVersion)();
|
|
33
|
-
if (latestVersion !== currentVersion) {
|
|
34
|
-
(0, logger_1.trace)(`You are running an older version of the agent. Please update to the latest version: ${latestVersion}.`);
|
|
35
|
-
}
|
|
36
|
-
}
|
|
37
|
-
catch (error) {
|
|
38
|
-
// ignore
|
|
39
|
-
}
|
|
40
|
-
};
|
|
41
26
|
const createMcpServer = () => {
|
|
42
27
|
const server = new mcp_js_1.McpServer({
|
|
43
28
|
name: "mobile-mcp",
|
|
@@ -49,6 +34,8 @@ const createMcpServer = () => {
|
|
|
49
34
|
});
|
|
50
35
|
// an empty object to satisfy windsurf
|
|
51
36
|
const noParams = zod_1.z.object({});
|
|
37
|
+
// will be replaced later by 'initialize' jsonrpc request
|
|
38
|
+
let clientName = "unknown";
|
|
52
39
|
const tool = (name, description, paramsSchema, cb) => {
|
|
53
40
|
const wrappedCb = async (args) => {
|
|
54
41
|
try {
|
|
@@ -89,6 +76,7 @@ const createMcpServer = () => {
|
|
|
89
76
|
Product: "mobile-mcp",
|
|
90
77
|
Version: (0, exports.getAgentVersion)(),
|
|
91
78
|
NodeVersion: process.version,
|
|
79
|
+
AgentName: clientName,
|
|
92
80
|
};
|
|
93
81
|
await fetch(url, {
|
|
94
82
|
method: "POST",
|
|
@@ -110,6 +98,19 @@ const createMcpServer = () => {
|
|
|
110
98
|
// ignore
|
|
111
99
|
}
|
|
112
100
|
};
|
|
101
|
+
const reportMobilecliVersion = async () => {
|
|
102
|
+
try {
|
|
103
|
+
const path = (0, mobilecli_1.getMobilecliPath)();
|
|
104
|
+
const output = (0, node_child_process_1.execFileSync)(path, ["--version"], { encoding: "utf8" }).toString().trim();
|
|
105
|
+
const version = output.startsWith("mobilecli version ")
|
|
106
|
+
? output.split(" ").pop()
|
|
107
|
+
: output;
|
|
108
|
+
await posthog("mobilecli_check", { MobilecliVersion: version || output });
|
|
109
|
+
}
|
|
110
|
+
catch (error) {
|
|
111
|
+
await posthog("mobilecli_check", { MobilecliVersion: "failed" });
|
|
112
|
+
}
|
|
113
|
+
};
|
|
113
114
|
posthog("launch", {}).then();
|
|
114
115
|
const simulatorManager = new iphone_simulator_1.SimctlManager();
|
|
115
116
|
const getRobotFromDevice = (device) => {
|
|
@@ -348,8 +349,21 @@ const createMcpServer = () => {
|
|
|
348
349
|
const orientation = await robot.getOrientation();
|
|
349
350
|
return `Current device orientation is ${orientation}`;
|
|
350
351
|
});
|
|
351
|
-
// async
|
|
352
|
-
|
|
352
|
+
// async report mobilecli version
|
|
353
|
+
reportMobilecliVersion().then();
|
|
354
|
+
const hook = server.connect;
|
|
355
|
+
server.connect = (transport) => {
|
|
356
|
+
transport.onmessage = (message) => {
|
|
357
|
+
if ("method" in message) {
|
|
358
|
+
const request = message;
|
|
359
|
+
if (request.method === "initialize") {
|
|
360
|
+
const initialize = request;
|
|
361
|
+
clientName = initialize.params.clientInfo.name || "unknown";
|
|
362
|
+
}
|
|
363
|
+
}
|
|
364
|
+
};
|
|
365
|
+
return hook.apply(server, [transport]);
|
|
366
|
+
};
|
|
353
367
|
return server;
|
|
354
368
|
};
|
|
355
369
|
exports.createMcpServer = createMcpServer;
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@mobilenext/mobile-mcp",
|
|
3
3
|
"mcpName": "io.github.mobile-next/mobile-mcp",
|
|
4
|
-
"version": "0.0.
|
|
4
|
+
"version": "0.0.30-beta",
|
|
5
5
|
"description": "Mobile MCP",
|
|
6
6
|
"repository": {
|
|
7
7
|
"type": "git",
|
|
@@ -28,7 +28,8 @@
|
|
|
28
28
|
"commander": "14.0.0",
|
|
29
29
|
"express": "5.1.0",
|
|
30
30
|
"fast-xml-parser": "5.2.5",
|
|
31
|
-
"zod-to-json-schema": "3.24.6"
|
|
31
|
+
"zod-to-json-schema": "3.24.6",
|
|
32
|
+
"@mobilenext/mobilecli": "0.0.25"
|
|
32
33
|
},
|
|
33
34
|
"devDependencies": {
|
|
34
35
|
"@eslint/eslintrc": "^3.2.0",
|