Skip to content

Unable to set default simulator/emulator from environment variables — session may pick non-installed simulator #180

Description

@dpearson2699

Description

When running XcodeBuildMCP from an MCP client, there doesn't appear to be a way to set the server's simulator/emulator default via environment variables or the MCP server config. As a result, when a model/agent starts a new session and tools run for the first time, the session-aware defaults can end up using a simulator name (e.g. from examples like "iPhone 16") that isn't installed on the host. This causes downstream tool failures (xcodebuild/simctl errors) and confusing errors for agents.

Behavior observed

  • Session defaults are stored in an in-memory SessionStore and are only populated by calling the session_set_defaults tool (or directly via sessionStore.setDefaults() in tests).
  • There is no documented or implemented environment variable such as XCODEBUILDMCP_DEFAULT_SIMULATOR or similar that the server reads on startup to seed the SessionStore.
  • Clients/agents that do not explicitly call session_set_defaults (or that rely on example names) sometimes cause the server to attempt actions on simulators that are not present.

Reproduction (minimal)

  1. Start XcodeBuildMCP server normally (e.g. via npx xcodebuildmcp@latest or the VS Code MCP config).
  2. From an agent or client, call a session-aware tool that relies on simulator defaults without first calling session_set_defaults, for example build_run_sim or launch_app_sim.
  3. The tool may resolve a simulator name coming from examples/tests (e.g. "iPhone 16") or an unset/empty store, and fail with simctl/xcodebuild errors if that simulator isn't installed.

Why this is problematic

  • Agents often expect an MCP server to provide stable defaults or allow a way to configure them at server start. Relying solely on session RPC calls leaves a race where the first tool run may fail.
  • Examples and scaffolded output include simulator names ("iPhone 16") which look like sensible defaults but aren't guaranteed to exist on every host — leading to unexpected failures.

Suggested fixes / enhancements

  1. Add server startup seeding from environment variables or config (preferred):
    • Add env vars such as XCODEBUILDMCP_DEFAULT_SIMULATOR_NAME and/or XCODEBUILDMCP_DEFAULT_SIMULATOR_ID that the server reads on startup and uses to call sessionStore.setDefaults(...) or populate the initial session defaults. Document these in docs/CONFIGURATION.md and docs/SESSION_DEFAULTS.md.
  2. Or: allow mcp.json (client server config) to include an initial sessionDefaults object which is merged into the SessionStore when the MCP server process starts.
  3. Improve resolution fallback: when a named simulator is provided but not found, provide a clearer error / fallback strategy (e.g., auto-select a compatible installed simulator and warn, or fail fast with actionable instructions to call session-set-defaults).
  4. Prefer encouraging use of simulatorId (UUID) in examples/docs or add a helper that resolves the best-available simulator for a named example so scaffolded commands are less likely to fail.

Relevant files in repo

  • src/utils/session-store.ts (in-memory store)
  • src/utils/typed-tool-factory.ts (merging session defaults with args)
  • src/mcp/tools/session-management/session_set_defaults.ts
  • docs/CONFIGURATION.md and docs/SESSION_DEFAULTS.md
  • Example usage: scaffold/docs referencing iPhone 16 e.g. src/mcp/tools/project-scaffolding/scaffold_ios_project.ts

Potential implementation notes

  • On server startup, read the env vars and call the same sessionStore.setDefaults() code path used by session-set-defaults so the behavior is centralized and tested.
  • If adding env config, clearly document precedence: explicit session_set_defaults RPC calls should still override the startup env values.

Would be happy to open a small PR implementing the startup env var seeding (and adding docs) if you want. Thanks for maintaining this project — this change would make headless/agent workflows much more robust.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Fields

    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions