android-build-mcp

android-build-mcp

An MCP server that gives coding agents hands and eyes on an Android device, providing 19 tools for building, testing, installing, UI inspection, input, logs, and toolchain diagnosis. It returns concise, structured results to make the build-debug loop efficient.

Category
访问服务器

README

android-build-mcp

CI License: MIT

An MCP server that gives a coding agent hands and eyes on an Android device.

Your agent can already shell out to gradlew and adb. The problem is what that costs: a failed build dumps four thousand lines of task progress into the context window, tap coordinates get guessed off a screenshot, and a JDK/Gradle mismatch sends it bisecting application code for an hour over an error that had nothing to do with the app.

This is the build-debug loop made cheap. 19 tools covering build, test, install, launch, screenshot, UI inspection, input, logs, and toolchain diagnosis — each one shaped to return the smallest thing that answers the question.

You: "The start button doesn't do anything on the tablet. Fix it."

Agent: android_doctor          -> toolchain OK, Gradle 8.7 / JDK 17 compatible
       android_build           -> assembleDebug + install + launch
       android_set_rotation    -> landscape
       android_dump_ui         -> Button "start" at (1580, 890), clickable=false
       android_logcat          -> IllegalStateException in onMeasure
       ...reads the layout, edits it, rebuilds, taps the button, confirms

Install

