Skip to content
Merged
23 changes: 20 additions & 3 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,21 +1,38 @@
# Changelog

## [Unreleased]

### Breaking
- By default when the `enabledWorkflows` configuration option or `XCODEBUILDMCP_ENABLED_WORKFLOWS` environment variable is not set or empty, XcodeBuildMCP will default to loading only the `simulator` workflow. This is a change in behaviour; previously it would load all workflows and therefore tools by default.

This change reduces the number of tools loaded by default and requires the user to opt in to enable additional sets of tools based on their project or workflow requirements.

The simulator workflow is the default because it is the most common use case based on opt-in analytics data.

For more information see the [CONFIGURATION.md](docs/CONFIGURATION.md) documentation.

- Tool names and descriptions have been made more concise to reduce token consumption. Tool argument names that are self-explanatory have had their descriptions removed entirely.

### Added
- Add Smithery support for packaging/distribution.
- Add DAP-based debugger backend and simulator debugging toolset (attach, breakpoints, stack, variables, LLDB command).
- Add session-status MCP resource with session identifiers.
- Add UI automation guard that blocks UI tools when the debugger is paused.
- Add manage-workflows tool for live workflow selection updates.
- Add a bundled XcodeBuildMCP skill to improve MCP client tool discovery.
- Add `manage-workflows` tool to allow agents to change the workflows enable/disabling tools at runtime. This requires clients to support tools changed notifications. (opt-in only)
- Add XcodeBuildMCP skill to improve MCP client tool use/discovery, this needs to be installed see [README.md](README.md) for more information.
- Added support for `.xcodebuildmcp/config.yaml` files for runtime configuration, this is a more flexible and powerful way to configure XcodeBuildMCP than environment variables.
- Added support for session-aware defaults that are persisted between sessions in the config file.

### Changed
- Migrate to Zod v4.
- Improve session default handling (reconcile mutual exclusivity and ignore explicit undefined clears).
- Auto-include workflow-discovery when workflow selection is configured.
- Remove dynamic tool discovery (`discover_tools`) and `XCODEBUILDMCP_DYNAMIC_TOOLS`. Use `XCODEBUILDMCP_ENABLED_WORKFLOWS` to limit startup tool registration.
- Add MCP tool annotations to all tools.

- Route runtime configuration reads through the config store with layered precedence.
- Treat missing/empty `enabledWorkflows` as "load all workflows".
- Add config.yaml support for DAP/log capture tuning (`dapRequestTimeoutMs`, `dapLogEvents`, `launchJsonWaitMs`).

### Fixed
- Update UI automation guard guidance to point at `debug_continue` when paused.
- Fix tool loading bugs in static tool registration.
Expand Down
20 changes: 20 additions & 0 deletions config.example.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
schemaVersion: 1
enabledWorkflows: ["simulator", "ui-automation", "debugging"]
experimentalWorkflowDiscovery: false
disableSessionDefaults: false
incrementalBuildsEnabled: false
sessionDefaults:
projectPath: "./MyApp.xcodeproj" # xor workspacePath
workspacePath: "./MyApp.xcworkspace" # xor projectPath
scheme: "MyApp"
configuration: "Debug"
simulatorName: "iPhone 16" # xor simulatorId
simulatorId: "<UUID>" # xor simulatorName
deviceId: "<UUID>"
useLatestOS: true
arch: "arm64"
suppressWarnings: false
derivedDataPath: "./.derivedData"
preferXcodebuild: false
platform: "iOS"
bundleId: "com.example.myapp"
196 changes: 126 additions & 70 deletions docs/CONFIGURATION.md
Original file line number Diff line number Diff line change
@@ -1,77 +1,28 @@
# Configuration

XcodeBuildMCP is configured through environment variables provided by your MCP client. Here is a single example showing how to add options to a typical MCP config:

```json
"XcodeBuildMCP": {
"command": "npx",
"args": ["-y", "xcodebuildmcp@latest"],
"env": {
"XCODEBUILDMCP_ENABLED_WORKFLOWS": "simulator,device,project-discovery",
"INCREMENTAL_BUILDS_ENABLED": "false",
"XCODEBUILDMCP_DISABLE_SESSION_DEFAULTS": "false",
"XCODEBUILDMCP_SENTRY_DISABLED": "false"
}
}
```

## Workflow selection

By default, XcodeBuildMCP loads the `simulator` workflow at startup (plus `session-management`). If you want a smaller or different tool surface, set `XCODEBUILDMCP_ENABLED_WORKFLOWS` to a comma-separated list of workflow directory names. The `session-management` workflow is always auto-included since other tools depend on it. When `XCODEBUILDMCP_DEBUG=true`, the `doctor` workflow is also auto-included.

**Available workflows:**
- `device` (14 tools) - iOS Device Development
- `simulator` (19 tools) - iOS Simulator Development
- `logging` (4 tools) - Log Capture & Management
- `macos` (11 tools) - macOS Development
- `project-discovery` (5 tools) - Project Discovery
- `project-scaffolding` (2 tools) - Project Scaffolding
- `utilities` (1 tool) - Project Utilities
- `session-management` (3 tools) - session-management
- `workflow-discovery` (1 tool) - Workflow Discovery
- `debugging` (8 tools) - Simulator Debugging
- `simulator-management` (8 tools) - Simulator Management
- `swift-package` (6 tools) - Swift Package Manager
- `doctor` (1 tool) - System Doctor
- `ui-testing` (11 tools) - UI Testing & Automation

## Incremental build support

XcodeBuildMCP includes experimental support for incremental builds. This feature is disabled by default and can be enabled by setting the `INCREMENTAL_BUILDS_ENABLED` environment variable to `true`.

