@mobilenext/mobile-mcp 0.0.61 → 0.0.62

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 CHANGED
@@ -3,6 +3,8 @@
3
3
  This is a [Model Context Protocol (MCP) server](https://github.com/modelcontextprotocol) that enables scalable mobile automation, development through a platform-agnostic interface, eliminating the need for distinct iOS or Android knowledge. You can run it on emulators, simulators, and real devices (iOS and Android).
4
4
  This server allows Agents and LLMs to interact with native iOS/Android applications and devices through structured accessibility snapshots or coordinate-based taps based on screenshots.
5
5
 
6
+ **Works with Claude Code, Codex, Gemini, GitHub Copilot, Antigravity** — or any MCP-compatible client.
7
+
6
8
  <h4 align="center">
7
9
  <a href="https://github.com/mobile-next/mobile-mcp">
8
10
  <img src="https://img.shields.io/github/stars/mobile-next/mobile-mcp" alt="Mobile Next Stars" />
@@ -19,7 +21,7 @@ This server allows Agents and LLMs to interact with native iOS/Android applicati
19
21
  <a href="https://github.com/mobile-next/mobile-mcp/wiki">
20
22
  <img src="https://img.shields.io/badge/documentation-wiki-blue" alt="wiki" />
21
23
  </a>
22
- <a href="https://mobilenexthq.com/join-slack">
24
+ <a href="https://mobilenext.ai/join-slack">
23
25
  <img src="https://img.shields.io/badge/join-Slack-blueviolet?logo=slack&style=flat" alt="join on Slack" />
24
26
  </a>
25
27
  </h4>
@@ -34,14 +36,6 @@ https://github.com/user-attachments/assets/bb084777-beb3-4930-ae6f-8d3fe694ddde
34
36
  </a>
35
37
  </p>
36
38
 
37
- ### 🚀 Mobile MCP Roadmap: Building the Future of Mobile
38
-
39
- Join us on our journey as we continuously enhance Mobile MCP!
40
- Check out our detailed roadmap to see upcoming features, improvements, and milestones. Your feedback is invaluable in shaping the future of mobile automation.
41
-
42
- 👉 [Explore the Roadmap](https://github.com/orgs/mobile-next/projects/3)
43
-
44
-
45
39
  ### Main use cases
46
40
 
47
41
  How we help to scale mobile automation:
@@ -54,28 +48,23 @@ How we help to scale mobile automation:
54
48
 
55
49
  ## Main Features
56
50
 
57
- - 🚀 **Fast and lightweight**: Uses native accessibility trees for most interactions, or screenshot based coordinates where a11y labels are not available.
58
- - 🤖 **LLM-friendly**: No computer vision model required in Accessibility (Snapshot).
59
- - 🧿 **Visual Sense**: Evaluates and analyses what's actually rendered on screen to decide the next action. If accessibility data or view-hierarchy coordinates are unavailable, it falls back to screenshot-based analysis.
60
- - 📊 **Deterministic tool application**: Reduces ambiguity found in purely screenshot-based approaches by relying on structured data whenever possible.
61
- - 📺 **Extract structured data**: Enables you to extract structred data from anything visible on screen.
51
+ - 🚀 **Accessibility-first — fast and cheap**: drives apps from the native accessibility tree (no vision model, no image tokens), falling back to screenshots + coordinates only when needed.
52
+ - 📱 **One API, every target**: the same tools work across iOS and Android — simulators, emulators, and real devices.
53
+ - 🧠 **No platform expertise required**: no XCUITest, no Espresso, no per-platform glue describe the goal and the agent does it.
54
+ - 🧰 **Full device control**: taps, swipes, and gestures; app install/launch/terminate; screen recording; hardware buttons; deep links; orientation.
55
+ - 📊 **Structured, deterministic output**: reads real UI elements and extracts structured data, cutting the ambiguity of screenshot-only approaches.
62
56
 
63
57
  ### 🎯 Platform Support
64
58
 
65
- | Platform | Supported |
66
- |----------|:---------:|
67
- | iOS Real Device | ✅ |
68
- | iOS Simulator | ✅ |
69
- | Android Real Device | ✅ |
70
- | Android Emulator | ✅ |
59
+ | Target | Supported | Setup |
60
+ |---|:---:|---|
61
+ | iOS Simulator | ✅ | Xcode + a booted simulator (`xcrun simctl`) |
62
+ | iOS Real Device | ✅ | go-ios + WebDriverAgent + tunnel |
63
+ | Android Emulator | ✅ | Android SDK + running emulator (`adb`) |
64
+ | Android Real Device | ✅ | `adb` + USB debugging enabled & authorized |
71
65
 
72
66
  ## 🔧 Available MCP Tools
73
67
 
74
- <details>
75
- <summary>📱 <strong>Click to expand tool list</strong> - List of Mobile MCP tools for automation and development</summary>
76
-
77
- > For detailed implementation and parameter specifications, see [`src/server.ts`](src/server.ts)
78
-
79
68
  ### Device Management
80
69
  - **`mobile_list_available_devices`** - List all available devices (simulators, emulators, and real devices)
81
70
  - **`mobile_get_screen_size`** - Get the screen size of the mobile device in pixels
@@ -97,18 +86,17 @@ How we help to scale mobile automation:
97
86
  - **`mobile_double_tap_on_screen`** - Double-tap at specific coordinates
98
87
  - **`mobile_long_press_on_screen_at_coordinates`** - Long press at specific coordinates
99
88
  - **`mobile_swipe_on_screen`** - Swipe in any direction (up, down, left, right)
89
+ - **`mobile_start_screen_recording`** - Start recording the device screen to a video file
90
+ - **`mobile_stop_screen_recording`** - Stop the active screen recording and save the video
100
91
 
101
92
  ### Input & Navigation
102
93
  - **`mobile_type_keys`** - Type text into focused elements with optional submit
103
94
  - **`mobile_press_button`** - Press device buttons (HOME, BACK, VOLUME_UP/DOWN, ENTER, etc.)
104
95
  - **`mobile_open_url`** - Open URLs in the device browser
105
96
 
106
- ### Platform Support
107
- - **iOS**: Simulators and real devices via native accessibility and WebDriverAgent
108
- - **Android**: Emulators and real devices via ADB and UI Automator
109
- - **Cross-platform**: Unified API works across both iOS and Android
110
-
111
- </details>
97
+ ### Crash Reports
98
+ - **`mobile_list_crashes`** - List crash reports available on the device
99
+ - **`mobile_get_crash`** - Get the full content of a crash report by its ID
112
100
 
113
101
  ## 🏗️ Mobile MCP Architecture
114
102
 
@@ -124,6 +112,18 @@ How we help to scale mobile automation:
124
112
  More details in our [wiki page](https://github.com/mobile-next/mobile-mcp/wiki) for setup, configuration and debugging related questions.
125
113
 
126
114
 
115
+ ## Prerequisites
116
+
117
+ What you will need to connect MCP with your agent and mobile devices:
118
+
119
+ - [Xcode command line tools](https://developer.apple.com/xcode/resources/)
120
+ - [Android Platform Tools](https://developer.android.com/tools/releases/platform-tools)
121
+ - [node.js](https://nodejs.org/en/download/) v20+
122
+ - [MCP](https://modelcontextprotocol.io/introduction) supported foundational models or agents, like [Claude MCP](https://modelcontextprotocol.io/quickstart/server), [OpenAI Agent SDK](https://openai.github.io/openai-agents-python/mcp/), [Copilot Studio](https://www.microsoft.com/en-us/microsoft-copilot/blog/copilot-studio/introducing-model-context-protocol-mcp-in-copilot-studio-simplified-integration-with-ai-apps-and-agents/)
123
+
124
+ For iOS **real devices** (simulators and Android don't need these), you'll also need [go-ios](https://github.com/danielpaulus/go-ios), [WebDriverAgent](https://github.com/appium/WebDriverAgent) installed on the device, and an iOS device tunnel. See the [wiki](https://github.com/mobile-next/mobile-mcp/wiki) for setup.
125
+
126
+
127
127
  ## Installation and configuration
128
128
 
129
129
  **Standard config** works in most of the tools:
@@ -165,6 +165,24 @@ amp mcp add mobile-mcp -- npx @mobilenext/mobile-mcp@latest
165
165
 
166
166
  </details>
167
167
 
168
+ <details>
169
+ <summary>Antigravity 2</summary>
170
+
171
+ Antigravity doesn't have a CLI command to add MCP servers, so add it manually. Edit `~/.gemini/config/mcp_config.json` and add:
172
+
173
+ ```json
174
+ {
175
+ "mcpServers": {
176
+ "mobile-mcp": {
177
+ "command": "npx",
178
+ "args": ["-y", "@mobilenext/mobile-mcp@latest"]
179
+ }
180
+ }
181
+ }
182
+ ```
183
+
184
+ </details>
185
+
168
186
  <details>
169
187
  <summary>Cline</summary>
170
188
 
@@ -324,16 +342,6 @@ Follow the MCP Servers documentation. For example in `~/.config/opencode/opencod
324
342
 
325
343
  </details>
326
344
 
327
- <details>
328
- <summary>Qodo Gen</summary>
329
-
330
- Open [Qodo Gen](https://docs.qodo.ai/qodo-documentation/qodo-gen) chat panel in VSCode or IntelliJ → Connect more tools → + Add new MCP → Paste the standard config above.
331
-
332
- Click <code>Save</code>.
333
-
334
- </details>
335
-
336
-
337
345
  <details>
338
346
  <summary>Windsurf</summary>
339
347
 
@@ -350,6 +358,14 @@ Or add the standard config under `mcpServers` in your settings as shown above.
350
358
 
351
359
  [Read more in our wiki](https://github.com/mobile-next/mobile-mcp/wiki)! 🚀
352
360
 
361
+ ### ✅ Verify it works
362
+
363
+ Once the server is configured, ask your agent to list devices:
364
+
365
+ > list available devices
366
+
367
+ You should get back your running simulators, emulators, and connected devices. If you do, Mobile MCP is wired up correctly. If the list is empty, make sure a simulator or emulator is running (see [Prerequisites](#prerequisites)) — for more help, check the [wiki](https://github.com/mobile-next/mobile-mcp/wiki).
368
+
353
369
  ### SSE Server Mode
354
370
 
355
371
  By default, Mobile MCP runs over stdio. To start an SSE server instead, use the `--listen` flag:
@@ -379,14 +395,14 @@ When set, all requests must include the header `Authorization: Bearer my-secret-
379
395
  ### 🛠️ How to Use 📝
380
396
 
381
397
  After adding the MCP server to your IDE/Client, you can instruct your AI assistant to use the available tools.
382
- For example, in Cursor's agent mode, you could use the prompts below to quickly validate, test and iterate on UI intereactions, read information from screen, go through complex workflows.
398
+ For example, in Cursor's agent mode, you could use the prompts below to quickly validate, test and iterate on UI interactions, read information from screen, go through complex workflows.
383
399
  Be descriptive, straight to the point.
384
400
 
385
401
  ### ✨ Example Prompts
386
402
 
387
403
  #### Workflows
388
404
 
389
- You can specifiy detailed workflows in a single prompt, verify business logic, setup automations. You can go crazy:
405
+ You can specify detailed workflows in a single prompt, verify business logic, setup automations. You can go crazy:
390
406
 
391
407
  **Search for a video, comment, like and share it.**
392
408
  ```
@@ -442,14 +458,15 @@ Gmail to contacts "team@example.com".
442
458
  ```
443
459
  [More prompt examples can be found here.](https://github.com/mobile-next/mobile-mcp/wiki/Prompt-Example-repo-list)
444
460
 
445
- ## Prerequisites
461
+ ## Running & configuration
446
462
 
447
- What you will need to connect MCP with your agent and mobile devices:
463
+ ### Environment variables
448
464
 
449
- - [Xcode command line tools](https://developer.apple.com/xcode/resources/)
450
- - [Android Platform Tools](https://developer.android.com/tools/releases/platform-tools)
451
- - [node.js](https://nodejs.org/en/download/) v22+
452
- - [MCP](https://modelcontextprotocol.io/introduction) supported foundational models or agents, like [Claude MCP](https://modelcontextprotocol.io/quickstart/server), [OpenAI Agent SDK](https://openai.github.io/openai-agents-python/mcp/), [Copilot Studio](https://www.microsoft.com/en-us/microsoft-copilot/blog/copilot-studio/introducing-model-context-protocol-mcp-in-copilot-studio-simplified-integration-with-ai-apps-and-agents/)
465
+ | Variable | Description | Example |
466
+ |---|---|---|
467
+ | `MOBILEMCP_AUTH` | Require a Bearer token on the SSE server — every request must then send `Authorization: Bearer <token>`. | `MOBILEMCP_AUTH=my-secret-token` |
468
+ | `MOBILEMCP_DISABLE_TELEMETRY` | Disable anonymous usage telemetry. | `MOBILEMCP_DISABLE_TELEMETRY=1` |
469
+ | `MOBILEMCP_ALLOW_UNSAFE_URLS` | Allow `mobile_open_url` to open non-standard URL schemes (blocked by default). | `MOBILEMCP_ALLOW_UNSAFE_URLS=1` |
453
470
 
454
471
  ### Simulators, Emulators, and Real Devices
455
472
 
@@ -496,6 +513,29 @@ On iOS, you'll need Xcode and to run the Simulator before using Mobile MCP with
496
513
  - `xcrun simctl list`
497
514
  - `xcrun simctl boot "iPhone 16"`
498
515
 
516
+ ## 🧩 Part of Mobile Next
517
+
518
+ Mobile MCP is one piece of a toolkit for driving real mobile devices:
519
+
520
+ - **[mobilewright](https://github.com/mobile-next/mobilewright)** — "Playwright for mobile." When you're ready to turn agent-driven exploration into **repeatable, deterministic tests** for iOS and Android, graduate to mobilewright.
521
+ - **[mobilecli](https://github.com/mobile-next/mobilecli)** — the universal device CLI that Mobile MCP is built on: control devices, simulators, and emulators from the command line or a JSON-RPC API.
522
+ - **[Mobile Next Cloud](https://mobilenext.ai)** — run all of it against real iOS and Android devices in the cloud, on demand.
523
+
524
+ ## 🚀 Roadmap
525
+
526
+ We're continuously improving Mobile MCP. See what we're building next in [ROADMAP.md](ROADMAP.md) — priorities are shaped heavily by community feedback, so tell us what you'd like to see.
527
+
528
+ ## 🤝 Contributing
529
+
530
+ Contributions are welcome — code, docs, bug reports, and ideas.
531
+
532
+ - ⭐ **[Star the repo](https://github.com/mobile-next/mobile-mcp)** — the easiest way to help others discover Mobile MCP.
533
+ - Read [CONTRIBUTING.md](CONTRIBUTING.md) for how to build, test, and open a pull request.
534
+ - Browse [open issues](https://github.com/mobile-next/mobile-mcp/issues) to find something to work on.
535
+ - Questions and ideas are also welcome in our [Slack community](https://mobilenext.ai/join-slack).
536
+
537
+ Please also review our [Code of Conduct](CODE_OF_CONDUCT.md).
538
+
499
539
  # Thanks to all contributors ❤️
500
540
 
501
541
  ### We appreciate everyone who has helped improve this project.
package/lib/android.js CHANGED
@@ -111,7 +111,11 @@ class AndroidRobot {
111
111
  if (!screenSize) {
112
112
  throw new Error("Failed to get screen size");
113
113
  }
114
- const scale = 1;
114
+ const screenDensity = this.adb("shell", "wm", "density")
115
+ .toString()
116
+ .split(" ")
117
+ .pop();
118
+ const scale = screenDensity ? +screenDensity / 160 : 1;
115
119
  const [width, height] = screenSize.split("x").map(Number);
116
120
  return { width, height, scale };
117
121
  }
package/lib/server.js CHANGED
@@ -51,10 +51,11 @@ const createMcpServer = () => {
51
51
  try {
52
52
  (0, logger_1.trace)(`Invoking ${name} with args: ${JSON.stringify(args)}`);
53
53
  const start = +new Date();
54
- const response = await cb(args);
54
+ const telemetry = {};
55
+ const response = await cb(args, telemetry);
55
56
  const duration = +new Date() - start;
56
57
  (0, logger_1.trace)(`=> ${response}`);
57
- posthog("tool_invoked", { "ToolName": name, "Duration": duration }).then();
58
+ posthog("tool_invoked", { "ToolName": name, "Duration": duration, ...telemetry }).then();
58
59
  return {
59
60
  content: [{ type: "text", text: response }],
60
61
  };
@@ -174,7 +175,7 @@ const createMcpServer = () => {
174
175
  }
175
176
  throw new robot_1.ActionableError(`Device "${deviceId}" not found. Use the mobile_list_available_devices tool to see available devices.`);
176
177
  };
177
- tool("mobile_list_available_devices", "List Devices", "List all available devices. This includes both physical mobile devices and mobile simulators and emulators. It returns both Android and iOS devices.", {}, { readOnlyHint: true }, async ({}) => {
178
+ tool("mobile_list_available_devices", "List Devices", "List all available devices. This includes both physical mobile devices and mobile simulators and emulators. It returns both Android and iOS devices.", {}, { readOnlyHint: true }, async ({}, telemetry) => {
178
179
  // from today onward, we must have mobilecli working
179
180
  ensureMobilecliAvailable();
180
181
  const iosManager = new ios_1.IosManager();
@@ -182,6 +183,7 @@ const createMcpServer = () => {
182
183
  const devices = [];
183
184
  // Get Android devices with details
184
185
  const androidDevices = androidManager.getConnectedDevicesWithDetails();
186
+ telemetry.AndroidCount = androidDevices.length;
185
187
  for (const device of androidDevices) {
186
188
  devices.push({
187
189
  id: device.deviceId,
@@ -193,8 +195,10 @@ const createMcpServer = () => {
193
195
  });
194
196
  }
195
197
  // Get iOS physical devices with details
198
+ telemetry.IosRealCount = 0;
196
199
  try {
197
200
  const iosDevices = iosManager.listDevicesWithDetails();
201
+ telemetry.IosRealCount = iosDevices.length;
198
202
  for (const device of iosDevices) {
199
203
  devices.push({
200
204
  id: device.deviceId,
@@ -209,14 +213,21 @@ const createMcpServer = () => {
209
213
  catch (error) {
210
214
  // If go-ios is not available, silently skip
211
215
  }
212
- // Get iOS simulators from mobilecli (excluding offline devices)
216
+ // Get iOS simulators from mobilecli, including offline ones so we can
217
+ // report how many are installed vs booted. only booted ones are returned.
213
218
  const response = mobilecli.getDevices({
214
219
  platform: "ios",
215
220
  type: "simulator",
216
- includeOffline: false,
221
+ includeOffline: true,
217
222
  });
223
+ telemetry.IosSimInstalledCount = 0;
224
+ telemetry.IosSimCount = 0;
218
225
  if (response.status === "ok" && response.data && response.data.devices) {
219
- for (const device of response.data.devices) {
226
+ const simulators = response.data.devices;
227
+ const booted = simulators.filter(device => device.state === "online");
228
+ telemetry.IosSimInstalledCount = simulators.length;
229
+ telemetry.IosSimCount = booted.length;
230
+ for (const device of booted) {
220
231
  devices.push({
221
232
  id: device.id,
222
233
  name: device.name,
package/lib/utils.js CHANGED
@@ -12,7 +12,10 @@ const node_os_1 = __importDefault(require("node:os"));
12
12
  const node_fs_1 = __importDefault(require("node:fs"));
13
13
  const robot_1 = require("./robot");
14
14
  function validatePackageName(packageName) {
15
- if (!/^[a-zA-Z0-9._]+$/.test(packageName)) {
15
+ // iOS bundle identifiers (which flow through this same "packageName" parameter
16
+ // for launch/terminate) are allowed to contain hyphens per Apple's CFBundleIdentifier
17
+ // format, e.g. "com.some-company.app".
18
+ if (!/^[a-zA-Z0-9._-]+$/.test(packageName)) {
16
19
  throw new robot_1.ActionableError(`Invalid package name: "${packageName}"`);
17
20
  }
18
21
  }
@@ -21,6 +24,15 @@ function validateLocale(locale) {
21
24
  throw new robot_1.ActionableError(`Invalid locale: "${locale}"`);
22
25
  }
23
26
  }
27
+ function resolveRoot(root) {
28
+ const resolved = node_path_1.default.resolve(root);
29
+ try {
30
+ return node_fs_1.default.realpathSync(resolved);
31
+ }
32
+ catch {
33
+ return resolved;
34
+ }
35
+ }
24
36
  function getAllowedRoots() {
25
37
  const roots = [
26
38
  node_os_1.default.tmpdir(),
@@ -31,7 +43,10 @@ function getAllowedRoots() {
31
43
  roots.push("/tmp");
32
44
  roots.push("/private/tmp");
33
45
  }
34
- return roots.map(r => node_path_1.default.resolve(r));
46
+ // Resolve symlinks so roots line up with resolveWithSymlinks() below. On macOS,
47
+ // os.tmpdir() itself lives under /var/folders/..., and /var is a symlink to
48
+ // /private/var, so without this the real temp directory never matches here.
49
+ return roots.map(resolveRoot);
35
50
  }
36
51
  function isPathUnderRoot(filePath, root) {
37
52
  const relative = node_path_1.default.relative(root, filePath);
package/package.json CHANGED
@@ -1,14 +1,14 @@
1
1
  {
2
2
  "name": "@mobilenext/mobile-mcp",
3
3
  "mcpName": "io.github.mobile-next/mobile-mcp",
4
- "version": "0.0.61",
4
+ "version": "0.0.62",
5
5
  "description": "Mobile MCP",
6
6
  "repository": {
7
7
  "type": "git",
8
8
  "url": "git+https://github.com/mobile-next/mobile-mcp.git"
9
9
  },
10
10
  "engines": {
11
- "node": ">=18"
11
+ "node": ">=20"
12
12
  },
13
13
  "license": "Apache-2.0",
14
14
  "scripts": {
@@ -29,10 +29,10 @@
29
29
  "commander": "14.0.0",
30
30
  "express": "5.1.0",
31
31
  "fast-xml-parser": "5.8.0",
32
+ "mobilewright": "0.0.48",
32
33
  "qs": "^6.15.0",
33
34
  "zod": "^4.1.13",
34
- "zod-to-json-schema": "3.25.0",
35
- "mobilewright": "0.0.45"
35
+ "zod-to-json-schema": "3.25.0"
36
36
  },
37
37
  "devDependencies": {
38
38
  "@eslint/eslintrc": "^3.2.0",