mirror of
https://github.com/Heretek-AI/Android-RE.git
synced 2026-07-18 10:04:48 -04:00
8722cd710c
Two new items, both rooted in the 2026-06-05 survey of the 5 revanced-* repos in Input/ and the sibling RE-Library site: 1. RE-Library (MIT) is now peer-registered as the 6th MCP server in .mcp.json. The peer is opt-in via `just install-re-library` and is read-only. Five high-traffic skills each gain a "Background reading (peer MCP)" subsection that calls mcp__re-library__* for generic RE patterns before writing Frida hooks or MASVS reports. 15 new tests in tests/test_mcp_config.py lock the wiring in. 2. The dynamic MCP server's install_apk tool now runs a clean-room 3-strategy install ladder (adb_install -> push_then_pm_install -> staged_install) so it works on Android 14+ devices where the one-shot `adb install` is rejected with INSTALL_FAILED_OWNER_BLOCKED. Implementation is written from AOSP docs, not lifted from the GPLv3 source. 11 new unit tests + 2 new dry-run tests + 3 new @pytest.mark.device e2e tests. Survey review lives at docs/research/2026-06-05-revanced-input-survey.md. Side fix: remove unused `asyncio_mode = "auto"` from pyproject.toml (no test in the suite uses @pytest.mark.asyncio, and the line fails --strict-config under pytest 9 + pytest-asyncio 1.4). Verification: 176 passed, 1 skipped, 5 deselected (e2e). ruff clean, mypy --strict on the new module clean. No named commercial apps / vendors / DRM schemes in any new artifact per the no-named-apps policy. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
209 lines
9.4 KiB
Markdown
209 lines
9.4 KiB
Markdown
# MCP Tool Reference
|
|
|
|
> Auto-generated reference for every tool exposed by every Android-RE MCP
|
|
> server. Source of truth is the `mcp_servers/<server>/src/.../server.py`
|
|
> `FastMCP` registration. If this page drifts from the code, the code wins.
|
|
|
|
## Output convention
|
|
|
|
Every file-producing MCP tool accepts an `output_path` (single file) or
|
|
`output_dir` (directory) parameter. When omitted, the path is derived
|
|
from
|
|
[`android_re_core.paths.output_dir_for(apk_path)`](../android_re_core/src/android_re_core/paths.py):
|
|
|
|
```
|
|
Output/<apk-basename>-<short-sha>/<subdir>/<file>
|
|
```
|
|
|
|
Override the base with the `ANDROID_RE_OUTPUT_DIR` env var (read once
|
|
at import time of `android_re_core.paths`). The default base is
|
|
`<repo-root>/Output/`; the directory is git-ignored. The full
|
|
convention is documented in [`output-convention.md`](output-convention.md).
|
|
|
|
| Tool | Default subdir | Default filename |
|
|
|---|---|---|
|
|
| `finalize_triage` | `Output/<apk>-<sha>/<triage_id>/` | `triage-<id>.{md,json,sarif}` |
|
|
| `get_masvs_coverage` | `Output/<apk>-<sha>/masvs/` | `coverage.json` |
|
|
| `build_sarif_report` | `Output/<apk>-<sha>/masvs/` | `report.sarif` |
|
|
| `scan_secrets` | `Output/<apk>-<sha>/secrets/` | `secrets-findings.json` |
|
|
| `scan_with_quark` | `Output/<apk>-<sha>/secrets/quark/` | (quark's native layout) |
|
|
| `run_androwarn` | `Output/<apk>-<sha>/secrets/` | `androwarn.json` |
|
|
| `build_native_report` | `Output/<apk>-<sha>/native/` | `native-report.json` |
|
|
| `build_session_report` | `Output/<apk>-<sha>/dynamic/` | `session-report.json` |
|
|
| `rebuild_apk` | `Output/<apk>-<sha>/repackage/` | `rebuilt.apk` |
|
|
| `create_gradle_project` | (required) | n/a |
|
|
| `take_screenshot` | `Output/<apk>-<sha>/dynamic/` | `screenshot-<ts>.png` |
|
|
| `screenrecord` | `Output/<apk>-<sha>/dynamic/` | `screenrecord-<ts>.mp4` |
|
|
| `dump_heap` | (required) | n/a |
|
|
| `setup_mitm` | `Output/<apk>-<sha>/network/` | n/a |
|
|
|
|
## Servers
|
|
|
|
| Server | Module |
|
|
|----------------------|------------------------------------------|
|
|
| `android-re-static` | `mcp_servers.static.android_re_mcp_static` |
|
|
| `android-re-native` | `mcp_servers.native.android_re_mcp_native` |
|
|
| `android-re-dynamic` | `mcp_servers.dynamic.android_re_mcp_dynamic` |
|
|
| `android-re-triage` | `mcp_servers.triage.android_re_mcp_triage` |
|
|
| `mcp_bridge` | `mcp_bridge` (TypeScript) |
|
|
|
|
## android-re-static
|
|
|
|
26 tools (Phase 1 + 2 + 3 + Decompilation pipeline).
|
|
|
|
Project lifecycle:
|
|
- `open_project(apk_path, project_id?, max_size?) -> {project_id, sha256, size, ...}`
|
|
- `close_project(project_id) -> {ok}`
|
|
- `list_projects() -> [ProjectSummary]`
|
|
|
|
Manifest:
|
|
- `read_manifest(project_id, formatted?) -> manifest XML or structured`
|
|
- `list_components(project_id, component_type?) -> [Component]`
|
|
- `get_permissions(project_id, classification?) -> [Permission]`
|
|
|
|
DEX:
|
|
- `find_classes(project_id, query, limit?, exact?) -> [Class]`
|
|
- `find_methods(project_id, class_name?, name_substring?, native_only?, limit?) -> [Method]`
|
|
|
|
Decompilation (jadx):
|
|
- `decompile_class(project_id, class_name, deobfuscate=False, threads=None, output_format="java") -> {source, found, workdir, deobfuscated, output_format}`
|
|
- `decompile_method(project_id, class_name, method_name, descriptor, deobfuscate=False, output_format="java") -> {source, found, start_line, end_line, full_class_source, workdir, reason}` — slices the decompiled class by method signature; `start_line` / `end_line` are 1-indexed.
|
|
- `decompile_apk(project_id, force=False, deobfuscate=False, threads=None, output_format="java", limit=500, offset=0) -> {class_count, files, total_files, truncated, jadx_duration_s}` — enumerates the decompiled tree.
|
|
- `read_source(project_id, path, deobfuscate=False, output_format="java") -> {content, found, line_count, byte_size, reason}` — reads a file by path; refuses `..` and files > 10 MB.
|
|
|
|
Smali / repackage:
|
|
- `get_smali(project_id, class_name) -> {smali, found, workdir}`
|
|
- `decode_apk(project_id, force=False) -> {workdir, class_count, smali_dirs, manifest_path}`
|
|
- `rebuild_apk(project_id, output_path?, confirm=False) -> {output_path, size}` — requires `confirm=true`.
|
|
- `patch_manifest(project_id, patch, confirm=False) -> {applied, changes, ...}` — dry-run by default.
|
|
|
|
Signing:
|
|
- `verify_signature(project_id) -> {signed, versions, signers, ...}`
|
|
- `get_certificate_info(project_id, signer_index?) -> {subject, issuer, ..., fingerprint_sha256}`
|
|
|
|
Native (delegated from `android-re-native`):
|
|
- `list_native_libs(project_id) -> [lib_path]`
|
|
- `analyze_elf(project_id, lib_name) -> {format, architecture, security, sections, imports, exports}`
|
|
- `disassemble_native(project_id, lib_name, symbol?, offset?, length?, max_instructions?) -> [instruction]`
|
|
|
|
Secrets / reports:
|
|
- `scan_secrets(project_id, rules="default", limit=500) -> [SecretFinding]`
|
|
- `scan_with_quark(project_id, timeout_s=300) -> {matched_rules}`
|
|
- `run_androwarn(project_id, timeout_s=300) -> [Warning]`
|
|
- `build_sarif_report(project_id) -> SARIF log`
|
|
- `get_masvs_coverage(project_id) -> {by_group, controls, findings}`
|
|
|
|
Each decompile tool caches its workdir under
|
|
`/tmp/android-re/<project_id>-jadx-{deobf,plain}-{java,kotlin}/`.
|
|
`deobfuscate` and `output_format` are part of the cache key.
|
|
|
|
## android-re-native
|
|
|
|
(Phase 2) 19 tools — see `mcp_servers/native/src/.../server.py`.
|
|
|
|
## android-re-dynamic
|
|
|
|
(Phase 3) 30+ tools — see `mcp_servers/dynamic/src/.../server.py`.
|
|
|
|
### `install_apk` (SDK-34+ aware)
|
|
|
|
`install_apk(serial, apk_path, replace=True, allow_downgrade=False, confirm=false, output_path=None) -> InstallResult`
|
|
|
|
The dynamic server's `install_apk` tool delegates to
|
|
`android_re_core.device.adb_install.install_apk`, which runs a
|
|
3-strategy install ladder:
|
|
|
|
1. `adb_install` — one-shot `adb -s <serial> install [-r] [-d] <apk>`.
|
|
Pre-34 fast path; tried first on every API level.
|
|
2. `push_then_pm_install` — push the APK to `/data/local/tmp/`
|
|
on the device, then `pm install [-r] [-d] <tmp_path>`. Primary
|
|
escalation on API 34+.
|
|
3. `staged_install` — `pm install-create` / `-write` / `-commit`.
|
|
Last-resort fallback on API 34+ when (2) also fails.
|
|
|
|
Returns a structured `InstallResult`:
|
|
|
|
```json
|
|
{
|
|
"status": "success" | "failure" | "partial",
|
|
"api_level": 34,
|
|
"strategy": "adb_install" | "push_then_pm_install" | "staged_install",
|
|
"output": "Success\n",
|
|
"package": "com.example",
|
|
"elapsed_s": 1.23
|
|
}
|
|
```
|
|
|
|
`confirm=false` (the default) does **not** call adb. It writes a
|
|
structured dry-run summary to
|
|
`Output/<apk>-<short-sha>/dynamic/install-attempt.dry-run.json`
|
|
listing the strategy ladder, then returns the `confirm_required`
|
|
error envelope. Override the path with `output_path=...`.
|
|
|
|
Failure modes the ladder handles explicitly:
|
|
|
|
- `INSTALL_FAILED_OWNER_BLOCKED`, `INSTALL_FAILED_USER_RESTRICTED`,
|
|
`INSTALL_FAILED_VERSION_DOWNGRADE` → strategy 2.
|
|
- `INSTALL_FAILED_INSUFFICIENT_STORAGE`, `INSTALL_FAILED_NO_INSTALL`,
|
|
`INSTALL_FAILED_INTERNAL_ERROR` → strategy 3.
|
|
- An unknown 4th mode surfaces in `output` for triage; the
|
|
implementer can extend the ladder with a 5-line PR.
|
|
|
|
The `ANDROID_RE_FORCE_STAGED=1` env var forces strategy 1 only
|
|
(for testing the override path; not the staged path itself).
|
|
|
|
**TS bridge parity gap** — the TypeScript `mcp_bridge` `adb_install`
|
|
tool still uses adbkit's `install()` and does not support the
|
|
SDK-34+ fix. Callers using the TS bridge on an API 34+ device
|
|
should use the Python dynamic server's `install_apk` instead.
|
|
|
|
## android-re-triage
|
|
|
|
(Phase 4) 12 tools — orchestrator; composes the other three.
|
|
|
|
## mcp_bridge (TypeScript)
|
|
|
|
(Phase 3) 18 tools — ADB / screencap / logcat / frida-ps.
|
|
|
|
## MCP resources
|
|
|
|
| Resource URI | Provided by |
|
|
|---------------------------------------------|--------------------------|
|
|
| `apk://<project_id>/manifest` | `android-re-static` |
|
|
| `apk://<project_id>/smali/<fqcn>` | `android-re-static` |
|
|
| `apk://<project_id>/source/<fqcn>` | `android-re-static` |
|
|
| `native://<project_id>/lib/<lib_name>/...` | `android-re-native` |
|
|
| `device://<serial>/<topic>` | `mcp_bridge` |
|
|
|
|
## Peer MCP servers
|
|
|
|
Android-RE's `.mcp.json` can register peer MCP servers alongside
|
|
the 5 in-workspace ones. Peers are external projects that live
|
|
outside this repo; they're opt-in and have no destructive tools.
|
|
|
|
### `re-library` (MIT)
|
|
|
|
Wrapper around the [RE-Library](https://heretek-ai.github.io/RE-Library/)
|
|
corpus — 8 categories (`android`, `ios`, `native`, `anti-analysis`,
|
|
`drm`, `packers`, `tools`, `web-hybrid`) of generic RE knowledge.
|
|
Used by 5 Android-RE skills as a "Background reading (peer MCP)"
|
|
step before writing Frida hooks or MASVS reports.
|
|
|
|
5 tools, all read-only:
|
|
|
|
- `mcp__re-library__list_categories()` — enumerate the 8 categories
|
|
with entry counts.
|
|
- `mcp__re-library__list_entries(category)` — lightweight summary
|
|
of one category (titles + summaries + difficulty).
|
|
- `mcp__re-library__search_re(query, category?, platform?, max_results?)` —
|
|
free-text search with snippet + score. Returns up to `max_results`
|
|
hits (default 5, max 50).
|
|
- `mcp__re-library__get_entry(slug)` — full body of one entry,
|
|
indexed by `<category>/<NN>-<slug>`.
|
|
- `mcp__re-library__get_anti_analysis_techniques(platform?)` —
|
|
convenience aggregator over the `anti-analysis` category.
|
|
|
|
Install once with `just install-re-library` (the `.mcp.json`
|
|
entry uses `uv tool run --from re-library-mcp …` as a fallback
|
|
if the package is not pre-warmed).
|