Skip to main content
Glama

openLink

Open URLs in the default browser on Android or iOS devices for mobile automation testing and navigation.

Instructions

Open a URL in the default browser

Input Schema

TableJSON Schema
NameRequiredDescriptionDefault
urlYesURL to open in the default browser
platformYesPlatform of the device

Implementation Reference

  • Handler function that creates an OpenURL instance and executes it with the provided URL, returning a standardized tool response.
    const openLinkHandler = async (device: BootedDevice, args: OpenLinkArgs) => { const openUrl = new OpenURL(device); const result = await openUrl.execute(args.url); return createJSONToolResponse({ message: `Opened link ${args.url}`, observation: result.observation, ...result }); };
  • Zod schema defining the input arguments for the openLink tool: url and platform.
    export const openLinkSchema = z.object({ url: z.string().describe("URL to open in the default browser"), platform: z.enum(["android", "ios"]).describe("Platform of the device") });
  • Registration of the openLink tool with ToolRegistry, including name, description, schema, and handler.
    "openLink", "Open a URL in the default browser", openLinkSchema, openLinkHandler, false // Does not support progress notifications );
  • OpenURL class providing the core implementation for opening URLs on Android (via adb am start) and iOS (via axe.openUrl), used by the openLink handler.
    export class OpenURL extends BaseVisualChange { constructor(device: BootedDevice, adb: AdbUtils | null = null, axe: Axe | null = null) { super(device, adb, axe); this.device = device; } async execute( url: string, ): Promise<OpenURLResult> { logger.info(`[OpenURL] Starting URL open request: ${url}`); // Validate URL if (!url || !url.trim()) { logger.error("[OpenURL] Invalid URL provided"); return { success: false, url: url || "", error: "Invalid URL provided" }; } const trimmedUrl = url.trim(); logger.info(`[OpenURL] Processing URL: ${trimmedUrl}`); // Handle package: URLs specially - delegate to LaunchApp if (trimmedUrl.startsWith("package:")) { logger.info("[OpenURL] Detected package URL, extracting package name"); const packageName = trimmedUrl.replace("package:", ""); if (!packageName) { logger.error("[OpenURL] No package name found in package URL"); return { success: false, url: trimmedUrl, error: "Invalid package URL - no package name specified" }; } logger.info(`[OpenURL] Launching app with package name: ${packageName}`); try { // Use LaunchApp to properly launch the application const launchApp = new LaunchApp(this.device, this.adb); const launchResult = await launchApp.execute(packageName, false, true); if (launchResult.success) { logger.info(`[OpenURL] Successfully launched app ${packageName}`); return { success: true, url: trimmedUrl }; } else { logger.error(`[OpenURL] Failed to launch app ${packageName}: ${launchResult.error}`); return { success: false, url: trimmedUrl, error: `Failed to launch app: ${launchResult.error}` }; } } catch (error) { logger.error(`[OpenURL] Exception while launching app ${packageName}:`, error); return { success: false, url: trimmedUrl, error: `Failed to launch app: ${error}` }; } } // Handle regular URLs (http, https, mailto, tel, etc.) logger.info(`[OpenURL] Processing as regular URL: ${trimmedUrl}`); return this.observedInteraction( async () => { // Platform-specific URL opening execution switch (this.device.platform) { case "android": return await this.executeAndroidOpenURL(url); case "ios": return await this.executeiOSOpenURL(url); default: throw new Error(`Unsupported platform: ${this.device.platform}`); } }, { changeExpected: false, timeoutMs: 12000 } ); } /** * Execute Android-specific URL opening * @param url - URL to open * @returns Result of the URL opening operation */ private async executeAndroidOpenURL(url: string): Promise<OpenURLResult> { await this.adb.executeCommand(`shell am start -a android.intent.action.VIEW -d "${url}"`); return { success: true, url }; } /** * Execute iOS-specific URL opening * @param url - URL to open * @returns Result of the URL opening operation */ private async executeiOSOpenURL(url: string): Promise<OpenURLResult> { await this.axe.openUrl(url); return { success: true, url }; } }

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