Requires Node 18+, the Android SDK platform-tools, and a JDK (Android Studio's bundled one is found automatically).

Not on npm yet — install from source:

git clone https://github.com/jjs03111/android-build-mcp
cd android-build-mcp
npm install && npm run build

Claude Code

claude mcp add android -- node /absolute/path/to/android-build-mcp/dist/index.js

Any MCP client — add to the client's server config:

{
  "mcpServers": {
    "android": {
      "command": "node",
      "args": ["/absolute/path/to/android-build-mcp/dist/index.js"]
    }
  }
}

No configuration needed if you have a standard Android Studio install. Run android_doctor to confirm.

What this does beyond wrapping adb

It knows why builds fail. JDK/Gradle incompatibility is checked before the build starts, so you get "JDK 23 is newer than Gradle 8.7 supports (max 22)" instead of Unsupported class file major version 67 after a two-minute wait. SDK location not found, signature mismatches on install, and INSTALL_FAILED codes all come back with the actual remedy attached.

It doesn't flood the context. A failed Gradle build is thousands of lines, nearly all of it task progress. The failure summary keeps the compiler diagnostics and the FAILURE: block and drops the rest — typically a 50%+ reduction, all of it noise. Logcat filters to your app's pid. android_dump_ui returns text and coordinates instead of a megabyte of screenshot when what you needed was the label on a button.

It recognises failures it has seen before. Every failure path — Gradle, install, crash logs — runs its output past a set of known Android failure modes whose symptoms point nowhere near their causes. When one matches, the fix arrives attached to the error, not in a document somebody has to remember to consult:

  • Gradle refusing to run on a too-new JDK (Unsupported class file major version)
  • SDK location not found on a fresh clone, because local.properties is gitignored
  • OEM battery management killing foreground services within seconds on Samsung and Xiaomi
  • adb shell input text silently dropping every non-ASCII character
  • GridLayout cells collapsing when weights meet wrap_content
  • Package visibility filtering returning empty lists on Android 11+
  • Signature mismatches on install, and stale package references after an external uninstall

android_pitfalls exposes the same set for browsing and searching. An agent that hits one of these otherwise starts bisecting application code that was never the problem.

It finds your toolchain. adb via ANDROID_HOME, the platform's standard SDK locations, then PATH. The JDK via Android Studio's bundled JBR — chosen because it is version-matched to AGP, unlike whatever is on PATH. Gradle is launched through the wrapper's main class rather than gradlew.bat, which both sidesteps Node's refusal to spawn .bat files and guarantees the validated JDK is the one that runs.

Tools

Device

Tool Purpose
android_list_devices Connected devices with Android version, screen size, density, rotation
android_connect_wifi Promote a USB device to wireless adb, or reconnect to a known address

Build

Tool Purpose
android_build Gradle assemble, optionally install and launch in one call
android_test Run unit or instrumented tests, reporting which ones failed
android_install Install an APK
android_launch Start an app, optionally cold
android_clear_data Wipe an app's data without uninstalling it
android_uninstall Remove an app

Inspect

Tool Purpose
android_screenshot PNG of the screen, inline or to a file
android_dump_ui View hierarchy as text, with tap coordinates for every element
android_logcat Logs filtered by package, tag, priority, or the crash buffer
android_shell Arbitrary adb shell command

Interact

Tool Purpose
android_tap Tap or long-press
android_swipe Swipe, scroll, drag
android_input_text Type into the focused field
android_key_event Back, Home, Enter, arrows, volume
android_set_rotation Force an orientation, or restore auto-rotate

Diagnose

Tool Purpose
android_doctor Check adb, SDK, JDK, devices, and JDK/Gradle compatibility
android_pitfalls Look up known failure modes by error text, topic, or keyword

How this compares

vs. letting an agent run gradlew and adb through a shell tool. It already can, and when a build succeeds the difference is small. The difference shows up on failure and at scale: a failed build here returns the compiler errors instead of several thousand lines of task progress, a JDK/Gradle mismatch is caught before the build rather than two minutes into it, logs come back scoped to your app's process, and android_dump_ui hands over exact tap coordinates instead of the agent estimating them off a screenshot. Shell output is also unstructured, so every result has to be re-read by the model.

vs. mobile-mcp and other device-control servers. Those cover device automation — tap, swipe, screenshot, element inspection — and mobile-mcp covers iOS too, which this does not. The overlap is real, and if driving a device is all you need, they are the more established choice. What they do not cover is the build side: compiling the project, resolving the application id out of Gradle, installing, running tests, and explaining why the toolchain refused. That is what this server is for. Testing an app you did not build? Prefer theirs. Writing the app? This closes the edit-run-read cycle.

vs. Android Studio. Not a competitor. This exists so an agent can do the parts of the loop that do not need a person watching. Keep the IDE open.

Configuration

Everything is auto-detected. Override only if you need to:

Variable Purpose
ANDROID_HOME / ANDROID_SDK_ROOT Android SDK root
ANDROID_MCP_ADB Path to the adb binary
ANDROID_MCP_JAVA_HOME JDK to build with

Security

android_shell runs arbitrary commands on the connected device, and the build tools execute the target project's Gradle wrapper — which is code from that project. Point this at repositories you trust, the same way you would before opening one in an IDE. Nothing is sent anywhere: every tool talks only to the local adb server and the local filesystem.

android_clear_data and android_uninstall destroy app data irrecoverably; both are marked with destructiveHint so clients that gate destructive tools can prompt before running them.

Known limitations

  • android_input_text cannot type non-ASCII characters, nor the literal sequence %s. Both are limitations of Android's input text command: it is ASCII-only, and it decodes %s to a space with no escape available (even %%s decodes to % ). The tool rejects both cases with an explanation rather than silently mangling the text. Use an adb-driven IME (ADBKeyBoard) for CJK.
  • android_dump_ui cannot see inside WebView content; uiautomator only exposes the WebView node itself. Use android_screenshot for WebView-based UIs.
  • android_dump_ui cannot see past a locked screen either — you get the keyguard, not the app.
  • Wireless adb requires the host and the device to be on the same LAN. A VPN interface on the host does not bridge to the device's network, and routers with AP isolation block it outright. android_connect_wifi detects the subnet mismatch case and says so rather than reporting a bare timeout.
  • Release builds require the project's own signing config.
  • Developed and manually verified on Windows against a physical device (Galaxy A16, Android 16) and an emulator (API 35). macOS and Linux run the unit tests and a server smoke check in CI, and Linux additionally runs the full end-to-end suite on an emulator — but neither has been driven by hand, so rough edges in toolchain discovery are likelier there. Reports welcome.

Development

npm install
npm run build
npm test          # unit tests
npm run typecheck

npm test needs no device. The end-to-end suite does — start an emulator or plug in a phone, then:

node test/e2e/run.mjs

It prefers an emulator when one is running, so it will not rotate the screen or inject input on a phone you happen to have plugged in.

Contributing

The most useful contribution is a pitfall. If some Android failure cost you an afternoon because the symptom pointed nowhere near the cause, add it to src/services/pitfalls.ts: the symptom as you observed it, the actual cause, the fix, and — if the error has a recognisable signature — a regex so it fires automatically at the moment of failure instead of waiting to be looked up.

Bug reports that include the output of android_doctor are much faster to act on.

License

MIT

推荐服务器

Baidu Map

Baidu Map

百度地图核心API现已全面兼容MCP协议,是国内首家兼容MCP协议的地图服务商。

官方
精选
JavaScript
Playwright MCP Server

Playwright MCP Server

一个模型上下文协议服务器,它使大型语言模型能够通过结构化的可访问性快照与网页进行交互,而无需视觉模型或屏幕截图。

官方
精选
TypeScript
Magic Component Platform (MCP)

Magic Component Platform (MCP)

一个由人工智能驱动的工具,可以从自然语言描述生成现代化的用户界面组件,并与流行的集成开发环境(IDE)集成,从而简化用户界面开发流程。

官方
精选
本地
TypeScript
Audiense Insights MCP Server

Audiense Insights MCP Server

通过模型上下文协议启用与 Audiense Insights 账户的交互,从而促进营销洞察和受众数据的提取和分析,包括人口统计信息、行为和影响者互动。

官方
精选
本地
TypeScript
VeyraX

VeyraX

一个单一的 MCP 工具,连接你所有喜爱的工具:Gmail、日历以及其他 40 多个工具。

官方
精选
本地
graphlit-mcp-server

graphlit-mcp-server

模型上下文协议 (MCP) 服务器实现了 MCP 客户端与 Graphlit 服务之间的集成。 除了网络爬取之外,还可以将任何内容(从 Slack 到 Gmail 再到播客订阅源)导入到 Graphlit 项目中,然后从 MCP 客户端检索相关内容。

官方
精选
TypeScript
Kagi MCP Server

Kagi MCP Server

一个 MCP 服务器,集成了 Kagi 搜索功能和 Claude AI,使 Claude 能够在回答需要最新信息的问题时执行实时网络搜索。

官方
精选
Python
e2b-mcp-server

e2b-mcp-server

使用 MCP 通过 e2b 运行代码。

官方
精选
Neon MCP Server

Neon MCP Server

用于与 Neon 管理 API 和数据库交互的 MCP 服务器

官方
精选
Exa MCP Server

Exa MCP Server

模型上下文协议(MCP)服务器允许像 Claude 这样的 AI 助手使用 Exa AI 搜索 API 进行网络搜索。这种设置允许 AI 模型以安全和受控的方式获取实时的网络信息。

官方
精选