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
Available Tools
6 toolsaccessibility_spatialAccessibility SpatialC
Accessibility issues that are spatial or structural.
Touch targets under 48dp, interactive nodes fully covered by something else, and clickables a screen reader cannot announce.
| Name | Required | Description | Default |
|---|---|---|---|
| device | No | ||
| xml_path | No |
Output Schema
| Name | Required | Description |
|---|---|---|
No output parameters | ||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
No annotations are present, so the description carries the full behavioral burden. It does describe the kind of issues in scope, but says nothing about whether the operation mutates state, what it returns, what inputs it expects, or any side effects. The behavioral profile is largely unspecified.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
At two sentences, the description is compact and front-loaded with the core idea. The examples add useful specificity without padding, so the text is appropriately lean.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Even with an output schema present, the description omits the operational purpose and parameter semantics, and it does not connect to sibling tools. For a 2-parameter tool with no annotations, this is not enough for reliable invocation.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 0%, and the description never mentions device or xml_path. An agent must guess what these optional parameters mean, how they affect issue selection, and whether one or both are needed for meaningful output.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description is a noun phrase ('Accessibility issues that are spatial or structural') rather than an action; it never states a verb such as detects, filters, or returns. The examples clarify scope, but without a verb or relation to sibling tools an agent cannot tell whether this is a detector, a filter, or an issue categorizer.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
No when-to-use guidance is given. The sibling list (detect_issues, inspect_layout, element_context) suggests related workflows, but the description does not say when to prefer accessibility_spatial over them or what context requires this tool.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
compare_orientationsCompare OrientationsA
Run detect_issues in portrait and landscape and diff the findings.
The Android counterpart of checking a web page across breakpoints. This rotates the device and leaves it in portrait.
| Name | Required | Description | Default |
|---|---|---|---|
| device | No |
Output Schema
| Name | Required | Description |
|---|---|---|
No output parameters | ||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
No annotations exist, so the description carries the full burden. It explicitly discloses the key side effect: 'This rotates the device and leaves it in portrait.' This is important behavioral information an agent needs before invoking the tool.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is three short sentences with no filler. It leads with the core action, provides a useful analogy, and ends with the important side effect. Every sentence earns its place.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a simple tool with one optional parameter and an output schema, the description covers purpose and side effects well. However, the device parameter is completely undocumented, which leaves a real gap for correct invocation. The output schema may cover return values, but parameter semantics remain missing.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The schema has one parameter, device, with 0% schema description coverage, and the description never mentions this parameter at all. It does not explain what device accepts, whether null means default/active device, or how it affects the comparison. The description fails to compensate for the missing schema coverage.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description states a specific operation: run detect_issues in both portrait and landscape and diff the findings. It also distinguishes itself from the sibling detect_issues by framing it as the Android counterpart of cross-breakpoint web checking, so an agent can tell them apart.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description gives clear context for when to use the tool: when comparing Android layout/issue findings across orientations, analogous to checking web breakpoints. It does not explicitly enumerate exclusions or alternative single-orientation tools, but the intent is clear from the wording.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
detect_issuesDetect IssuesA
The main tool. Measured layout problems on the current screen.
Finds overlapping content, off-screen and clipped nodes, zero-size nodes, touch targets under Material's 48dp minimum, clickable nodes covered by something drawn later, and interactive nodes with no accessibility label. Each finding carries the geometry that produced it.
| Name | Required | Description | Default |
|---|---|---|---|
| device | No | ||
| xml_path | No |
Output Schema
| Name | Required | Description |
|---|---|---|
No output parameters | ||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
There are no annotations, so the description carries the behavioral burden. It clearly explains what the tool detects and that each finding includes the geometry that produced it, implying a read-only analysis. It does not explicitly state that no UI mutation occurs or mention environmental dependencies, but the behavior is largely transparent for a detection tool.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The definition is compact and front-loaded, starting with the general role and moving directly into a detailed but efficient enumeration of detected issue categories. The phrase 'The main tool' is somewhat generic and not strictly functional, but it does not cost much and the overall structure is easy to parse.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
An output schema exists, so return-value details are not required, and the description covers the main behavioral scope well. However, the optional parameters are completely undocumented and there is no guidance about when to use this general detector versus the specialized siblings, leaving meaningful gaps for an agent.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 0%, and neither device nor xml_path is described in the tool description. The description says 'current screen' but does not clarify whether these parameters select a device, load a saved hierarchy, or behave differently. The parameter names hint at their purpose, but the description adds no real semantic value beyond the schema.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description states a clear purpose: measuring layout problems on the current screen, and enumerates a concrete list of detected issue types (overlap, off-screen/clipped, zero-size, undersized touch targets, covered clickables, missing accessibility labels). This distinguishes it from sibling tools like inspect_layout and element_context as a broad screen-level diagnostic scanner.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Calling it 'the main tool' positions it as a first-line general layout auditor, and 'on the current screen' clarifies the context. It does not explicitly state when to prefer a sibling tool instead, but the purpose is clear enough that an agent can infer when to invoke it.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
element_contextElement ContextA
Deep dive on one node: its geometry, ancestry, siblings and collisions.
selector matches a resource-id, then exact text, then a substring of
text or content-desc.
| Name | Required | Description | Default |
|---|---|---|---|
| device | No | ||
| selector | Yes | ||
| xml_path | No |
Output Schema
| Name | Required | Description |
|---|---|---|
No output parameters | ||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations, the description carries the full burden. It adds useful behavioral detail about selector resolution order, but does not explicitly disclose whether the operation is read-only or whether any permissions are required. For an inspection tool this is a moderate gap, not a severe one.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Two sentences, no filler, and the main purpose is front-loaded. The selector-resolution sentence earns its place and is directly actionable for an agent.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
The output schema exists, so return values are covered externally, and the primary required parameter is well documented. Missing pieces include optional parameter meanings and an explicit statement about side effects or read-only behavior, leaving the definition adequate but not fully complete.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The required `selector` parameter is well explained with the matching order (resource-id, exact text, then substring of text/content-desc). However, schema description coverage is 0% and the optional `device` and `xml_path` parameters are left completely unexplained, so the description only partially compensates.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states the tool's focus: 'Deep dive on one node' and lists the outputs it provides (geometry, ancestry, siblings, collisions). It distinguishes from layout-wide siblings like inspect_layout by emphasizing a single node, but does not explicitly name a sibling alternative.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The selector matching precedence is clearly specified, which tells the agent exactly how to target a node. 'Deep dive on one node' provides clear context for when to use the tool, though it does not explicitly state when not to use it or which sibling tool to prefer.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
inspect_layoutInspect LayoutA
Full computed layout of the current screen: every node with its bounds.
The Android counterpart of reading getBoundingClientRect() on a web page.
Set interactive_only to get just the touchable nodes.
| Name | Required | Description | Default |
|---|---|---|---|
| device | No | ||
| xml_path | No | ||
| max_nodes | No | ||
| interactive_only | No |
Output Schema
| Name | Required | Description |
|---|---|---|
No output parameters | ||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations, the description carries the full burden of explaining behavior. It usefully states that the tool returns computed layout data with bounds, not raw structure, and that interactive_only filters to touchable nodes. However, it overstates by claiming 'every node' while the schema's max_nodes defaults to 400, and it does not mention xml_path side effects or output limits.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is three concise sentences with the core behavior front-loaded. The Android/getBoundingClientRect analogy adds context without bloat, and the final sentence briefly ties the only discussed parameter to a concrete use case. No sentence is wasted.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
The tool has four optional parameters and zero schema descriptions, yet only interactive_only is addressed. Output limits, device selection, and xml_path behavior remain undocumented, and the 'every node' phrasing conflicts with the default max_nodes. The output schema reduces the need to document return shapes, but it cannot compensate for these gaps.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The schema has 0% description coverage, so the description must compensate for parameter semantics, but it only explains interactive_only. device, xml_path, and max_nodes receive no meaningful guidance, and the interaction between max_nodes and the claim of 'every node' is left unclear. This is partial compensation at best.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description opens with a specific result — the full computed layout of the current screen with every node's bounds — making the tool's function immediately clear. This also distinguishes it from sibling tools like element_context and accessibility_spatial, which concern individual elements or accessibility rather than the whole layout tree. Although the verb is implicit, the resource and scope are unmistakable.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The getBoundingClientRect() analogy provides a concrete, recognizable use case, signaling this tool is for computed geometry of the entire screen. It does not explicitly name alternatives or state when not to use it, but the context is clear enough to guide invocation.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
list_devicesList DevicesA
List attached Android devices and emulators, with their adb state.
| Name | Required | Description | Default |
|---|---|---|---|
No parameters | |||
Output Schema
| Name | Required | Description |
|---|---|---|
No output parameters | ||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
There are no annotations, so the description is the only safety and behavior signal. The verb 'List' implies a non-mutating read-only operation, and 'adb state' hints at the output, but nothing is said about adb server prerequisites, failure modes, or side effects. It is minimally transparent but not misleading.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
A single 11-word sentence that front-loads the action and object. No filler or repetition of the title beyond what is necessary.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
With no parameters and an output schema available, the description covers the core invocation need. It leaves out explicit usage routing and behavioral caveats, but the tool is simple enough that these are minor gaps.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The tool takes zero parameters and schema coverage is 100%, so there is nothing for the description to clarify. The baseline of 4 applies because the one-line description is sufficient for an argument-free tool.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb ('List'), a concrete resource ('attached Android devices and emulators'), and a distinctive detail ('with their adb state'). This clearly separates it from the UI-inspection siblings even without reading their descriptions.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
No sentence explains when to call list_devices versus alternatives, and no sibling is mentioned. The intended use is implied by the name and description, but the agent gets no explicit context or when-not-to-use guidance.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
Tool Schema Changelog
Recent tool additions, removals, and schema changes observed during successful MCP inspections.
6 tool updates
v0.1.0- First observed
accessibility_spatial - First observed
compare_orientations - First observed
detect_issues - First observed
element_context - First observed
inspect_layout - First observed
list_devices
TDQS
Scored across 6 tools
detect_issues and accessibility_spatial overlap significantly: both detect touch targets under 48dp, covered interactive nodes, and accessibility labeling problems. inspect_layout and element_context also both expose geometry, though one is screen-wide and the other node-specific, creating boundary ambiguity.
Four tools follow a verb_noun pattern (list_devices, inspect_layout, detect_issues, compare_orientations), but element_context and accessibility_spatial break the pattern with noun-first names. The mixed conventions are still readable and not chaotic.
Six tools is well-scoped for an Android layout inspector: device enumeration, layout inspection, issue detection, deep node context, accessibility-specific checks, and orientation comparison. Each tool has a clear role in the workflow, and the count is neither thin nor bloated.
The tool surface covers the main inspection lifecycle: enumerate devices, dump layout, identify issues, drill into a node, run accessibility checks, and compare orientations. Minor gaps exist, such as no screenshot capture or explicit way to filter issues by type, but agents can accomplish core layout analysis workflows.
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-
- FlicenseAqualityDmaintenanceEnables 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-