install_app
Install mobile applications on Android or iOS devices by providing platform-specific artifacts like APK files or .app bundles.
Instructions
Install an app on a device or simulator. For Android, installs an APK. For iOS, installs an .app bundle.
Input Schema
TableJSON Schema
| Name | Required | Description | Default |
|---|---|---|---|
| platform | Yes | Target platform | |
| appPath | Yes | Path to the app artifact (APK for Android, .app bundle for iOS) | |
| deviceId | No | Device ID or name (optional, uses first running device if not specified) |
Implementation Reference
- src/tools/build/install-app.ts:38-56 (handler)Main handler function for the 'install_app' MCP tool. Validates arguments and dispatches to Android or iOS specific installers.export async function installApp(args: InstallAppArgs): Promise<InstallResult> { const { platform, appPath, deviceId } = args; // Validate platform if (!isPlatform(platform)) { throw Errors.invalidArguments(`Invalid platform: ${platform}. Must be 'android' or 'ios'`); } // Validate app path if (!appPath || appPath.trim().length === 0) { throw Errors.invalidArguments('appPath is required'); } if (platform === 'android') { return installAndroidApp(appPath, deviceId); } else { return installIOSApplication(appPath, deviceId); } }
- src/tools/build/install-app.ts:15-22 (schema)TypeScript interface defining the input schema for the install_app tool.export interface InstallAppArgs { /** Target platform */ platform: string; /** Path to the app artifact (APK or .app bundle) */ appPath: string; /** Target device ID or name (optional, uses first available if not specified) */ deviceId?: string; }
- src/tools/build/install-app.ts:138-164 (registration)Registration function for the install_app tool, defining the tool name, description, JSON input schema, and linking to the handler.export function registerInstallAppTool(): void { getToolRegistry().register( 'install_app', { description: 'Install an app on a device or simulator. For Android, installs an APK. For iOS, installs an .app bundle.', inputSchema: createInputSchema( { platform: { type: 'string', enum: ['android', 'ios'], description: 'Target platform', }, appPath: { type: 'string', description: 'Path to the app artifact (APK for Android, .app bundle for iOS)', }, deviceId: { type: 'string', description: 'Device ID or name (optional, uses first running device if not specified)', }, }, ['platform', 'appPath'] ), }, (args) => installApp(args as unknown as InstallAppArgs) ); }
- src/tools/build/install-app.ts:61-96 (helper)Helper function implementing Android-specific app installation logic, including device selection and APK installation via adb.async function installAndroidApp( apkPath: string, deviceId?: string ): Promise<InstallResult> { // 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 }; } // Install the APK await installApk(apkPath, targetDevice.id); return { success: true, platform: 'android', deviceId: targetDevice.id, deviceName: targetDevice.name, appPath: apkPath, }; }
- Helper function implementing iOS-specific app installation logic, including simulator selection and .app bundle installation via simctl.async function installIOSApplication( appPath: string, deviceId?: string ): Promise<InstallResult> { // 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 }; } // Install the app await installIOSApp(appPath, targetDevice.id); return { success: true, platform: 'ios', deviceId: targetDevice.id, deviceName: targetDevice.name, appPath, }; }