Skip to main content
Glama

list_simulators

Retrieve available iOS simulators for testing and development, with options to filter by platform, state, or device name.

Instructions

List available iOS simulators

Input Schema

TableJSON Schema
NameRequiredDescriptionDefault
platformNoFilter by platform
stateNoFilter by simulator state
nameNoFilter by device name (partial match, case-insensitive)

Implementation Reference

  • MCPController implementation for 'list_simulators' tool, including name, description, input schema, tool definition, and execute method that handles filtering and formatting of simulator list.
    export class ListSimulatorsController implements MCPController { readonly name = 'list_simulators'; readonly description = 'List available iOS simulators'; constructor( private useCase: ListSimulatorsUseCase ) {} get inputSchema() { return { type: 'object' as const, properties: { platform: { type: 'string' as const, description: 'Filter by platform', enum: ['iOS', 'tvOS', 'watchOS', 'visionOS'] as const }, state: { type: 'string' as const, description: 'Filter by simulator state', enum: ['Booted', 'Shutdown'] as const }, name: { type: 'string' as const, description: 'Filter by device name (partial match, case-insensitive)' } }, required: [] 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 { platform?: string; state?: string; name?: string }; // Use the new validation functions const platform = Platform.parseOptional(input.platform); const state = SimulatorState.parseOptional(input.state); const request = ListSimulatorsRequest.create(platform, state, input.name); const result = await this.useCase.execute(request); if (!result.isSuccess) { return { content: [{ type: 'text', text: `❌ ${ErrorFormatter.format(result.error!)}` }] }; } if (result.count === 0) { return { content: [{ type: 'text', text: '🔍 No simulators found' }] }; } const lines: string[] = [ `✅ Found ${result.count} simulator${result.count === 1 ? '' : 's'}`, '' ]; for (const simulator of result.simulators) { lines.push(`• ${simulator.name} (${simulator.udid}) - ${simulator.state} - ${simulator.runtime}`); } return { content: [{ type: 'text', text: lines.join('\n') }] }; } catch (error) { return { content: [{ type: 'text', text: `❌ ${ErrorFormatter.format(error as Error)}` }] }; } } }
  • src/index.ts:77-118 (registration)
    Registers the ListSimulatorsController (via factory) along with other tools in the MCP server's tool map.
    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'); }
  • Input schema definition for the list_simulators tool, defining optional filters for platform, state, and name.
    get inputSchema() { return { type: 'object' as const, properties: { platform: { type: 'string' as const, description: 'Filter by platform', enum: ['iOS', 'tvOS', 'watchOS', 'visionOS'] as const }, state: { type: 'string' as const, description: 'Filter by simulator state', enum: ['Booted', 'Shutdown'] as const }, name: { type: 'string' as const, description: 'Filter by device name (partial match, case-insensitive)' } }, required: [] as const }; }
  • Factory that creates the ListSimulatorsController with its dependencies (use case, repository, shell executor).
    export class ListSimulatorsControllerFactory { static create(): ListSimulatorsController { const execAsync = promisify(exec); const executor = new ShellCommandExecutorAdapter(execAsync); const deviceRepository = new DeviceRepository(executor); const useCase = new ListSimulatorsUseCase(deviceRepository); return new ListSimulatorsController(useCase); } }
  • Low-level helper method that executes 'xcrun simctl list devices --json' and parses available simulators, used indirectly via repository.
    async listSimulators(platform?: Platform): Promise<SimulatorDevice[]> { try { const { stdout } = await execAsync('xcrun simctl list devices --json'); const data = JSON.parse(stdout); const devices: SimulatorDevice[] = []; for (const [runtime, deviceList] of Object.entries(data.devices)) { const extractedPlatform = this.extractPlatformFromRuntime(runtime); // Filter by platform if specified if (platform && !this.matchesPlatform(extractedPlatform, platform)) { continue; } for (const device of deviceList as any[]) { if (device.isAvailable) { devices.push(new SimulatorDevice( device.udid, device.name, extractedPlatform, runtime )); } } } return devices; } catch (error: any) { logger.error({ error: error.message }, 'Failed to list simulators'); throw new Error(`Failed to list simulators: ${error.message}`); } }

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/Stefan-Nitu/mcp-xcode'

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