Skip to main content
Glama

handleIntentChooser

Automatically handle system intent chooser dialogs by specifying preferences for app selection, including always, just once, or custom app packages.

Instructions

Automatically handle system intent chooser dialog with specified preferences

Input Schema

TableJSON Schema
NameRequiredDescriptionDefault
preferenceNoPreference for handling intent chooser (default: 'just_once')
customAppPackageNoSpecific app package to select when preference is 'custom'

Implementation Reference

  • The primary handler function for the handleIntentChooser MCP tool. It instantiates HandleIntentChooser class and executes it with provided arguments, then formats the response.
    const handleIntentChooserHandler = async (device: BootedDevice, args: HandleIntentChooserArgs) => { try { const handleIntentChooser = new HandleIntentChooser(device); const result = await handleIntentChooser.execute( args.preference || "just_once", args.customAppPackage, ); return createJSONToolResponse({ message: result.detected ? `Intent chooser handled with preference: ${args.preference || "just_once"}` : "No intent chooser detected", success: result.success, detected: result.detected, action: result.action, appSelected: result.appSelected, error: result.error, observation: result.observation }); } catch (error) { logger.error(`[handleIntentChooser] Failed to handle intent chooser: ${error}`); throw new ActionableError(`Failed to handle intent chooser: ${error}`); } };
  • Tool registration call that adds handleIntentChooser to the ToolRegistry with its schema and handler.
    ToolRegistry.registerDeviceAware( "handleIntentChooser", "Automatically handle system intent chooser dialog with specified preferences", handleIntentChooserSchema, handleIntentChooserHandler, false // Does not support progress notifications );
  • Zod schema for validating input arguments to the handleIntentChooser tool: preference (enum) and optional customAppPackage.
    export const handleIntentChooserSchema = z.object({ preference: z.enum(["always", "just_once", "custom"]).optional().describe("Preference for handling intent chooser (default: 'just_once')"), customAppPackage: z.string().optional().describe("Specific app package to select when preference is 'custom'"), });
  • Core execution logic in HandleIntentChooser class: observes view hierarchy and delegates handling to DeepLinkManager.
    async execute( preference: "always" | "just_once" | "custom" = "just_once", customAppPackage?: string ): Promise<IntentChooserResult> { return this.observedInteraction( async (observeResult: ObserveResult) => { const viewHierarchy = observeResult.viewHierarchy; if (!viewHierarchy) { return { success: false, error: "View hierarchy not found" }; } return await this.deepLinkManager.handleIntentChooser( viewHierarchy, preference, customAppPackage ); }, { changeExpected: false, timeoutMs: 500, } ); }
  • Core helper method implementing the intent chooser handling logic: detects chooser, locates appropriate button/app based on preference, and performs ADB tap.
    async handleIntentChooser( viewHierarchy: ViewHierarchyResult, preference: "always" | "just_once" | "custom" = "just_once", customAppPackage?: string ): Promise<IntentChooserResult> { try { const detected = this.detectIntentChooser(viewHierarchy); if (!detected) { return { success: true, detected: false }; } logger.info(`[DeepLinkManager] Intent chooser detected, preference: ${preference}`); // Parse the view hierarchy to find buttons const rootNodes = this.elementUtils.extractRootNodes(viewHierarchy); let targetElement = null; if (preference === "always") { // Look for "Always" button for (const rootNode of rootNodes) { targetElement = this.findButtonByText(rootNode, ["Always", "ALWAYS"]); if (targetElement) {break;} } } else if (preference === "just_once") { // Look for "Just once" button for (const rootNode of rootNodes) { targetElement = this.findButtonByText(rootNode, ["Just once", "JUST ONCE", "Once"]); if (targetElement) {break;} } } else if (preference === "custom" && customAppPackage) { // Look for specific app in the list for (const rootNode of rootNodes) { targetElement = this.findAppInChooser(rootNode, customAppPackage); if (targetElement) {break;} } } if (targetElement) { // Simulate tap on the target element const center = this.elementUtils.getElementCenter(targetElement); await this.adbUtils.executeCommand(`shell input tap ${center.x} ${center.y}`); logger.info(`[DeepLinkManager] Tapped on intent chooser option at (${center.x}, ${center.y})`); return { success: true, detected: true, action: preference, appSelected: customAppPackage }; } else { return { success: false, detected: true, error: `Could not find target element for preference: ${preference}` }; } } catch (error) { logger.error(`[DeepLinkManager] Failed to handle intent chooser: ${error}`); return { success: false, detected: true, error: error instanceof Error ? error.message : String(error) }; } }

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/zillow/auto-mobile'

If you have feedback or need assistance with the MCP directory API, please join our Discord server