android_uiautomator_find
Locate Android UI elements by resource ID or text content for automation testing and device control.
Instructions
Find UI elements by resource ID or text using UIAutomator
Input Schema
| Name | Required | Description | Default |
|---|---|---|---|
| resourceId | No | Resource ID to search for (e.g., com.example.app:id/button_submit) | |
| text | No | Text content to search for | |
| deviceSerial | No | Specific device serial number to target (optional) |
Implementation Reference
- src/index.ts:168-188 (registration)Tool registration in MCP server tools array: defines name, description, and input schema for 'android_uiautomator_find'.
{ name: 'android_uiautomator_find', description: 'Find UI elements by resource ID or text using UIAutomator', inputSchema: { type: 'object', properties: { resourceId: { type: 'string', description: 'Resource ID to search for (e.g., com.example.app:id/button_submit)', }, text: { type: 'string', description: 'Text content to search for', }, deviceSerial: { type: 'string', description: 'Specific device serial number to target (optional)', }, }, }, }, - src/index.ts:476-477 (registration)Tool dispatch registration in the main switch statement for handling tool calls.
case 'android_uiautomator_find': return await uiautomatorFindHandler(this.adb, args); - src/handlers.ts:285-314 (handler)Main handler function that validates input, selects the appropriate ADB method based on resourceId or text, executes it, and formats the response.
export async function uiautomatorFindHandler( adb: ADBWrapper, args: any ): Promise<{ content: Array<{ type: string; text: string }> }> { const { resourceId, text, deviceSerial } = args as UIAutomatorFindArgs; if (!resourceId && !text) { throw new Error('Either resourceId or text must be provided'); } try { let result: string; if (resourceId) { result = await adb.findElementByResourceId(resourceId, deviceSerial); } else { result = await adb.findElementByText(text!, deviceSerial); } return { content: [ { type: 'text', text: result, }, ], }; } catch (error) { throw new Error(`UIAutomator find failed: ${error instanceof Error ? error.message : String(error)}`); } } - src/adb-wrapper.ts:443-461 (helper)Core helper function that dumps UI hierarchy XML using uiautomator dump, reads it, and checks if the specified resource-id exists in the XML.
async findElementByResourceId(resourceId: string, deviceSerial?: string): Promise<string> { const device = await this.getTargetDevice(deviceSerial); // Get the UI hierarchy as XML const hierarchyFile = '/sdcard/window_dump.xml'; await this.exec(['shell', 'uiautomator', 'dump', hierarchyFile], device); // Read the XML file const { stdout } = await this.exec(['shell', 'cat', hierarchyFile], device); // Clean up await this.exec(['shell', 'rm', hierarchyFile], device); // Parse and search for resource ID if (stdout.includes(`resource-id="${resourceId}"`)) { return `Found element with resource-id: ${resourceId}`; } else { return `Element with resource-id: ${resourceId} not found`; } } - src/adb-wrapper.ts:466-482 (helper)Core helper function for text-based search: dumps UI XML and checks for matching text attribute.
async findElementByText(text: string, deviceSerial?: string): Promise<string> { const device = await this.getTargetDevice(deviceSerial); const hierarchyFile = '/sdcard/window_dump.xml'; await this.exec(['shell', 'uiautomator', 'dump', hierarchyFile], device); const { stdout } = await this.exec(['shell', 'cat', hierarchyFile], device); // Clean up await this.exec(['shell', 'rm', hierarchyFile], device); // Search for text if (stdout.includes(`text="${text}"`) || stdout.includes(`>${text}</`)) { return `Found element with text: ${text}`; } else { return `Element with text: ${text} not found`; } }