Skip to main content
Glama

launch_app_device

Launch an app on a physical Apple device by specifying the device UDID and app bundle ID using XcodeBuildMCP. Simplifies app deployment and testing workflows on iOS, iPadOS, watchOS, tvOS, and visionOS devices.

Instructions

Launches an app on a physical Apple device (iPhone, iPad, Apple Watch, Apple TV, Apple Vision Pro). Requires deviceId and bundleId.

Input Schema

TableJSON Schema
NameRequiredDescriptionDefault
bundleIdYesBundle identifier of the app to launch (e.g., "com.example.MyApp")
deviceIdYesUDID of the device (obtained from list_devices)

Implementation Reference

  • The main handler function launch_app_deviceLogic that executes the tool logic: launches the app using xcrun devicectl, parses JSON output for process ID, and returns success/error response.
    export async function launch_app_deviceLogic( params: LaunchAppDeviceParams, executor: CommandExecutor, ): Promise<ToolResponse> { const { deviceId, bundleId } = params; log('info', `Launching app ${bundleId} on device ${deviceId}`); try { // Use JSON output to capture process ID const tempJsonPath = join(tmpdir(), `launch-${Date.now()}.json`); const result = await executor( [ 'xcrun', 'devicectl', 'device', 'process', 'launch', '--device', deviceId, '--json-output', tempJsonPath, '--terminate-existing', bundleId, ], 'Launch app on device', true, // useShell undefined, // env ); if (!result.success) { return { content: [ { type: 'text', text: `Failed to launch app: ${result.error}`, }, ], isError: true, }; } // Parse JSON to extract process ID let processId: number | undefined; try { const jsonContent = await fs.readFile(tempJsonPath, 'utf8'); const parsedData: unknown = JSON.parse(jsonContent); // Type guard to validate the parsed data structure if ( parsedData && typeof parsedData === 'object' && 'result' in parsedData && parsedData.result && typeof parsedData.result === 'object' && 'process' in parsedData.result && parsedData.result.process && typeof parsedData.result.process === 'object' && 'processIdentifier' in parsedData.result.process && typeof parsedData.result.process.processIdentifier === 'number' ) { const launchData = parsedData as LaunchDataResponse; processId = launchData.result?.process?.processIdentifier; } // Clean up temp file await fs.unlink(tempJsonPath).catch(() => {}); } catch (error) { log('warn', `Failed to parse launch JSON output: ${error}`); } let responseText = `✅ App launched successfully\n\n${result.output}`; if (processId) { responseText += `\n\nProcess ID: ${processId}`; responseText += `\n\nNext Steps:`; responseText += `\n1. Interact with your app on the device`; responseText += `\n2. Stop the app: stop_app_device({ deviceId: "${deviceId}", processId: ${processId} })`; } return { content: [ { type: 'text', text: responseText, }, ], }; } catch (error) { const errorMessage = error instanceof Error ? error.message : String(error); log('error', `Error launching app on device: ${errorMessage}`); return { content: [ { type: 'text', text: `Failed to launch app on device: ${errorMessage}`, }, ], isError: true, }; } }
  • Zod schema defining input parameters: deviceId (UDID) and bundleId.
    const launchAppDeviceSchema = z.object({ deviceId: z.string().describe('UDID of the device (obtained from list_devices)'), bundleId: z .string() .describe('Bundle identifier of the app to launch (e.g., "com.example.MyApp")'), });
  • Tool registration: exports default object with name, description, schema (without deviceId for session), and handler created via createSessionAwareTool.
    export default { name: 'launch_app_device', description: 'Launches an app on a connected device.', schema: launchAppDeviceSchema.omit({ deviceId: true } as const).shape, handler: createSessionAwareTool<LaunchAppDeviceParams>({ internalSchema: launchAppDeviceSchema as unknown as z.ZodType<LaunchAppDeviceParams>, logicFunction: launch_app_deviceLogic, getExecutor: getDefaultCommandExecutor, requirements: [{ allOf: ['deviceId'], message: 'deviceId is required' }], }), };

Other Tools

Related Tools

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/cameroncooke/XcodeBuildMCP'

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