@xi0yu/android-reverse-tools
v1.0.0
Published
MCP server for Android reverse engineering — ADB, Frida, UIAutomator, JADX, JEB
Maintainers
Readme
android-reverse-tools
android-reverse-tools is an MCP server for Android reverse engineering workflows, exposed as one tool surface for ADB, Frida, UIAutomator2, JADX, and JEB.
Typical use cases: local MCP clients, scripted device inspection, APK triage, runtime instrumentation, UI-driven test flows, and decompiler-backed code lookup.
Features
- Single MCP server entrypoint
stdio, SSE, and streamable HTTP transports- ADB device, shell, file, app, logcat, and network tools
- Frida process, session, injection, and script generation tools
- UIAutomator2 screen inspection and action tools
- JADX class, method, manifest, strings, xref, and rename tools
- JEB project, class, method, field, manifest, rename, and protobuf tools
- Optional module loading with per-module diagnostics
- Works from npm and from source
Installation
Requirements
| Item | Required | Notes |
| --- | --- | --- |
| Node.js | yes | >= 18 for the npm wrapper |
| uv | yes | required by the npm wrapper and source workflow |
| Python | source install only | >= 3.11 |
| adb | ADB tools | must be in PATH |
| frida-server | Frida runtime tools | not required for script generators |
| uiautomator2 | UI tools | optional Python dependency |
| JADX MCP plugin | JADX tools | plugin must be running in JADX-GUI |
| JEB MCP plugin | JEB tools | plugin must be running in JEB Pro |
npm
npm install -g @xi0yu/android-reverse-toolspnpm
pnpm add -g @xi0yu/android-reverse-toolsyarn
yarn global add @xi0yu/android-reverse-toolsFrom source
cd /Users/zhangxiaoyu/Workspace/reverse-mcp
pip install -e ".[all]"Quick Start
Start a minimal local server:
npx -y @xi0yu/android-reverse-tools --disable-jadx --disable-jeb --disable-uiautomatorMinimal client config:
{
"mcpServers": {
"android-reverse-tools": {
"command": "npx",
"args": [
"-y",
"@xi0yu/android-reverse-tools",
"--disable-jadx",
"--disable-jeb",
"--disable-uiautomator"
]
}
}
}Run the full server from source:
cd /Users/zhangxiaoyu/Workspace/reverse-mcp
uv run android-reverse-toolsUsage / API
The server exposes MCP tools directly. Tool names use module prefixes such as adb_*, frida_*, ui_*, jadx_*, and jeb_*.
CLI
| API | Params | Returns | Notes |
| --- | --- | --- | --- |
| android-reverse-tools | --transport? string, --host? string, --port? number, module flags | process exit code | starts the MCP server |
| android-reverse-tools --help | none | help text | prints CLI reference |
ADB
| API | Params | Returns | Notes |
| --- | --- | --- | --- |
| adb_list_devices | none | string | connected devices |
| adb_device_info | device_id?: string | string | model, SDK, ABI, props |
| adb_shell | device_id?: string, command: string | string | shell command output |
| adb_pull | device_id?: string, remote: string, local?: string | string | pull file or directory |
| adb_push | device_id?: string, local: string, remote?: string | string | push file or directory |
| adb_logcat | device_id?: string, lines?: number, tag?: string, level?: string, package?: string | string | recent log output |
| adb_performance | device_id?: string | string | JSON metrics for CPU, memory, disk, network, battery |
| adb_screen_record | device_id?: string, output?: string, duration?: number, bitrate_mbps?: number, size?: string | string | records screen on device |
Frida
| API | Params | Returns | Notes |
| --- | --- | --- | --- |
| frida_check | none | dict | runtime availability |
| frida_list_processes | device_id?: string | dict | process list |
| frida_list_apps | device_id?: string | dict | installed app list |
| frida_create_session | pid: number, device_id?: string | dict | creates managed session |
| frida_exec | session_id: string, js: string, keep_alive?: boolean | dict | executes script in session |
| frida_messages | session_id: string | dict | drains collected messages |
| frida_run_script | target: string, script: string, device_id?: string | dict | one-shot attach and execute |
| frida_generate_script_bypass_ssl | none | dict | returns JS source |
UIAutomator2
| API | Params | Returns | Notes |
| --- | --- | --- | --- |
| ui_get_screen | serial?: string | string | JSON screen state, elements, device info |
| ui_tap | selectors or x/y, serial?: string, timeout?: number | string | tap element or coordinates |
| ui_input | text: string, target selectors, clear?: boolean, serial?: string | string | enter text into focused or matched field |
| ui_swipe | direction?: string, scale?: number, bounds?: string, serial?: string | string | scroll gesture |
| ui_wait_for | selectors, timeout?: number, exists?: boolean, serial?: string | string | wait for appear/disappear |
| ui_scroll_to_find | selectors, direction?: string, max_swipes?: number, click?: boolean, serial?: string | string | find item in long list |
| ui_switch_device | serial: string | string | changes default UI device |
| ui_screenshot | serial?: string, path?: string | string | saves screenshot locally |
JADX
| API | Params | Returns | Notes |
| --- | --- | --- | --- |
| jadx_status | none | string | plugin reachability |
| jadx_fetch_current_class | none | dict | current selected class |
| jadx_get_class_source | class_name: string | dict | class source |
| jadx_search_classes | search_term: string, package?: string, search_in?: string, offset?: number, count?: number | dict | keyword search |
| jadx_get_manifest_component | component_type: string, only_exported?: boolean | dict | manifest subset |
| jadx_xrefs_to_method | class_name: string, method_name: string, offset?: number, count?: number | dict | method references |
| jadx_rename_class | class_name: string, new_name: string | dict | rename class in JADX |
| jadx_debug_stack_frames | none | dict | active debugger stack |
JEB
| API | Params | Returns | Notes |
| --- | --- | --- | --- |
| jeb_ping | none | string | plugin reachability |
| jeb_load_project | apk_or_dex_path: string | string | opens new project |
| jeb_get_class_code | class_signature: string | string | decompiled class |
| jeb_get_method_code | class_name: string, method_name: string | string | decompiled method |
| jeb_get_manifest | info_type?: string | string | structured manifest data |
| jeb_find_class | class_signature: string | string | class lookup |
| jeb_rename_method | class_name: string, method_name: string, new_name: string, ignore?: boolean | string | rename in JEB |
| jeb_parse_protobuf | class_signature: string | string | protobuf structure extraction |
Configuration
| Field | Type | Default | Description |
| --- | --- | --- | --- |
| transport | stdio \| sse \| http | stdio | MCP transport |
| host | string | 127.0.0.1 | bind host for SSE / HTTP |
| port | number | 8765 | bind port for SSE / HTTP |
| disable-adb | boolean | false | disable ADB tools |
| disable-frida | boolean | false | disable Frida tools |
| disable-uiautomator | boolean | false | disable UIAutomator2 tools |
| disable-jadx | boolean | false | disable JADX tools |
| disable-jeb | boolean | false | disable JEB tools |
| jadx-host | string | 127.0.0.1 | JADX plugin host |
| jadx-port | number | 8650 | JADX plugin port |
| jeb-host | string | 127.0.0.1 | JEB plugin host |
| jeb-port | number | 16161 | JEB plugin port |
| jeb-path | string | /mcp | JEB plugin HTTP path |
Environment variables:
| Field | Type | Default | Description |
| --- | --- | --- | --- |
| TRANSPORT | string | unset | same as --transport |
| HOST | string | unset | same as --host |
| PORT | string | unset | same as --port |
| JEB_HOST | string | unset | same as --jeb-host |
| JEB_PORT | string | unset | same as --jeb-port |
| JEB_PATH | string | unset | same as --jeb-path |
Design
The runtime is a single FastMCP server. Each backend registers its own tool namespace at startup. Backends are optional; unavailable modules are skipped with diagnostics instead of failing the whole process.
The npm package is a thin wrapper. It delegates execution to uv, which runs the Python server from the packaged source tree. The Python package remains the source of truth for tool registration and transport handling.
Tool names stay flat. Namespacing is done by prefix rather than nested objects because MCP clients usually surface tools as a single list.
Examples
ADB + Frida only
{
"mcpServers": {
"android-reverse-tools": {
"command": "npx",
"args": [
"-y",
"@xi0yu/android-reverse-tools",
"--disable-jadx",
"--disable-jeb",
"--disable-uiautomator"
]
}
}
}Full stack over SSE
android-reverse-tools --transport sse --host 127.0.0.1 --port 8765http://127.0.0.1:8765/sseFAQ
uv is not in PATH
Install uv first. The npm wrapper does not bundle it.
ui_* tools do not appear
uiautomator2 is optional. Install from source with Python extras if UI tools are required.
jadx_* or jeb_* tools are unavailable
The server starts without those modules when the corresponding plugin is not reachable. Check plugin host, port, and path.
License
MIT
