# Configuration
XcodeBuildMCP reads configuration from a project config file. The config file is optional but provides deterministic, repo-scoped behavior for every session.
## Contents
- [Config file](#config-file)
- [Session defaults](#session-defaults)
- [Workflow selection](#workflow-selection)
- [Build settings](#build-settings)
- [Debugging and logging](#debugging-and-logging)
- [UI automation](#ui-automation)
- [Templates](#templates)
- [Telemetry](#telemetry)
- [Quick reference](#quick-reference)
- [Environment variables (legacy)](#environment-variables-legacy)
---
## Config file
Create a config file at your workspace root:
```
<workspace-root>/.xcodebuildmcp/config.yaml
```
Minimal example:
```yaml
schemaVersion: 1
enabledWorkflows: ["simulator", "ui-automation", "debugging"]
```
Full example options:
```yaml
schemaVersion: 1
# Workflow selection
enabledWorkflows: ["simulator", "ui-automation", "debugging"]
experimentalWorkflowDiscovery: false
# Session defaults
disableSessionDefaults: false
sessionDefaults:
projectPath: "./MyApp.xcodeproj"
scheme: "MyApp"
configuration: "Debug"
simulatorName: "iPhone 16"
platform: "iOS"
useLatestOS: true
arch: "arm64"
suppressWarnings: true
derivedDataPath: "./.derivedData"
preferXcodebuild: false
bundleId: "com.example.myapp"
# Build settings
incrementalBuildsEnabled: false
# Debugging
debug: 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
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.
### Enabling and disabling
Session defaults are enabled by default. To disable them:
```yaml
disableSessionDefaults: true
```
When disabled, agents must pass explicit parameters on every tool call (legacy behavior).
### Setting defaults from config
Seed defaults at server startup by adding a `sessionDefaults` block:
```yaml
sessionDefaults:
projectPath: "./MyApp.xcodeproj"
scheme: "MyApp"
configuration: "Debug"
simulatorName: "iPhone 16"
```
### Setting defaults from an agent
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`.
### Session defaults reference
| 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 16`). 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. |
### Mutual exclusivity rules
- If both `projectPath` and `workspacePath` are set, `workspacePath` wins.
- If both `simulatorId` and `simulatorName` are set, `simulatorId` wins.
---
## Workflow selection
Workflows determine which tools are available. By default only the `simulator` workflow is loaded.
```yaml
enabledWorkflows: ["simulator", "ui-automation", "debugging"]
```
See [TOOLS.md](TOOLS.md) for available workflows and their tools.
To proxy Xcode IDE tools (Xcode 26+ `xcrun mcpbridge`), enable `xcode-ide`. See [XCODE_IDE_MCPBRIDGE.md](XCODE_IDE_MCPBRIDGE.md).
### Experimental workflow discovery
Enables a `manage-workflows` tool that agents can use to add/remove workflows at runtime.
```yaml
experimentalWorkflowDiscovery: true
```
> [!IMPORTANT]
> Requires client support for tools changed notifications. At the time of writing, Cursor, Claude Code, and Codex do not support this.
---
## Build settings
### Incremental builds
Enable incremental builds to speed up repeated builds:
```yaml
incrementalBuildsEnabled: true
```
> [!IMPORTANT]
> Incremental builds are experimental and may not work for all projects. Agents can bypass this setting per-call if needed.
---
## Debugging and logging
### Debug logging
Enable debug logging and the doctor diagnostic tool:
```yaml
debug: true
```
### Debugger backend
Select the debugger backend:
```yaml
debuggerBackend: "dap" # or "lldb-cli"
```
Default is `dap`. Changing this is not generally recommended.
### DAP settings
Tune the DAP backend:
```yaml
dapRequestTimeoutMs: 30000 # default: 30000
dapLogEvents: true # default: false
```
### Device log capture
Control how long to wait for devicectl JSON output:
```yaml
launchJsonWaitMs: 8000 # default: 8000
```
---
## UI automation
### Debugger guard
Block UI automation tools when the debugger is paused to prevent failures:
```yaml
uiDebuggerGuardMode: "error" # "error" | "warn" | "off"
```
Default is `error`.
### AXe binary
UI automation and simulator video capture require AXe, which is bundled by default. To use a different version:
```yaml
axePath: "/opt/axe/bin/axe"
```
See the [AXe repository](https://github.com/cameroncooke/axe) for more information.
---
## Templates
The scaffold tools pull templates from GitHub. Override the default locations and versions:
```yaml
iosTemplatePath: "/path/to/ios/templates"
iosTemplateVersion: "v1.2.3"
macosTemplatePath: "/path/to/macos/templates"
macosTemplateVersion: "v1.2.3"
```
Default templates:
- iOS: [XcodeBuildMCP-iOS-Template](https://github.com/cameroncooke/XcodeBuildMCP-iOS-Template)
- macOS: [XcodeBuildMCP-macOS-Template](https://github.com/cameroncooke/XcodeBuildMCP-macOS-Template)
---
## Telemetry
By default, error logs are sent to Sentry. To disable:
```yaml
# Environment variable only (no config.yaml option)
# XCODEBUILDMCP_SENTRY_DISABLED=true
```
See [PRIVACY.md](PRIVACY.md) for more information.
---
## Quick reference
| Option | Type | Default |
|--------|------|---------|
| `schemaVersion` | number | Required (`1`) |
| `enabledWorkflows` | string[] | `["simulator"]` |
| `experimentalWorkflowDiscovery` | boolean | `false` |
| `disableSessionDefaults` | boolean | `false` |
| `sessionDefaults` | object | `{}` |
| `incrementalBuildsEnabled` | boolean | `false` |
| `debug` | 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 |
---
## Environment variables (legacy)
Environment variables are supported for backwards compatibility but the config file is preferred.
| Config option | Environment variable |
|---------------|---------------------|
| `enabledWorkflows` | `XCODEBUILDMCP_ENABLED_WORKFLOWS` (comma-separated) |
| `experimentalWorkflowDiscovery` | `XCODEBUILDMCP_EXPERIMENTAL_WORKFLOW_DISCOVERY` |
| `disableSessionDefaults` | `XCODEBUILDMCP_DISABLE_SESSION_DEFAULTS` |
| `incrementalBuildsEnabled` | `INCREMENTAL_BUILDS_ENABLED` |
| `debug` | `XCODEBUILDMCP_DEBUG` |
| `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` |
| (no config option) | `XCODEBUILDMCP_SENTRY_DISABLED` |
Config file takes precedence over environment variables when both are set.
---
## Related docs
- Session defaults: [SESSION_DEFAULTS.md](SESSION_DEFAULTS.md)
- Tools reference: [TOOLS.md](TOOLS.md)
- Privacy and telemetry: [PRIVACY.md](PRIVACY.md)
- Troubleshooting: [TROUBLESHOOTING.md](TROUBLESHOOTING.md)