Skip to main content
Glama
launch-app.ts5.15 kB
/** * launch_app Tool Handler * MCP tool for launching apps on devices/simulators */ import { Platform, isPlatform } from '../../models/constants.js'; import { Errors } from '../../models/errors.js'; import { launchApp as launchAndroidApp, listDevices as listAndroidDevices } from '../../platforms/android/adb.js'; import { launchApp as launchIOSApp, listDevices as listIOSDevices, getBootedDevice } from '../../platforms/ios/simctl.js'; import { getToolRegistry, createInputSchema } from '../register.js'; /** * Input arguments for launch_app tool */ export interface LaunchAppArgs { /** Target platform */ platform: string; /** Package name (Android) or bundle ID (iOS) */ appId: string; /** Target device ID or name (optional, uses first available if not specified) */ deviceId?: string; /** Clear app data before launch (Android only) */ clearData?: boolean; /** Arguments to pass to the app (iOS only) */ launchArguments?: string[]; } /** * Result of launch operation */ export interface LaunchResult { success: boolean; platform: Platform; deviceId: string; deviceName: string; appId: string; } /** * Launch app tool handler */ export async function launchApp(args: LaunchAppArgs): Promise<LaunchResult> { const { platform, appId, deviceId, clearData = false, launchArguments } = args; // Validate platform if (!isPlatform(platform)) { throw Errors.invalidArguments(`Invalid platform: ${platform}. Must be 'android' or 'ios'`); } // Validate app ID if (!appId || appId.trim().length === 0) { throw Errors.invalidArguments('appId is required'); } if (platform === 'android') { return launchAndroid(appId, deviceId, clearData); } else { return launchIOS(appId, deviceId, launchArguments); } } /** * Launch Android app */ async function launchAndroid( packageName: string, deviceId?: string, clearData?: boolean ): Promise<LaunchResult> { // Find device if not specified let targetDevice: { id: string; name: string }; if (deviceId) { const devices = await listAndroidDevices(); const found = devices.find( (d) => d.id === deviceId || d.name === deviceId || d.model === deviceId ); if (!found) { throw Errors.deviceNotFound(deviceId, devices.map((d) => `${d.id} (${d.name})`)); } targetDevice = { id: found.id, name: found.name }; } else { const devices = await listAndroidDevices(); const bootedDevice = devices.find((d) => d.status === 'booted'); if (!bootedDevice) { throw Errors.invalidArguments('No running Android device found. Boot a device first.'); } targetDevice = { id: bootedDevice.id, name: bootedDevice.name }; } // Launch the app await launchAndroidApp(packageName, targetDevice.id, { clearData }); return { success: true, platform: 'android', deviceId: targetDevice.id, deviceName: targetDevice.name, appId: packageName, }; } /** * Launch iOS app */ async function launchIOS( bundleId: string, deviceId?: string, launchArguments?: string[] ): Promise<LaunchResult> { // Find device if not specified let targetDevice: { id: string; name: string }; if (deviceId) { const devices = await listIOSDevices(); const found = devices.find((d) => d.id === deviceId || d.name === deviceId); if (!found) { throw Errors.deviceNotFound(deviceId, devices.map((d) => `${d.id} (${d.name})`)); } targetDevice = { id: found.id, name: found.name }; } else { const bootedDevice = await getBootedDevice(); if (!bootedDevice) { throw Errors.invalidArguments('No running iOS simulator found. Boot a simulator first.'); } targetDevice = { id: bootedDevice.id, name: bootedDevice.name }; } // Launch the app await launchIOSApp(bundleId, targetDevice.id, { arguments: launchArguments }); return { success: true, platform: 'ios', deviceId: targetDevice.id, deviceName: targetDevice.name, appId: bundleId, }; } /** * Register the launch_app tool */ export function registerLaunchAppTool(): void { getToolRegistry().register( 'launch_app', { description: 'Launch an installed app on a device or simulator.', inputSchema: createInputSchema( { platform: { type: 'string', enum: ['android', 'ios'], description: 'Target platform', }, appId: { type: 'string', description: 'Package name (Android) or bundle ID (iOS)', }, deviceId: { type: 'string', description: 'Device ID or name (optional, uses first running device if not specified)', }, clearData: { type: 'boolean', description: 'Clear app data before launch (Android only, default: false)', }, launchArguments: { type: 'array', items: { type: 'string' }, description: 'Arguments to pass to the app (iOS only)', }, }, ['platform', 'appId'] ), }, (args) => launchApp(args as unknown as LaunchAppArgs) ); }

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/abd3lraouf/specter-mcp'

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