android-layout-inspector-mcp
Provides spatial inspection of a live Android UI over adb and uiautomator, detecting measured layout issues such as overlaps, clipping, off-screen nodes, zero-size elements, small touch targets, occluded interactive elements, and accessibility problems on connected devices or emulators.
Inspects Jetpack Compose UI hierarchies on Android, supports resource-id selection when Compose semantics use testTagsAsResourceId, and detects Compose trees that are not properly inspectable by id.
Click on "Deploy Server".
Wait a few minutes for the server to deploy. Once ready, it will show a "Started" state.
In the chat, type
@followed by the MCP server name and your instructions, e.g., "@android-layout-inspector-mcpcheck the current screen for overlapping views and small touch targets"
That's it! The server will respond to your query, and you can continue using it as needed.
Here is a step-by-step guide with screenshots.
android-layout-inspector-mcp
Spatial inspection of a live Android UI for AI agents. Pulls the real view
hierarchy off a device or emulator over adb + uiautomator, and reports
layout problems as measured geometry — overlap area in px², touch targets
in dp, clipped fractions — not as an opinion about a screenshot.
The Android counterpart of layout-inspector-mcp, which does the same job for web pages via Playwright.
Why
An agent that changes a layout has no way to know whether the result overlaps, clips, or leaves a control too small to tap. Screenshots are the obvious answer and the wrong one: judging a 4px collision by looking at pixels is guesswork, and legitimate overlays get reported as bugs.
This measures instead. Every node's bounds, cross-referenced for intersections, with the overlap area in px² and touch targets converted to dp against the device's real density. Deterministic and reproducible: it tells you which two nodes collide, not "something looks off". Use a screenshot afterwards to confirm a finding looks wrong to a human, not to find it.
No Android Studio required.
Related MCP server: Android Mobile MCP
Requirements
Python 3.11+
uv— used by the plugin launch pathadbonPATH, orADB_PATH, orANDROID_HOMEpointing at an SDK that containsplatform-tools/adbA device with USB debugging on, or a running emulator
Install as a plugin
claude plugin install android-layout-inspector --marketplace Rixmerz/claude-pluginsInstall as a plain MCP server
git clone https://github.com/Rixmerz/android-layout-inspector-mcp.git
cd android-layout-inspector-mcp
uv sync
claude mcp add android-layout-inspector -- uv run --project "$PWD" android-layout-inspector-mcpTools
Tool | Purpose |
| The main one. Every check below, sorted by severity, each with the geometry that produced it. |
| Full computed hierarchy: bounds in px and dp, class, ids, flags. |
| Deep dive on one node — ancestry, siblings, children, and what collides with it. Matches a resource-id, then exact text, then a substring. |
| Touch targets under 48dp, interactive nodes covered by something else, clickables a screen reader cannot announce. |
| Runs the checks in portrait and landscape and diffs them. The Android answer to responsive breakpoints. |
| Attached devices and their adb state. |
Every analysis tool accepts xml_path instead of a device, so a saved
uiautomator dump can be analysed in CI with no hardware attached.
What it detects
Check | Fires when |
| Two unrelated leaf nodes with content collide. Ancestor/descendant overlap is the layout working, not a bug, and is never reported. Sub-4px² and sub-2% intersections are treated as rounding. |
| A node with content falls partly or wholly outside the viewport. |
| A node carries text, a description or a click handler but was laid out with no area. |
| An enabled interactive node is under 48dp on either axis — Material's minimum, not the web's 44px. |
| A clickable node is fully covered by an unrelated node drawn after it, so the tap never reaches it. |
| A clickable node has no text, no |
| See below. |
Jetpack Compose: the one thing you must do
By default a Compose screen collapses into a handful of anonymous
android.view.View nodes. The geometry is real, but nothing can be selected
by id, which makes every finding much harder to act on. Add this to your root
composable:
@OptIn(ExperimentalComposeUiApi::class)
Surface(
modifier = Modifier
.fillMaxSize()
.semantics { testTagsAsResourceId = true }
) { /* ... */ }Then every Modifier.testTag("boton_sumar") shows up as
resource-id="boton_sumar". detect_issues raises
compose_not_inspectable when it sees a Compose tree that skipped this.
What this deliberately does not do
Three things are measurable on the web and are not recoverable from a
uiautomator dump. They are left out rather than approximated:
Text truncation. uiautomator reports the full string even when the view
ellipsized it — verified on both a classic TextView with
android:ellipsize="end" and a Compose Text with TextOverflow.Ellipsis.
There is no signal in the dump, so no check pretends to find one.
Fully off-screen nodes on a live device. Android drops them from the
hierarchy before uiautomator ever sees them. The offscreen check still
fires on saved dumps and on partially clipped nodes, which is the case that
actually reaches the dump.
Real occlusion by opacity. Draw order and containment are known; alpha and
elevation are not. occluded_interactive requires full geometric containment
by a later sibling, which is conservative on purpose.
One more caveat worth knowing: Compose already expands every clickable to
48dp for accessibility, so small_touch_target mostly catches classic View
layouts and code that overrides LocalMinimumInteractiveComponentSize.
Verified
uv run pytest — unit checks on crafted hierarchies plus a fixture captured
from a real emulator.
End to end against a Pixel 8 AVD (API 36, 1080x2400 @ 420dpi):
overlap (15211px², 74% of the smaller node), unlabeled_interactive on two
Compose buttons, small_touch_target on a 24x24dp Button in a classic View
layout, and compare_orientations correctly reading 1080x2400 in portrait and
2400x1080 in landscape.
License
MIT
This server cannot be deployed
Maintenance
Related MCP Connectors
Drive real devices from your AI Coding tool. Embed a client SDK (Unity, Godot, Flutter, iOS/macOS, Android, React Native, Web) in your app, then capture screenshots, traverse the UI tree, inject taps and key events, and run automated test tasks on the physical device over a secure relay.
Control real Android and iOS devices with LLM agents — tap, swipe, type, automate flows.
remote debug iOS/Android/Unity/Godot/Flutter/RN/Web on real-device.ui-tree/screenshots/taps,tests.
Melaya is a remote MCP server. It gives an assistant hands on your own Android phone and browser: it reads the screen through the accessibility tree, then taps, types and navigates inside the apps and sites you allow-list, with no per-app API. It also builds, schedules and runs agent pipelines across 6k+ connected tools. OAuth 2.1, nothing to install.
Related MCP Servers
- FlicenseBqualityDmaintenanceEnables AI agents to interact with Android devices through visual UI element detection and automated interactions. Provides comprehensive Android automation capabilities including touch gestures, text input, screenshots, and video recording via uiautomator2.124-
- FlicenseAqualityCmaintenanceEnables AI agents to interact with Android devices through UI manipulation, screen capture, touch gestures, text input, and app management via ADB. Provides comprehensive mobile automation capabilities including element detection, navigation, and application control for Android device testing and interaction.94-
- AlicenseBqualityBmaintenanceEnables AI agents to control Android devices and emulators through direct UI interaction, allowing app navigation, automated testing, and real-world task execution via ADB without computer vision or scripts.182MIT
- FlicenseBqualityCmaintenanceEnables AI assistants to observe, reason about, and control connected Android devices via ADB, providing tools for screenshots, UI hierarchy parsing, semantic element clicking, gestures, text input, and app lifecycle management.13-