@mobilenext/mobile-mcp 0.0.8 → 0.0.9
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/README.md +9 -10
- package/lib/index.js +2 -1
- package/lib/server.js +11 -11
- package/package.json +5 -3
package/README.md
CHANGED
|
@@ -73,29 +73,28 @@ What you will need to connect MCP with your agent and mobile devices:
|
|
|
73
73
|
### Simulators, Emulators, and Physical Devices
|
|
74
74
|
|
|
75
75
|
When launched, Mobile MCP can connect to:
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
76
|
+
- iOS Simulators on macOS/Linux
|
|
77
|
+
- Android Emulators on Linux/Windows/macOS
|
|
78
|
+
- Physical iOS or Android devices (requires proper platform tools and drivers)
|
|
79
79
|
|
|
80
80
|
Make sure you have your mobile platform SDKs (Xcode, Android SDK) installed and configured properly before running Mobile Next Mobile MCP.
|
|
81
81
|
|
|
82
|
-
|
|
83
82
|
### Running in "headless" mode on Simulators/Emulators
|
|
84
83
|
|
|
85
|
-
When you do not have
|
|
84
|
+
When you do not have a physical phone connected to your machine, you can run Mobile MCP with an emulator or simulator in the background.
|
|
86
85
|
|
|
87
86
|
For example, on Android:
|
|
88
|
-
|
|
89
|
-
|
|
87
|
+
1. Start an emulator (avdmanager / emulator command).
|
|
88
|
+
2. Run Mobile MCP with the desired flags
|
|
90
89
|
|
|
91
90
|
On iOS, you'll need Xcode and to run the Simulator before using Mobile MCP with that simulator instance.
|
|
92
|
-
`xcrun simctl list`
|
|
93
|
-
`xcrun simctl boot "iPhone 16"`
|
|
91
|
+
- `xcrun simctl list`
|
|
92
|
+
- `xcrun simctl boot "iPhone 16"`
|
|
94
93
|
|
|
95
94
|
|
|
96
95
|
# Mobile Commands and interaction tools
|
|
97
96
|
|
|
98
|
-
|
|
97
|
+
The commands and tools support both accessibility-based locators (preferred) and coordinate-based inputs, giving you flexibility when accessibility/automation IDs are missing for reliable and seemless automation.
|
|
99
98
|
|
|
100
99
|
## mobile_install_app
|
|
101
100
|
- **Description:** Installs an app onto the device/emulator
|
package/lib/index.js
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
1
2
|
"use strict";
|
|
2
3
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
4
|
const stdio_js_1 = require("@modelcontextprotocol/sdk/server/stdio.js");
|
|
@@ -7,7 +8,7 @@ async function main() {
|
|
|
7
8
|
const transport = new stdio_js_1.StdioServerTransport();
|
|
8
9
|
const server = (0, server_1.createMcpServer)();
|
|
9
10
|
await server.connect(transport);
|
|
10
|
-
(0, logger_1.error)("
|
|
11
|
+
(0, logger_1.error)("mobile-mcp server running on stdio");
|
|
11
12
|
}
|
|
12
13
|
main().catch(err => {
|
|
13
14
|
console.error("Fatal error in main():", err);
|
package/lib/server.js
CHANGED
|
@@ -16,7 +16,7 @@ const getAgentVersion = () => {
|
|
|
16
16
|
};
|
|
17
17
|
const createMcpServer = () => {
|
|
18
18
|
const server = new mcp_js_1.McpServer({
|
|
19
|
-
name: "
|
|
19
|
+
name: "mobile-mcp",
|
|
20
20
|
version: getAgentVersion(),
|
|
21
21
|
capabilities: {
|
|
22
22
|
resources: {},
|
|
@@ -43,7 +43,7 @@ const createMcpServer = () => {
|
|
|
43
43
|
};
|
|
44
44
|
server.tool(name, description, paramsSchema, args => wrappedCb(args));
|
|
45
45
|
};
|
|
46
|
-
tool("
|
|
46
|
+
tool("list_apps_on_device", "List all apps on device", {}, async ({}) => {
|
|
47
47
|
/*
|
|
48
48
|
const result = execSync(`adb shell pm list packages`)
|
|
49
49
|
.toString()
|
|
@@ -54,17 +54,17 @@ const createMcpServer = () => {
|
|
|
54
54
|
const result = (0, android_1.listApps)();
|
|
55
55
|
return `Found these packages on device: ${result.join(",")}`;
|
|
56
56
|
});
|
|
57
|
-
tool("
|
|
57
|
+
tool("launch_app", "Launch an app on mobile device", {
|
|
58
58
|
packageName: zod_1.z.string().describe("The package name of the app to launch"),
|
|
59
59
|
}, async ({ packageName }) => {
|
|
60
60
|
(0, child_process_1.execSync)(`adb shell monkey -p "${packageName}" -c android.intent.category.LAUNCHER 1`);
|
|
61
61
|
return `Launched app ${packageName}`;
|
|
62
62
|
});
|
|
63
|
-
tool("
|
|
63
|
+
tool("get_screen_size", "Get the screen size of the mobile device in pixels", {}, async ({}) => {
|
|
64
64
|
const screenSize = (0, android_1.getScreenSize)();
|
|
65
65
|
return `Screen size is ${screenSize[0]}x${screenSize[1]} pixels`;
|
|
66
66
|
});
|
|
67
|
-
tool("
|
|
67
|
+
tool("click_on_screen_at_coordinates", "Click on the screen at given x,y coordinates", {
|
|
68
68
|
x: zod_1.z.number().describe("The x coordinate to click between 0 and 1"),
|
|
69
69
|
y: zod_1.z.number().describe("The y coordinate to click between 0 and 1"),
|
|
70
70
|
}, async ({ x, y }) => {
|
|
@@ -74,36 +74,36 @@ const createMcpServer = () => {
|
|
|
74
74
|
(0, child_process_1.execSync)(`adb shell input tap ${x0} ${y0}`);
|
|
75
75
|
return `Clicked on screen at coordinates: ${x}, ${y}`;
|
|
76
76
|
});
|
|
77
|
-
tool("
|
|
77
|
+
tool("list_elements_on_screen", "List elements on screen and their coordinates, based on text or accessibility label", {}, async ({}) => {
|
|
78
78
|
const elements = (0, android_1.getElementsOnScreen)();
|
|
79
79
|
return `Found these elements on screen: ${JSON.stringify(elements)}`;
|
|
80
80
|
});
|
|
81
|
-
tool("
|
|
81
|
+
tool("press_button", "Press a button on device", {
|
|
82
82
|
button: zod_1.z.string().describe("The button to press. Supported buttons: KEYCODE_BACK, KEYCODE_HOME, KEYCODE_MENU, KEYCODE_VOLUME_UP, KEYCODE_VOLUME_DOWN, KEYCODE_ENTER"),
|
|
83
83
|
}, async ({ button }) => {
|
|
84
84
|
(0, child_process_1.execSync)(`adb shell input keyevent ${button}`);
|
|
85
85
|
return `Pressed the button: ${button}`;
|
|
86
86
|
});
|
|
87
|
-
tool("
|
|
87
|
+
tool("open_url", "Open a URL in browser on device", {
|
|
88
88
|
url: zod_1.z.string().describe("The URL to open"),
|
|
89
89
|
}, async ({ url }) => {
|
|
90
90
|
(0, child_process_1.execSync)(`adb shell am start -a android.intent.action.VIEW -d "${url}"`);
|
|
91
91
|
return `Opened URL: ${url}`;
|
|
92
92
|
});
|
|
93
|
-
tool("
|
|
93
|
+
tool("swipe_on_screen", "Swipe on the screen", {
|
|
94
94
|
direction: zod_1.z.enum(["up", "down"]).describe("The direction to swipe"),
|
|
95
95
|
}, async ({ direction }) => {
|
|
96
96
|
(0, android_1.swipe)(direction);
|
|
97
97
|
return `Swiped ${direction} on screen`;
|
|
98
98
|
});
|
|
99
|
-
tool("
|
|
99
|
+
tool("type_text", "Type text into the focused element", {
|
|
100
100
|
text: zod_1.z.string().describe("The text to type"),
|
|
101
101
|
}, async ({ text }) => {
|
|
102
102
|
const _text = text.replace(/ /g, "\\ ");
|
|
103
103
|
(0, child_process_1.execSync)(`adb shell input text "${_text}"`);
|
|
104
104
|
return `Typed text: ${text}`;
|
|
105
105
|
});
|
|
106
|
-
server.tool("
|
|
106
|
+
server.tool("take_device_screenshot", "Take a screenshot of the mobile device", {}, async ({}) => {
|
|
107
107
|
try {
|
|
108
108
|
const screenshot = await (0, android_1.takeScreenshot)();
|
|
109
109
|
// Scale down the screenshot by 50%
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@mobilenext/mobile-mcp",
|
|
3
|
-
"version": "0.0.
|
|
3
|
+
"version": "0.0.9",
|
|
4
4
|
"description": "Mobile MCP",
|
|
5
5
|
"repository": {
|
|
6
6
|
"type": "git",
|
|
@@ -11,10 +11,9 @@
|
|
|
11
11
|
},
|
|
12
12
|
"license": "Apache-2.0",
|
|
13
13
|
"scripts": {
|
|
14
|
-
"build": "tsc",
|
|
14
|
+
"build": "tsc && chmod +x lib/index.js",
|
|
15
15
|
"lint": "eslint .",
|
|
16
16
|
"watch": "tsc --watch",
|
|
17
|
-
"start": "node lib/index.js",
|
|
18
17
|
"clean": "rm -rf lib"
|
|
19
18
|
},
|
|
20
19
|
"exports": {
|
|
@@ -45,6 +44,9 @@
|
|
|
45
44
|
"typescript": "^5.8.2"
|
|
46
45
|
},
|
|
47
46
|
"main": "index.js",
|
|
47
|
+
"bin": {
|
|
48
|
+
"mcp-server-mobile": "lib/index.js"
|
|
49
|
+
},
|
|
48
50
|
"directories": {
|
|
49
51
|
"lib": "lib"
|
|
50
52
|
},
|