Skip to main content
Glama
atom2ueki

MCP Server for iOS Simulator

create-simulator-session

Generate and manage iOS simulator sessions programmatically by specifying device details, platform version, timeout, and autoboot settings using MCP Server for iOS Simulator.

Input Schema

TableJSON Schema
NameRequiredDescriptionDefault
autobootNo
deviceNameNo
platformVersionNo
timeoutNo

Implementation Reference

  • Registration of the 'create-simulator-session' MCP tool, including Zod input schema and the complete handler function that delegates to simulatorManager.createSession and handles autoboot, warnings, and errors.
      'create-simulator-session',
      {
        deviceName: z.string().optional(),
        platformVersion: z.string().optional(),
        timeout: z.number().optional(),
        autoboot: z.boolean().optional()
      },
      async (params) => {
        fileLogger.info('Creating simulator session', params);
        
        // Adding a warning before even trying to create a session
        fileLogger.info('Warning user about session-based approach');
        const warningText = "\n⚠️ WARNING: You're using the complex session-based approach ⚠️\n" +
                           "For most users, we recommend the simpler direct UDID approach instead:\n\n" +
                           "1. First run: list-available-simulators\n" +
                           "2. Then use: boot-simulator-by-udid with the UDID from the list\n\n" +
                           "Proceeding with session creation anyway...\n";
        
        try {
          // Get available simulators to provide helpful error messages if needed
          const availableSimulators = await simulatorManager.getAllSimulators();
          
          const session = await simulatorManager.createSession({
            deviceName: params.deviceName,
            platformVersion: params.platformVersion,
            timeout: params.timeout
          });
          
          // Automatically boot the simulator if requested (default to true)
          const shouldBoot = params.autoboot !== false;
          let bootResult = null;
          
          if (shouldBoot) {
            fileLogger.info(`Auto-booting simulator session: ${session.id}`);
            bootResult = await simulatorManager.bootSimulator(session.id);
            
            if (!bootResult) {
              fileLogger.warn(`Failed to auto-boot simulator session: ${session.id}`);
            } else {
              fileLogger.info(`Successfully auto-booted simulator session: ${session.id}`);
            }
          }
          
          return {
            content: [{
              type: 'text',
              text: warningText + JSON.stringify({
                ...session,
                booted: shouldBoot ? bootResult : false
              })
            }]
          };
        } catch (error) {
          fileLogger.error('Failed to create simulator session', { error });
          
          // Get available simulators to provide helpful error messages
          let helpText = "";
          try {
            const availableSimulators = await simulatorManager.getAllSimulators();
            
            // Group by iOS version for better readability
            const devicesByVersion: 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);
            });
            
            // Generate helpful message with available devices
            helpText = "\n\n⚠️ ERROR, BUT DON'T WORRY! There's a much easier way: ⚠️\n\n";
            helpText += "Instead of using sessions, try the direct UDID approach:\n";
            helpText += "1. Run 'list-available-simulators' to see all available simulators\n";
            helpText += "2. Choose one from the list and boot it directly with its UDID\n\n";
            
            helpText += "Available simulators you can use:\n";
            for (const [version, devices] of Object.entries(devicesByVersion)) {
              const formattedVersion = version.replace(/-/g, '.');
              helpText += `\n📱 iOS ${formattedVersion}:\n`;
              helpText += devices.sort().map((d: string) => `  - ${d}`).join('\n');
              helpText += '\n';
            }
            
            // Try to suggest a specific device if possible
            if (params.deviceName) {
              const matchSimulators = availableSimulators.filter(sim => 
                sim.name.toLowerCase().includes(params.deviceName?.toLowerCase() || "")
              );
              
              if (matchSimulators.length > 0) {
                const suggestedSim = matchSimulators[0];
                helpText += "\n💡 Try this instead:\n";
                helpText += `Run: list-available-simulators\n`;
                helpText += `Then: boot-simulator-by-udid with udid='${suggestedSim.udid}'\n`;
              }
            }
            
          } catch (helpError) {
            helpText = "\nCould not retrieve list of available simulators.";
          }
          
          return {
            content: [{
              type: 'text',
              text: `${helpText}\n\nOriginal error: ${error instanceof Error ? error.message : String(error)}`
            }],
            isError: true
          };
        }
      }
    );
  • Execution handler for create-simulator-session tool. Creates warning about preferred UDID methods, calls simulatorManager.createSession, optionally boots the simulator, provides detailed error messages with available simulators, and returns structured response.
    async (params) => {
      fileLogger.info('Creating simulator session', params);
      
      // Adding a warning before even trying to create a session
      fileLogger.info('Warning user about session-based approach');
      const warningText = "\n⚠️ WARNING: You're using the complex session-based approach ⚠️\n" +
                         "For most users, we recommend the simpler direct UDID approach instead:\n\n" +
                         "1. First run: list-available-simulators\n" +
                         "2. Then use: boot-simulator-by-udid with the UDID from the list\n\n" +
                         "Proceeding with session creation anyway...\n";
      
      try {
        // Get available simulators to provide helpful error messages if needed
        const availableSimulators = await simulatorManager.getAllSimulators();
        
        const session = await simulatorManager.createSession({
          deviceName: params.deviceName,
          platformVersion: params.platformVersion,
          timeout: params.timeout
        });
        
        // Automatically boot the simulator if requested (default to true)
        const shouldBoot = params.autoboot !== false;
        let bootResult = null;
        
        if (shouldBoot) {
          fileLogger.info(`Auto-booting simulator session: ${session.id}`);
          bootResult = await simulatorManager.bootSimulator(session.id);
          
          if (!bootResult) {
            fileLogger.warn(`Failed to auto-boot simulator session: ${session.id}`);
          } else {
            fileLogger.info(`Successfully auto-booted simulator session: ${session.id}`);
          }
        }
        
        return {
          content: [{
            type: 'text',
            text: warningText + JSON.stringify({
              ...session,
              booted: shouldBoot ? bootResult : false
            })
          }]
        };
      } catch (error) {
        fileLogger.error('Failed to create simulator session', { error });
        
        // Get available simulators to provide helpful error messages
        let helpText = "";
        try {
          const availableSimulators = await simulatorManager.getAllSimulators();
          
          // Group by iOS version for better readability
          const devicesByVersion: 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);
          });
          
          // Generate helpful message with available devices
          helpText = "\n\n⚠️ ERROR, BUT DON'T WORRY! There's a much easier way: ⚠️\n\n";
          helpText += "Instead of using sessions, try the direct UDID approach:\n";
          helpText += "1. Run 'list-available-simulators' to see all available simulators\n";
          helpText += "2. Choose one from the list and boot it directly with its UDID\n\n";
          
          helpText += "Available simulators you can use:\n";
          for (const [version, devices] of Object.entries(devicesByVersion)) {
            const formattedVersion = version.replace(/-/g, '.');
            helpText += `\n📱 iOS ${formattedVersion}:\n`;
            helpText += devices.sort().map((d: string) => `  - ${d}`).join('\n');
            helpText += '\n';
          }
          
          // Try to suggest a specific device if possible
          if (params.deviceName) {
            const matchSimulators = availableSimulators.filter(sim => 
              sim.name.toLowerCase().includes(params.deviceName?.toLowerCase() || "")
            );
            
            if (matchSimulators.length > 0) {
              const suggestedSim = matchSimulators[0];
              helpText += "\n💡 Try this instead:\n";
              helpText += `Run: list-available-simulators\n`;
              helpText += `Then: boot-simulator-by-udid with udid='${suggestedSim.udid}'\n`;
            }
          }
          
        } catch (helpError) {
          helpText = "\nCould not retrieve list of available simulators.";
        }
        
        return {
          content: [{
            type: 'text',
            text: `${helpText}\n\nOriginal error: ${error instanceof Error ? error.message : String(error)}`
          }],
          isError: true
        };
      }
    }
  • Input schema using Zod for validating tool parameters: deviceName, platformVersion, timeout (optional), autoboot (optional boolean).
    {
      deviceName: z.string().optional(),
      platformVersion: z.string().optional(),
      timeout: z.number().optional(),
      autoboot: z.boolean().optional()
  • Core helper method implementing simulator session creation logic. Finds matching simulator using tiered search strategies based on deviceName/platformVersion, wraps appium-ios-simulator instance with session metadata and unique ID, manages in-memory session tracking.
    async createSession(options: SimulatorOptions = {}): Promise<SimulatorSession> {
      try {
        // Use provided options or defaults from config
        const deviceName = options.deviceName || config.simulator.defaultDevice;
        const platformVersion = options.platformVersion || config.simulator.defaultOS;
        const timeout = options.timeout || config.simulator.timeout;
    
        fileLogger.info(`Creating simulator session with device: ${deviceName}, OS: ${platformVersion}`);
    
        // Get all available simulators
        const simulators = await this.getAllSimulators();
        
        // Log available matching simulators for debugging
        this.logMatchingSimulators(simulators, deviceName);
        
        // If UDID is provided directly, use it
        if (deviceName.match(/^[0-9A-F]{8}-([0-9A-F]{4}-){3}[0-9A-F]{12}$/i)) {
          const udidMatch = simulators.find(sim => sim.udid === deviceName);
          if (udidMatch && udidMatch.isAvailable) {
            fileLogger.info(`Found simulator with exact UDID match: ${udidMatch.name}`);
            return this.createSessionFromSimulator(udidMatch, timeout);
          }
        }
        
        // Find matching simulator using a tiered approach
        let matchingSimulator: SimulatorInfo | undefined;
        
        // Tier 1: Exact name match (most strict)
        matchingSimulator = this.findExactNameMatch(simulators, deviceName, platformVersion);
        
        // Tier 2: Word boundary matching (prevent "iPhone 14" from matching "iPhone 14 Pro")
        if (!matchingSimulator) {
          matchingSimulator = this.findWordBoundaryMatch(simulators, deviceName, platformVersion);
        }
        
        // Tier 3: Substring matching (most lenient, last resort)
        if (!matchingSimulator) {
          matchingSimulator = this.findSubstringMatch(simulators, deviceName, platformVersion);
        }
    
        if (!matchingSimulator) {
          throw new Error(`No matching simulator found for device: ${deviceName}, OS: ${platformVersion}`);
        }
    
        return this.createSessionFromSimulator(matchingSimulator, timeout);
      } catch (error) {
        fileLogger.error('Failed to create simulator session', { error });
        throw error;
      }
    }
Behavior1/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Tool has no description.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness1/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Tool has no description.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness1/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

Tool has no description.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters1/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Tool has no description.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose1/5

Does the description clearly state what the tool does and how it differs from similar tools?

Tool has no description.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines1/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Tool has no description.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

Install Server

Other Tools

Related Tools

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