Skip to main content
Glama

XcodeBuildMCP

simulator-utils.ts4.63 kB
/** * Simulator utility functions for name to UUID resolution */ import type { CommandExecutor } from './execution/index.ts'; import { ToolResponse } from '../types/common.ts'; import { log } from './logging/index.ts'; import { createErrorResponse } from './responses/index.ts'; /** * UUID regex pattern to check if a string looks like a UUID */ const UUID_REGEX = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i; /** * Determines the simulator UUID from either a UUID or name. * * Behavior: * - If simulatorUuid provided: return it directly * - Else if simulatorName looks like a UUID (regex): treat it as UUID and return it * - Else: resolve name → UUID via simctl and return the match (isAvailable === true) * * @param params Object containing optional simulatorUuid or simulatorName * @param executor Command executor for running simctl commands * @returns Object with uuid, optional warning, or error */ export async function determineSimulatorUuid( params: { simulatorUuid?: string; simulatorName?: string }, executor: CommandExecutor, ): Promise<{ uuid?: string; warning?: string; error?: ToolResponse }> { // If UUID is provided directly, use it if (params.simulatorUuid) { log('info', `Using provided simulator UUID: ${params.simulatorUuid}`); return { uuid: params.simulatorUuid }; } // If name is provided, check if it's actually a UUID if (params.simulatorName) { // Check if the "name" is actually a UUID string if (UUID_REGEX.test(params.simulatorName)) { log( 'info', `Simulator name '${params.simulatorName}' appears to be a UUID, using it directly`, ); return { uuid: params.simulatorName, warning: `The simulatorName '${params.simulatorName}' appears to be a UUID. Consider using simulatorUuid parameter instead.`, }; } // Resolve name to UUID via simctl log('info', `Looking up simulator UUID for name: ${params.simulatorName}`); const listResult = await executor( ['xcrun', 'simctl', 'list', 'devices', 'available', '-j'], 'List available simulators', ); if (!listResult.success) { return { error: createErrorResponse( 'Failed to list simulators', listResult.error ?? 'Unknown error', ), }; } try { interface SimulatorDevice { udid: string; name: string; isAvailable: boolean; } interface DevicesData { devices: Record<string, SimulatorDevice[]>; } const devicesData = JSON.parse(listResult.output ?? '{}') as DevicesData; // Search through all runtime sections for the named device for (const runtime of Object.keys(devicesData.devices)) { const devices = devicesData.devices[runtime]; if (!Array.isArray(devices)) continue; // Look for exact name match with isAvailable === true const device = devices.find( (d) => d.name === params.simulatorName && d.isAvailable === true, ); if (device) { log('info', `Found simulator '${params.simulatorName}' with UUID: ${device.udid}`); return { uuid: device.udid }; } } // If no available device found, check if device exists but is unavailable for (const runtime of Object.keys(devicesData.devices)) { const devices = devicesData.devices[runtime]; if (!Array.isArray(devices)) continue; const unavailableDevice = devices.find( (d) => d.name === params.simulatorName && d.isAvailable === false, ); if (unavailableDevice) { return { error: createErrorResponse( `Simulator '${params.simulatorName}' exists but is not available`, 'The simulator may need to be downloaded or is incompatible with the current Xcode version', ), }; } } // Device not found at all return { error: createErrorResponse( `Simulator '${params.simulatorName}' not found`, 'Please check the simulator name or use "xcrun simctl list devices" to see available simulators', ), }; } catch (parseError) { return { error: createErrorResponse( 'Failed to parse simulator list', parseError instanceof Error ? parseError.message : String(parseError), ), }; } } // Neither UUID nor name provided return { error: createErrorResponse( 'No simulator identifier provided', 'Either simulatorUuid or simulatorName is required', ), }; }

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