Skip to main content
Glama

MCP Xcode

by Stefan-Nitu
SimulatorInfo.ts3.51 kB
import { execAsync } from '../../utils.js'; import { createModuleLogger } from '../../logger.js'; import { SimulatorDevice, Platform } from '../../types.js'; const logger = createModuleLogger('SimulatorInfo'); /** * Provides information about simulators * Single responsibility: Query simulator state and logs */ export class SimulatorInfo { /** * List all available simulators, optionally filtered by platform */ async list(platform?: Platform, showAll = false): 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)) { // Filter by platform if specified if (platform) { const runtimeLower = runtime.toLowerCase(); const platformLower = platform.toLowerCase(); // Handle visionOS which is internally called xrOS const isVisionOS = platformLower === 'visionos' && runtimeLower.includes('xros'); const isOtherPlatform = platformLower !== 'visionos' && runtimeLower.includes(platformLower); if (!isVisionOS && !isOtherPlatform) { continue; } } for (const device of deviceList as any[]) { if (!showAll && !device.isAvailable) { continue; } devices.push({ udid: device.udid, name: device.name, state: device.state, deviceTypeIdentifier: device.deviceTypeIdentifier, runtime: runtime.replace('com.apple.CoreSimulator.SimRuntime.', ''), isAvailable: device.isAvailable }); } } return devices; } catch (error: any) { logger.error({ error: error.message }, 'Failed to list simulators'); throw new Error(`Failed to list simulators: ${error.message}`); } } /** * Get device logs from the simulator */ async logs(deviceId?: string, predicate?: string, last: string = '5m'): Promise<string> { let command = `xcrun simctl spawn `; if (deviceId) { command += `"${deviceId}" `; } else { command += 'booted '; } command += `log show --style syslog --last ${last}`; if (predicate) { command += ` --predicate '${predicate}'`; } try { const { stdout } = await execAsync(command, { maxBuffer: 10 * 1024 * 1024 }); // Return last 100 lines to keep it manageable const lines = stdout.split('\n').slice(-100); return lines.join('\n'); } catch (error: any) { logger.error({ error: error.message, deviceId, predicate }, 'Failed to get device logs'); throw new Error(`Failed to get device logs: ${error.message}`); } } /** * Get the state of a specific device */ async getDeviceState(deviceId: string): Promise<string> { const devices = await this.list(undefined, true); const device = devices.find(d => d.udid === deviceId || d.name === deviceId); if (!device) { throw new Error(`Device '${deviceId}' not found`); } return device.state; } /** * Check if a device is available */ async isAvailable(deviceId: string): Promise<boolean> { const devices = await this.list(undefined, true); const device = devices.find(d => d.udid === deviceId || d.name === deviceId); return device?.isAvailable || false; } }

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