boot_simulator
Start a specified simulator by providing its UDID or name, enabling developers to test Apple platform projects directly through Xcode without leaving their editor.
Instructions
Boot a simulator
Input Schema
TableJSON Schema
| Name | Required | Description | Default |
|---|---|---|---|
| deviceId | Yes | Device UDID or name of the simulator to boot |
Implementation Reference
- BootSimulatorController implements the MCPController interface for the 'boot_simulator' tool. Includes inputSchema, getToolDefinition, and the main execute method that validates input, executes the use case, and formats the response.export class BootSimulatorController implements MCPController { readonly name = 'boot_simulator'; readonly description = 'Boot a simulator'; constructor( private useCase: BootSimulatorUseCase ) {} get inputSchema() { return { type: 'object' as const, properties: { deviceId: { type: 'string' as const, description: 'Device UDID or name of the simulator to boot' } }, required: ['deviceId'] as const }; } getToolDefinition() { return { name: this.name, description: this.description, inputSchema: this.inputSchema }; } async execute(args: unknown): Promise<{ content: Array<{ type: string; text: string }> }> { try { // Cast to expected shape const input = args as { deviceId: unknown }; // Create domain value object - will validate const deviceId = DeviceId.create(input.deviceId); // Create domain request const request = BootRequest.create(deviceId); // Execute use case const result = await this.useCase.execute(request); // Format response return { content: [{ type: 'text', text: this.formatResult(result) }] }; } catch (error: any) { // Handle validation and other errors consistently const message = ErrorFormatter.format(error); return { content: [{ type: 'text', text: `❌ ${message}` }] }; } } private formatResult(result: BootResult): string { const { outcome, diagnostics } = result; switch (outcome) { case BootOutcome.Booted: return `✅ Successfully booted simulator: ${diagnostics.simulatorName} (${diagnostics.simulatorId})`; case BootOutcome.AlreadyBooted: return `✅ Simulator already booted: ${diagnostics.simulatorName} (${diagnostics.simulatorId})`; case BootOutcome.Failed: const { error } = diagnostics; if (error instanceof SimulatorNotFoundError) { // Use consistent error formatting with ❌ emoji return `❌ Simulator not found: ${error.deviceId}`; } if (error instanceof SimulatorBusyError) { // Handle simulator busy scenarios return `❌ Cannot boot simulator: currently ${error.currentState.toLowerCase()}`; } if (error instanceof BootCommandFailedError) { const message = ErrorFormatter.format(error); // Include simulator context if available if (diagnostics.simulatorName && diagnostics.simulatorId) { return `❌ ${diagnostics.simulatorName} (${diagnostics.simulatorId}) - ${message}`; } return `❌ ${message}`; } // Shouldn't happen but handle gracefully const fallbackMessage = error ? ErrorFormatter.format(error) : 'Boot operation failed'; return `❌ ${fallbackMessage}`; } } }
- src/index.ts:77-118 (registration)In registerTools(), BootSimulatorControllerFactory.create() is called (line 82) to instantiate the controller, which is then registered in the tools Map by name via the loop (lines 112-115).private registerTools() { // Create instances of all tools const toolInstances = [ // Simulator management ListSimulatorsControllerFactory.create(), BootSimulatorControllerFactory.create(), ShutdownSimulatorControllerFactory.create(), // new ViewSimulatorScreenTool(), // Build and test // new BuildSwiftPackageTool(), // new RunSwiftPackageTool(), BuildXcodeControllerFactory.create(), InstallAppControllerFactory.create(), // new RunXcodeTool(), // new TestXcodeTool(), // new TestSwiftPackageTool(), // new CleanBuildTool(), // Archive and export // new ArchiveProjectTool(), // new ExportIPATool(), // Project info and schemes // new ListSchemesTool(), // new GetBuildSettingsTool(), // new GetProjectInfoTool(), // new ListTargetsTool(), // App management // new InstallAppTool(), // new UninstallAppTool(), // Device logs // new GetDeviceLogsTool(), // Advanced project management // new ManageDependenciesTool() ]; // Register each tool by its name for (const tool of toolInstances) { const definition = tool.getToolDefinition(); this.tools.set(definition.name, tool); } logger.info({ toolCount: this.tools.size }, 'Tools registered'); }
- Core use case logic for booting simulator: locates simulator, checks state, boots if necessary, handles errors like not found, busy, or command failure.export class BootSimulatorUseCase implements IBootSimulatorUseCase { constructor( private simulatorLocator: ISimulatorLocator, private simulatorControl: ISimulatorControl ) {} async execute(request: BootRequest): Promise<BootResult> { // Find the simulator const simulator = await this.simulatorLocator.findSimulator(request.deviceId); if (!simulator) { return BootResult.failed( request.deviceId, '', // No name available since simulator wasn't found new SimulatorNotFoundError(request.deviceId) ); } // Check simulator state if (simulator.state === SimulatorState.Booted) { return BootResult.alreadyBooted( simulator.id, simulator.name, { platform: simulator.platform, runtime: simulator.runtime } ); } // Handle Booting state - simulator is already in the process of booting if (simulator.state === SimulatorState.Booting) { return BootResult.alreadyBooted( simulator.id, simulator.name, { platform: simulator.platform, runtime: simulator.runtime } ); } // Handle ShuttingDown state - can't boot while shutting down if (simulator.state === SimulatorState.ShuttingDown) { return BootResult.failed( simulator.id, simulator.name, new SimulatorBusyError(SimulatorState.ShuttingDown) ); } // Boot the simulator (handles Shutdown state) try { await this.simulatorControl.boot(simulator.id); return BootResult.booted( simulator.id, simulator.name, { platform: simulator.platform, runtime: simulator.runtime } ); } catch (error: any) { return BootResult.failed( simulator.id, simulator.name, new BootCommandFailedError(error.stderr || error.message || '') ); } } }
- Factory that composes all dependencies for BootSimulatorController: shell executor, adapters, use case, dependency checker, and decorator.export class BootSimulatorControllerFactory { static create(): MCPController { // Create the shell executor that all adapters will use const execAsync = promisify(exec); const executor = new ShellCommandExecutorAdapter(execAsync); // Create infrastructure adapters const simulatorLocator = new SimulatorLocatorAdapter(executor); const simulatorControl = new SimulatorControlAdapter(executor); // Create the use case with all dependencies const useCase = new BootSimulatorUseCase( simulatorLocator, simulatorControl ); // Create the controller const controller = new BootSimulatorController(useCase); // Create dependency checker const dependencyChecker = new DependencyChecker(executor); // Wrap with dependency checking decorator const decoratedController = new DependencyCheckingDecorator( controller, ['xcrun'], // simctl is part of xcrun dependencyChecker ); return decoratedController; }