get_ui_tree
Retrieve the UI element hierarchy of the current Android screen to identify interactive elements with bounds, text, resource IDs, and state for automation tasks.
Instructions
Get the UI element hierarchy of the current screen. Returns interactive elements with their bounds, text, resource IDs, and state. Use this to find elements before tapping.
Input Schema
TableJSON Schema
| Name | Required | Description | Default |
|---|---|---|---|
| device_id | No | Device ID (optional if only one device) |
Implementation Reference
- src/adb.ts:232-247 (handler)The implementation of the getUiTree method which retrieves the UI hierarchy from the device.
async getUiTree(deviceId?: string): Promise<UiElement[]> { let xml: string; try { const raw = await this.exec(["shell", "uiautomator", "dump", "/dev/tty"], deviceId); const xmlStart = raw.indexOf("<?xml"); const hierarchyStart = raw.indexOf("<hierarchy"); const start = xmlStart !== -1 ? xmlStart : hierarchyStart; if (start === -1) throw new Error("No XML found in /dev/tty output"); xml = raw.substring(start); } catch { await this.exec(["shell", "uiautomator", "dump", "/sdcard/window_dump.xml"], deviceId); xml = await this.exec(["shell", "cat", "/sdcard/window_dump.xml"], deviceId); } return this.parseUiXml(xml); } - src/index.ts:124-144 (registration)MCP tool registration for "get_ui_tree" in src/index.ts.
server.tool( "get_ui_tree", "Get the UI element hierarchy of the current screen. Returns interactive elements with their bounds, text, resource IDs, and state. Use this to find elements before tapping.", { device_id: z.string().optional().describe("Device ID (optional if only one device)") }, async ({ device_id }) => { const elements = await adb.getUiTree(device_id); const summary = elements.map((el, i) => { const parts: string[] = [`[${i}]`]; if (el.resourceId) parts.push(`id:${el.resourceId}`); if (el.text) parts.push(`text:"${el.text}"`); if (el.contentDesc) parts.push(`desc:"${el.contentDesc}"`); parts.push(`class:${el.className.split(".").pop()}`); parts.push(`center:(${el.center.x},${el.center.y})`); const flags: string[] = []; if (el.clickable) flags.push("clickable"); if (el.scrollable) flags.push("scrollable"); if (el.checked) flags.push("checked"); if (el.focused) flags.push("focused"); if (!el.enabled) flags.push("disabled"); if (flags.length) parts.push(`[${flags.join(",")}]`); return parts.join(" ");