XcodeBuildMCP reads configuration from environment variables and/or a project config file. Both are optional but provide deterministic behavior for every session.
- Environment variables
- Config file
- Configuration layering
- Session defaults
- Workflow selection
- Build settings
- Debugging and logging
- UI automation
- Templates
- Telemetry
- Quick reference
Environment variables are the recommended configuration method for MCP client integration. Set them in the env field of your MCP client config (e.g., mcp_config.json for Windsurf, .vscode/mcp.json for VS Code, claude_desktop_config.json for Claude Desktop).
This approach works reliably across all MCP clients regardless of working directory, and avoids the need for filesystem-based config discovery.
| Config option | Environment variable |
|---|---|
enabledWorkflows |
XCODEBUILDMCP_ENABLED_WORKFLOWS (comma-separated) |
experimentalWorkflowDiscovery |
XCODEBUILDMCP_EXPERIMENTAL_WORKFLOW_DISCOVERY |
disableSessionDefaults |
XCODEBUILDMCP_DISABLE_SESSION_DEFAULTS |
disableXcodeAutoSync |
XCODEBUILDMCP_DISABLE_XCODE_AUTO_SYNC |
incrementalBuildsEnabled |
INCREMENTAL_BUILDS_ENABLED |
debug |
XCODEBUILDMCP_DEBUG |
sentryDisabled |
XCODEBUILDMCP_SENTRY_DISABLED |
debuggerBackend |
XCODEBUILDMCP_DEBUGGER_BACKEND |
dapRequestTimeoutMs |
XCODEBUILDMCP_DAP_REQUEST_TIMEOUT_MS |
dapLogEvents |
XCODEBUILDMCP_DAP_LOG_EVENTS |
launchJsonWaitMs |
XBMCP_LAUNCH_JSON_WAIT_MS |
uiDebuggerGuardMode |
XCODEBUILDMCP_UI_DEBUGGER_GUARD_MODE |
axePath |
XCODEBUILDMCP_AXE_PATH |
iosTemplatePath |
XCODEBUILDMCP_IOS_TEMPLATE_PATH |
iosTemplateVersion |
XCODEBUILD_MCP_IOS_TEMPLATE_VERSION |
macosTemplatePath |
XCODEBUILDMCP_MACOS_TEMPLATE_PATH |
macosTemplateVersion |
XCODEBUILD_MCP_MACOS_TEMPLATE_VERSION |
| Session default | Environment variable |
|---|---|
workspacePath |
XCODEBUILDMCP_WORKSPACE_PATH |
projectPath |
XCODEBUILDMCP_PROJECT_PATH |
scheme |
XCODEBUILDMCP_SCHEME |
configuration |
XCODEBUILDMCP_CONFIGURATION |
simulatorName |
XCODEBUILDMCP_SIMULATOR_NAME |
simulatorId |
XCODEBUILDMCP_SIMULATOR_ID |
simulatorPlatform |
XCODEBUILDMCP_SIMULATOR_PLATFORM |
deviceId |
XCODEBUILDMCP_DEVICE_ID |
platform |
XCODEBUILDMCP_PLATFORM |
useLatestOS |
XCODEBUILDMCP_USE_LATEST_OS |
arch |
XCODEBUILDMCP_ARCH |
suppressWarnings |
XCODEBUILDMCP_SUPPRESS_WARNINGS |
derivedDataPath |
XCODEBUILDMCP_DERIVED_DATA_PATH |
preferXcodebuild |
XCODEBUILDMCP_PREFER_XCODEBUILD |
bundleId |
XCODEBUILDMCP_BUNDLE_ID |
Use one of these as a starting point and fill in your workspace path and scheme.
macOS app
{
"mcpServers": {
"XcodeBuildMCP": {
"command": "npx",
"args": ["-y", "xcodebuildmcp@latest", "mcp"],
"env": {
"XCODEBUILDMCP_ENABLED_WORKFLOWS": "coverage,debugging,doctor,logging,macos,project-discovery,project-scaffolding,swift-package,ui-automation,utilities,xcode-ide",
"XCODEBUILDMCP_WORKSPACE_PATH": "/Users/me/MyApp/MyApp.xcworkspace",
"XCODEBUILDMCP_SCHEME": "MyApp",
"XCODEBUILDMCP_PLATFORM": "macOS"
}
}
}
}
macosprovides build/run/test/stop tools for macOS apps. No simulator workflow needed — macOS apps run natively.
iOS app
{
"mcpServers": {
"XcodeBuildMCP": {
"command": "npx",
"args": ["-y", "xcodebuildmcp@latest", "mcp"],
"env": {
"XCODEBUILDMCP_ENABLED_WORKFLOWS": "coverage,debugging,doctor,logging,project-discovery,project-scaffolding,simulator,swift-package,ui-automation,utilities,xcode-ide",
"XCODEBUILDMCP_WORKSPACE_PATH": "/Users/me/MyApp/MyApp.xcworkspace",
"XCODEBUILDMCP_SCHEME": "MyApp",
"XCODEBUILDMCP_PLATFORM": "iOS Simulator",
"XCODEBUILDMCP_SIMULATOR_NAME": "iPhone 16 Pro"
}
}
}
}
simulatorprovides build/run/test/install tools targeting iOS Simulator. UseXCODEBUILDMCP_SIMULATOR_NAMEorXCODEBUILDMCP_SIMULATOR_IDto pin the target device.
iOS + macOS (multi-platform or Catalyst)
{
"mcpServers": {
"XcodeBuildMCP": {
"command": "npx",
"args": ["-y", "xcodebuildmcp@latest", "mcp"],
"env": {
"XCODEBUILDMCP_ENABLED_WORKFLOWS": "coverage,debugging,doctor,logging,macos,project-discovery,project-scaffolding,simulator,swift-package,ui-automation,utilities,xcode-ide",
"XCODEBUILDMCP_WORKSPACE_PATH": "/Users/me/MyApp/MyApp.xcworkspace",
"XCODEBUILDMCP_SCHEME": "MyApp"
}
}
}
}Include both
simulatorandmacoswhen the project supports multiple platforms. OmitXCODEBUILDMCP_PLATFORMto let the agent choose per-command.
tvOS or watchOS app
{
"mcpServers": {
"XcodeBuildMCP": {
"command": "npx",
"args": ["-y", "xcodebuildmcp@latest", "mcp"],
"env": {
"XCODEBUILDMCP_ENABLED_WORKFLOWS": "debugging,doctor,logging,project-discovery,simulator,swift-package,utilities,xcode-ide",
"XCODEBUILDMCP_WORKSPACE_PATH": "/Users/me/MyApp/MyApp.xcworkspace",
"XCODEBUILDMCP_SCHEME": "MyApp",
"XCODEBUILDMCP_PLATFORM": "tvOS Simulator"
}
}
}
}Replace
tvOS SimulatorwithwatchOS Simulatorfor watchOS. Coverage and UI automation are not available on these platforms.
You can also generate a config block interactively:
xcodebuildmcp setup --format mcp-jsonThe config file provides repo-scoped, version-controllable configuration. Create it at your workspace root:
<workspace-root>/.xcodebuildmcp/config.yaml
Or run the interactive setup wizard:
xcodebuildmcp setupMinimal example:
schemaVersion: 1
enabledWorkflows: ["simulator", "ui-automation", "debugging"]Full example options:
schemaVersion: 1
# Workflow selection
enabledWorkflows: ["simulator", "ui-automation", "debugging"]
customWorkflows:
my-workflow:
- build_run_sim
- record_sim_video
- screenshot
experimentalWorkflowDiscovery: false
# Session defaults
disableSessionDefaults: false
sessionDefaults:
projectPath: "./MyApp.xcodeproj"
scheme: "MyApp"
configuration: "Debug"
simulatorName: "iPhone 17"
platform: "iOS"
useLatestOS: true
arch: "arm64"
suppressWarnings: true
derivedDataPath: "./.derivedData"
preferXcodebuild: false
bundleId: "io.sentry.myapp"
# Build settings
incrementalBuildsEnabled: false
# Debugging
debug: false
sentryDisabled: false
debuggerBackend: "dap"
dapRequestTimeoutMs: 30000
dapLogEvents: false
launchJsonWaitMs: 8000
# UI automation
uiDebuggerGuardMode: "error"
axePath: "/opt/axe/bin/axe"
# Templates
iosTemplatePath: "/path/to/ios/templates"
iosTemplateVersion: "v1.2.3"
macosTemplatePath: "/path/to/macos/templates"
macosTemplateVersion: "v1.2.3"The schemaVersion field is required and currently only supports 1.
Session defaults allow you to set shared values once (project, scheme, simulator, etc.) that all tools reuse automatically. This reduces token usage and ensures consistent behavior.
Session defaults are enabled by default. To disable them:
disableSessionDefaults: trueWhen disabled, agents must pass explicit parameters on every tool call (legacy behavior).
Seed defaults at server startup by adding a sessionDefaults block:
sessionDefaults:
projectPath: "./MyApp.xcodeproj"
scheme: "MyApp"
configuration: "Debug"
simulatorName: "iPhone 17"Agents can call session_set_defaults at runtime. By default these are stored in memory only. To persist them to the config file, the agent sets persist: true.
| Option | Type | Description |
|---|---|---|
projectPath |
string | Path to .xcodeproj file. Mutually exclusive with workspacePath. |
workspacePath |
string | Path to .xcworkspace file. Takes precedence if both are set. |
scheme |
string | Build scheme name. |
configuration |
string | Build configuration (e.g., Debug, Release). |
simulatorName |
string | Simulator name (e.g., iPhone 17). Mutually exclusive with simulatorId. |
simulatorId |
string | Simulator UUID. Takes precedence if both are set. |
deviceId |
string | Physical device UUID. |
platform |
string | Target platform (e.g., iOS, macOS, watchOS, tvOS, visionOS). |
useLatestOS |
boolean | Use the latest available OS version for the simulator. |
arch |
string | Build architecture (e.g., arm64, x86_64). |
suppressWarnings |
boolean | Suppress compiler warnings in build output. |
derivedDataPath |
string | Custom path for derived data. |
preferXcodebuild |
boolean | Use xcodebuild instead of the experimental incremental build support (xcodemake). Only applies when incremental builds are enabled. Is designed for agent use to self correct after failed xcodemake build attempts. |
bundleId |
string | App bundle identifier. |
- If both
projectPathandworkspacePathare set,workspacePathwins. - If both
simulatorIdandsimulatorNameare set,simulatorIdwins.
Workflows determine which tools are available. By default only the simulator workflow is loaded.
enabledWorkflows: ["simulator", "ui-automation", "debugging"]See TOOLS.md for available workflows and their tools.
You can define your own workflow names in config and reference them from enabledWorkflows.
Each custom workflow is a list of tool names (MCP names), and only those tools are loaded for that workflow.
enabledWorkflows: ["my-workflow"]
customWorkflows:
my-workflow:
- build_run_sim
- record_sim_video
- screenshotNotes:
- Built-in implicit workflows are unchanged. Session-management tools are still auto-included, and the doctor workflow is still auto-included when
debug: true. - Custom workflow names are normalized to lowercase.
- Unknown tool names are ignored and logged as warnings.
To access Xcode IDE tools (Xcode 26+ xcrun mcpbridge), enable xcode-ide. This workflow exposes xcode_ide_list_tools and xcode_ide_call_tool for MCP clients. See XCODE_IDE_MCPBRIDGE.md.
Enables a manage-workflows tool that agents can use to add/remove workflows at runtime.
experimentalWorkflowDiscovery: trueImportant
Requires client support for tools changed notifications. At the time of writing, Cursor, Claude Code, and Codex do not support this.
Enable incremental builds to speed up repeated builds:
incrementalBuildsEnabled: trueImportant
Incremental builds are experimental and may not work for all projects. Agents can bypass this setting per-call if needed.
Enable debug logging and the doctor diagnostic tool:
debug: trueSelect the debugger backend:
debuggerBackend: "dap" # or "lldb-cli"Default is dap. Changing this is not generally recommended.
Tune the DAP backend:
dapRequestTimeoutMs: 30000 # default: 30000
dapLogEvents: true # default: falseControl how long to wait for devicectl JSON output:
launchJsonWaitMs: 8000 # default: 8000Block UI automation tools when the debugger is paused to prevent failures:
uiDebuggerGuardMode: "error" # "error" | "warn" | "off"Default is error.
UI automation and simulator video capture require AXe, which is bundled by default. To use a different version:
axePath: "/opt/axe/bin/axe"See the AXe repository for more information.
The scaffold tools pull templates from GitHub. Override the default locations and versions:
iosTemplatePath: "/path/to/ios/templates"
iosTemplateVersion: "v1.2.3"
macosTemplatePath: "/path/to/macos/templates"
macosTemplateVersion: "v1.2.3"Default templates:
By default, only internal XcodeBuildMCP runtime failures are sent to Sentry. User-domain errors (such as project build/test/config failures) are not sent. To disable telemetry entirely:
sentryDisabled: trueYou can also disable telemetry via environment variable:
XCODEBUILDMCP_SENTRY_DISABLED=trueSee PRIVACY.md for more information.
Notes:
- Sentry SDK logging is enabled for internal observability.
- Only explicitly opted-in internal logs are forwarded to Sentry; standard console logs are not auto-forwarded.
- Tool arguments and tool outputs are not captured by MCP wrapper telemetry (
recordInputs: false,recordOutputs: false).
| Option | Type | Default |
|---|---|---|
schemaVersion |
number | Required (1) |
enabledWorkflows |
string[] | ["simulator"] |
customWorkflows |
Record<string, string[]> | {} |
experimentalWorkflowDiscovery |
boolean | false |
disableSessionDefaults |
boolean | false |
sessionDefaults |
object | {} |
incrementalBuildsEnabled |
boolean | false |
debug |
boolean | false |
sentryDisabled |
boolean | false |
debuggerBackend |
string | "dap" |
dapRequestTimeoutMs |
number | 30000 |
dapLogEvents |
boolean | false |
launchJsonWaitMs |
number | 8000 |
uiDebuggerGuardMode |
string | "error" |
axePath |
string | Bundled |
iosTemplatePath |
string | GitHub default |
iosTemplateVersion |
string | Bundled version |
macosTemplatePath |
string | GitHub default |
macosTemplateVersion |
string | Bundled version |
When multiple configuration sources are present, they are merged with clear precedence:
session_set_defaultstool (highest) — agent runtime overrides, set during a session- Config file — project-local config (
config.yaml), committed to repo - Environment variables (lowest) — MCP client integration, set in
mcp_config.json
This follows the same pattern as tools like git config (--flag > --local > --global). Each layer serves a different context:
- Env vars are the portable MCP client integration path — they work regardless of working directory and are supported by every MCP client.
- Config file is for repo-scoped, version-controlled settings and interactive CLI usage.
- Tool calls are for agent-driven runtime adjustments.
- Session defaults: SESSION_DEFAULTS.md
- Tools reference: TOOLS.md
- Privacy and telemetry: PRIVACY.md
- Troubleshooting: TROUBLESHOOTING.md