Skip to content

Screenshots have lined squares drawn around icons #9

@SamuelMiller

Description

@SamuelMiller

There appears to be no way to have a clean screenshot of my phone. Every icon has a square drawn around it in the screenshot. Please consider adding this option to just allow clean screenshots, because sometimes I want to be able to give the screenshot to Claude Code and have it create a design system around it, for example. I have show layout bounds disabled on my phone.

This is what Claude Code says:
Unfortunately, the colored squares are added by the Android MCP tool itself - it's designed for automation/debugging and overlays UI element boundaries on the screenshot.

The Android MCP's State-Tool doesn't have an option to disable these overlays.

PS: Thanks so much for providing this MCP. I am suprised that Google doesn't have an official ADB mcp?

Image

I inquired about the issue using DeepWiki. This is what it reported:

Verification: Claude Code is Correct

Yes, Claude Code's statement is TRUE. The colored squares are indeed added by the Android MCP tool itself, and there is currently no option to disable these overlays.

Here's what happens:

  1. When you call the State-Tool with use_vision=True, it calls mobile.get_state(use_vision=use_vision) 1

  2. The get_state() method, when use_vision=True, always calls tree.annotated_screenshot() which adds the colored rectangles 2

  3. The annotated_screenshot() method draws colored bounding boxes around every interactive element using random colors and numeric labels 3

Currently, your only options are:

  • use_vision=True → Get annotated screenshot with colored boxes
  • use_vision=False → Get NO screenshot at all

There is no way to get a clean, unannotated screenshot.


Proposed Solution

Add a new parameter annotate to control whether screenshots should have overlays. Here's an example pull request with the necessary code changes:

Example Pull Request

PR Title: Add option for clean screenshots without UI element annotations

PR Description:

Adds an annotate parameter to allow users to capture clean screenshots without colored bounding boxes and labels. This enables use cases where users want unmodified screenshots for design analysis or documentation.

Changes Required:

File 1: main.py
Modify the State-Tool to accept an annotate parameter:

@mcp.tool('State-Tool',description='Get the state of the device. Optionally includes visual screenshot when use_vision=True. Set annotate=False for clean screenshots without UI element overlays.')
def state_tool(use_vision:bool=False, annotate:bool=True):
    mobile_state=mobile.get_state(use_vision=use_vision, annotate=annotate)
    return [mobile_state.tree_state.to_string()]+([Image(data=mobile_state.screenshot,format='PNG')] if use_vision else [])

File 2: src/mobile/__init__.py
Update get_state() to pass the annotate parameter:

def get_state(self, use_vision=False, annotate=True):
    try:
        tree = Tree(self)
        tree_state = tree.get_state()
        if use_vision:
            nodes=tree_state.interactive_elements
            if annotate:
                screenshot_image = tree.annotated_screenshot(nodes=nodes, scale=1.0)
            else:
                screenshot_image = self.get_screenshot(scale=1.0)
            screenshot = self.screenshot_in_bytes(screenshot_image)
        else:
            screenshot=None
        return MobileState(tree_state=tree_state, screenshot=screenshot)
    except Exception as e:
        raise RuntimeError(f"Failed to get device state: {e}")

Usage Examples:

# Get clean screenshot without annotations
state_tool(use_vision=True, annotate=False)

# Get annotated screenshot (default behavior, backward compatible)
state_tool(use_vision=True)
state_tool(use_vision=True, annotate=True)

# No screenshot (existing behavior)
state_tool(use_vision=False)

Notes

  • The solution maintains backward compatibility by defaulting annotate=True, so existing code continues to work unchanged
  • The get_screenshot() method already exists and captures clean screenshots 4
  • The only blocker was that get_state() had no conditional logic to choose between annotated and clean screenshots
  • The scale parameter should match (1.0) for consistency whether annotated or not
  • This enables your use case of providing clean screenshots to Claude for design system analysis

Citations

File: main.py (L34-35)

    mobile_state=mobile.get_state(use_vision=use_vision)
    return [mobile_state.tree_state.to_string()]+([Image(data=mobile_state.screenshot,format='PNG')] if use_vision else [])

File: src/mobile/init.py (L24-27)

            if use_vision:
                nodes=tree_state.interactive_elements
                annotated_screenshot=tree.annotated_screenshot(nodes=nodes,scale=1.0)
                screenshot=self.screenshot_in_bytes(annotated_screenshot)

File: src/mobile/init.py (L34-43)

    def get_screenshot(self,scale:float=0.7)->Image.Image:
        try:
            screenshot=self.device.screenshot()
            if screenshot is None:
                raise ValueError("Screenshot capture returned None.")
            size=(screenshot.width*scale, screenshot.height*scale)
            screenshot.thumbnail(size=size, resample=Image.Resampling.LANCZOS)
            return screenshot
        except Exception as e:
            raise RuntimeError(f"Failed to get screenshot: {e}")

File: src/tree/init.py (L73-85)

        def draw_annotation(label, node: ElementNode):
            bounding_box = node.bounding_box
            color = get_random_color()

            # Scale and pad the bounding box also clip the bounding box
            adjusted_box = (
                int(bounding_box.x1 * scale) + padding,
                int(bounding_box.y1 * scale) + padding,
                int(bounding_box.x2 * scale) + padding,
                int(bounding_box.y2 * scale) + padding
            )
            # Draw bounding box
            draw.rectangle(adjusted_box, outline=color, width=2)

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions