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}`);
      }
    }
Behavior2/5

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

No annotations are provided, so the description carries the full burden of behavioral disclosure. It states the action ('List') but doesn't describe what the output looks like (e.g., a list of simulator objects with properties), whether it's a read-only operation, or any constraints like rate limits. For a tool with no annotation coverage, this leaves significant gaps in understanding its behavior.

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

Conciseness5/5

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

The description is a single, efficient sentence that gets straight to the point without any fluff. It's front-loaded with the core action and resource, making it easy to parse quickly. Every word earns its place in conveying the essential purpose.

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

Completeness2/5

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

Given no annotations and no output schema, the description is incomplete for a tool with three parameters and potential behavioral complexity. It doesn't explain the output format, error conditions, or how filtering works beyond what's in the schema. For a listing tool in a developer context, more context on return values or usage patterns would be helpful.

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

Parameters3/5

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

Schema description coverage is 100%, so the schema fully documents all three parameters with descriptions and enums. The description adds no parameter-specific information beyond implying filtering (via 'available'), which is already covered by the schema. This meets the baseline for high schema coverage but doesn't provide extra semantic value.

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

Purpose4/5

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

The description clearly states the verb ('List') and resource ('available iOS simulators'), making the purpose immediately understandable. However, it doesn't distinguish this tool from potential sibling tools like 'boot_simulator' or 'shutdown_simulator' beyond the listing action, and the mention of 'iOS' in the description is slightly misleading since the schema shows support for multiple Apple platforms.

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

Usage Guidelines2/5

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

The description provides no guidance on when to use this tool versus alternatives. It doesn't mention that this is for listing simulators (vs. booting or shutting them down with sibling tools), nor does it explain prerequisites or typical use cases. The agent must infer usage from the name and context alone.

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

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