> [!IMPORTANT]
> Incremental builds are highly experimental and your mileage may vary. Please report issues to the [issue tracker](https://github.com/cameroncooke/XcodeBuildMCP/issues).

## Experimental workflow discovery

Set `XCODEBUILDMCP_EXPERIMENTAL_WORKFLOW_DISCOVERY=true` to auto-include the `workflow-discovery` workflow at startup.

The workflow discovery tool lets agents and clients enable or disable workflows at runtime. This can reduce upfront context by loading only what is needed as the session evolves. Note: most clients do not yet support the MCP notifications required for an agent harness to re-query the tool list after changes.

## Session-aware opt-out

By default, XcodeBuildMCP uses a session-aware mode: the LLM (or client) sets shared defaults once (simulator, device, project/workspace, scheme, etc.), and all tools reuse them. This cuts context bloat not just in each call payload, but also in the tool schemas themselves.

If you prefer the older, explicit style where each tool requires its own parameters, set `XCODEBUILDMCP_DISABLE_SESSION_DEFAULTS=true`. This restores the legacy schemas with per-call parameters while still honoring any session defaults you choose to set.
XcodeBuildMCP reads configuration from a project config file and environment variables. The config file is optional but provides deterministic, repo-scoped behavior for every session.

Leave this unset for the streamlined session-aware experience; enable it to force explicit parameters on each tool call.
## Precedence
For runtime config (non-session defaults), precedence is:
1. `.xcodebuildmcp/config.yaml`
2. Environment variables

## Project config (config.yaml)
## Config file (config.yaml)

You can provide deterministic session defaults for every AI coding session by creating a project config file at:
Create a config file at your workspace root.

```
<workspace-root>/.xcodebuildmcp/config.yaml
```

Notes:
- Put the file in your **workspace root** (where your Xcode project is located).
- Agents can persist changes by calling `session_set_defaults` with `"persist": true` (see below).

### Schema
Example:

```yaml
schemaVersion: 1
enabledWorkflows: ["simulator", "ui-automation", "debugging"]
experimentalWorkflowDiscovery: false
disableSessionDefaults: false
incrementalBuildsEnabled: false
sessionDefaults:
projectPath: "./MyApp.xcodeproj" # xor workspacePath
workspacePath: "./MyApp.xcworkspace" # xor projectPath
Expand All @@ -89,31 +40,136 @@ sessionDefaults:
bundleId: "com.example.myapp"
```

Behavior:
- Relative paths in `projectPath`, `workspacePath`, and `derivedDataPath` resolve against the workspace root at load time.
Notes:
- `schemaVersion` is required and currently only supports `1`.
- If both `projectPath` and `workspacePath` are set, **workspacePath wins**.
- If both `simulatorId` and `simulatorName` are set, **simulatorId wins**.

### Persisting defaults from an agent

By default, when the agent calls `session_set_defaults`, defaults are only stored in memory for that session. To persist them to the config file, ask the agent to set the `persist` flag to `true`.

## Workflow selection

You can configure workflows in either:
- `enabledWorkflows` in `config.yaml` (preferred), or
- via environment variable `XCODEBUILDMCP_ENABLED_WORKFLOWS` (comma-separated)

Notes:
- If `enabledWorkflows` is omitted, empty or not set, only the default `simulator` workflow is loaded.

See [TOOLS.md](TOOLS.md) for a list of available workflows and tools.

## Debug logging

Enable debug logging with:
- `debug: true` in `config.yaml` (preferred), or
- via environment variable `XCODEBUILDMCP_DEBUG=true`

This enables an extra doctor tool that agents can run to get MCP and system environment information useful for debugging issues with XcodeBuildMCP.

## Incremental build support

Enable incremental builds with either:
- `incrementalBuildsEnabled: true` in `config.yaml` (preferred), or
- via environment variable `INCREMENTAL_BUILDS_ENABLED=true`

> [!IMPORTANT]
> Incremental builds are experimental and won't work for all projects. If you encounter issues, you can disable the option. The agent can also bypass incremental builds by passing a flag when calling build tools.

## Experimental workflow discovery

Enable via:
- `experimentalWorkflowDiscovery: true` in `config.yaml` (preferred), or
- via environment variable `XCODEBUILDMCP_EXPERIMENTAL_WORKFLOW_DISCOVERY=true`

Enables experimental workflow discovery, this feature adds a `manage-workflows` tool that the agent can use to add/remove workflows at runtime. This requires clients to support tools changed notifications and therefore is an opt-in and experimental feature.

> [!IMPORTANT]
> The write is **patch-only**: only keys provided in that call are written (plus any removals needed for mutual exclusivity).
> At the time of writing, neither Cursor, Claude Code, nor Codex support tools changed notifications.

## Session-aware opt-out

Disable session-aware schemas with:
- `disableSessionDefaults: true` in `config.yaml` (preferred), or
- via environment variable `XCODEBUILDMCP_DISABLE_SESSION_DEFAULTS=true`

Disables the session-aware defaults feature. This means that the agent will need to set the defaults for each tool call explicitly. This is not recommended and will use more tokens per call. It's recommended to only enable this if your specific requirements need the build, device and simulator settings change frequently in a single coding session, i.e. monorepos with multiple projects.

## UI automation guard

Control UI automation when a debugger is paused with:
- `uiDebuggerGuardMode: "error" | "warn" | "off"` in `config.yaml` (preferred), or
- via environment variable `XCODEBUILDMCP_UI_DEBUGGER_GUARD_MODE=error|warn|off`

This feature is used to block UI tools when the debugger is paused, this is to prevent the agent from executing UI tools that will fail or return incorrect results when the debugger is paused.

Default is `error` when unset.

## Sentry telemetry opt-out

If you do not wish to send error logs to Sentry, set `XCODEBUILDMCP_SENTRY_DISABLED=true`.
Disable Sentry with:
- `XCODEBUILDMCP_SENTRY_DISABLED=true`

By default we send error logs to Sentry, this can be disabled to prevent any error logs from being sent.

See [PRIVACY.md](PRIVACY.md) for more information.

## AXe binary override

UI automation and simulator video capture require the AXe binary. By default, XcodeBuildMCP uses the bundled AXe when available, then falls back to `PATH`. To force a specific binary location, set `XCODEBUILDMCP_AXE_PATH` (preferred). `AXE_PATH` is also recognized for compatibility.
UI automation and simulator video capture require AXe. By default AXe is bundled with XcodeBuildMCP, but you can override the path to use a different version of AXe by setting these options.

Example:
Configure the binary path with:
- `axePath: "/opt/axe/bin/axe"` in `config.yaml` (preferred), or
- via environment variable `XCODEBUILDMCP_AXE_PATH=/opt/axe/bin/axe`

```
XCODEBUILDMCP_AXE_PATH=/opt/axe/bin/axe
```
For more information about AXe see the [AXe repository](https://github.com/cameroncooke/axe).

## Template overrides

The macOS and iOS scaffold tools pull templates from https://github.com/cameroncooke/XcodeBuildMCP-macOS-Template and https://github.com/cameroncooke/XcodeBuildMCP-iOS-Template respectively.

If you want to use your own source/fork for templates you can override the default locations and versions by setting these options.

Set custom template locations and versions with:
- `iosTemplatePath` / `macosTemplatePath` in `config.yaml` (preferred), or
- via environment variable `XCODEBUILDMCP_IOS_TEMPLATE_PATH=/path/to/ios/templates`
- via environment variable `XCODEBUILDMCP_MACOS_TEMPLATE_PATH=/path/to/macos/templates`
- `iosTemplateVersion` / `macosTemplateVersion` in `config.yaml`, or
- `XCODEBUILD_MCP_IOS_TEMPLATE_VERSION=v1.2.3`
- `XCODEBUILD_MCP_MACOS_TEMPLATE_VERSION=v1.2.3`

These override the default template versions bundled in the package.

## Debugger backend

Select the debugger backend with:
- `debuggerBackend: "dap" | "lldb-cli"` in `config.yaml`, or
- `XCODEBUILDMCP_DEBUGGER_BACKEND=dap|lldb-cli`

This overrides the debugger backend and defaults to `dap`. It's not generally recommended to change this.

## DAP backend settings

Tune the DAP backend with:
- `dapRequestTimeoutMs: 30000` in `config.yaml`, or
- `XCODEBUILDMCP_DAP_REQUEST_TIMEOUT_MS=30000`

This overrides the default request timeout of 30 seconds.

Enable DAP event logging with:
- `dapLogEvents: true` in `config.yaml`, or
- `XCODEBUILDMCP_DAP_LOG_EVENTS=true`

This enables logging of DAP events to the console.

## Device log capture JSON wait

Control how long we wait for devicectl JSON output with:
- `launchJsonWaitMs: 8000` in `config.yaml`, or
- `XBMCP_LAUNCH_JSON_WAIT_MS=8000`

This overrides the default wait time of 8 seconds for devicectl JSON output.

## Related docs
- Session defaults: [SESSION_DEFAULTS.md](SESSION_DEFAULTS.md)
Expand Down
13 changes: 11 additions & 2 deletions docs/GETTING_STARTED.md
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,15 @@ Most MCP clients use JSON configuration. Add the following to your client config
}
```

## Project config (optional)
For deterministic session defaults and runtime configuration, add a config file at:

```text
<workspace-root>/.xcodebuildmcp/config.yaml
```

See [CONFIGURATION.md](CONFIGURATION.md) for the full schema and examples.

## Client-specific configuration

### OpenAI Codex CLI
Expand All @@ -43,7 +52,7 @@ Codex uses TOML for MCP configuration. Add this to your Codex CLI config file:
[mcp_servers.XcodeBuildMCP]
command = "npx"
args = ["-y", "xcodebuildmcp@latest"]
env = { "INCREMENTAL_BUILDS_ENABLED" = "false", "XCODEBUILDMCP_SENTRY_DISABLED" = "false" }
env = { "XCODEBUILDMCP_SENTRY_DISABLED" = "false" }
```

If you see tool calls timing out (for example, `timed out awaiting tools/call after 60s`), increase the timeout:
Expand All @@ -61,7 +70,7 @@ https://github.com/openai/codex/blob/main/docs/config.md#connecting-to-mcp-serve
claude mcp add XcodeBuildMCP npx xcodebuildmcp@latest

# Or with environment variables
claude mcp add XcodeBuildMCP npx xcodebuildmcp@latest -e INCREMENTAL_BUILDS_ENABLED=false -e XCODEBUILDMCP_SENTRY_DISABLED=false
claude mcp add XcodeBuildMCP npx xcodebuildmcp@latest -e XCODEBUILDMCP_SENTRY_DISABLED=false
```

Note: XcodeBuildMCP requests xcodebuild to skip macro validation to avoid Swift Macro build errors.
Expand Down
16 changes: 6 additions & 10 deletions docs/SESSION_DEFAULTS.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,25 +7,21 @@ By default, XcodeBuildMCP uses a session-aware mode. The client sets shared defa
- Tools reuse those defaults automatically.
- Agent can call `session_show_defaults` to inspect current values.
- Agent can call `session_clear_defaults` to clear values when switching contexts.
- Defaults can also be seeded from `.xcodebuildmcp/config.yaml` at server startup.
- Defaults can be seeded from `.xcodebuildmcp/config.yaml` at server startup.

See the session-management tools in [TOOLS.md](TOOLS.md).

## Opting out
If you prefer explicit parameters on every tool call, set:
If you prefer explicit parameters on every tool call, set `disableSessionDefaults: true` in your `.xcodebuildmcp/config.yaml` file.

```json
"env": {
"XCODEBUILDMCP_DISABLE_SESSION_DEFAULTS": "true"
}
```
This restores the legacy schemas with per-call parameters while still honoring any defaults you choose to set.

This restores the legacy schemas with per-call parameters while still honoring any defaults you choose to set. Though this is not recommended, it can be useful in certain scenarios where you are working on monorepos or multiple projects at once.
See [CONFIGURATION.md](CONFIGURATION.md) for more information.

## Persisting defaults
Session defaults can be persisted between sessions by asking your agent to set the defaults with the `persist` flag set to `true`. This will save the defaults into `.xcodebuildmcp/config.yaml` at the root of your project's workspace.
Session defaults can be persisted between sessions by setting the `persist` flag to `true` on `session_set_defaults`. This writes to `.xcodebuildmcp/config.yaml` at the root of your workspace.

The persisted config is patch-only (only provided keys are written).
The persistence is patch-only: only keys provided in that call are written (plus any removals needed for mutual exclusivity).

You can also manually create the config file to essentially seed the defaults at startup; see [CONFIGURATION.md](CONFIGURATION.md) for more information.

Expand Down
6 changes: 3 additions & 3 deletions docs/TOOLS.md
Original file line number Diff line number Diff line change
Expand Up @@ -34,8 +34,8 @@ XcodeBuildMCP provides 72 tools organized into 14 workflow groups for comprehens

- `start_device_log_cap` - Start device log capture.
- `start_sim_log_cap` - Start sim log capture.
- `stop_device_log_cap` - Stop device log capture.
- `stop_sim_log_cap` - Stop sim log capture.
- `stop_device_log_cap` - Stop device app and return logs.
- `stop_sim_log_cap` - Stop sim app and return logs.
### macOS Development (`macos`)
**Purpose**: Complete macOS development workflow for both .xcodeproj and .xcworkspace files. Build, test, deploy, and manage macOS applications. (6 tools)

Expand Down Expand Up @@ -126,4 +126,4 @@ XcodeBuildMCP provides 72 tools organized into 14 workflow groups for comprehens

---

*This documentation is automatically generated by `scripts/update-tools-docs.ts` using static analysis. Last updated: 2026-01-27*
*This documentation is automatically generated by `scripts/update-tools-docs.ts` using static analysis. Last updated: 2026-01-28*
Loading
Loading