StaticApkAuditor MCP
Enables Android APK security auditing through natural language by decompiling APKs with Apktool and running static analysis heuristics for attack surface, permissions, secrets, crypto, native libraries, and more, with every analysis logged to disk as markdown reports.
README
StaticApkAuditor MCP
A Model Context Protocol (MCP) server that exposes Apktool-based decompilation plus a suite of custom static-analysis heuristics for Android APK security assessment, through natural-language commands in Claude Code / Claude Desktop.
What this is for
You point it at an APK. It decompiles it, then gives an AI assistant a set of tools to analyze the result — attack surface, permissions, hardcoded secrets, crypto usage, native libraries, business logic candidates — and cross-checks findings from other tools like MobSF. Every call is logged to disk as a markdown report, so you end up with an audit trail, not just a chat transcript.
This is a static-analysis aid, not a complete pentest. Several tools produce candidates for manual/dynamic verification, not confirmed vulnerabilities — this is called out explicitly in tool descriptions and in the built-in prompts. Runtime behavior (race conditions, workflow bypasses, actual data exfiltration) needs dynamic testing (Frida, Burp/mitmproxy, a real device) to confirm.
Quick Start
Assumes Java, Apktool, and Python 3.10+ are already installed (see Prerequisites below if not).
# 1. Set up the project folder
mkdir static-apk-auditor && cd static-apk-auditor
# 2. Create a venv and install the one dependency
python3 -m venv venv
source venv/bin/activate # Windows: venv\Scripts\activate
pip install -r requirements.txt
# 3. Sanity check — should hang waiting for stdio input, Ctrl+C to stop
python3 server.py
# 4. Register with Claude Code (adjust paths to your actual location)
claude mcp add static-apk-auditor \
--env APKTOOL_WORK_DIR=$(pwd)/data \
-- $(pwd)/venv/bin/python3 $(pwd)/server.py
# 5. Verify it connected
claude mcp list
Then, inside a claude session, in the same folder you ran claude mcp add from (registration defaults to that folder's scope):
/mcp__static-apk-auditor__security_audit
/absolute/path/to/some.apk
or just ask in plain language — the model will call decode_apk and the rest of the tools on its own:
Decompile /absolute/path/to/some.apk and give me a quick security triage.
See Prompts and Tools below for everything available, or run /mcp in a Claude Code session to browse them interactively.
Project structure
static-apk-auditor/ # your folder can be named anything — this is just an example
├── server.py # the MCP server — single file, FastMCP-based
├── requirements.txt # just "mcp"
├── README.md # this file
├── prompts/
│ ├── security_audit.md # 16-point checklist, OWASP Mobile Top 10 mapping
│ └── mobsf_review.md # MobSF finding validation workflow
├── venv/ # created locally, not part of the repo
└── data/ # created automatically on first decode_apk call
# (this is APKTOOL_WORK_DIR — see Configuration below)
Runtime data layout (created automatically)
Every APK you analyze gets its own self-contained folder under APKTOOL_WORK_DIR:
$APKTOOL_WORK_DIR/<apk_filename_without_extension>/
├── source/
│ └── <original>.apk # copy of the APK you pointed the tool at
├── decoded/
│ ├── AndroidManifest.xml
│ ├── smali/, smali_classes2/, ...
│ ├── res/, assets/, lib/
│ └── ... # apktool's decompiled output
├── reports/
│ ├── 20260706_175359_809_decode_apk.md
│ ├── 20260706_175412_112_analyze_manifest.md
│ ├── 20260706_175430_501_check_root_detection.md
│ └── ... # one markdown file per tool call, ever
└── final_reports/
├── 20260706_223500_123_security_audit.md
└── 20260706_224100_456_mobsf_review.md
# the finished, synthesized reports
# (Summary + Detailed Findings + Risk Table),
# saved explicitly via save_final_report
Every tool call — regardless of which tool, regardless of success or failure — writes a timestamped markdown file to that APK's reports/ folder. This isn't optional per-call logging; it's a decorator (@logged_tool) applied to every registered tool, so nothing calling into this server goes unrecorded. Each report contains the tool name, the parameters it was called with, and its full output.
reports/ and final_reports/ serve different purposes: reports/ is the raw call log (every individual tool invocation, useful for auditing exactly what was checked and when), while final_reports/ holds only the polished, human-readable write-ups — the actual deliverable you'd hand to a developer or client. The security_audit and mobsf_review prompts both end with a mandatory call to save_final_report, which is what populates final_reports/; without that call, the synthesized report only exists in the chat response and isn't persisted anywhere on disk.
Prerequisites
1. Java JDK 8+ (required by Apktool)
# Ubuntu/Debian
sudo apt update && sudo apt install default-jdk
# macOS
brew install openjdk
java -version
2. Apktool
# Ubuntu/Debian
sudo apt install apktool
# macOS
brew install apktool
apktool --version
3. Python 3.10+
python3 --version
4. (Optional) aapt — for full get_apk_info metadata without needing to decode first
brew install aapt # or: brew install --cask android-commandlinetools
If aapt isn't installed, get_apk_info falls back to parsing the already-decoded AndroidManifest.xml instead of failing silently.
Installation
git clone <your-repo-or-just-copy-the-files> static-apk-auditor
cd static-apk-auditor
python3 -m venv venv
source venv/bin/activate # Windows: venv\Scripts\activate
pip install -r requirements.txt
Sanity check:
python3 server.py
# Should hang waiting for stdio input (that's normal) — Ctrl+C to stop.
Connecting to Claude Code
claude mcp add apktool-pro \
--env APKTOOL_WORK_DIR=/absolute/path/to/static-apk-auditor/data \
-- /absolute/path/to/static-apk-auditor/venv/bin/python3 /absolute/path/to/static-apk-auditor/server.py
Verify:
claude mcp list
claude mcp get apktool-pro # should show "✔ Connected"
Note: claude mcp add registers the server scoped to the current directory by default (local scope). If you want it available from any project, add --scope user.
Connecting to Claude Desktop (alternative)
Edit your config file (macOS: ~/Library/Application Support/Claude/claude_desktop_config.json):
{
"mcpServers": {
"apktool-pro": {
"command": "/absolute/path/to/static-apk-auditor/venv/bin/python3",
"args": ["/absolute/path/to/static-apk-auditor/server.py"],
"env": {
"APKTOOL_WORK_DIR": "/absolute/path/to/static-apk-auditor/data"
}
}
}
}
Restart Claude Desktop after saving.
Configuration (environment variables)
| Variable | Default | Purpose |
|---|---|---|
APKTOOL_PATH |
apktool |
Path to the apktool executable, if not on PATH |
AAPT_PATH |
aapt |
Path to aapt, if not on PATH |
APKTOOL_WORK_DIR |
~/.static-apk-auditor |
Root folder for all per-APK source/decoded/reports data |
Tools
Core (decompilation & manifest)
| Tool | Parameters | Description |
|---|---|---|
decode_apk |
apk_path, force=False |
Decompiles an APK with apktool. Output persists under APKTOOL_WORK_DIR/<slug>/decoded/ (not a tempdir), and a copy of the source APK is kept in .../source/. |
get_apk_info |
apk_path |
Basic metadata: package, version, SDK levels, file size. Uses aapt if available, otherwise falls back to parsing the decoded manifest. |
build_apk |
decoded_dir, output_apk=None |
Rebuilds an APK from a (possibly modified) decoded directory. Output is unsigned — sign separately with apksigner. |
install_framework |
framework_apk |
Installs a system framework APK so apktool can decode system/OEM apps that reference it. |
analyze_manifest |
decoded_dir |
Parses AndroidManifest.xml directly via xml.etree: package/version/SDK, exported components (Activity/Service/Receiver/Provider), intent-filters/deep links, debuggable/allowBackup/taskAffinity. |
list_permissions |
decoded_dir |
Lists all requested permissions, flags which are classified "dangerous" by the Android permission model. |
extract_strings |
decoded_dir, locale="en" |
Extracts string resources for a given locale. |
find_smali_references |
decoded_dir, pattern, max_matches=200 |
Regex search across all decompiled .smali files, with file + line for each match. |
Security heuristics
| Tool | Parameters | Description |
|---|---|---|
list_native_libraries |
decoded_dir |
Lists .so libraries and CPU architectures shipped in the APK — flags code that smali search can't see into. |
check_ssl_pinning |
decoded_dir |
Scans for custom TrustManager/HostnameVerifier implementations that could defeat certificate validation, plus CertificatePinner usage and network_security_config.xml contents. |
check_pending_intents |
decoded_dir |
Finds PendingIntent.getActivity/getBroadcast/getService calls and flags ones without FLAG_IMMUTABLE nearby. |
extract_js_bundle_strings |
decoded_dir, pattern=<url regex> |
For React Native / Expo apps: searches assets/*.bundle and assets/*.js for a pattern (defaults to extracting URLs — usually where real backend endpoints leak). |
check_root_detection |
decoded_dir |
Scans for root/emulator detection and anti-tampering signatures: su-binary paths, RootBeer/RootTools, SafetyNet, Play Integrity, test-keys build tag, generic isRooted-style method names. Presence tells you what you'll need to bypass for dynamic testing; absence is itself a finding for sensitive apps. |
Business logic reconnaissance
| Tool | Parameters | Description |
|---|---|---|
map_sensitive_flows |
decoded_dir, extra_keywords=None |
Locates methods/classes whose names suggest sensitive operations (payments, entitlements, roles, discounts, quotas) and shows nearby invoke-* calls as lightweight call context. A candidate map for manual/dynamic review — not a confirmed vulnerability list. |
find_client_side_only_checks |
decoded_dir |
Heuristic: flags sensitive-keyword hits where a local comparison (if-*/cmp-*) appears without an adjacent network call — suggests the decision may be made client-side and potentially bypassable by patching + rebuilding. |
MobSF report validation
| Tool | Parameters | Description |
|---|---|---|
load_mobsf_report |
report_path |
Loads and normalizes a MobSF static-analysis JSON report (code_analysis, manifest_analysis, permissions, urls/emails/firebase_urls, network_security, certificate_analysis). Does not judge validity by itself. |
cross_validate_mobsf_finding |
decoded_dir, finding_pattern, mobsf_file_hint=None |
Cross-checks one MobSF finding against your own decompiled output (smali + string resources) to catch false positives. Returns evidence for the model to classify — Confirmed / False Positive / Needs Manual Review — it does not classify on its own. |
Prompts (guided workflows)
Prompts are invoked explicitly as slash commands in Claude Code (/apktool-pro:<name>), unlike tools, which the model calls on its own as needed.
| Prompt | Arguments | What it does |
|---|---|---|
security_audit |
apk_path |
Runs the full 16-point checklist (attack surface, permissions, secrets, crypto, WebView, storage, SSL pinning, task hijacking, root detection, exported receivers/providers, JS bundle, native libs, logging, dependency versions, PendingIntent mutability, business logic) and outputs: Summary → Detailed Findings (with Confidence rating + adb PoC steps) → Risk Table mapped to OWASP Mobile Top 10 (M1–M10). |
mobsf_review |
apk_path, mobsf_report_path |
Loads a MobSF JSON report, cross-validates every finding against the actual decompiled code, classifies each as Confirmed/False Positive/Needs Manual Review, re-assesses severity independently of MobSF's own rating, and produces a Prioritized Action List of Confirmed findings only. |
quick_triage |
apk_path |
Fast pass: exported components + dangerous permissions + obvious hardcoded secrets. For when you don't need the full audit. |
Usage examples
Use decode_apk to decompile /path/to/app.apk
/apktool-pro:security_audit apk_path="/path/to/app.apk"
Use check_root_detection on the decompiled output
/apktool-pro:mobsf_review apk_path="/path/to/app.apk" mobsf_report_path="/path/to/mobsf_report.json"
To see all available tools and their exact parameters at any time, run /mcp in a Claude Code session and select apktool-pro.
Getting a MobSF report
If you're running MobSF locally:
# upload the APK, get back a hash
curl -F 'file=@/path/to/app.apk' http://localhost:8000/api/v1/upload \
-H "Authorization: <MOBSF_API_KEY>"
# fetch the JSON report using that hash
curl -X POST http://localhost:8000/api/v1/report_json \
-H "Authorization: <MOBSF_API_KEY>" \
--data "hash=<hash_from_upload>" -o mobsf_report.json
Known limitations
- Static analysis only. Nothing here executes the app or intercepts real traffic. Business-logic findings and some "confirmed" static findings still need dynamic verification before you treat them as proven.
build_apkoutput is unsigned. Sign withapksignerbefore installing on a device.- Regex-based heuristics (
check_ssl_pinning,check_root_detection,map_sensitive_flows, etc.) can miss obfuscated/renamed code and can false-positive on unrelated matches — treat their output as a shortlist to review, not a verdict. install_frameworkis only needed for decoding system/OEM APKs that referenceframework-res.apk; most third-party app analysis won't need it.
Design notes
APKTOOL_WORK_DIRis always respected — every APK gets a persistent, self-contained folder (source/,decoded/,reports/,final_reports/); nothing writes to a throwaway tempdir.get_apk_infofalls back to parsing the decoded manifest ifaaptisn't installed, rather than returning nothing useful.- Every tool call is auto-logged (
reports/); finished, synthesized reports are saved separately viasave_final_report(final_reports/). - Built on
FastMCPfor straightforward tool/prompt registration.
Legal / responsible use
Only analyze APKs you own or have explicit written permission to test. Decompiled APKs may contain sensitive user data — handle output accordingly and clean up APKTOOL_WORK_DIR after an engagement if it contains client data. This tool does not perform any network exfiltration or active exploitation on its own; PoC commands in security_audit output (e.g. adb shell am start ...) are meant to be run manually against a device/emulator you control.
Recommended Servers
playwright-mcp
A Model Context Protocol server that enables LLMs to interact with web pages through structured accessibility snapshots without requiring vision models or screenshots.
Magic Component Platform (MCP)
An AI-powered tool that generates modern UI components from natural language descriptions, integrating with popular IDEs to streamline UI development workflow.
Audiense Insights MCP Server
Enables interaction with Audiense Insights accounts via the Model Context Protocol, facilitating the extraction and analysis of marketing insights and audience data including demographics, behavior, and influencer engagement.
VeyraX MCP
Single MCP tool to connect all your favorite tools: Gmail, Calendar and 40 more.
Kagi MCP Server
An MCP server that integrates Kagi search capabilities with Claude AI, enabling Claude to perform real-time web searches when answering questions that require up-to-date information.
graphlit-mcp-server
The Model Context Protocol (MCP) Server enables integration between MCP clients and the Graphlit service. Ingest anything from Slack to Gmail to podcast feeds, in addition to web crawling, into a Graphlit project - and then retrieve relevant contents from the MCP client.
Neon Database
MCP server for interacting with Neon Management API and databases
Exa Search
A Model Context Protocol (MCP) server lets AI assistants like Claude use the Exa AI Search API for web searches. This setup allows AI models to get real-time web information in a safe and controlled way.
Qdrant Server
This repository is an example of how to create a MCP server for Qdrant, a vector search engine.
E2B
Using MCP to run code via e2b.