mcp-android-emulator 1.2.1 → 1.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/README.md +348 -61
- package/dist/index.js +5 -6
- package/package.json +1 -1
- package/src/index.ts +5 -6
package/README.md
CHANGED
|
@@ -1,37 +1,40 @@
|
|
|
1
1
|
# MCP Android Emulator
|
|
2
2
|
|
|
3
|
+
[](https://www.npmjs.com/package/mcp-android-emulator)
|
|
4
|
+
[](https://opensource.org/licenses/MIT)
|
|
5
|
+
|
|
3
6
|
A Model Context Protocol (MCP) server that enables AI assistants like Claude to interact with Android devices and emulators via ADB (Android Debug Bridge).
|
|
4
7
|
|
|
5
8
|
## Features
|
|
6
9
|
|
|
7
10
|
- **Screenshots**: Capture device screen as base64 images
|
|
8
11
|
- **UI Inspection**: Get UI hierarchy (like DOM but for Android)
|
|
9
|
-
- **Touch Input**: Tap, swipe, scroll gestures
|
|
10
|
-
- **Text Input**: Type text
|
|
11
|
-
- **System Keys**: Press BACK, HOME, ENTER, etc.
|
|
12
|
+
- **Touch Input**: Tap, swipe, scroll, pinch zoom, multi-tap gestures
|
|
13
|
+
- **Text Input**: Type, clear, select all, set text in input fields
|
|
14
|
+
- **System Keys**: Press BACK, HOME, ENTER, VOLUME, etc.
|
|
12
15
|
- **App Management**: Launch, install, force stop, clear data
|
|
13
|
-
- **
|
|
14
|
-
- **
|
|
16
|
+
- **Clipboard**: Get and set clipboard content
|
|
17
|
+
- **Device Control**: Rotate screen, get device info
|
|
18
|
+
- **Logs**: Access logcat with filters and log levels
|
|
19
|
+
- **Wait & Assert**: Wait for elements, UI stability, assertions for testing
|
|
20
|
+
- **Safe Interactions**: Tap avoiding system bars, element bounds detection
|
|
15
21
|
|
|
16
22
|
## Requirements
|
|
17
23
|
|
|
18
24
|
- Node.js 18+
|
|
19
|
-
- Android
|
|
20
|
-
-
|
|
25
|
+
- ADB (Android Debug Bridge) installed
|
|
26
|
+
- One of the following:
|
|
27
|
+
- Android Studio Emulator (AVD)
|
|
28
|
+
- Redroid (Docker-based Android)
|
|
29
|
+
- Genymotion
|
|
30
|
+
- Physical Android device via USB/WiFi
|
|
21
31
|
|
|
22
32
|
## Installation
|
|
23
33
|
|
|
24
|
-
### From npm
|
|
34
|
+
### From npm (Recommended)
|
|
25
35
|
|
|
26
36
|
```bash
|
|
27
|
-
# Using npm
|
|
28
37
|
npm install -g mcp-android-emulator
|
|
29
|
-
|
|
30
|
-
# Using pnpm
|
|
31
|
-
pnpm add -g mcp-android-emulator
|
|
32
|
-
|
|
33
|
-
# Using yarn
|
|
34
|
-
yarn global add mcp-android-emulator
|
|
35
38
|
```
|
|
36
39
|
|
|
37
40
|
### From source
|
|
@@ -43,6 +46,27 @@ npm install
|
|
|
43
46
|
npm run build
|
|
44
47
|
```
|
|
45
48
|
|
|
49
|
+
## Quick Start
|
|
50
|
+
|
|
51
|
+
### 1. Ensure ADB is working
|
|
52
|
+
|
|
53
|
+
```bash
|
|
54
|
+
adb devices
|
|
55
|
+
# Should show your device/emulator
|
|
56
|
+
```
|
|
57
|
+
|
|
58
|
+
### 2. Add to Claude Code
|
|
59
|
+
|
|
60
|
+
```bash
|
|
61
|
+
claude mcp add android-emulator -- npx mcp-android-emulator
|
|
62
|
+
```
|
|
63
|
+
|
|
64
|
+
### 3. Start using
|
|
65
|
+
|
|
66
|
+
Ask Claude: "Take a screenshot of the Android device"
|
|
67
|
+
|
|
68
|
+
---
|
|
69
|
+
|
|
46
70
|
## Configuration
|
|
47
71
|
|
|
48
72
|
### Environment Variables
|
|
@@ -54,13 +78,15 @@ npm run build
|
|
|
54
78
|
|
|
55
79
|
### Claude Code Integration
|
|
56
80
|
|
|
57
|
-
|
|
81
|
+
**Option 1: CLI command**
|
|
58
82
|
|
|
59
83
|
```bash
|
|
60
|
-
claude mcp add android-emulator npx mcp-android-emulator
|
|
84
|
+
claude mcp add android-emulator -- npx mcp-android-emulator
|
|
61
85
|
```
|
|
62
86
|
|
|
63
|
-
|
|
87
|
+
**Option 2: Manual configuration**
|
|
88
|
+
|
|
89
|
+
Edit `~/.claude.json`:
|
|
64
90
|
|
|
65
91
|
```json
|
|
66
92
|
{
|
|
@@ -94,23 +120,56 @@ Add to `claude_desktop_config.json`:
|
|
|
94
120
|
}
|
|
95
121
|
```
|
|
96
122
|
|
|
97
|
-
|
|
123
|
+
---
|
|
124
|
+
|
|
125
|
+
## Available Tools (36 tools)
|
|
98
126
|
|
|
99
|
-
### Screen
|
|
127
|
+
### Screen Capture & UI
|
|
100
128
|
|
|
101
129
|
| Tool | Description |
|
|
102
130
|
|------|-------------|
|
|
103
131
|
| `screenshot` | Capture screen as base64 PNG image |
|
|
104
132
|
| `get_ui_tree` | Get UI element hierarchy with coordinates |
|
|
133
|
+
| `get_screen_size` | Get screen dimensions and density |
|
|
134
|
+
| `get_focused_element` | Get info about currently focused element |
|
|
135
|
+
| `is_element_visible` | Check if element is visible on screen |
|
|
136
|
+
| `get_element_bounds` | Get exact coordinates of an element |
|
|
137
|
+
| `assert_screen_contains` | Assert text is visible (for testing) |
|
|
138
|
+
|
|
139
|
+
### Touch Interactions
|
|
140
|
+
|
|
141
|
+
| Tool | Description |
|
|
142
|
+
|------|-------------|
|
|
105
143
|
| `tap` | Tap at specific coordinates |
|
|
106
144
|
| `tap_text` | Find element by text and tap it |
|
|
107
|
-
| `
|
|
145
|
+
| `tap_element` | Tap element by text or resource-id (more reliable) |
|
|
146
|
+
| `tap_safe` | Tap avoiding system navigation bars |
|
|
147
|
+
| `double_tap` | Double tap at coordinates |
|
|
108
148
|
| `long_press` | Long press for context menus |
|
|
109
|
-
| `
|
|
149
|
+
| `multi_tap` | Multiple rapid taps at same position |
|
|
110
150
|
| `swipe` | Swipe between two points |
|
|
111
151
|
| `scroll` | Scroll in a direction (up/down/left/right) |
|
|
112
|
-
| `
|
|
152
|
+
| `scroll_to_text` | Scroll until text is visible |
|
|
153
|
+
| `drag` | Drag gesture for drag & drop |
|
|
154
|
+
| `pinch_zoom` | Pinch zoom gesture (zoom in/out) |
|
|
155
|
+
|
|
156
|
+
### Text Input
|
|
157
|
+
|
|
158
|
+
| Tool | Description |
|
|
159
|
+
|------|-------------|
|
|
160
|
+
| `type_text` | Type text into focused input |
|
|
161
|
+
| `clear_input` | Clear focused text field |
|
|
162
|
+
| `select_all` | Select all text in focused field |
|
|
163
|
+
| `set_text` | Clear and type new text (combines both) |
|
|
164
|
+
|
|
165
|
+
### System & Keys
|
|
166
|
+
|
|
167
|
+
| Tool | Description |
|
|
168
|
+
|------|-------------|
|
|
113
169
|
| `press_key` | Press system key (BACK, HOME, ENTER, etc.) |
|
|
170
|
+
| `rotate_device` | Rotate to portrait or landscape |
|
|
171
|
+
| `set_clipboard` | Set text to device clipboard |
|
|
172
|
+
| `get_clipboard` | Get clipboard content |
|
|
114
173
|
|
|
115
174
|
### App Management
|
|
116
175
|
|
|
@@ -121,104 +180,324 @@ Add to `claude_desktop_config.json`:
|
|
|
121
180
|
| `list_packages` | List installed packages |
|
|
122
181
|
| `clear_app_data` | Clear app data |
|
|
123
182
|
| `force_stop` | Force stop an app |
|
|
183
|
+
| `get_current_activity` | Get currently focused activity |
|
|
124
184
|
|
|
125
185
|
### Device Info & Logs
|
|
126
186
|
|
|
127
187
|
| Tool | Description |
|
|
128
188
|
|------|-------------|
|
|
129
189
|
| `device_info` | Get device model, Android version, screen size |
|
|
130
|
-
| `get_logs` | Get logcat logs with
|
|
131
|
-
| `get_current_activity` | Get currently focused activity |
|
|
190
|
+
| `get_logs` | Get logcat logs with filters and log levels |
|
|
132
191
|
|
|
133
|
-
###
|
|
192
|
+
### Wait & Sync
|
|
134
193
|
|
|
135
194
|
| Tool | Description |
|
|
136
195
|
|------|-------------|
|
|
137
|
-
| `
|
|
138
|
-
| `
|
|
139
|
-
| `
|
|
196
|
+
| `wait_for_element` | Wait for element with text to appear |
|
|
197
|
+
| `wait_for_element_gone` | Wait for element to disappear |
|
|
198
|
+
| `wait_for_ui_stable` | Wait for UI to stop changing (after animations) |
|
|
140
199
|
|
|
141
|
-
|
|
200
|
+
---
|
|
142
201
|
|
|
143
|
-
|
|
144
|
-
|------|-------------|
|
|
145
|
-
| `wait_for_element` | Wait for UI element to appear |
|
|
202
|
+
## Emulator Setup Guides
|
|
146
203
|
|
|
147
|
-
|
|
204
|
+
### Option 1: Android Studio Emulator (AVD)
|
|
205
|
+
|
|
206
|
+
Best for: Local development on machines with display
|
|
207
|
+
|
|
208
|
+
```bash
|
|
209
|
+
# List available AVDs
|
|
210
|
+
emulator -list-avds
|
|
148
211
|
|
|
149
|
-
|
|
212
|
+
# Start emulator
|
|
213
|
+
emulator -avd YOUR_AVD_NAME
|
|
150
214
|
|
|
215
|
+
# Verify connection
|
|
216
|
+
adb devices
|
|
151
217
|
```
|
|
152
|
-
"Take a screenshot of the Android emulator"
|
|
153
218
|
|
|
154
|
-
|
|
219
|
+
### Option 2: Redroid (Docker) - Recommended for Servers
|
|
155
220
|
|
|
156
|
-
|
|
221
|
+
Best for: Headless servers, CI/CD, cloud VPS
|
|
157
222
|
|
|
158
|
-
|
|
223
|
+
Redroid runs Android in a Docker container without requiring KVM on x86.
|
|
159
224
|
|
|
160
|
-
|
|
225
|
+
```bash
|
|
226
|
+
# Run Redroid container
|
|
227
|
+
docker run -d --name redroid \
|
|
228
|
+
--privileged \
|
|
229
|
+
-p 5555:5555 \
|
|
230
|
+
redroid/redroid:13.0.0-latest \
|
|
231
|
+
androidboot.redroid_width=720 \
|
|
232
|
+
androidboot.redroid_height=1280 \
|
|
233
|
+
androidboot.redroid_dpi=320
|
|
234
|
+
|
|
235
|
+
# Connect ADB
|
|
236
|
+
adb connect localhost:5555
|
|
237
|
+
|
|
238
|
+
# Verify
|
|
239
|
+
adb devices
|
|
240
|
+
```
|
|
161
241
|
|
|
162
|
-
|
|
242
|
+
**For apps using network (React Native, Expo, etc.):**
|
|
243
|
+
|
|
244
|
+
```bash
|
|
245
|
+
# Forward ports from device to host
|
|
246
|
+
adb reverse tcp:8081 tcp:8081 # Metro bundler
|
|
247
|
+
adb reverse tcp:3000 tcp:3000 # API server
|
|
163
248
|
```
|
|
164
249
|
|
|
165
|
-
|
|
250
|
+
### Option 3: Genymotion
|
|
251
|
+
|
|
252
|
+
Best for: Local development, faster than AVD
|
|
253
|
+
|
|
254
|
+
1. Download from [genymotion.com](https://www.genymotion.com/)
|
|
255
|
+
2. Create and start a virtual device
|
|
256
|
+
3. Enable ADB bridge in settings
|
|
257
|
+
4. Connect: `adb connect localhost:5555`
|
|
166
258
|
|
|
167
|
-
|
|
259
|
+
### Option 4: Physical Device
|
|
168
260
|
|
|
261
|
+
Best for: Real-world testing
|
|
262
|
+
|
|
263
|
+
**USB Connection:**
|
|
264
|
+
1. Enable Developer Options on device
|
|
265
|
+
2. Enable USB Debugging
|
|
266
|
+
3. Connect via USB
|
|
267
|
+
4. Run `adb devices`
|
|
268
|
+
|
|
269
|
+
**WiFi Connection:**
|
|
169
270
|
```bash
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
-gpu swiftshader_indirect \
|
|
175
|
-
-memory 2048 \
|
|
176
|
-
-cores 2
|
|
271
|
+
# First connect via USB, then:
|
|
272
|
+
adb tcpip 5555
|
|
273
|
+
adb connect DEVICE_IP:5555
|
|
274
|
+
# Disconnect USB
|
|
177
275
|
```
|
|
178
276
|
|
|
277
|
+
---
|
|
278
|
+
|
|
279
|
+
## Running on Cloud/VPS Servers
|
|
280
|
+
|
|
281
|
+
### Prerequisites
|
|
282
|
+
|
|
283
|
+
- Linux server (Ubuntu 20.04+ recommended)
|
|
284
|
+
- Docker installed
|
|
285
|
+
- At least 4GB RAM, 2 CPU cores
|
|
286
|
+
|
|
287
|
+
### Step-by-Step Setup
|
|
288
|
+
|
|
289
|
+
#### 1. Install ADB
|
|
290
|
+
|
|
291
|
+
```bash
|
|
292
|
+
# Ubuntu/Debian
|
|
293
|
+
sudo apt update
|
|
294
|
+
sudo apt install android-tools-adb
|
|
295
|
+
|
|
296
|
+
# Verify
|
|
297
|
+
adb version
|
|
298
|
+
```
|
|
299
|
+
|
|
300
|
+
#### 2. Run Redroid
|
|
301
|
+
|
|
302
|
+
```bash
|
|
303
|
+
docker run -d --name redroid \
|
|
304
|
+
--privileged \
|
|
305
|
+
-p 5555:5555 \
|
|
306
|
+
redroid/redroid:13.0.0-latest \
|
|
307
|
+
androidboot.redroid_width=720 \
|
|
308
|
+
androidboot.redroid_height=1280 \
|
|
309
|
+
androidboot.redroid_dpi=320
|
|
310
|
+
```
|
|
311
|
+
|
|
312
|
+
#### 3. Connect ADB
|
|
313
|
+
|
|
314
|
+
```bash
|
|
315
|
+
adb connect localhost:5555
|
|
316
|
+
adb devices # Should show "localhost:5555 device"
|
|
317
|
+
```
|
|
318
|
+
|
|
319
|
+
#### 4. Install Node.js and MCP
|
|
320
|
+
|
|
321
|
+
```bash
|
|
322
|
+
# Install Node.js 18+
|
|
323
|
+
curl -fsSL https://deb.nodesource.com/setup_18.x | sudo -E bash -
|
|
324
|
+
sudo apt install -y nodejs
|
|
325
|
+
|
|
326
|
+
# Install MCP
|
|
327
|
+
npm install -g mcp-android-emulator
|
|
328
|
+
```
|
|
329
|
+
|
|
330
|
+
#### 5. Configure Claude Code
|
|
331
|
+
|
|
332
|
+
```bash
|
|
333
|
+
claude mcp add android-emulator -- npx mcp-android-emulator
|
|
334
|
+
```
|
|
335
|
+
|
|
336
|
+
### Running AVD Headless (Alternative)
|
|
337
|
+
|
|
338
|
+
If you have KVM support:
|
|
339
|
+
|
|
340
|
+
```bash
|
|
341
|
+
# Install Android SDK
|
|
342
|
+
sudo apt install openjdk-11-jdk
|
|
343
|
+
wget https://dl.google.com/android/repository/commandlinetools-linux-latest.zip
|
|
344
|
+
# ... setup SDK ...
|
|
345
|
+
|
|
346
|
+
# Run emulator headless
|
|
347
|
+
emulator -avd YOUR_AVD \
|
|
348
|
+
-no-window \
|
|
349
|
+
-no-audio \
|
|
350
|
+
-no-boot-anim \
|
|
351
|
+
-gpu swiftshader_indirect \
|
|
352
|
+
-memory 2048 \
|
|
353
|
+
-cores 2
|
|
354
|
+
```
|
|
355
|
+
|
|
356
|
+
---
|
|
357
|
+
|
|
358
|
+
## Usage Examples
|
|
359
|
+
|
|
360
|
+
Once configured, ask Claude to:
|
|
361
|
+
|
|
362
|
+
```
|
|
363
|
+
"Take a screenshot of the Android device"
|
|
364
|
+
|
|
365
|
+
"Tap on the Login button"
|
|
366
|
+
|
|
367
|
+
"Type 'hello@example.com' in the email field and press Enter"
|
|
368
|
+
|
|
369
|
+
"Scroll down until you see 'Submit' and tap it"
|
|
370
|
+
|
|
371
|
+
"Launch the Chrome app and navigate to google.com"
|
|
372
|
+
|
|
373
|
+
"Get error logs from the last 100 lines"
|
|
374
|
+
|
|
375
|
+
"Wait for the loading spinner to disappear, then take a screenshot"
|
|
376
|
+
|
|
377
|
+
"Check if 'Welcome' text is visible on screen"
|
|
378
|
+
|
|
379
|
+
"Rotate the device to landscape mode"
|
|
380
|
+
```
|
|
381
|
+
|
|
382
|
+
### Automated Testing Example
|
|
383
|
+
|
|
384
|
+
```
|
|
385
|
+
"Test the login flow:
|
|
386
|
+
1. Take a screenshot of the initial state
|
|
387
|
+
2. Type 'testuser' in the username field
|
|
388
|
+
3. Type 'password123' in the password field
|
|
389
|
+
4. Tap the Login button
|
|
390
|
+
5. Wait for the UI to stabilize
|
|
391
|
+
6. Assert that 'Dashboard' is visible
|
|
392
|
+
7. Take a final screenshot"
|
|
393
|
+
```
|
|
394
|
+
|
|
395
|
+
---
|
|
396
|
+
|
|
179
397
|
## Troubleshooting
|
|
180
398
|
|
|
181
399
|
### ADB not found
|
|
182
400
|
|
|
183
|
-
Set the `ADB_PATH` environment variable:
|
|
184
|
-
|
|
185
401
|
```bash
|
|
402
|
+
# Check if ADB is installed
|
|
403
|
+
which adb
|
|
404
|
+
|
|
405
|
+
# If not found, install it
|
|
406
|
+
sudo apt install android-tools-adb # Ubuntu/Debian
|
|
407
|
+
brew install android-platform-tools # macOS
|
|
408
|
+
|
|
409
|
+
# Or set custom path
|
|
186
410
|
export ADB_PATH=/path/to/android-sdk/platform-tools/adb
|
|
187
411
|
```
|
|
188
412
|
|
|
189
413
|
### No devices connected
|
|
190
414
|
|
|
191
|
-
Check device connection:
|
|
192
|
-
|
|
193
415
|
```bash
|
|
416
|
+
# List devices
|
|
194
417
|
adb devices
|
|
195
|
-
```
|
|
196
418
|
|
|
197
|
-
|
|
419
|
+
# If using Redroid, connect explicitly
|
|
420
|
+
adb connect localhost:5555
|
|
198
421
|
|
|
199
|
-
|
|
422
|
+
# Check if emulator is fully booted
|
|
200
423
|
adb shell getprop sys.boot_completed # Should return "1"
|
|
201
424
|
```
|
|
202
425
|
|
|
203
426
|
### Permission denied on screenshots
|
|
204
427
|
|
|
205
|
-
Ensure the screenshot directory is writable:
|
|
206
|
-
|
|
207
428
|
```bash
|
|
208
429
|
mkdir -p /tmp/android-screenshots
|
|
209
430
|
chmod 755 /tmp/android-screenshots
|
|
210
431
|
```
|
|
211
432
|
|
|
433
|
+
### Redroid container won't start
|
|
434
|
+
|
|
435
|
+
```bash
|
|
436
|
+
# Check logs
|
|
437
|
+
docker logs redroid
|
|
438
|
+
|
|
439
|
+
# Ensure privileged mode
|
|
440
|
+
docker run --privileged ...
|
|
441
|
+
|
|
442
|
+
# Try different Android version
|
|
443
|
+
docker run ... redroid/redroid:11.0.0-latest
|
|
444
|
+
```
|
|
445
|
+
|
|
446
|
+
### Apps can't reach localhost services
|
|
447
|
+
|
|
448
|
+
```bash
|
|
449
|
+
# Forward ports from device to host
|
|
450
|
+
adb reverse tcp:8081 tcp:8081
|
|
451
|
+
adb reverse tcp:3000 tcp:3000
|
|
452
|
+
|
|
453
|
+
# Verify
|
|
454
|
+
adb reverse --list
|
|
455
|
+
```
|
|
456
|
+
|
|
457
|
+
---
|
|
458
|
+
|
|
459
|
+
## Changelog
|
|
460
|
+
|
|
461
|
+
### v1.2.3 (Latest)
|
|
462
|
+
- Updated documentation with comprehensive setup guides
|
|
463
|
+
- Added emulator comparison (AVD, Redroid, Genymotion, Physical)
|
|
464
|
+
- Added cloud/VPS deployment instructions
|
|
465
|
+
- Added troubleshooting section
|
|
466
|
+
|
|
467
|
+
### v1.2.2
|
|
468
|
+
- Fixed `set_clipboard` and `get_clipboard` for Redroid/Docker compatibility
|
|
469
|
+
- Uses `/data/local/tmp` as fallback path
|
|
470
|
+
|
|
471
|
+
### v1.2.0
|
|
472
|
+
- Added 14 new tools:
|
|
473
|
+
- `get_screen_size`, `is_element_visible`, `get_element_bounds`
|
|
474
|
+
- `scroll_to_text`, `wait_for_ui_stable`, `wait_for_element_gone`
|
|
475
|
+
- `multi_tap`, `pinch_zoom`, `tap_safe`, `tap_element`
|
|
476
|
+
- `set_clipboard`, `get_clipboard`, `rotate_device`
|
|
477
|
+
- `get_focused_element`, `assert_screen_contains`
|
|
478
|
+
|
|
479
|
+
### v1.1.0
|
|
480
|
+
- Added `double_tap`, `drag`, `set_text`, `select_all`, `clear_input`
|
|
481
|
+
|
|
482
|
+
### v1.0.0
|
|
483
|
+
- Initial release with core functionality
|
|
484
|
+
|
|
485
|
+
---
|
|
486
|
+
|
|
212
487
|
## Development
|
|
213
488
|
|
|
214
489
|
```bash
|
|
490
|
+
# Clone repo
|
|
491
|
+
git clone https://github.com/Anjos2/mcp-android-emulator.git
|
|
492
|
+
cd mcp-android-emulator
|
|
493
|
+
|
|
215
494
|
# Install dependencies
|
|
216
495
|
npm install
|
|
217
496
|
|
|
218
497
|
# Build
|
|
219
498
|
npm run build
|
|
220
499
|
|
|
221
|
-
# Watch mode
|
|
500
|
+
# Watch mode for development
|
|
222
501
|
npm run dev
|
|
223
502
|
```
|
|
224
503
|
|
|
@@ -230,8 +509,16 @@ MIT License - see [LICENSE](LICENSE) for details.
|
|
|
230
509
|
|
|
231
510
|
Contributions are welcome! Please feel free to submit a Pull Request.
|
|
232
511
|
|
|
512
|
+
### Ideas for contributions:
|
|
513
|
+
- Support for multiple connected devices
|
|
514
|
+
- Screen recording
|
|
515
|
+
- File transfer (push/pull)
|
|
516
|
+
- Network simulation
|
|
517
|
+
- Battery/GPS simulation
|
|
518
|
+
|
|
233
519
|
## Related Projects
|
|
234
520
|
|
|
235
521
|
- [Model Context Protocol](https://modelcontextprotocol.io/)
|
|
236
522
|
- [Android Debug Bridge (ADB)](https://developer.android.com/tools/adb)
|
|
237
|
-
- [Claude Code](https://claude.ai/
|
|
523
|
+
- [Claude Code](https://claude.ai/code)
|
|
524
|
+
- [Redroid](https://github.com/remote-android/redroid-doc)
|
package/dist/index.js
CHANGED
|
@@ -41,7 +41,7 @@ async function shell(command) {
|
|
|
41
41
|
// Create MCP server
|
|
42
42
|
const server = new McpServer({
|
|
43
43
|
name: "android-emulator",
|
|
44
|
-
version: "1.2.
|
|
44
|
+
version: "1.2.3",
|
|
45
45
|
});
|
|
46
46
|
// =====================================================
|
|
47
47
|
// TOOL: screenshot
|
|
@@ -917,15 +917,14 @@ server.tool("set_clipboard", "Set text to the device clipboard", {
|
|
|
917
917
|
// Try multiple paths for compatibility (standard emulators vs Redroid/Docker)
|
|
918
918
|
const paths = ["/data/local/tmp/clipboard_temp.txt", "/sdcard/clipboard_temp.txt"];
|
|
919
919
|
let success = false;
|
|
920
|
-
let usedPath = "";
|
|
921
920
|
for (const clipPath of paths) {
|
|
922
921
|
try {
|
|
923
|
-
|
|
922
|
+
// Use single quotes to ensure the entire command runs on device (pipe included)
|
|
923
|
+
await shell(`'echo "${base64Text}" | base64 -d > ${clipPath}'`);
|
|
924
924
|
// Verify write succeeded
|
|
925
|
-
const verify = await shell(`cat ${clipPath} 2>/dev/null
|
|
926
|
-
if (verify.length > 0) {
|
|
925
|
+
const verify = await shell(`cat ${clipPath} 2>/dev/null`);
|
|
926
|
+
if (verify && verify.length > 0) {
|
|
927
927
|
success = true;
|
|
928
|
-
usedPath = clipPath;
|
|
929
928
|
break;
|
|
930
929
|
}
|
|
931
930
|
}
|
package/package.json
CHANGED
package/src/index.ts
CHANGED
|
@@ -47,7 +47,7 @@ async function shell(command: string): Promise<string> {
|
|
|
47
47
|
// Create MCP server
|
|
48
48
|
const server = new McpServer({
|
|
49
49
|
name: "android-emulator",
|
|
50
|
-
version: "1.2.
|
|
50
|
+
version: "1.2.3",
|
|
51
51
|
});
|
|
52
52
|
|
|
53
53
|
// =====================================================
|
|
@@ -1194,16 +1194,15 @@ server.tool(
|
|
|
1194
1194
|
// Try multiple paths for compatibility (standard emulators vs Redroid/Docker)
|
|
1195
1195
|
const paths = ["/data/local/tmp/clipboard_temp.txt", "/sdcard/clipboard_temp.txt"];
|
|
1196
1196
|
let success = false;
|
|
1197
|
-
let usedPath = "";
|
|
1198
1197
|
|
|
1199
1198
|
for (const clipPath of paths) {
|
|
1200
1199
|
try {
|
|
1201
|
-
|
|
1200
|
+
// Use single quotes to ensure the entire command runs on device (pipe included)
|
|
1201
|
+
await shell(`'echo "${base64Text}" | base64 -d > ${clipPath}'`);
|
|
1202
1202
|
// Verify write succeeded
|
|
1203
|
-
const verify = await shell(`cat ${clipPath} 2>/dev/null
|
|
1204
|
-
if (verify.length > 0) {
|
|
1203
|
+
const verify = await shell(`cat ${clipPath} 2>/dev/null`);
|
|
1204
|
+
if (verify && verify.length > 0) {
|
|
1205
1205
|
success = true;
|
|
1206
|
-
usedPath = clipPath;
|
|
1207
1206
|
break;
|
|
1208
1207
|
}
|
|
1209
1208
|
} catch {
|