AndroidBuildMCP

Give your AI agent hands on Android. AndroidBuildMCP is an MCP server that lets any MCP client (Claude Code, Cursor, ...) build, deploy, drive and debug real Android apps: Gradle builds with readable errors, emulator management, adb deployment, logcat capture and full UI automation.
Quick start
Requirements: Node 18+, the Android SDK (ANDROID_HOME or a default install), and a JDK 17+ for Gradle builds.
No install step โ npx fetches the server on first run.
Claude Code
claude mcp add androidbuild -- npx -y @asjackson/androidbuild-mcp
Any other MCP client
{
"mcpServers": {
"androidbuild": {
"command": "npx",
"args": ["-y", "@asjackson/androidbuild-mcp"]
}
}
}
Run from source instead
git clone https://github.com/dev-jackson/androidbuild-mcp.git
cd androidbuild-mcp
npm install && npm run build
claude mcp add androidbuild -- node /absolute/path/to/androidbuild-mcp/dist/index.js
Then ask your agent to run doctor โ it checks the SDK, adb, emulator, Java and connected devices, and tells you exactly what is missing.
What your agent can do
- Build and test โ
build_app compiles and returns compact file:line compiler errors instead of a thousand lines of Gradle noise. test_app / test_instrumented return parsed pass/fail summaries. Lint, clean, coverage (Kover/Jacoco) included.
- Manage emulators โ list, create, boot (waits for full boot, returns the serial), wipe, and kill AVDs. Set GPS location, dark mode, and a clean demo status bar for screenshots.
- Deploy โ
build_run compiles, installs and launches in one call. Install/uninstall/clear-data/app-info via adb, with the right device auto-selected when only one is connected.
- See the screen โ
snapshot_ui returns the UI as a compact list of named elements with tap coordinates (Compose semantics merged, noise filtered). screenshot returns an image; with annotate: true it draws numbered boxes using vision, catching text inside images and WebViews.
- Touch the screen โ tap, scroll, swipe, drag, long-press, type (keyboard-aware, with clear/submit), hardware keys, and
wait_for_ui to poll until an element appears.
- Read the logs โ background logcat capture filtered to your app, one-shot dumps, and the crash buffer for stack traces.
- Start new apps โ
scaffold_android_project generates a minimal Compose project that builds out of the box.
Session defaults (session_set_defaults) mean you configure project, module, variant and device once โ every other call then works without arguments.
53 tools over stdio. Every tool takes plain arguments and returns text (or an image, for screenshot).
Environment and project
| Tool | Description |
|---|
doctor | Check SDK, adb, emulator, avdmanager, Java and connected devices; reports what is missing |
discover_projects | Find Android/Gradle projects under a path |
list_modules | List modules declared in settings.gradle(.kts) |
list_variants | List build variants of a module |
get_app_id | Read the applicationId of a module |
show_gradle_config | Show Gradle, AGP, Kotlin and version-catalog entries |
Session defaults
| Tool | Description |
|---|
session_set_defaults | Set default project, module, variant, serial and appId for all later calls |
session_show_defaults | Show the current defaults |
session_clear_defaults | Clear all defaults, or only the listed keys |
Build, test and quality
| Tool | Description |
|---|
build_app | Build an APK; returns compact file:line compiler errors |
build_run | Build, install and launch in one call |
test_app | Run JVM unit tests with a parsed pass/fail summary |
test_instrumented | Run instrumented tests on a device |
lint | Run Android Lint and summarize the report |
clean | Run gradle clean |
get_apk_path | Locate the most recent APK without building |
stop_gradle | Stop the project's Gradle daemons |
get_coverage_report | Run Kover/Jacoco and summarize line coverage per package |
get_file_coverage | Show covered/uncovered lines of one source file |
Devices and emulators
| Tool | Description |
|---|
list_devices | List devices with serial, state, model, Android version, API level |
list_avds | List AVDs and which are running |
boot_emulator | Boot an AVD and wait for full boot; returns the serial |
kill_emulator | Shut down a running emulator |
create_avd | Create an AVD from an installed system image |
delete_avd | Delete an AVD |
set_emulator_location | Set GPS location |
set_appearance | Switch dark/light mode |
statusbar_demo_mode | Clean status bar for screenshots |
App lifecycle
| Tool | Description |
|---|
install_app | Install an APK (adb install -r) |
launch_app | Launch by application id, resolving the launcher activity |
stop_app | Force-stop a running app |
uninstall_app | Uninstall an app |
clear_app_data | Reset an app to fresh-install state |
get_app_info | Version, target/min SDK, install path, running PID |
UI automation
| Tool | Description |
|---|
snapshot_ui | Dump the UI as named elements with exact tap coordinates |
screenshot | Capture the screen; annotate: true draws numbered boxes |
tap_element | Tap element #N from the last annotated screenshot |
tap | Tap at pixels or screen percentages |
scroll | Scroll in a direction with a safe computed swipe |
swipe | Swipe between two points |
drag | Drag from one point to another |
long_press | Long-press, holding 1000 ms |
type_text | Type into the focused field, waiting for the keyboard |
key_press | Press BACK, HOME, ENTER, DPAD_*, or any keycode |
key_sequence | Press several keys in order |
wait_for_ui | Poll until an element appears |
Logs and recording
| Tool | Description |
|---|
get_logs | One-shot logcat dump, filterable by app and tag |
get_crash_logs | Crash buffer: Java exceptions, native crashes, ANRs |
start_log_capture | Start background logcat capture to a file |
stop_log_capture | Stop capture and return the file plus the last lines |
record_video_start | Start screen recording (max 3 minutes) |
record_video_stop | Stop recording and pull the MP4 |
Scaffolding
| Tool | Description |
|---|
scaffold_android_project | Create a minimal Compose app that builds out of the box |
Tapping accurately
Everything adb-side shares one coordinate space (device pixels), but MCP clients often display screenshots scaled โ estimating pixel positions by eye from the image sends taps to the wrong place. Three safe ways to hit the target:
snapshot_ui โ returns exact device-pixel centers for every named element. Preferred.
screenshot { annotate: true } + tap_element { element: N } โ tap by the number drawn on the image; the mapping is resolved on the original PNG, so client-side scaling cannot distort it.
tap { xPct, yPct } โ screen percentages (0-1), also available on long_press/swipe/drag. Resolution-independent.
Raw tap { x, y } still works when you have real pixel coordinates.
Reliability
Every tool was exercised against real emulators and real projects โ happy paths and corner cases โ before release; the scenario-by-scenario evidence is in qa-results.md. Some of the details that keep agent flows from misfiring:
type_text waits for the soft keyboard before injecting (typing right after focusing a field silently drops the first characters otherwise).
scroll computes a long, slow swipe from the screen size โ short fast swipes get ignored by some lists. long_press holds 1000 ms, which launchers require.
- Taps outside the screen are rejected with the actual screen size instead of silently doing nothing.
- Text-heavy screens (e-book WebViews and the like) are capped and searchable with
snapshot_ui { filter } instead of flooding the context.
- Build/test/device failures come back as short, actionable messages with the next tool to call.
- Google's Android CLI enables
screenshot { annotate: true }. doctor prints the one-line installer for your OS.
- The ADBKeyboard IME enables non-ASCII
type_text (adb alone is ASCII-only). Install its APK once; the server uses it automatically.
Development
npm install
npm test
npm run dev
npm run build
License
MIT โ see LICENSE.
Conceptually inspired by XcodeBuildMCP; independent implementation built around the Android toolchain.