mobile-device-mcp 0.2.1 → 0.2.3

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/LICENSE ADDED
@@ -0,0 +1,83 @@
1
+ Business Source License 1.1
2
+
3
+ Parameters
4
+
5
+ Licensor: Saransh Bamania
6
+ Licensed Work: mobile-device-mcp v0.2.1
7
+ The Licensed Work is (c) 2026 Saransh Bamania.
8
+ Additional Use Grant: You may make production use of the Licensed Work,
9
+ provided your use does not include offering the
10
+ Licensed Work to third parties as a commercial
11
+ product or service, or using it as part of a
12
+ paid device testing or automation platform.
13
+ Individual and non-commercial use is always permitted.
14
+ Change Date: 2030-03-23
15
+ Change License: Apache License, Version 2.0
16
+
17
+ -----------------------------------------------------------------------------
18
+
19
+ Business Source License 1.1
20
+
21
+ License text copyright (c) 2017 MariaDB Corporation Ab, All Rights Reserved.
22
+ "Business Source License" is a trademark of MariaDB Corporation Ab.
23
+
24
+ Terms
25
+
26
+ The Licensor hereby grants you the right to copy, modify, create derivative
27
+ works, redistribute, and make non-production use of the Licensed Work. The
28
+ Licensor may make an Additional Use Grant, above, permitting limited
29
+ production use.
30
+
31
+ Effective on the Change Date, or the fourth anniversary of the first publicly
32
+ available distribution of a specific version of the Licensed Work under this
33
+ License, whichever comes first, the Licensor hereby grants you rights under
34
+ the terms of the Change License, and the rights granted in the paragraph
35
+ above terminate.
36
+
37
+ If your use of the Licensed Work does not comply with the requirements
38
+ currently in effect as described in this License, you must purchase a
39
+ commercial license from the Licensor, its affiliated entities, or authorized
40
+ resellers, or you must refrain from using the Licensed Work.
41
+
42
+ All copies of the original and modified Licensed Work, and derivative works
43
+ of the Licensed Work, are subject to this License. This License applies
44
+ separately for each version of the Licensed Work and the Change Date may vary
45
+ for each version of the Licensed Work released by Licensor.
46
+
47
+ You must conspicuously display this License on each original or modified copy
48
+ of the Licensed Work. If you receive the Licensed Work in original or
49
+ modified form from a third party, the terms and conditions set forth in this
50
+ License apply to your use of that work.
51
+
52
+ Any use of the Licensed Work in violation of this License will automatically
53
+ terminate your rights under this License for the current and all other
54
+ versions of the Licensed Work.
55
+
56
+ This License does not grant you any right in any trademark or logo of
57
+ Licensor or its affiliates (provided that you may use a trademark or logo of
58
+ Licensor as expressly required by this License).
59
+
60
+ TO THE EXTENT PERMITTED BY APPLICABLE LAW, THE LICENSED WORK IS PROVIDED ON
61
+ AN "AS IS" BASIS. LICENSOR HEREBY DISCLAIMS ALL WARRANTIES AND CONDITIONS,
62
+ EXPRESS OR IMPLIED, INCLUDING (WITHOUT LIMITATION) WARRANTIES OF
63
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, NON-INFRINGEMENT, AND
64
+ TITLE.
65
+
66
+ MariaDB hereby grants you permission to use this License's text to license
67
+ your works, and to refer to it using the trademark "Business Source License",
68
+ as long as you comply with the Covenants of Licensor below.
69
+
70
+ Covenants of Licensor
71
+
72
+ In consideration of the right to use this License's text and the "Business
73
+ Source License" name and trademark, Licensor covenants to MariaDB, and to all
74
+ other recipients of the licensed work to be provided under this License:
75
+
76
+ 1. To specify as the Change License the Apache License, Version 2.0, which
77
+ is a license compatible with GPL Version 2.0 or later.
78
+
79
+ 2. To specify as the Additional Use Grant the text set forth above.
80
+
81
+ 3. To specify a Change Date.
82
+
83
+ 4. Not to modify this License in any other way.
package/README.md CHANGED
@@ -1,225 +1,322 @@
1
- # mobile-device-mcp
2
-
3
- MCP server that gives AI coding assistants (Claude Code, Cursor, Windsurf) the ability to **see and interact with mobile devices**. 34 tools for screenshots, UI inspection, touch interaction, AI-powered visual analysis, and Flutter widget tree inspection.
4
-
5
- > AI assistants can read your code but can't see your phone. This fixes that.
6
-
7
- ## The Problem
8
-
9
- Web developers have browser DevTools, Playwright, and Puppeteer — AI assistants can click around, take screenshots, and verify fixes. Mobile developers? They're stuck manually screenshotting, copying logs, and describing what's on screen. They're **human middleware** between the AI and the device.
10
-
11
- ## What This Does
12
-
13
- ```
14
- Developer: "The login button doesn't work"
15
-
16
- Without this tool: With this tool:
17
- 1. Manually screenshot 1. AI calls take_screenshot sees the screen
18
- 2. Paste into AI chat 2. AI calls smart_tap("login button") taps it
19
- 3. AI guesses what's wrong 3. AI calls verify_screen("error message shown") sees result
20
- 4. Apply fix, rebuild 4. AI calls visual_diff confirms fix worked
21
- 5. Repeat 4-5 times 5. Done.
22
- ```
23
-
24
- ## Quick Start
25
-
26
- ### Prerequisites
27
- - Node.js 18+
28
- - Android device/emulator connected via ADB
29
- - ADB installed (Android SDK Platform Tools)
30
-
31
- ### Setup (One-time, 30 seconds)
32
-
33
- 1. **Get a Google AI key** (free tier available): [aistudio.google.com/apikey](https://aistudio.google.com/apikey)
34
-
35
- 2. **Add `.mcp.json` to your project root:**
36
-
37
- ```json
38
- {
39
- "mcpServers": {
40
- "mobile-device": {
41
- "type": "stdio",
42
- "command": "npx",
43
- "args": ["-y", "mobile-device-mcp"],
44
- "env": {
45
- "GOOGLE_API_KEY": "your-google-api-key"
46
- }
47
- }
48
- }
49
- }
50
- ```
51
-
52
- 3. **Open your AI coding assistant** from that directory. That's it.
53
-
54
- The server starts and stops automatically — you never run it manually. Your AI assistant manages it as a background process via the MCP protocol.
55
-
56
- ### Verify It Works
57
-
58
- **Claude Code:** type `/mcp` you should see `mobile-device: Connected`
59
-
60
- **Cursor:** check MCP panel in settings
61
-
62
- Then just talk to your phone:
63
-
64
- ```
65
- You: "Open my app, tap the login button, type test@email.com in the email field"
66
- AI: [takes screenshot → sees the screen → smart_tap("login button") → smart_type("email field", "test@email.com")]
67
-
68
- You: "Find all the bugs on this screen"
69
- AI: [analyze_screen → inspects layout, checks for overflow, missing labels, broken states]
70
-
71
- You: "Navigate to settings and verify dark mode works"
72
- AI: [smart_tap("settings") → take_screenshot → smart_tap("dark mode toggle") → visual_diff → reports result]
73
- ```
74
-
75
- No test scripts. No manual screenshots. Just describe what you want in plain English.
76
-
77
- ### Works with Any AI Coding Assistant
78
-
79
- | Tool | Config file | Docs |
80
- |------|------------|------|
81
- | **Claude Code** | `.mcp.json` in project root | [claude.ai/docs](https://claude.ai/docs) |
82
- | **Cursor** | `.cursor/mcp.json` | [cursor.com/docs](https://cursor.com/docs) |
83
- | **VS Code + Copilot** | MCP settings | [code.visualstudio.com](https://code.visualstudio.com) |
84
- | **Windsurf** | MCP settings | [windsurf.com](https://windsurf.com) |
85
-
86
- All use the same JSON config — just put it in the right file for your editor.
87
-
88
- ### Drop Into Any Project
89
-
90
- Copy `.mcp.json` into any mobile project — Flutter, React Native, Kotlin, Swift — and your AI assistant gets device superpowers in that directory. No global install needed.
91
-
92
- ## Tools (34 total)
93
-
94
- ### Phase 1 Device Control (18 tools)
95
-
96
- | Tool | What it does |
97
- |------|-------------|
98
- | `list_devices` | List all connected Android devices/emulators |
99
- | `get_device_info` | Model, manufacturer, Android version, SDK level |
100
- | `get_screen_size` | Screen resolution in pixels |
101
- | `take_screenshot` | Capture screenshot (PNG or JPEG, configurable quality & resize) |
102
- | `get_ui_elements` | Get the accessibility/UI element tree as structured JSON |
103
- | `tap` | Tap at coordinates |
104
- | `double_tap` | Double tap at coordinates |
105
- | `long_press` | Long press at coordinates |
106
- | `swipe` | Swipe between two points |
107
- | `type_text` | Type text into the focused field |
108
- | `press_key` | Press a key (home, back, enter, volume, etc.) |
109
- | `list_apps` | List installed apps |
110
- | `get_current_app` | Get the foreground app |
111
- | `launch_app` | Launch an app by package name |
112
- | `stop_app` | Force stop an app |
113
- | `install_app` | Install an APK |
114
- | `uninstall_app` | Uninstall an app |
115
- | `get_logs` | Get logcat entries with filtering |
116
-
117
- ### Phase 2 — AI Visual Analysis (8 tools)
118
-
119
- These tools use AI vision (Claude or Gemini) to understand what's on screen. Requires `ANTHROPIC_API_KEY` or `GOOGLE_API_KEY`.
120
-
121
- | Tool | What it does |
122
- |------|-------------|
123
- | `analyze_screen` | AI describes the screen: app name, screen type, interactive elements, visible text, suggestions |
124
- | `find_element` | Find a UI element by description: *"the login button"*, *"email input field"* |
125
- | `smart_tap` | Find an element by description and tap it in one step |
126
- | `smart_type` | Find an input field by description, focus it, and type text |
127
- | `suggest_actions` | Plan actions to achieve a goal: *"log into the app"*, *"add item to cart"* |
128
- | `visual_diff` | Compare current screen with a previous screenshot — what changed? |
129
- | `extract_text` | Extract all visible text from the screen (AI-powered OCR) |
130
- | `verify_screen` | Verify an assertion: *"the login was successful"*, *"error message is showing"* |
131
-
132
- ### Phase 3 Flutter Widget Tree (8 tools)
133
-
134
- These tools connect to a running Flutter app in debug/profile mode via the Dart VM Service Protocol. Maps every widget to its source code location (`file:line`).
135
-
136
- | Tool | What it does |
137
- |------|-------------|
138
- | `flutter_connect` | Discover and connect to a running Flutter app on the device |
139
- | `flutter_disconnect` | Disconnect from the Flutter app and clean up resources |
140
- | `flutter_get_widget_tree` | Get the full widget tree (summary or detailed) |
141
- | `flutter_get_widget_details` | Get detailed properties of a specific widget by ID |
142
- | `flutter_find_widget` | Search the widget tree by type, text, or description |
143
- | `flutter_get_source_map` | Map every widget to its source code location (file:line:column) |
144
- | `flutter_screenshot_widget` | Screenshot a specific widget in isolation |
145
- | `flutter_debug_paint` | Toggle debug paint overlay (shows widget boundaries & padding) |
146
-
147
- ## Performance
148
-
149
- The server is optimized to minimize latency and AI token costs:
150
-
151
- - **3-tier element search**: local text match (<1ms) → cached AI → fresh AI. `smart_tap` is 37x faster than naive AI calls.
152
- - **Screenshot compression**: AI tools auto-compress to JPEG q=80, 720w — **65% smaller** (251KB → 88KB) with zero quality loss. Saves ~55K tokens per screenshot.
153
- - **Parallel capture**: Screenshot + UI tree fetched simultaneously via `Promise.all()`.
154
- - **TTL caching**: 3-second cache avoids redundant ADB calls for rapid-fire tool usage.
155
-
156
- ## Environment Variables
157
-
158
- | Variable | Description | Default |
159
- |----------|-------------|---------|
160
- | `ANTHROPIC_API_KEY` | Anthropic API key for Claude vision | — |
161
- | `GOOGLE_API_KEY` or `GEMINI_API_KEY` | Google API key for Gemini vision (recommended — cheapest) | — |
162
- | `MCP_AI_PROVIDER` | Force AI provider: `"anthropic"` or `"google"` | Auto-detected |
163
- | `MCP_AI_MODEL` | Override AI model | `gemini-2.5-flash` / `claude-sonnet-4-20250514` |
164
- | `MCP_ADB_PATH` | Custom ADB binary path | Auto-discovered |
165
- | `MCP_DEFAULT_DEVICE` | Default device serial | Auto-discovered |
166
- | `MCP_SCREENSHOT_FORMAT` | `"png"` or `"jpeg"` | `jpeg` |
167
- | `MCP_SCREENSHOT_QUALITY` | JPEG quality (1-100) | `80` |
168
- | `MCP_SCREENSHOT_MAX_WIDTH` | Resize screenshots to this max width | `720` |
169
- | `MCP_AI_SCREENSHOT` | Send screenshots to AI (`"true"`/`"false"`) | `true` |
170
- | `MCP_AI_UITREE` | Send UI tree to AI (`"true"`/`"false"`) | `true` |
171
-
172
- ## Architecture
173
-
174
- ```
175
- src/
176
- ├── index.ts # CLI entry point (auto-discovery, env config)
177
- ├── server.ts # MCP server factory
178
- ├── types.ts # Shared interfaces
179
- ├── drivers/android/ # ADB driver (DeviceDriver implementation)
180
- │ ├── adb.ts # Low-level ADB command wrapper
181
- │ └── index.ts # AndroidDriver class
182
- ├── tools/ # MCP tool registrations
183
- │ ├── device-tools.ts # Device management
184
- │ ├── screen-tools.ts # Screenshots & UI inspection
185
- │ ├── interaction-tools.ts # Touch, type, keys
186
- │ ├── app-tools.ts # App management
187
- │ ├── log-tools.ts # Logcat
188
- │ ├── ai-tools.ts # AI-powered tools
189
- │ └── flutter-tools.ts # Flutter widget inspection tools
190
- ├── drivers/flutter/ # Dart VM Service driver
191
- │ ├── index.ts # FlutterDriver (discovery, inspection, source mapping)
192
- │ └── vm-service.ts # JSON-RPC 2.0 WebSocket client (DDS redirect handling)
193
- ├── ai/ # AI visual analysis engine
194
- │ ├── client.ts # Multi-provider client (Anthropic + Google)
195
- │ ├── prompts.ts # System prompts & UI element summarizer
196
- │ ├── analyzer.ts # ScreenAnalyzer orchestrator
197
- │ └── element-search.ts # Local element search (no AI needed)
198
- └── utils/
199
- ├── discovery.ts # ADB auto-discovery
200
- └── image.ts # PNG parsing, JPEG compression, bilinear resize
201
- ```
202
-
203
- ## Roadmap
204
-
205
- - [x] Phase 1: Android ADB device control (18 tools)
206
- - [x] Phase 2: AI visual analysis layer (8 tools)
207
- - [x] Multi-provider AI (Anthropic Claude + Google Gemini)
208
- - [x] Performance optimization (3-tier search, caching, parallel capture)
209
- - [x] Screenshot compression pipeline (JPEG, resize, configurable quality)
210
- - [x] npm publish (`npx mobile-device-mcp`)
211
- - [x] Phase 3: Flutter widget tree integration (8 tools, Dart VM Service Protocol)
212
- - [ ] Phase 4: iOS support (simulators via xcrun simctl, devices via idevice)
213
- - [ ] Phase 5: Monetization (license keys, usage analytics)
214
- - [ ] Multi-device orchestration
215
-
216
- ## Tested On
217
-
218
- - Pixel 8, Android 16, SDK 36 44/44 tests passed (22 device + 10 AI + 12 Flutter)
219
- - Flutter 3.41.3, metroping app (debug mode)
220
- - Google Gemini 2.5 Flash
221
- - Windows 11 + wireless ADB
222
-
223
- ## License
224
-
225
- MIT
1
+ # mobile-device-mcp
2
+
3
+ [![npm version](https://img.shields.io/npm/v/mobile-device-mcp)](https://www.npmjs.com/package/mobile-device-mcp)
4
+ [![npm downloads](https://img.shields.io/npm/dm/mobile-device-mcp)](https://www.npmjs.com/package/mobile-device-mcp)
5
+ [![GitHub stars](https://img.shields.io/github/stars/saranshbamania/mobile-device-mcp)](https://github.com/saranshbamania/mobile-device-mcp)
6
+ [![License: BSL 1.1](https://img.shields.io/badge/License-BSL%201.1-blue.svg)](LICENSE)
7
+
8
+ MCP server that gives AI coding assistants (Claude Code, Cursor, Windsurf) the ability to **see and interact with mobile devices**. 49 tools for screenshots, UI inspection, touch interaction, AI-powered visual analysis, Flutter widget tree inspection, video recording, and test generation.
9
+
10
+ > AI assistants can read your code but can't see your phone. This fixes that.
11
+
12
+ ## Why This One?
13
+
14
+ | Feature | mobile-device-mcp | mobile-next/mobile-mcp | appium/appium-mcp |
15
+ |---------|:-:|:-:|:-:|
16
+ | Total tools | **49** | 20 | ~15 |
17
+ | Setup | `npx` (30 sec) | `npx` | Requires Appium server |
18
+ | AI visual analysis | **12 tools** (Claude + Gemini) | None | Vision-based finding |
19
+ | Flutter widget tree | **10 tools** (Dart VM Service) | None | None |
20
+ | Smart element finding | **4-tier** (<1ms local search) | Accessibility tree only | XPath/selectors |
21
+ | Companion app (23x faster UI tree) | Yes | No | No |
22
+ | Video recording | Yes | No | No |
23
+ | Test script generation | **TS, Python, JSON** | No | Java/TestNG only |
24
+ | iOS simulator support | Yes | Yes | Yes |
25
+ | iOS real device | Planned | Yes | Yes |
26
+ | Screenshot compression | **89%** (251KB->28KB) | None | 50-80% |
27
+ | Multi-provider AI | Claude + Gemini | N/A | Single provider |
28
+ | Price | Free tier + Pro | Free | Free |
29
+
30
+ ## The Problem
31
+
32
+ Web developers have browser DevTools, Playwright, and Puppeteer -- AI assistants can click around, take screenshots, and verify fixes. Mobile developers? They're stuck manually screenshotting, copying logs, and describing what's on screen. They're **human middleware** between the AI and the device.
33
+
34
+ ## What This Does
35
+
36
+ ```
37
+ Developer: "The login button doesn't work"
38
+
39
+ Without this tool: With this tool:
40
+ 1. Manually screenshot 1. AI calls take_screenshot -> sees the screen
41
+ 2. Paste into AI chat 2. AI calls smart_tap("login button") -> taps it
42
+ 3. AI guesses what's wrong 3. AI calls verify_screen("error message shown") -> sees result
43
+ 4. Apply fix, rebuild 4. AI calls visual_diff -> confirms fix worked
44
+ 5. Repeat 4-5 times 5. Done.
45
+ ```
46
+
47
+ ## Quick Start
48
+
49
+ ### Prerequisites
50
+ - Node.js 18+
51
+ - Android device/emulator connected via ADB
52
+ - ADB installed (Android SDK Platform Tools)
53
+
54
+ ### Setup (One-time, 30 seconds)
55
+
56
+ 1. **Get a Google AI key** (free tier available): [aistudio.google.com/apikey](https://aistudio.google.com/apikey)
57
+
58
+ 2. **Add `.mcp.json` to your project root:**
59
+
60
+ ```json
61
+ {
62
+ "mcpServers": {
63
+ "mobile-device": {
64
+ "type": "stdio",
65
+ "command": "npx",
66
+ "args": ["-y", "mobile-device-mcp"],
67
+ "env": {
68
+ "GOOGLE_API_KEY": "your-google-api-key"
69
+ }
70
+ }
71
+ }
72
+ }
73
+ ```
74
+
75
+ 3. **Open your AI coding assistant** from that directory. That's it.
76
+
77
+ The server starts and stops automatically -- you never run it manually. Your AI assistant manages it as a background process via the MCP protocol.
78
+
79
+ ### Verify It Works
80
+
81
+ **Claude Code:** type `/mcp` -- you should see `mobile-device: Connected`
82
+
83
+ **Cursor:** check MCP panel in settings
84
+
85
+ Then just talk to your phone:
86
+
87
+ ```
88
+ You: "Open my app, tap the login button, type test@email.com in the email field"
89
+ AI: [takes screenshot -> sees the screen -> smart_tap("login button") -> smart_type("email field", "test@email.com")]
90
+
91
+ You: "Find all the bugs on this screen"
92
+ AI: [analyze_screen -> inspects layout, checks for overflow, missing labels, broken states]
93
+
94
+ You: "Navigate to settings and verify dark mode works"
95
+ AI: [smart_tap("settings") -> take_screenshot -> smart_tap("dark mode toggle") -> visual_diff -> reports result]
96
+ ```
97
+
98
+ No test scripts. No manual screenshots. Just describe what you want in plain English.
99
+
100
+ ### Works with Any AI Coding Assistant
101
+
102
+ | Tool | Config file | Docs |
103
+ |------|------------|------|
104
+ | **Claude Code** | `.mcp.json` in project root | [claude.ai/docs](https://claude.ai/docs) |
105
+ | **Cursor** | `.cursor/mcp.json` | [cursor.com/docs](https://cursor.com/docs) |
106
+ | **VS Code + Copilot** | MCP settings | [code.visualstudio.com](https://code.visualstudio.com) |
107
+ | **Windsurf** | MCP settings | [windsurf.com](https://windsurf.com) |
108
+
109
+ All use the same JSON config -- just put it in the right file for your editor.
110
+
111
+ ### Drop Into Any Project
112
+
113
+ Copy `.mcp.json` into any mobile project -- Flutter, React Native, Kotlin, Swift -- and your AI assistant gets device superpowers in that directory. No global install needed.
114
+
115
+ ## Free vs Pro
116
+
117
+ <a name="pro"></a>
118
+
119
+ ### Free (14 tools) -- no license key needed
120
+
121
+ | Tool | What it does |
122
+ |------|-------------|
123
+ | `list_devices` | List all connected Android devices/emulators |
124
+ | `get_device_info` | Model, manufacturer, Android version, SDK level |
125
+ | `get_screen_size` | Screen resolution in pixels |
126
+ | `take_screenshot` | Capture screenshot (PNG or JPEG, configurable quality & resize) |
127
+ | `get_ui_elements` | Get the accessibility/UI element tree as structured JSON |
128
+ | `tap` | Tap at coordinates |
129
+ | `double_tap` | Double tap at coordinates |
130
+ | `long_press` | Long press at coordinates |
131
+ | `swipe` | Swipe between two points |
132
+ | `type_text` | Type text into the focused field |
133
+ | `press_key` | Press a key (home, back, enter, volume, etc.) |
134
+ | `list_apps` | List installed apps |
135
+ | `get_current_app` | Get the foreground app |
136
+ | `get_logs` | Get logcat entries with filtering |
137
+
138
+ ### Pro (35 additional tools) -- requires license key
139
+
140
+ Unlock all 49 tools by setting `MOBILE_MCP_LICENSE_KEY` in your `.mcp.json`:
141
+
142
+ ```json
143
+ {
144
+ "mcpServers": {
145
+ "mobile-device": {
146
+ "type": "stdio",
147
+ "command": "npx",
148
+ "args": ["-y", "mobile-device-mcp"],
149
+ "env": {
150
+ "GOOGLE_API_KEY": "your-google-api-key",
151
+ "MOBILE_MCP_LICENSE_KEY": "your-license-key"
152
+ }
153
+ }
154
+ }
155
+ }
156
+ ```
157
+
158
+ #### AI Visual Analysis (12 tools)
159
+
160
+ Use AI vision (Claude or Gemini) to understand what's on screen.
161
+
162
+ | Tool | What it does |
163
+ |------|-------------|
164
+ | `analyze_screen` | AI describes the screen: app name, screen type, interactive elements, visible text, suggestions |
165
+ | `find_element` | Find a UI element by description: *"the login button"*, *"email input field"* |
166
+ | `smart_tap` | Find an element by description and tap it in one step |
167
+ | `smart_type` | Find an input field by description, focus it, and type text |
168
+ | `suggest_actions` | Plan actions to achieve a goal: *"log into the app"*, *"add item to cart"* |
169
+ | `visual_diff` | Compare current screen with a previous screenshot -- what changed? |
170
+ | `extract_text` | Extract all visible text from the screen (AI-powered OCR) |
171
+ | `verify_screen` | Verify an assertion: *"the login was successful"*, *"error message is showing"* |
172
+ | `wait_for_settle` | Wait until the screen stops changing |
173
+ | `wait_for_element` | Wait for a specific element to appear on screen |
174
+ | `handle_popup` | Detect and dismiss popups, dialogs, permission prompts |
175
+ | `fill_form` | Fill multiple form fields in one step |
176
+
177
+ #### Flutter Widget Tree (10 tools)
178
+
179
+ Connect to running Flutter apps via Dart VM Service Protocol. Maps every widget to its source code location (`file:line`).
180
+
181
+ | Tool | What it does |
182
+ |------|-------------|
183
+ | `flutter_connect` | Discover and connect to a running Flutter app on the device |
184
+ | `flutter_disconnect` | Disconnect from the Flutter app and clean up resources |
185
+ | `flutter_get_widget_tree` | Get the full widget tree (summary or detailed) |
186
+ | `flutter_get_widget_details` | Get detailed properties of a specific widget by ID |
187
+ | `flutter_find_widget` | Search the widget tree by type, text, or description |
188
+ | `flutter_get_source_map` | Map every widget to its source code location (file:line:column) |
189
+ | `flutter_screenshot_widget` | Screenshot a specific widget in isolation |
190
+ | `flutter_debug_paint` | Toggle debug paint overlay (shows widget boundaries & padding) |
191
+ | `flutter_hot_reload` | Hot reload Flutter app (preserves state) |
192
+ | `flutter_hot_restart` | Hot restart Flutter app (resets state) |
193
+
194
+ #### iOS Simulator (4 tools)
195
+
196
+ macOS only. Control iOS simulators via `xcrun simctl`.
197
+
198
+ | Tool | What it does |
199
+ |------|-------------|
200
+ | `ios_list_simulators` | List available iOS simulators |
201
+ | `ios_boot_simulator` | Boot a simulator by name or UDID |
202
+ | `ios_shutdown_simulator` | Shut down a running simulator |
203
+ | `ios_screenshot` | Take a screenshot of a simulator |
204
+
205
+ #### Video Recording (2 tools)
206
+
207
+ | Tool | What it does |
208
+ |------|-------------|
209
+ | `record_screen` | Start recording the device screen |
210
+ | `stop_recording` | Stop recording and save the video |
211
+
212
+ #### Test Generation (3 tools)
213
+
214
+ | Tool | What it does |
215
+ |------|-------------|
216
+ | `start_test_recording` | Start recording your MCP tool calls |
217
+ | `stop_test_recording` | Stop recording and generate a test script |
218
+ | `get_recorded_actions` | Get recorded actions as TypeScript, Python, or JSON |
219
+
220
+ #### App Management (4 tools)
221
+
222
+ | Tool | What it does |
223
+ |------|-------------|
224
+ | `launch_app` | Launch an app by package name |
225
+ | `stop_app` | Force stop an app |
226
+ | `install_app` | Install an APK |
227
+ | `uninstall_app` | Uninstall an app |
228
+
229
+ ## Performance
230
+
231
+ The server is optimized to minimize latency and AI token costs:
232
+
233
+ - **4-tier element search**: companion app (instant) -> local text match (<1ms) -> cached AI -> fresh AI. `smart_tap` is **35x faster** than naive AI calls (205ms vs 7.6s).
234
+ - **Companion app**: AccessibilityService-based Android app provides UI tree in 105ms (23x faster than UIAutomator's 2448ms). Auto-installs on first use.
235
+ - **Screenshot compression**: AI tools auto-compress to JPEG q=60, 400w -- **89% smaller** (251KB -> 28KB) with zero AI quality loss.
236
+ - **Parallel capture**: Screenshot + UI tree fetched simultaneously via `Promise.all()`.
237
+ - **TTL caching**: 5-second cache avoids redundant ADB calls for rapid-fire tool usage.
238
+
239
+ ## Environment Variables
240
+
241
+ | Variable | Description | Default |
242
+ |----------|-------------|---------|
243
+ | `GOOGLE_API_KEY` or `GEMINI_API_KEY` | Google API key for Gemini vision (recommended) | -- |
244
+ | `ANTHROPIC_API_KEY` | Anthropic API key for Claude vision | -- |
245
+ | `MOBILE_MCP_LICENSE_KEY` | License key to unlock Pro tools | -- |
246
+ | `MCP_AI_PROVIDER` | Force AI provider: `"anthropic"` or `"google"` | Auto-detected |
247
+ | `MCP_AI_MODEL` | Override AI model | `gemini-2.5-flash` / `claude-sonnet-4-20250514` |
248
+ | `MCP_ADB_PATH` | Custom ADB binary path | Auto-discovered |
249
+ | `MCP_DEFAULT_DEVICE` | Default device serial | Auto-discovered |
250
+ | `MCP_SCREENSHOT_FORMAT` | `"png"` or `"jpeg"` | `jpeg` |
251
+ | `MCP_SCREENSHOT_QUALITY` | JPEG quality (1-100) | `80` |
252
+ | `MCP_SCREENSHOT_MAX_WIDTH` | Resize screenshots to this max width | `720` |
253
+
254
+ ## Architecture
255
+
256
+ ```
257
+ src/
258
+ |-- index.ts # CLI entry point (auto-discovery, env config)
259
+ |-- server.ts # MCP server factory
260
+ |-- license.ts # License validation and tier gating
261
+ |-- types.ts # Shared interfaces
262
+ |-- drivers/android/ # ADB driver (DeviceDriver implementation)
263
+ | |-- adb.ts # Low-level ADB command wrapper
264
+ | |-- companion-client.ts # TCP client for companion app
265
+ | +-- index.ts # AndroidDriver class (4-strategy UI element retrieval)
266
+ |-- drivers/flutter/ # Dart VM Service driver
267
+ | |-- index.ts # FlutterDriver (discovery, inspection, source mapping, hot reload)
268
+ | +-- vm-service.ts # JSON-RPC 2.0 WebSocket client (DDS redirect handling)
269
+ |-- drivers/ios/ # iOS Simulator driver (macOS only)
270
+ | |-- index.ts # IOSSimulatorDriver via xcrun simctl
271
+ | +-- simctl.ts # Low-level simctl command wrapper
272
+ |-- tools/ # MCP tool registrations (free + pro gating)
273
+ | |-- device-tools.ts # Device management
274
+ | |-- screen-tools.ts # Screenshots & UI inspection
275
+ | |-- interaction-tools.ts # Touch, type, keys
276
+ | |-- app-tools.ts # App management
277
+ | |-- log-tools.ts # Logcat
278
+ | |-- ai-tools.ts # AI-powered tools
279
+ | |-- flutter-tools.ts # Flutter widget inspection
280
+ | |-- ios-tools.ts # iOS simulator tools
281
+ | |-- video-tools.ts # Screen recording
282
+ | +-- recording-tools.ts # Test generation
283
+ |-- recording/ # Test script generation
284
+ | |-- recorder.ts # ActionRecorder (records MCP tool calls)
285
+ | +-- generator.ts # TestGenerator (TypeScript/Python/JSON output)
286
+ |-- ai/ # AI visual analysis engine
287
+ | |-- client.ts # Multi-provider client (Anthropic + Google)
288
+ | |-- prompts.ts # System prompts & UI element summarizer
289
+ | |-- analyzer.ts # ScreenAnalyzer orchestrator (caching, parallel capture)
290
+ | +-- element-search.ts # Local element search (text/alias matching, no AI needed)
291
+ +-- utils/
292
+ |-- discovery.ts # ADB auto-discovery
293
+ +-- image.ts # PNG parsing, JPEG compression, bilinear resize
294
+
295
+ companion-app/ # Android companion app (Kotlin)
296
+ # AccessibilityService + TCP JSON-RPC for fast UI tree
297
+ ```
298
+
299
+ ## Roadmap
300
+
301
+ - [ ] iOS physical device support
302
+ - [ ] Multi-device orchestration
303
+ - [ ] CI/CD integration
304
+ - [ ] Cloud device farm support
305
+
306
+ ## Tested On
307
+
308
+ - **Devices**: Pixel 8 (Android 16), Samsung Galaxy series, Android emulators
309
+ - **Apps**: Telegram, Instagram, Spotify, WhatsApp, YouTube, Chrome, Settings, and Flutter apps
310
+ - **AI Providers**: Google Gemini 2.5 Flash, Anthropic Claude
311
+ - **Platforms**: Windows 11, macOS (iOS simulators)
312
+ - **Connection**: USB and wireless ADB
313
+
314
+ ## License
315
+
316
+ [Business Source License 1.1](LICENSE)
317
+
318
+ - **Free for individuals and non-commercial use**
319
+ - **Commercial use requires a paid license**
320
+ - Converts to Apache 2.0 on March 23, 2030
321
+
322
+ See [LICENSE](LICENSE) for full terms.
@@ -0,0 +1,25 @@
1
+ export type LicenseTier = "free" | "pro";
2
+ export interface LicenseInfo {
3
+ tier: LicenseTier;
4
+ valid: boolean;
5
+ }
6
+ /** Tools included in the free tier */
7
+ export declare const FREE_TOOLS: Set<string>;
8
+ /** Upgrade message shown when a free user calls a pro tool */
9
+ export declare const PRO_UPGRADE_MESSAGE: {
10
+ content: {
11
+ type: "text";
12
+ text: string;
13
+ }[];
14
+ isError: boolean;
15
+ };
16
+ /**
17
+ * Validate the license key.
18
+ *
19
+ * Current implementation: presence check.
20
+ * Future: integrate with Keygen.sh or xPay for real validation.
21
+ */
22
+ export declare function validateLicense(): LicenseInfo;
23
+ /** Log the license tier on startup */
24
+ export declare function logLicenseStatus(info: LicenseInfo): void;
25
+ //# sourceMappingURL=license.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"license.d.ts","sourceRoot":"","sources":["../src/license.ts"],"names":[],"mappings":"AAMA,MAAM,MAAM,WAAW,GAAG,MAAM,GAAG,KAAK,CAAC;AAEzC,MAAM,WAAW,WAAW;IAC1B,IAAI,EAAE,WAAW,CAAC;IAClB,KAAK,EAAE,OAAO,CAAC;CAChB;AAED,sCAAsC;AACtC,eAAO,MAAM,UAAU,aAoBrB,CAAC;AAEH,8DAA8D;AAC9D,eAAO,MAAM,mBAAmB;;;;;;CAe/B,CAAC;AAEF;;;;;GAKG;AACH,wBAAgB,eAAe,IAAI,WAAW,CAU7C;AAED,sCAAsC;AACtC,wBAAgB,gBAAgB,CAAC,IAAI,EAAE,WAAW,GAAG,IAAI,CAMxD"}
@@ -0,0 +1,68 @@
1
+ // ============================================================
2
+ // License key validation and tier management
3
+ // ============================================================
4
+ const PREFIX = "[mobile-device-mcp]";
5
+ /** Tools included in the free tier */
6
+ export const FREE_TOOLS = new Set([
7
+ // Device info (3)
8
+ "list_devices",
9
+ "get_device_info",
10
+ "get_screen_size",
11
+ // Screenshots & UI tree (2)
12
+ "take_screenshot",
13
+ "get_ui_elements",
14
+ // Basic interaction (6)
15
+ "tap",
16
+ "double_tap",
17
+ "long_press",
18
+ "swipe",
19
+ "type_text",
20
+ "press_key",
21
+ // Basic app management (2)
22
+ "list_apps",
23
+ "get_current_app",
24
+ // Logs (1)
25
+ "get_logs",
26
+ ]);
27
+ /** Upgrade message shown when a free user calls a pro tool */
28
+ export const PRO_UPGRADE_MESSAGE = {
29
+ content: [
30
+ {
31
+ type: "text",
32
+ text: [
33
+ "This is a Pro feature. Upgrade to unlock all 49 tools including AI vision, Flutter inspection, test generation, and more.",
34
+ "",
35
+ "Get your license key at: https://github.com/saranshbamania/mobile-device-mcp#pro",
36
+ "",
37
+ "Then add to your .mcp.json:",
38
+ ' "MOBILE_MCP_LICENSE_KEY": "your-key-here"',
39
+ ].join("\n"),
40
+ },
41
+ ],
42
+ isError: true,
43
+ };
44
+ /**
45
+ * Validate the license key.
46
+ *
47
+ * Current implementation: presence check.
48
+ * Future: integrate with Keygen.sh or xPay for real validation.
49
+ */
50
+ export function validateLicense() {
51
+ const key = process.env.MOBILE_MCP_LICENSE_KEY;
52
+ if (!key || key.trim() === "") {
53
+ return { tier: "free", valid: true };
54
+ }
55
+ // TODO: Replace with Keygen.sh API validation when payment is set up
56
+ // For now, any non-empty key is treated as valid pro license
57
+ return { tier: "pro", valid: true };
58
+ }
59
+ /** Log the license tier on startup */
60
+ export function logLicenseStatus(info) {
61
+ if (info.tier === "pro") {
62
+ process.stderr.write(`${PREFIX} License: Pro (all 49 tools enabled)\n`);
63
+ }
64
+ else {
65
+ process.stderr.write(`${PREFIX} License: Free (14 tools — upgrade to Pro for all 49)\n`);
66
+ }
67
+ }
68
+ //# sourceMappingURL=license.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"license.js","sourceRoot":"","sources":["../src/license.ts"],"names":[],"mappings":"AAAA,+DAA+D;AAC/D,6CAA6C;AAC7C,+DAA+D;AAE/D,MAAM,MAAM,GAAG,qBAAqB,CAAC;AASrC,sCAAsC;AACtC,MAAM,CAAC,MAAM,UAAU,GAAG,IAAI,GAAG,CAAC;IAChC,kBAAkB;IAClB,cAAc;IACd,iBAAiB;IACjB,iBAAiB;IACjB,4BAA4B;IAC5B,iBAAiB;IACjB,iBAAiB;IACjB,wBAAwB;IACxB,KAAK;IACL,YAAY;IACZ,YAAY;IACZ,OAAO;IACP,WAAW;IACX,WAAW;IACX,2BAA2B;IAC3B,WAAW;IACX,iBAAiB;IACjB,WAAW;IACX,UAAU;CACX,CAAC,CAAC;AAEH,8DAA8D;AAC9D,MAAM,CAAC,MAAM,mBAAmB,GAAG;IACjC,OAAO,EAAE;QACP;YACE,IAAI,EAAE,MAAe;YACrB,IAAI,EAAE;gBACJ,2HAA2H;gBAC3H,EAAE;gBACF,kFAAkF;gBAClF,EAAE;gBACF,6BAA6B;gBAC7B,6CAA6C;aAC9C,CAAC,IAAI,CAAC,IAAI,CAAC;SACb;KACF;IACD,OAAO,EAAE,IAAI;CACd,CAAC;AAEF;;;;;GAKG;AACH,MAAM,UAAU,eAAe;IAC7B,MAAM,GAAG,GAAG,OAAO,CAAC,GAAG,CAAC,sBAAsB,CAAC;IAE/C,IAAI,CAAC,GAAG,IAAI,GAAG,CAAC,IAAI,EAAE,KAAK,EAAE,EAAE,CAAC;QAC9B,OAAO,EAAE,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,IAAI,EAAE,CAAC;IACvC,CAAC;IAED,qEAAqE;IACrE,6DAA6D;IAC7D,OAAO,EAAE,IAAI,EAAE,KAAK,EAAE,KAAK,EAAE,IAAI,EAAE,CAAC;AACtC,CAAC;AAED,sCAAsC;AACtC,MAAM,UAAU,gBAAgB,CAAC,IAAiB;IAChD,IAAI,IAAI,CAAC,IAAI,KAAK,KAAK,EAAE,CAAC;QACxB,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,GAAG,MAAM,wCAAwC,CAAC,CAAC;IAC1E,CAAC;SAAM,CAAC;QACN,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,GAAG,MAAM,yDAAyD,CAAC,CAAC;IAC3F,CAAC;AACH,CAAC"}
@@ -1 +1 @@
1
- {"version":3,"file":"server.d.ts","sourceRoot":"","sources":["../src/server.ts"],"names":[],"mappings":"AAIA,OAAO,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AAEpE,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,YAAY,CAAC;AAY/C;;;;;GAKG;AACH,wBAAgB,YAAY,CAAC,MAAM,EAAE,YAAY,GAAG;IAClD,MAAM,EAAE,SAAS,CAAC;IAClB,KAAK,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,CAAC;CAC5B,CAoCA"}
1
+ {"version":3,"file":"server.d.ts","sourceRoot":"","sources":["../src/server.ts"],"names":[],"mappings":"AAIA,OAAO,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AAEpE,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,YAAY,CAAC;AAa/C;;;;;GAKG;AACH,wBAAgB,YAAY,CAAC,MAAM,EAAE,YAAY,GAAG;IAClD,MAAM,EAAE,SAAS,CAAC;IAClB,KAAK,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,CAAC;CAC5B,CAwCA"}
package/dist/server.js CHANGED
@@ -10,8 +10,9 @@ import { registerAllTools } from "./tools/index.js";
10
10
  import { AIClient } from "./ai/client.js";
11
11
  import { ScreenAnalyzer } from "./ai/analyzer.js";
12
12
  import { ActionRecorder } from "./recording/recorder.js";
13
+ import { validateLicense, logLicenseStatus } from "./license.js";
13
14
  /** Server version — matches package.json */
14
- const SERVER_VERSION = "0.1.0";
15
+ const SERVER_VERSION = "0.2.1";
15
16
  /**
16
17
  * Create a configured MCP server ready to start.
17
18
  *
@@ -41,7 +42,10 @@ export function createServer(config) {
41
42
  }, flutterDriver);
42
43
  }
43
44
  const recorder = new ActionRecorder();
44
- registerAllTools(server, () => driver, () => analyzer, () => flutterDriver, () => driver, () => recorder, () => iosDriver);
45
+ // Validate license and gate pro tools
46
+ const license = validateLicense();
47
+ logLicenseStatus(license);
48
+ registerAllTools(server, () => driver, () => analyzer, () => flutterDriver, () => driver, () => recorder, () => iosDriver, license);
45
49
  async function start() {
46
50
  const transport = new StdioServerTransport();
47
51
  await server.connect(transport);
@@ -1 +1 @@
1
- {"version":3,"file":"server.js","sourceRoot":"","sources":["../src/server.ts"],"names":[],"mappings":"AAAA,+DAA+D;AAC/D,uDAAuD;AACvD,+DAA+D;AAE/D,OAAO,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AACpE,OAAO,EAAE,oBAAoB,EAAE,MAAM,2CAA2C,CAAC;AAEjF,OAAO,EAAE,aAAa,EAAE,MAAM,4BAA4B,CAAC;AAC3D,OAAO,EAAE,aAAa,EAAE,MAAM,4BAA4B,CAAC;AAC3D,OAAO,EAAE,kBAAkB,EAAE,MAAM,wBAAwB,CAAC;AAC5D,OAAO,EAAE,gBAAgB,EAAE,MAAM,kBAAkB,CAAC;AACpD,OAAO,EAAE,QAAQ,EAAE,MAAM,gBAAgB,CAAC;AAC1C,OAAO,EAAE,cAAc,EAAE,MAAM,kBAAkB,CAAC;AAClD,OAAO,EAAE,cAAc,EAAE,MAAM,yBAAyB,CAAC;AAEzD,4CAA4C;AAC5C,MAAM,cAAc,GAAG,OAAO,CAAC;AAE/B;;;;;GAKG;AACH,MAAM,UAAU,YAAY,CAAC,MAAoB;IAI/C,MAAM,MAAM,GAAG,IAAI,SAAS,CAAC;QAC3B,IAAI,EAAE,mBAAmB;QACzB,OAAO,EAAE,cAAc;KACxB,CAAC,CAAC;IAEH,MAAM,MAAM,GAAG,IAAI,aAAa,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC;IACjD,MAAM,aAAa,GAAG,IAAI,aAAa,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC;IAExD,qCAAqC;IACrC,IAAI,SAAS,GAA8B,IAAI,CAAC;IAChD,IAAI,OAAO,CAAC,QAAQ,KAAK,QAAQ,EAAE,CAAC;QAClC,SAAS,GAAG,IAAI,kBAAkB,EAAE,CAAC;IACvC,CAAC;IAED,mCAAmC;IACnC,IAAI,QAAQ,GAA0B,IAAI,CAAC;IAC3C,IAAI,MAAM,CAAC,EAAE,IAAI,MAAM,CAAC,EAAE,CAAC,MAAM,EAAE,CAAC;QAClC,MAAM,QAAQ,GAAG,IAAI,QAAQ,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC;QACzC,QAAQ,GAAG,IAAI,cAAc,CAAC,QAAQ,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,EAAE;YACzD,MAAM,EAAE,MAAM,CAAC,gBAAgB;YAC/B,OAAO,EAAE,MAAM,CAAC,iBAAiB;YACjC,QAAQ,EAAE,MAAM,CAAC,kBAAkB;SACpC,EAAE,aAAa,CAAC,CAAC;IACpB,CAAC;IAED,MAAM,QAAQ,GAAG,IAAI,cAAc,EAAE,CAAC;IAEtC,gBAAgB,CAAC,MAAM,EAAE,GAAG,EAAE,CAAC,MAAM,EAAE,GAAG,EAAE,CAAC,QAAQ,EAAE,GAAG,EAAE,CAAC,aAAa,EAAE,GAAG,EAAE,CAAC,MAAM,EAAE,GAAG,EAAE,CAAC,QAAQ,EAAE,GAAG,EAAE,CAAC,SAAS,CAAC,CAAC;IAE3H,KAAK,UAAU,KAAK;QAClB,MAAM,SAAS,GAAG,IAAI,oBAAoB,EAAE,CAAC;QAC7C,MAAM,MAAM,CAAC,OAAO,CAAC,SAAS,CAAC,CAAC;IAClC,CAAC;IAED,OAAO,EAAE,MAAM,EAAE,KAAK,EAAE,CAAC;AAC3B,CAAC"}
1
+ {"version":3,"file":"server.js","sourceRoot":"","sources":["../src/server.ts"],"names":[],"mappings":"AAAA,+DAA+D;AAC/D,uDAAuD;AACvD,+DAA+D;AAE/D,OAAO,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AACpE,OAAO,EAAE,oBAAoB,EAAE,MAAM,2CAA2C,CAAC;AAEjF,OAAO,EAAE,aAAa,EAAE,MAAM,4BAA4B,CAAC;AAC3D,OAAO,EAAE,aAAa,EAAE,MAAM,4BAA4B,CAAC;AAC3D,OAAO,EAAE,kBAAkB,EAAE,MAAM,wBAAwB,CAAC;AAC5D,OAAO,EAAE,gBAAgB,EAAE,MAAM,kBAAkB,CAAC;AACpD,OAAO,EAAE,QAAQ,EAAE,MAAM,gBAAgB,CAAC;AAC1C,OAAO,EAAE,cAAc,EAAE,MAAM,kBAAkB,CAAC;AAClD,OAAO,EAAE,cAAc,EAAE,MAAM,yBAAyB,CAAC;AACzD,OAAO,EAAE,eAAe,EAAE,gBAAgB,EAAE,MAAM,cAAc,CAAC;AAEjE,4CAA4C;AAC5C,MAAM,cAAc,GAAG,OAAO,CAAC;AAE/B;;;;;GAKG;AACH,MAAM,UAAU,YAAY,CAAC,MAAoB;IAI/C,MAAM,MAAM,GAAG,IAAI,SAAS,CAAC;QAC3B,IAAI,EAAE,mBAAmB;QACzB,OAAO,EAAE,cAAc;KACxB,CAAC,CAAC;IAEH,MAAM,MAAM,GAAG,IAAI,aAAa,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC;IACjD,MAAM,aAAa,GAAG,IAAI,aAAa,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC;IAExD,qCAAqC;IACrC,IAAI,SAAS,GAA8B,IAAI,CAAC;IAChD,IAAI,OAAO,CAAC,QAAQ,KAAK,QAAQ,EAAE,CAAC;QAClC,SAAS,GAAG,IAAI,kBAAkB,EAAE,CAAC;IACvC,CAAC;IAED,mCAAmC;IACnC,IAAI,QAAQ,GAA0B,IAAI,CAAC;IAC3C,IAAI,MAAM,CAAC,EAAE,IAAI,MAAM,CAAC,EAAE,CAAC,MAAM,EAAE,CAAC;QAClC,MAAM,QAAQ,GAAG,IAAI,QAAQ,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC;QACzC,QAAQ,GAAG,IAAI,cAAc,CAAC,QAAQ,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,EAAE;YACzD,MAAM,EAAE,MAAM,CAAC,gBAAgB;YAC/B,OAAO,EAAE,MAAM,CAAC,iBAAiB;YACjC,QAAQ,EAAE,MAAM,CAAC,kBAAkB;SACpC,EAAE,aAAa,CAAC,CAAC;IACpB,CAAC;IAED,MAAM,QAAQ,GAAG,IAAI,cAAc,EAAE,CAAC;IAEtC,sCAAsC;IACtC,MAAM,OAAO,GAAG,eAAe,EAAE,CAAC;IAClC,gBAAgB,CAAC,OAAO,CAAC,CAAC;IAE1B,gBAAgB,CAAC,MAAM,EAAE,GAAG,EAAE,CAAC,MAAM,EAAE,GAAG,EAAE,CAAC,QAAQ,EAAE,GAAG,EAAE,CAAC,aAAa,EAAE,GAAG,EAAE,CAAC,MAAM,EAAE,GAAG,EAAE,CAAC,QAAQ,EAAE,GAAG,EAAE,CAAC,SAAS,EAAE,OAAO,CAAC,CAAC;IAEpI,KAAK,UAAU,KAAK;QAClB,MAAM,SAAS,GAAG,IAAI,oBAAoB,EAAE,CAAC;QAC7C,MAAM,MAAM,CAAC,OAAO,CAAC,SAAS,CAAC,CAAC;IAClC,CAAC;IAED,OAAO,EAAE,MAAM,EAAE,KAAK,EAAE,CAAC;AAC3B,CAAC"}
@@ -14,6 +14,7 @@ import type { ScreenAnalyzer } from "../ai/analyzer.js";
14
14
  import type { FlutterDriver } from "../drivers/flutter/index.js";
15
15
  import type { ActionRecorder } from "../recording/recorder.js";
16
16
  import type { IOSSimulatorDriver } from "../drivers/ios/index.js";
17
+ import type { LicenseInfo } from "../license.js";
17
18
  export { registerDeviceTools, registerScreenTools, registerInteractionTools, registerAppTools, registerLogTools, registerFlutterTools, registerVideoTools, registerRecordingTools, registerIOSTools, };
18
19
  /**
19
20
  * Register every MCP tool with the server.
@@ -26,5 +27,5 @@ export { registerDeviceTools, registerScreenTools, registerInteractionTools, reg
26
27
  * if AI features are disabled.
27
28
  * @param getFlutter — A factory/getter that returns the FlutterDriver.
28
29
  */
29
- export declare function registerAllTools(server: McpServer, getDriver: () => DeviceDriver, getAnalyzer: () => ScreenAnalyzer | null, getFlutter: () => FlutterDriver, getAndroidDriver?: () => AndroidDriver, getRecorder?: () => ActionRecorder, getIOSDriver?: () => IOSSimulatorDriver | null): void;
30
+ export declare function registerAllTools(server: McpServer, getDriver: () => DeviceDriver, getAnalyzer: () => ScreenAnalyzer | null, getFlutter: () => FlutterDriver, getAndroidDriver?: () => AndroidDriver, getRecorder?: () => ActionRecorder, getIOSDriver?: () => IOSSimulatorDriver | null, license?: LicenseInfo): void;
30
31
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/tools/index.ts"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AACzE,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAChD,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,6BAA6B,CAAC;AAEjE,OAAO,EAAE,mBAAmB,EAAE,MAAM,mBAAmB,CAAC;AACxD,OAAO,EAAE,mBAAmB,EAAE,MAAM,mBAAmB,CAAC;AACxD,OAAO,EAAE,wBAAwB,EAAE,MAAM,wBAAwB,CAAC;AAClE,OAAO,EAAE,gBAAgB,EAAE,MAAM,gBAAgB,CAAC;AAClD,OAAO,EAAE,gBAAgB,EAAE,MAAM,gBAAgB,CAAC;AAElD,OAAO,EAAE,oBAAoB,EAAE,MAAM,oBAAoB,CAAC;AAC1D,OAAO,EAAE,kBAAkB,EAAE,MAAM,kBAAkB,CAAC;AACtD,OAAO,EAAE,sBAAsB,EAAE,MAAM,sBAAsB,CAAC;AAC9D,OAAO,EAAE,gBAAgB,EAAE,MAAM,gBAAgB,CAAC;AAClD,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,mBAAmB,CAAC;AACxD,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,6BAA6B,CAAC;AACjE,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,0BAA0B,CAAC;AAC/D,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,yBAAyB,CAAC;AAElE,OAAO,EACL,mBAAmB,EACnB,mBAAmB,EACnB,wBAAwB,EACxB,gBAAgB,EAChB,gBAAgB,EAChB,oBAAoB,EACpB,kBAAkB,EAClB,sBAAsB,EACtB,gBAAgB,GACjB,CAAC;AA8CF;;;;;;;;;;GAUG;AACH,wBAAgB,gBAAgB,CAC9B,MAAM,EAAE,SAAS,EACjB,SAAS,EAAE,MAAM,YAAY,EAC7B,WAAW,EAAE,MAAM,cAAc,GAAG,IAAI,EACxC,UAAU,EAAE,MAAM,aAAa,EAC/B,gBAAgB,CAAC,EAAE,MAAM,aAAa,EACtC,WAAW,CAAC,EAAE,MAAM,cAAc,EAClC,YAAY,CAAC,EAAE,MAAM,kBAAkB,GAAG,IAAI,GAC7C,IAAI,CAoBN"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/tools/index.ts"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AACzE,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAChD,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,6BAA6B,CAAC;AAEjE,OAAO,EAAE,mBAAmB,EAAE,MAAM,mBAAmB,CAAC;AACxD,OAAO,EAAE,mBAAmB,EAAE,MAAM,mBAAmB,CAAC;AACxD,OAAO,EAAE,wBAAwB,EAAE,MAAM,wBAAwB,CAAC;AAClE,OAAO,EAAE,gBAAgB,EAAE,MAAM,gBAAgB,CAAC;AAClD,OAAO,EAAE,gBAAgB,EAAE,MAAM,gBAAgB,CAAC;AAElD,OAAO,EAAE,oBAAoB,EAAE,MAAM,oBAAoB,CAAC;AAC1D,OAAO,EAAE,kBAAkB,EAAE,MAAM,kBAAkB,CAAC;AACtD,OAAO,EAAE,sBAAsB,EAAE,MAAM,sBAAsB,CAAC;AAC9D,OAAO,EAAE,gBAAgB,EAAE,MAAM,gBAAgB,CAAC;AAClD,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,mBAAmB,CAAC;AACxD,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,6BAA6B,CAAC;AACjE,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,0BAA0B,CAAC;AAC/D,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,yBAAyB,CAAC;AAElE,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,eAAe,CAAC;AAEjD,OAAO,EACL,mBAAmB,EACnB,mBAAmB,EACnB,wBAAwB,EACxB,gBAAgB,EAChB,gBAAgB,EAChB,oBAAoB,EACpB,kBAAkB,EAClB,sBAAsB,EACtB,gBAAgB,GACjB,CAAC;AAgFF;;;;;;;;;;GAUG;AACH,wBAAgB,gBAAgB,CAC9B,MAAM,EAAE,SAAS,EACjB,SAAS,EAAE,MAAM,YAAY,EAC7B,WAAW,EAAE,MAAM,cAAc,GAAG,IAAI,EACxC,UAAU,EAAE,MAAM,aAAa,EAC/B,gBAAgB,CAAC,EAAE,MAAM,aAAa,EACtC,WAAW,CAAC,EAAE,MAAM,cAAc,EAClC,YAAY,CAAC,EAAE,MAAM,kBAAkB,GAAG,IAAI,EAC9C,OAAO,CAAC,EAAE,WAAW,GACpB,IAAI,CAyBN"}
@@ -12,6 +12,7 @@ import { registerFlutterTools } from "./flutter-tools.js";
12
12
  import { registerVideoTools } from "./video-tools.js";
13
13
  import { registerRecordingTools } from "./recording-tools.js";
14
14
  import { registerIOSTools } from "./ios-tools.js";
15
+ import { FREE_TOOLS, PRO_UPGRADE_MESSAGE } from "../license.js";
15
16
  export { registerDeviceTools, registerScreenTools, registerInteractionTools, registerAppTools, registerLogTools, registerFlutterTools, registerVideoTools, registerRecordingTools, registerIOSTools, };
16
17
  // Tools that are part of the recording system itself — don't record these
17
18
  const RECORDING_TOOLS = new Set([
@@ -19,6 +20,34 @@ const RECORDING_TOOLS = new Set([
19
20
  "stop_test_recording",
20
21
  "get_recorded_actions",
21
22
  ]);
23
+ /**
24
+ * Create a proxy that intercepts registerTool calls for pro tools.
25
+ * If the user is on the free tier, pro tools are still registered
26
+ * (so they appear in the tool list) but return an upgrade message.
27
+ */
28
+ function createLicenseProxy(server) {
29
+ const originalRegisterTool = server.registerTool.bind(server);
30
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
31
+ server.registerTool = (name, config, cb) => {
32
+ if (FREE_TOOLS.has(name)) {
33
+ return originalRegisterTool(name, config, cb);
34
+ }
35
+ // Pro tool on free tier: register it with [PRO] tag but gate the handler
36
+ const proConfig = {
37
+ ...config,
38
+ title: config.title ? `${config.title} [Pro]` : undefined,
39
+ description: config.description
40
+ ? `[Pro] ${config.description}`
41
+ : undefined,
42
+ };
43
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
44
+ const gatedCb = async (..._args) => {
45
+ return PRO_UPGRADE_MESSAGE;
46
+ };
47
+ return originalRegisterTool(name, proConfig, gatedCb);
48
+ };
49
+ return server;
50
+ }
22
51
  /**
23
52
  * Create a proxy around McpServer that intercepts registerTool calls
24
53
  * to auto-record tool invocations when the ActionRecorder is active.
@@ -61,9 +90,13 @@ function createRecordingProxy(server, getRecorder) {
61
90
  * if AI features are disabled.
62
91
  * @param getFlutter — A factory/getter that returns the FlutterDriver.
63
92
  */
64
- export function registerAllTools(server, getDriver, getAnalyzer, getFlutter, getAndroidDriver, getRecorder, getIOSDriver) {
65
- // Wrap server with recording proxy if recorder is available
66
- const registrationServer = getRecorder ? createRecordingProxy(server, getRecorder) : server;
93
+ export function registerAllTools(server, getDriver, getAnalyzer, getFlutter, getAndroidDriver, getRecorder, getIOSDriver, license) {
94
+ // Wrap server with license gating proxy if on free tier
95
+ let registrationServer = license && license.tier === "free"
96
+ ? createLicenseProxy(server)
97
+ : server;
98
+ // Wrap with recording proxy if recorder is available
99
+ registrationServer = getRecorder ? createRecordingProxy(registrationServer, getRecorder) : registrationServer;
67
100
  registerDeviceTools(registrationServer, getDriver);
68
101
  registerScreenTools(registrationServer, getDriver);
69
102
  registerInteractionTools(registrationServer, getDriver);
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/tools/index.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/tools/index.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "mobile-device-mcp",
3
- "version": "0.2.1",
3
+ "version": "0.2.3",
4
4
  "description": "MCP server that gives AI coding assistants (Claude, Cursor, Windsurf) the ability to see and interact with Android mobile devices via ADB — AI-powered visual inspection, element finding, and device automation",
5
5
  "type": "module",
6
6
  "main": "dist/index.js",
@@ -69,5 +69,5 @@
69
69
  "screen-analysis",
70
70
  "ui-automation"
71
71
  ],
72
- "license": "MIT"
72
+ "license": "BUSL-1.1"
73
73
  }