mcadb 0.3.1__tar.gz
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.
- mcadb-0.3.1/.gitignore +69 -0
- mcadb-0.3.1/CLAUDE.md +74 -0
- mcadb-0.3.1/Dockerfile +28 -0
- mcadb-0.3.1/PKG-INFO +275 -0
- mcadb-0.3.1/README.md +251 -0
- mcadb-0.3.1/docker-compose.yml +17 -0
- mcadb-0.3.1/pyproject.toml +60 -0
- mcadb-0.3.1/src/__init__.py +20 -0
- mcadb-0.3.1/src/config.py +100 -0
- mcadb-0.3.1/src/mixins/__init__.py +19 -0
- mcadb-0.3.1/src/mixins/apps.py +569 -0
- mcadb-0.3.1/src/mixins/base.py +169 -0
- mcadb-0.3.1/src/mixins/devices.py +460 -0
- mcadb-0.3.1/src/mixins/files.py +321 -0
- mcadb-0.3.1/src/mixins/input.py +511 -0
- mcadb-0.3.1/src/mixins/screenshot.py +398 -0
- mcadb-0.3.1/src/mixins/ui.py +367 -0
- mcadb-0.3.1/src/models.py +36 -0
- mcadb-0.3.1/src/server.py +237 -0
- mcadb-0.3.1/uv.lock +1716 -0
mcadb-0.3.1/.gitignore
ADDED
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
# Python
|
|
2
|
+
__pycache__/
|
|
3
|
+
*.py[cod]
|
|
4
|
+
*$py.class
|
|
5
|
+
*.so
|
|
6
|
+
.Python
|
|
7
|
+
build/
|
|
8
|
+
develop-eggs/
|
|
9
|
+
dist/
|
|
10
|
+
downloads/
|
|
11
|
+
eggs/
|
|
12
|
+
.eggs/
|
|
13
|
+
lib/
|
|
14
|
+
lib64/
|
|
15
|
+
parts/
|
|
16
|
+
sdist/
|
|
17
|
+
var/
|
|
18
|
+
wheels/
|
|
19
|
+
*.egg-info/
|
|
20
|
+
.installed.cfg
|
|
21
|
+
*.egg
|
|
22
|
+
MANIFEST
|
|
23
|
+
|
|
24
|
+
# Virtual environments
|
|
25
|
+
.env
|
|
26
|
+
.venv
|
|
27
|
+
env/
|
|
28
|
+
venv/
|
|
29
|
+
ENV/
|
|
30
|
+
env.bak/
|
|
31
|
+
venv.bak/
|
|
32
|
+
|
|
33
|
+
# IDE
|
|
34
|
+
.vscode/
|
|
35
|
+
.idea/
|
|
36
|
+
*.swp
|
|
37
|
+
*.swo
|
|
38
|
+
*~
|
|
39
|
+
|
|
40
|
+
# OS
|
|
41
|
+
.DS_Store
|
|
42
|
+
.DS_Store?
|
|
43
|
+
._*
|
|
44
|
+
.Spotlight-V100
|
|
45
|
+
.Trashes
|
|
46
|
+
ehthumbs.db
|
|
47
|
+
Thumbs.db
|
|
48
|
+
|
|
49
|
+
# Testing
|
|
50
|
+
.coverage
|
|
51
|
+
.pytest_cache/
|
|
52
|
+
htmlcov/
|
|
53
|
+
.tox/
|
|
54
|
+
|
|
55
|
+
# Linting
|
|
56
|
+
.ruff_cache/
|
|
57
|
+
.mypy_cache/
|
|
58
|
+
|
|
59
|
+
# Screenshots and recordings
|
|
60
|
+
*.png
|
|
61
|
+
*.jpg
|
|
62
|
+
*.jpeg
|
|
63
|
+
*.mp4
|
|
64
|
+
|
|
65
|
+
# Docker
|
|
66
|
+
.dockerignore
|
|
67
|
+
|
|
68
|
+
# uv
|
|
69
|
+
.uv/
|
mcadb-0.3.1/CLAUDE.md
ADDED
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
# CLAUDE.md
|
|
2
|
+
|
|
3
|
+
This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
|
|
4
|
+
|
|
5
|
+
## Project Overview
|
|
6
|
+
|
|
7
|
+
mcadb - A FastMCP server exposing Android Debug Bridge (ADB) functionality through the Model Context Protocol. Enables AI assistants to automate Android devices via screenshots, input simulation, app control, UI inspection, file transfer, and shell commands.
|
|
8
|
+
|
|
9
|
+
## Commands
|
|
10
|
+
|
|
11
|
+
```bash
|
|
12
|
+
# Install dependencies
|
|
13
|
+
uv sync
|
|
14
|
+
|
|
15
|
+
# Run the server locally
|
|
16
|
+
uv run mcadb
|
|
17
|
+
|
|
18
|
+
# Run directly with uvx (no install needed)
|
|
19
|
+
uvx mcadb
|
|
20
|
+
|
|
21
|
+
# Development dependencies
|
|
22
|
+
uv sync --group dev
|
|
23
|
+
|
|
24
|
+
# Linting and formatting
|
|
25
|
+
uv run ruff check src/
|
|
26
|
+
uv run ruff format src/
|
|
27
|
+
|
|
28
|
+
# Type checking
|
|
29
|
+
uv run mypy src/
|
|
30
|
+
|
|
31
|
+
# Docker (requires privileged mode for USB access)
|
|
32
|
+
docker compose up --build
|
|
33
|
+
```
|
|
34
|
+
|
|
35
|
+
## Architecture
|
|
36
|
+
|
|
37
|
+
Modular MCPMixin architecture with 50 tools across 6 domain mixins:
|
|
38
|
+
|
|
39
|
+
- **`src/server.py`**: FastMCP app and `ADBServer` class (thin orchestrator inheriting all mixins)
|
|
40
|
+
- **`src/config.py`**: Persistent singleton config (`~/.config/adb-mcp/config.json`)
|
|
41
|
+
- **`src/models.py`**: Pydantic models (`DeviceInfo`, `CommandResult`, `ScreenshotResult`)
|
|
42
|
+
- **`src/mixins/base.py`**: Core ADB execution with `run_adb()`, `run_shell()`, and injection-safe `run_shell_args()` using `shlex.quote()`
|
|
43
|
+
- **`src/mixins/devices.py`**: Device discovery, info, logcat, reboot
|
|
44
|
+
- **`src/mixins/input.py`**: Tap, swipe, scroll, keys, text, clipboard, shell command
|
|
45
|
+
- **`src/mixins/apps.py`**: Launch, close, install, intents, broadcasts
|
|
46
|
+
- **`src/mixins/screenshot.py`**: Screen capture, recording, display settings
|
|
47
|
+
- **`src/mixins/ui.py`**: Accessibility tree dump, element search, text polling
|
|
48
|
+
- **`src/mixins/files.py`**: Push, pull, list, delete, exists
|
|
49
|
+
|
|
50
|
+
### Key Patterns
|
|
51
|
+
|
|
52
|
+
- All tools use `run_shell_args()` (injection-safe) except `shell_command` which intentionally uses `run_shell()` for raw commands
|
|
53
|
+
- Developer mode tools are gated by `is_developer_mode()` checks and tagged with `tags={"developer"}`
|
|
54
|
+
- Destructive operations use `ctx.elicit()` for user confirmation
|
|
55
|
+
- `@mcp_tool()` and `@mcp_resource()` decorators from `fastmcp.contrib.mcp_mixin`
|
|
56
|
+
|
|
57
|
+
## MCP Client Configuration
|
|
58
|
+
|
|
59
|
+
```json
|
|
60
|
+
{
|
|
61
|
+
"mcpServers": {
|
|
62
|
+
"mcadb": {
|
|
63
|
+
"command": "uvx",
|
|
64
|
+
"args": ["mcadb"]
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
```
|
|
69
|
+
|
|
70
|
+
## Device Requirements
|
|
71
|
+
|
|
72
|
+
- ADB installed and accessible in PATH
|
|
73
|
+
- USB debugging enabled on Android device
|
|
74
|
+
- For Docker: `--privileged` flag and `/dev/bus/usb` volume mount required
|
mcadb-0.3.1/Dockerfile
ADDED
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
FROM python:3.11-slim
|
|
2
|
+
|
|
3
|
+
# Install system dependencies including ADB
|
|
4
|
+
RUN apt-get update && apt-get install -y \
|
|
5
|
+
android-tools-adb \
|
|
6
|
+
android-tools-fastboot \
|
|
7
|
+
usbutils \
|
|
8
|
+
&& rm -rf /var/lib/apt/lists/*
|
|
9
|
+
|
|
10
|
+
# Install uv
|
|
11
|
+
COPY --from=ghcr.io/astral-sh/uv:latest /uv /bin/uv
|
|
12
|
+
|
|
13
|
+
# Set working directory
|
|
14
|
+
WORKDIR /app
|
|
15
|
+
|
|
16
|
+
# Copy project files
|
|
17
|
+
COPY pyproject.toml uv.lock* ./
|
|
18
|
+
|
|
19
|
+
# Install dependencies
|
|
20
|
+
RUN uv sync --frozen
|
|
21
|
+
|
|
22
|
+
# Copy source code
|
|
23
|
+
COPY src/ ./src/
|
|
24
|
+
|
|
25
|
+
# Expose ADB server port (optional, mainly for debugging)
|
|
26
|
+
EXPOSE 5037
|
|
27
|
+
|
|
28
|
+
CMD ["uv", "run", "mcadb"]
|
mcadb-0.3.1/PKG-INFO
ADDED
|
@@ -0,0 +1,275 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: mcadb
|
|
3
|
+
Version: 0.3.1
|
|
4
|
+
Summary: Android ADB MCP Server for device automation via Model Context Protocol
|
|
5
|
+
Project-URL: Homepage, https://git.supported.systems/MCP/mcp-adb
|
|
6
|
+
Project-URL: Documentation, https://git.supported.systems/MCP/mcp-adb#readme
|
|
7
|
+
Project-URL: Repository, https://git.supported.systems/MCP/mcp-adb
|
|
8
|
+
Author-email: Ryan Malloy <ryan@supported.systems>
|
|
9
|
+
License: MIT
|
|
10
|
+
Keywords: adb,android,automation,fastmcp,mcp
|
|
11
|
+
Classifier: Development Status :: 4 - Beta
|
|
12
|
+
Classifier: Intended Audience :: Developers
|
|
13
|
+
Classifier: License :: OSI Approved :: MIT License
|
|
14
|
+
Classifier: Programming Language :: Python :: 3
|
|
15
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
16
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
17
|
+
Classifier: Programming Language :: Python :: 3.13
|
|
18
|
+
Classifier: Topic :: Software Development :: Testing
|
|
19
|
+
Classifier: Topic :: System :: Hardware :: Hardware Drivers
|
|
20
|
+
Requires-Python: >=3.11
|
|
21
|
+
Requires-Dist: fastmcp<3.0.0,>=2.14.0
|
|
22
|
+
Requires-Dist: pydantic>=2.12.0
|
|
23
|
+
Description-Content-Type: text/markdown
|
|
24
|
+
|
|
25
|
+
# mcadb
|
|
26
|
+
|
|
27
|
+
A [Model Context Protocol](https://modelcontextprotocol.io/) server that gives AI assistants direct control over Android devices through ADB. Point any MCP-compatible client at a phone plugged into USB, and it can take screenshots, tap buttons, launch apps, inspect UI elements, transfer files, and run shell commands — all through structured, type-safe tool calls.
|
|
28
|
+
|
|
29
|
+
Built on [FastMCP](https://gofastmcp.com/) with a modular mixin architecture. 50 tools across 6 domains. Tested on real hardware.
|
|
30
|
+
|
|
31
|
+
## Quick Start
|
|
32
|
+
|
|
33
|
+
```bash
|
|
34
|
+
# Run directly (no install)
|
|
35
|
+
uvx mcadb
|
|
36
|
+
|
|
37
|
+
# Or install and run
|
|
38
|
+
uv add mcadb
|
|
39
|
+
mcadb
|
|
40
|
+
```
|
|
41
|
+
|
|
42
|
+
### MCP Client Configuration
|
|
43
|
+
|
|
44
|
+
Add to your MCP client's config (Claude Desktop, Claude Code, etc.):
|
|
45
|
+
|
|
46
|
+
```json
|
|
47
|
+
{
|
|
48
|
+
"mcpServers": {
|
|
49
|
+
"mcadb": {
|
|
50
|
+
"command": "uvx",
|
|
51
|
+
"args": ["mcadb"]
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
```
|
|
56
|
+
|
|
57
|
+
For Claude Code:
|
|
58
|
+
```bash
|
|
59
|
+
claude mcp add mcadb -- uvx mcadb
|
|
60
|
+
```
|
|
61
|
+
|
|
62
|
+
For local development:
|
|
63
|
+
```bash
|
|
64
|
+
claude mcp add mcadb -- uv run --directory /path/to/mcp-adb mcadb
|
|
65
|
+
```
|
|
66
|
+
|
|
67
|
+
## Prerequisites
|
|
68
|
+
|
|
69
|
+
- **Python 3.11+**
|
|
70
|
+
- **ADB** installed and on `PATH` (`adb devices` should work)
|
|
71
|
+
- **USB debugging** enabled on the Android device
|
|
72
|
+
- Device connected via USB (or `adb connect` for network)
|
|
73
|
+
|
|
74
|
+
## What Can It Do?
|
|
75
|
+
|
|
76
|
+
### Standard Tools (always available)
|
|
77
|
+
|
|
78
|
+
| Domain | Tool | What it does |
|
|
79
|
+
|--------|------|-------------|
|
|
80
|
+
| **Devices** | `devices_list` | Discover connected devices (USB + network) |
|
|
81
|
+
| | `devices_use` | Set active device for multi-device setups |
|
|
82
|
+
| | `devices_current` | Show which device is selected |
|
|
83
|
+
| | `device_info` | Battery, WiFi, storage, Android version, model |
|
|
84
|
+
| **Input** | `input_tap` | Tap at screen coordinates |
|
|
85
|
+
| | `input_swipe` | Swipe between two points |
|
|
86
|
+
| | `input_scroll_down` | Scroll down (auto-detects screen size) |
|
|
87
|
+
| | `input_scroll_up` | Scroll up (auto-detects screen size) |
|
|
88
|
+
| | `input_back` | Press Back |
|
|
89
|
+
| | `input_home` | Press Home |
|
|
90
|
+
| | `input_recent_apps` | Open app switcher |
|
|
91
|
+
| | `input_key` | Send any key event (`VOLUME_UP`, `ENTER`, etc.) |
|
|
92
|
+
| | `input_text` | Type text into focused field |
|
|
93
|
+
| | `clipboard_set` | Set clipboard (handles special chars), optional auto-paste |
|
|
94
|
+
| **Apps** | `app_launch` | Launch app by package name |
|
|
95
|
+
| | `app_open_url` | Open URL in default browser |
|
|
96
|
+
| | `app_close` | Force stop an app |
|
|
97
|
+
| | `app_current` | Get the foreground app and activity |
|
|
98
|
+
| **Screen** | `screenshot` | Capture screen as PNG |
|
|
99
|
+
| | `screen_size` | Get display resolution |
|
|
100
|
+
| | `screen_density` | Get display DPI |
|
|
101
|
+
| | `screen_on` / `screen_off` | Wake or sleep the display |
|
|
102
|
+
| **UI** | `ui_dump` | Dump accessibility tree (all visible elements) |
|
|
103
|
+
| | `ui_find_element` | Search for elements by text, ID, class, or description |
|
|
104
|
+
| | `wait_for_text` | Poll until text appears on screen |
|
|
105
|
+
| | `wait_for_text_gone` | Poll until text disappears |
|
|
106
|
+
| | `tap_text` | Find an element by text and tap it |
|
|
107
|
+
| **Config** | `config_status` | Show current settings |
|
|
108
|
+
| | `config_set_developer_mode` | Toggle developer tools |
|
|
109
|
+
| | `config_set_screenshot_dir` | Set where screenshots are saved |
|
|
110
|
+
|
|
111
|
+
### Developer Mode Tools
|
|
112
|
+
|
|
113
|
+
Enable with `config_set_developer_mode(true)` to unlock power-user tools. Destructive operations (uninstall, clear data, reboot, delete) require user confirmation via MCP elicitation.
|
|
114
|
+
|
|
115
|
+
| Domain | Tool | What it does |
|
|
116
|
+
|--------|------|-------------|
|
|
117
|
+
| **Shell** | `shell_command` | Run any shell command on device |
|
|
118
|
+
| **Input** | `input_long_press` | Press and hold gesture |
|
|
119
|
+
| **Apps** | `app_list_packages` | List installed packages (with filters) |
|
|
120
|
+
| | `app_install` | Install APK from host |
|
|
121
|
+
| | `app_uninstall` | Remove an app (with confirmation) |
|
|
122
|
+
| | `app_clear_data` | Wipe app data (with confirmation) |
|
|
123
|
+
| | `activity_start` | Launch activity with full intent control |
|
|
124
|
+
| | `broadcast_send` | Send broadcast intents |
|
|
125
|
+
| **Screen** | `screen_record` | Record screen to MP4 |
|
|
126
|
+
| | `screen_set_size` | Override display resolution |
|
|
127
|
+
| | `screen_reset_size` | Restore original resolution |
|
|
128
|
+
| **Device** | `device_reboot` | Reboot device (with confirmation) |
|
|
129
|
+
| | `logcat_capture` | Capture system logs |
|
|
130
|
+
| | `logcat_clear` | Clear log buffer |
|
|
131
|
+
| **Files** | `file_push` | Transfer file to device |
|
|
132
|
+
| | `file_pull` | Transfer file from device |
|
|
133
|
+
| | `file_list` | List directory contents |
|
|
134
|
+
| | `file_delete` | Delete file (with confirmation) |
|
|
135
|
+
| | `file_exists` | Check if file exists |
|
|
136
|
+
|
|
137
|
+
### Resources
|
|
138
|
+
|
|
139
|
+
| URI | Description |
|
|
140
|
+
|-----|-------------|
|
|
141
|
+
| `adb://devices` | Connected device list |
|
|
142
|
+
| `adb://device/{id}` | Detailed device properties |
|
|
143
|
+
| `adb://apps/current` | Currently focused app |
|
|
144
|
+
| `adb://screen/info` | Screen resolution and DPI |
|
|
145
|
+
| `adb://help` | Tool reference and tips |
|
|
146
|
+
|
|
147
|
+
## Usage Examples
|
|
148
|
+
|
|
149
|
+
**Screenshot + UI inspection loop** (how an AI assistant typically navigates):
|
|
150
|
+
```
|
|
151
|
+
1. screenshot() → See what's on screen
|
|
152
|
+
2. ui_dump() → Get element tree with tap coordinates
|
|
153
|
+
3. tap_text("Settings") → Tap the "Settings" element
|
|
154
|
+
4. wait_for_text("Wi-Fi") → Wait for the screen to load
|
|
155
|
+
5. screenshot() → Verify the result
|
|
156
|
+
```
|
|
157
|
+
|
|
158
|
+
**Open a URL and check what loaded:**
|
|
159
|
+
```
|
|
160
|
+
1. app_open_url("https://example.com")
|
|
161
|
+
2. wait_for_text("Example Domain")
|
|
162
|
+
3. screenshot()
|
|
163
|
+
```
|
|
164
|
+
|
|
165
|
+
**Install and launch an APK** (developer mode):
|
|
166
|
+
```
|
|
167
|
+
1. config_set_developer_mode(true)
|
|
168
|
+
2. app_install("/path/to/app.apk")
|
|
169
|
+
3. app_launch("com.example.myapp")
|
|
170
|
+
4. logcat_capture(filter_spec="MyApp:D *:S")
|
|
171
|
+
```
|
|
172
|
+
|
|
173
|
+
**Multi-device workflow:**
|
|
174
|
+
```
|
|
175
|
+
1. devices_list() → See all connected devices
|
|
176
|
+
2. devices_use("SERIAL_NUMBER") → Select target device
|
|
177
|
+
3. device_info() → Check battery, WiFi, storage
|
|
178
|
+
4. screenshot() → Capture from selected device
|
|
179
|
+
```
|
|
180
|
+
|
|
181
|
+
## Architecture
|
|
182
|
+
|
|
183
|
+
The server uses FastMCP's [MCPMixin](https://gofastmcp.com/) pattern to organize 50 tools into focused, single-responsibility modules:
|
|
184
|
+
|
|
185
|
+
```
|
|
186
|
+
src/
|
|
187
|
+
server.py ← FastMCP app, ADBServer (thin orchestrator)
|
|
188
|
+
config.py ← Persistent config (~/.config/adb-mcp/config.json)
|
|
189
|
+
models.py ← Pydantic models (DeviceInfo, CommandResult, ScreenshotResult)
|
|
190
|
+
mixins/
|
|
191
|
+
base.py ← ADB command execution, injection-safe shell quoting
|
|
192
|
+
devices.py ← Device discovery, info, logcat, reboot
|
|
193
|
+
input.py ← Tap, swipe, scroll, keys, text, clipboard, shell
|
|
194
|
+
apps.py ← Launch, close, install, intents, broadcasts
|
|
195
|
+
screenshot.py ← Capture, recording, display settings
|
|
196
|
+
ui.py ← Accessibility tree, element search, text polling
|
|
197
|
+
files.py ← Push, pull, list, delete, exists
|
|
198
|
+
```
|
|
199
|
+
|
|
200
|
+
`ADBServer` inherits all six mixins. Each mixin calls `run_shell_args()` (injection-safe) or `run_adb()` on the base class. The base handles device targeting, subprocess execution, and timeouts.
|
|
201
|
+
|
|
202
|
+
## Security Model
|
|
203
|
+
|
|
204
|
+
All tools that accept user-provided values use **injection-safe command execution**:
|
|
205
|
+
|
|
206
|
+
- **`run_shell_args()`** quotes every argument with `shlex.quote()` before sending to the device shell. This is the default for all tools.
|
|
207
|
+
- **`run_shell()`** (string form) is only used by the developer-mode `shell_command` tool, where the user intentionally provides a raw command.
|
|
208
|
+
- **`input_text()`** rejects special characters (`$ ( ) ; | & < >` etc.) and directs users to `clipboard_set()` instead.
|
|
209
|
+
- **`input_key()`** strips non-alphanumeric characters from key codes.
|
|
210
|
+
- **Destructive operations** (uninstall, clear data, delete, reboot) require user confirmation via MCP elicitation.
|
|
211
|
+
- **Developer mode** is off by default and must be explicitly enabled. Settings persist at `~/.config/adb-mcp/config.json`.
|
|
212
|
+
|
|
213
|
+
## Docker
|
|
214
|
+
|
|
215
|
+
```bash
|
|
216
|
+
docker build -t mcadb .
|
|
217
|
+
docker run --privileged -v /dev/bus/usb:/dev/bus/usb mcadb
|
|
218
|
+
```
|
|
219
|
+
|
|
220
|
+
The `--privileged` flag and USB volume mount are required for ADB to detect physical devices.
|
|
221
|
+
|
|
222
|
+
MCP client config for Docker:
|
|
223
|
+
```json
|
|
224
|
+
{
|
|
225
|
+
"mcpServers": {
|
|
226
|
+
"mcadb": {
|
|
227
|
+
"command": "docker",
|
|
228
|
+
"args": ["run", "-i", "--privileged", "-v", "/dev/bus/usb:/dev/bus/usb", "mcadb"]
|
|
229
|
+
}
|
|
230
|
+
}
|
|
231
|
+
}
|
|
232
|
+
```
|
|
233
|
+
|
|
234
|
+
## Development
|
|
235
|
+
|
|
236
|
+
```bash
|
|
237
|
+
# Clone and install
|
|
238
|
+
git clone https://git.supported.systems/MCP/mcp-adb.git
|
|
239
|
+
cd mcp-adb
|
|
240
|
+
uv sync --group dev
|
|
241
|
+
|
|
242
|
+
# Run locally
|
|
243
|
+
uv run mcadb
|
|
244
|
+
|
|
245
|
+
# Lint
|
|
246
|
+
uv run ruff check src/
|
|
247
|
+
|
|
248
|
+
# Format
|
|
249
|
+
uv run ruff format src/
|
|
250
|
+
|
|
251
|
+
# Type check
|
|
252
|
+
uv run mypy src/
|
|
253
|
+
```
|
|
254
|
+
|
|
255
|
+
## Configuration
|
|
256
|
+
|
|
257
|
+
Settings are stored at `~/.config/adb-mcp/config.json` (override with `ADB_MCP_CONFIG_DIR` env var):
|
|
258
|
+
|
|
259
|
+
```json
|
|
260
|
+
{
|
|
261
|
+
"developer_mode": false,
|
|
262
|
+
"default_screenshot_dir": null,
|
|
263
|
+
"auto_select_single_device": true
|
|
264
|
+
}
|
|
265
|
+
```
|
|
266
|
+
|
|
267
|
+
| Setting | Default | Description |
|
|
268
|
+
|---------|---------|-------------|
|
|
269
|
+
| `developer_mode` | `false` | Unlock advanced tools (shell, install, reboot, etc.) |
|
|
270
|
+
| `default_screenshot_dir` | `null` | Directory for screenshots/recordings (null = cwd) |
|
|
271
|
+
| `auto_select_single_device` | `true` | Skip device selection when only one is connected |
|
|
272
|
+
|
|
273
|
+
## License
|
|
274
|
+
|
|
275
|
+
MIT
|
mcadb-0.3.1/README.md
ADDED
|
@@ -0,0 +1,251 @@
|
|
|
1
|
+
# mcadb
|
|
2
|
+
|
|
3
|
+
A [Model Context Protocol](https://modelcontextprotocol.io/) server that gives AI assistants direct control over Android devices through ADB. Point any MCP-compatible client at a phone plugged into USB, and it can take screenshots, tap buttons, launch apps, inspect UI elements, transfer files, and run shell commands — all through structured, type-safe tool calls.
|
|
4
|
+
|
|
5
|
+
Built on [FastMCP](https://gofastmcp.com/) with a modular mixin architecture. 50 tools across 6 domains. Tested on real hardware.
|
|
6
|
+
|
|
7
|
+
## Quick Start
|
|
8
|
+
|
|
9
|
+
```bash
|
|
10
|
+
# Run directly (no install)
|
|
11
|
+
uvx mcadb
|
|
12
|
+
|
|
13
|
+
# Or install and run
|
|
14
|
+
uv add mcadb
|
|
15
|
+
mcadb
|
|
16
|
+
```
|
|
17
|
+
|
|
18
|
+
### MCP Client Configuration
|
|
19
|
+
|
|
20
|
+
Add to your MCP client's config (Claude Desktop, Claude Code, etc.):
|
|
21
|
+
|
|
22
|
+
```json
|
|
23
|
+
{
|
|
24
|
+
"mcpServers": {
|
|
25
|
+
"mcadb": {
|
|
26
|
+
"command": "uvx",
|
|
27
|
+
"args": ["mcadb"]
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
```
|
|
32
|
+
|
|
33
|
+
For Claude Code:
|
|
34
|
+
```bash
|
|
35
|
+
claude mcp add mcadb -- uvx mcadb
|
|
36
|
+
```
|
|
37
|
+
|
|
38
|
+
For local development:
|
|
39
|
+
```bash
|
|
40
|
+
claude mcp add mcadb -- uv run --directory /path/to/mcp-adb mcadb
|
|
41
|
+
```
|
|
42
|
+
|
|
43
|
+
## Prerequisites
|
|
44
|
+
|
|
45
|
+
- **Python 3.11+**
|
|
46
|
+
- **ADB** installed and on `PATH` (`adb devices` should work)
|
|
47
|
+
- **USB debugging** enabled on the Android device
|
|
48
|
+
- Device connected via USB (or `adb connect` for network)
|
|
49
|
+
|
|
50
|
+
## What Can It Do?
|
|
51
|
+
|
|
52
|
+
### Standard Tools (always available)
|
|
53
|
+
|
|
54
|
+
| Domain | Tool | What it does |
|
|
55
|
+
|--------|------|-------------|
|
|
56
|
+
| **Devices** | `devices_list` | Discover connected devices (USB + network) |
|
|
57
|
+
| | `devices_use` | Set active device for multi-device setups |
|
|
58
|
+
| | `devices_current` | Show which device is selected |
|
|
59
|
+
| | `device_info` | Battery, WiFi, storage, Android version, model |
|
|
60
|
+
| **Input** | `input_tap` | Tap at screen coordinates |
|
|
61
|
+
| | `input_swipe` | Swipe between two points |
|
|
62
|
+
| | `input_scroll_down` | Scroll down (auto-detects screen size) |
|
|
63
|
+
| | `input_scroll_up` | Scroll up (auto-detects screen size) |
|
|
64
|
+
| | `input_back` | Press Back |
|
|
65
|
+
| | `input_home` | Press Home |
|
|
66
|
+
| | `input_recent_apps` | Open app switcher |
|
|
67
|
+
| | `input_key` | Send any key event (`VOLUME_UP`, `ENTER`, etc.) |
|
|
68
|
+
| | `input_text` | Type text into focused field |
|
|
69
|
+
| | `clipboard_set` | Set clipboard (handles special chars), optional auto-paste |
|
|
70
|
+
| **Apps** | `app_launch` | Launch app by package name |
|
|
71
|
+
| | `app_open_url` | Open URL in default browser |
|
|
72
|
+
| | `app_close` | Force stop an app |
|
|
73
|
+
| | `app_current` | Get the foreground app and activity |
|
|
74
|
+
| **Screen** | `screenshot` | Capture screen as PNG |
|
|
75
|
+
| | `screen_size` | Get display resolution |
|
|
76
|
+
| | `screen_density` | Get display DPI |
|
|
77
|
+
| | `screen_on` / `screen_off` | Wake or sleep the display |
|
|
78
|
+
| **UI** | `ui_dump` | Dump accessibility tree (all visible elements) |
|
|
79
|
+
| | `ui_find_element` | Search for elements by text, ID, class, or description |
|
|
80
|
+
| | `wait_for_text` | Poll until text appears on screen |
|
|
81
|
+
| | `wait_for_text_gone` | Poll until text disappears |
|
|
82
|
+
| | `tap_text` | Find an element by text and tap it |
|
|
83
|
+
| **Config** | `config_status` | Show current settings |
|
|
84
|
+
| | `config_set_developer_mode` | Toggle developer tools |
|
|
85
|
+
| | `config_set_screenshot_dir` | Set where screenshots are saved |
|
|
86
|
+
|
|
87
|
+
### Developer Mode Tools
|
|
88
|
+
|
|
89
|
+
Enable with `config_set_developer_mode(true)` to unlock power-user tools. Destructive operations (uninstall, clear data, reboot, delete) require user confirmation via MCP elicitation.
|
|
90
|
+
|
|
91
|
+
| Domain | Tool | What it does |
|
|
92
|
+
|--------|------|-------------|
|
|
93
|
+
| **Shell** | `shell_command` | Run any shell command on device |
|
|
94
|
+
| **Input** | `input_long_press` | Press and hold gesture |
|
|
95
|
+
| **Apps** | `app_list_packages` | List installed packages (with filters) |
|
|
96
|
+
| | `app_install` | Install APK from host |
|
|
97
|
+
| | `app_uninstall` | Remove an app (with confirmation) |
|
|
98
|
+
| | `app_clear_data` | Wipe app data (with confirmation) |
|
|
99
|
+
| | `activity_start` | Launch activity with full intent control |
|
|
100
|
+
| | `broadcast_send` | Send broadcast intents |
|
|
101
|
+
| **Screen** | `screen_record` | Record screen to MP4 |
|
|
102
|
+
| | `screen_set_size` | Override display resolution |
|
|
103
|
+
| | `screen_reset_size` | Restore original resolution |
|
|
104
|
+
| **Device** | `device_reboot` | Reboot device (with confirmation) |
|
|
105
|
+
| | `logcat_capture` | Capture system logs |
|
|
106
|
+
| | `logcat_clear` | Clear log buffer |
|
|
107
|
+
| **Files** | `file_push` | Transfer file to device |
|
|
108
|
+
| | `file_pull` | Transfer file from device |
|
|
109
|
+
| | `file_list` | List directory contents |
|
|
110
|
+
| | `file_delete` | Delete file (with confirmation) |
|
|
111
|
+
| | `file_exists` | Check if file exists |
|
|
112
|
+
|
|
113
|
+
### Resources
|
|
114
|
+
|
|
115
|
+
| URI | Description |
|
|
116
|
+
|-----|-------------|
|
|
117
|
+
| `adb://devices` | Connected device list |
|
|
118
|
+
| `adb://device/{id}` | Detailed device properties |
|
|
119
|
+
| `adb://apps/current` | Currently focused app |
|
|
120
|
+
| `adb://screen/info` | Screen resolution and DPI |
|
|
121
|
+
| `adb://help` | Tool reference and tips |
|
|
122
|
+
|
|
123
|
+
## Usage Examples
|
|
124
|
+
|
|
125
|
+
**Screenshot + UI inspection loop** (how an AI assistant typically navigates):
|
|
126
|
+
```
|
|
127
|
+
1. screenshot() → See what's on screen
|
|
128
|
+
2. ui_dump() → Get element tree with tap coordinates
|
|
129
|
+
3. tap_text("Settings") → Tap the "Settings" element
|
|
130
|
+
4. wait_for_text("Wi-Fi") → Wait for the screen to load
|
|
131
|
+
5. screenshot() → Verify the result
|
|
132
|
+
```
|
|
133
|
+
|
|
134
|
+
**Open a URL and check what loaded:**
|
|
135
|
+
```
|
|
136
|
+
1. app_open_url("https://example.com")
|
|
137
|
+
2. wait_for_text("Example Domain")
|
|
138
|
+
3. screenshot()
|
|
139
|
+
```
|
|
140
|
+
|
|
141
|
+
**Install and launch an APK** (developer mode):
|
|
142
|
+
```
|
|
143
|
+
1. config_set_developer_mode(true)
|
|
144
|
+
2. app_install("/path/to/app.apk")
|
|
145
|
+
3. app_launch("com.example.myapp")
|
|
146
|
+
4. logcat_capture(filter_spec="MyApp:D *:S")
|
|
147
|
+
```
|
|
148
|
+
|
|
149
|
+
**Multi-device workflow:**
|
|
150
|
+
```
|
|
151
|
+
1. devices_list() → See all connected devices
|
|
152
|
+
2. devices_use("SERIAL_NUMBER") → Select target device
|
|
153
|
+
3. device_info() → Check battery, WiFi, storage
|
|
154
|
+
4. screenshot() → Capture from selected device
|
|
155
|
+
```
|
|
156
|
+
|
|
157
|
+
## Architecture
|
|
158
|
+
|
|
159
|
+
The server uses FastMCP's [MCPMixin](https://gofastmcp.com/) pattern to organize 50 tools into focused, single-responsibility modules:
|
|
160
|
+
|
|
161
|
+
```
|
|
162
|
+
src/
|
|
163
|
+
server.py ← FastMCP app, ADBServer (thin orchestrator)
|
|
164
|
+
config.py ← Persistent config (~/.config/adb-mcp/config.json)
|
|
165
|
+
models.py ← Pydantic models (DeviceInfo, CommandResult, ScreenshotResult)
|
|
166
|
+
mixins/
|
|
167
|
+
base.py ← ADB command execution, injection-safe shell quoting
|
|
168
|
+
devices.py ← Device discovery, info, logcat, reboot
|
|
169
|
+
input.py ← Tap, swipe, scroll, keys, text, clipboard, shell
|
|
170
|
+
apps.py ← Launch, close, install, intents, broadcasts
|
|
171
|
+
screenshot.py ← Capture, recording, display settings
|
|
172
|
+
ui.py ← Accessibility tree, element search, text polling
|
|
173
|
+
files.py ← Push, pull, list, delete, exists
|
|
174
|
+
```
|
|
175
|
+
|
|
176
|
+
`ADBServer` inherits all six mixins. Each mixin calls `run_shell_args()` (injection-safe) or `run_adb()` on the base class. The base handles device targeting, subprocess execution, and timeouts.
|
|
177
|
+
|
|
178
|
+
## Security Model
|
|
179
|
+
|
|
180
|
+
All tools that accept user-provided values use **injection-safe command execution**:
|
|
181
|
+
|
|
182
|
+
- **`run_shell_args()`** quotes every argument with `shlex.quote()` before sending to the device shell. This is the default for all tools.
|
|
183
|
+
- **`run_shell()`** (string form) is only used by the developer-mode `shell_command` tool, where the user intentionally provides a raw command.
|
|
184
|
+
- **`input_text()`** rejects special characters (`$ ( ) ; | & < >` etc.) and directs users to `clipboard_set()` instead.
|
|
185
|
+
- **`input_key()`** strips non-alphanumeric characters from key codes.
|
|
186
|
+
- **Destructive operations** (uninstall, clear data, delete, reboot) require user confirmation via MCP elicitation.
|
|
187
|
+
- **Developer mode** is off by default and must be explicitly enabled. Settings persist at `~/.config/adb-mcp/config.json`.
|
|
188
|
+
|
|
189
|
+
## Docker
|
|
190
|
+
|
|
191
|
+
```bash
|
|
192
|
+
docker build -t mcadb .
|
|
193
|
+
docker run --privileged -v /dev/bus/usb:/dev/bus/usb mcadb
|
|
194
|
+
```
|
|
195
|
+
|
|
196
|
+
The `--privileged` flag and USB volume mount are required for ADB to detect physical devices.
|
|
197
|
+
|
|
198
|
+
MCP client config for Docker:
|
|
199
|
+
```json
|
|
200
|
+
{
|
|
201
|
+
"mcpServers": {
|
|
202
|
+
"mcadb": {
|
|
203
|
+
"command": "docker",
|
|
204
|
+
"args": ["run", "-i", "--privileged", "-v", "/dev/bus/usb:/dev/bus/usb", "mcadb"]
|
|
205
|
+
}
|
|
206
|
+
}
|
|
207
|
+
}
|
|
208
|
+
```
|
|
209
|
+
|
|
210
|
+
## Development
|
|
211
|
+
|
|
212
|
+
```bash
|
|
213
|
+
# Clone and install
|
|
214
|
+
git clone https://git.supported.systems/MCP/mcp-adb.git
|
|
215
|
+
cd mcp-adb
|
|
216
|
+
uv sync --group dev
|
|
217
|
+
|
|
218
|
+
# Run locally
|
|
219
|
+
uv run mcadb
|
|
220
|
+
|
|
221
|
+
# Lint
|
|
222
|
+
uv run ruff check src/
|
|
223
|
+
|
|
224
|
+
# Format
|
|
225
|
+
uv run ruff format src/
|
|
226
|
+
|
|
227
|
+
# Type check
|
|
228
|
+
uv run mypy src/
|
|
229
|
+
```
|
|
230
|
+
|
|
231
|
+
## Configuration
|
|
232
|
+
|
|
233
|
+
Settings are stored at `~/.config/adb-mcp/config.json` (override with `ADB_MCP_CONFIG_DIR` env var):
|
|
234
|
+
|
|
235
|
+
```json
|
|
236
|
+
{
|
|
237
|
+
"developer_mode": false,
|
|
238
|
+
"default_screenshot_dir": null,
|
|
239
|
+
"auto_select_single_device": true
|
|
240
|
+
}
|
|
241
|
+
```
|
|
242
|
+
|
|
243
|
+
| Setting | Default | Description |
|
|
244
|
+
|---------|---------|-------------|
|
|
245
|
+
| `developer_mode` | `false` | Unlock advanced tools (shell, install, reboot, etc.) |
|
|
246
|
+
| `default_screenshot_dir` | `null` | Directory for screenshots/recordings (null = cwd) |
|
|
247
|
+
| `auto_select_single_device` | `true` | Skip device selection when only one is connected |
|
|
248
|
+
|
|
249
|
+
## License
|
|
250
|
+
|
|
251
|
+
MIT
|