Skip to main content
Glama
atom2ueki

MCP Server for iOS Simulator

list-available-simulators

Retrieve a list of available iOS simulators via the MCP Server for iOS Simulator, enabling programmatic control and management of simulator environments.

Input Schema

TableJSON Schema
NameRequiredDescriptionDefault

No arguments

Implementation Reference

  • The main handler function for the 'list-available-simulators' tool. It calls simulatorManager.getAllSimulators(), groups by iOS version, formats a readable table with UDIDs, states, and provides workflow instructions.
    async () => { fileLogger.info('Listing all available simulators'); try { const availableSimulators = await simulatorManager.getAllSimulators(); // Group by iOS version for better readability const devicesByVersion: Record<string, string[]> = {}; const udidMap: Record<string, string> = {}; availableSimulators.forEach(simulator => { const version = simulator.runtime.replace('com.apple.CoreSimulator.SimRuntime.iOS-', '').replace(/\./g, '-'); if (!devicesByVersion[version]) { devicesByVersion[version] = []; } devicesByVersion[version].push(simulator.name); udidMap[`${simulator.name}-${version}`] = simulator.udid; }); // Generate table format with UDIDs let tableText = "⭐️ AVAILABLE SIMULATORS - USE THESE UDIDs TO BOOT DIRECTLY ⭐️\n"; tableText += "─────────────────────────────────────────────────────\n"; tableText += "NAME | iOS VERSION | STATE | UDID\n"; tableText += "─────────────────────────────────────────────────────\n"; for (const [version, devices] of Object.entries(devicesByVersion)) { const formattedVersion = version.replace(/-/g, '.'); devices.sort().forEach((deviceName: string) => { const simulator = availableSimulators.find(s => s.name === deviceName && s.runtime.includes(version.replace(/-/g, '.'))); const state = simulator ? simulator.state : 'Unknown'; const udid = simulator ? simulator.udid : 'Unknown'; tableText += `${deviceName.padEnd(20)} | iOS ${formattedVersion.padEnd(9)} | ${state.padEnd(8)} | ${udid}\n`; }); } tableText += "─────────────────────────────────────────────────────\n"; tableText += "\n💡 RECOMMENDED WORKFLOW:\n"; tableText += "1️⃣ FIRST: Find the simulator you want from the list above\n"; tableText += "2️⃣ THEN: Use 'boot-simulator-by-udid' with udid='COPY_UDID_FROM_ABOVE'\n"; tableText += "3️⃣ FINALLY: When done, use 'shutdown-simulator-by-udid' with the same UDID\n\n"; tableText += "❌ AVOID using session-based methods like 'create-simulator-session' unless you specifically need advanced features\n"; // For debugging, append the original JSON at the bottom tableText += "\nOriginal JSON data:\n```\n"; tableText += JSON.stringify(availableSimulators, null, 2); tableText += "\n```"; return { content: [{ type: 'text', text: tableText }] }; } catch (error) { fileLogger.error('Failed to list available simulators', { error }); return { content: [{ type: 'text', text: `Error: ${error instanceof Error ? error.message : String(error)}` }], isError: true }; } }
  • Registration of the 'list-available-simulators' MCP tool in the registerSimulatorControl method using this.server.tool with empty input schema.
    this.server.tool( 'list-available-simulators', {}, async () => { fileLogger.info('Listing all available simulators'); try { const availableSimulators = await simulatorManager.getAllSimulators(); // Group by iOS version for better readability const devicesByVersion: Record<string, string[]> = {}; const udidMap: Record<string, string> = {}; availableSimulators.forEach(simulator => { const version = simulator.runtime.replace('com.apple.CoreSimulator.SimRuntime.iOS-', '').replace(/\./g, '-'); if (!devicesByVersion[version]) { devicesByVersion[version] = []; } devicesByVersion[version].push(simulator.name); udidMap[`${simulator.name}-${version}`] = simulator.udid; }); // Generate table format with UDIDs let tableText = "⭐️ AVAILABLE SIMULATORS - USE THESE UDIDs TO BOOT DIRECTLY ⭐️\n"; tableText += "─────────────────────────────────────────────────────\n"; tableText += "NAME | iOS VERSION | STATE | UDID\n"; tableText += "─────────────────────────────────────────────────────\n"; for (const [version, devices] of Object.entries(devicesByVersion)) { const formattedVersion = version.replace(/-/g, '.'); devices.sort().forEach((deviceName: string) => { const simulator = availableSimulators.find(s => s.name === deviceName && s.runtime.includes(version.replace(/-/g, '.'))); const state = simulator ? simulator.state : 'Unknown'; const udid = simulator ? simulator.udid : 'Unknown'; tableText += `${deviceName.padEnd(20)} | iOS ${formattedVersion.padEnd(9)} | ${state.padEnd(8)} | ${udid}\n`; }); } tableText += "─────────────────────────────────────────────────────\n"; tableText += "\n💡 RECOMMENDED WORKFLOW:\n"; tableText += "1️⃣ FIRST: Find the simulator you want from the list above\n"; tableText += "2️⃣ THEN: Use 'boot-simulator-by-udid' with udid='COPY_UDID_FROM_ABOVE'\n"; tableText += "3️⃣ FINALLY: When done, use 'shutdown-simulator-by-udid' with the same UDID\n\n"; tableText += "❌ AVOID using session-based methods like 'create-simulator-session' unless you specifically need advanced features\n"; // For debugging, append the original JSON at the bottom tableText += "\nOriginal JSON data:\n```\n"; tableText += JSON.stringify(availableSimulators, null, 2); tableText += "\n```"; return { content: [{ type: 'text', text: tableText }] }; } catch (error) { fileLogger.error('Failed to list available simulators', { error }); return { content: [{ type: 'text', text: `Error: ${error instanceof Error ? error.message : String(error)}` }], isError: true }; } } );
  • Core helper function that executes 'xcrun simctl list devices -j', parses the JSON output, and returns structured list of all available simulators with UDID, name, state, runtime, and availability.
    async getAllSimulators(): Promise<SimulatorInfo[]> { try { const execAsync = promisify(exec); // Use simctl directly to avoid potential stdout corruption const { stdout } = await execAsync('xcrun simctl list devices -j'); // Safely parse the JSON output const devices = JSON.parse(stdout).devices; const allSimulators: SimulatorInfo[] = []; // Parse the output to find all devices for (const runtime in devices) { const runtimeDevices = devices[runtime]; for (const device of runtimeDevices) { allSimulators.push({ udid: device.udid, name: device.name, state: device.state, runtime: runtime, isAvailable: device.isAvailable !== false }); } } fileLogger.info(`Found ${allSimulators.length} simulators`); return allSimulators; } catch (error) { fileLogger.error('Failed to get simulators', { error }); return []; } }

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/atom2ueki/mcp-server-ios-simulator'

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