Doramagic Project Pack · Human Manual
XcodeBuildMCP
A Model Context Protocol (MCP) server and CLI that provides tools for agent use when working on iOS and macOS projects.
Project Overview & System Architecture
Related topics: Tool Catalog, Manifests & Workflows, UI Automation, Debugging & Simulator Operations, Configuration, Session Management & Extensibility
Continue reading this section for the full explanation and source context.
Related Pages
Related topics: Tool Catalog, Manifests & Workflows, UI Automation, Debugging & Simulator Operations, Configuration, Session Management & Extensibility
Project Overview & System Architecture
1. Purpose and Scope
XcodeBuildMCP is a Model Context Protocol (MCP) server and command-line tool that exposes Apple platform development workflows (iOS, macOS, watchOS, tvOS, visionOS) to AI agents and human operators. The project is described in README.md as "A Model Context Protocol (MCP) server and CLI that provides tools for agent use when working on iOS and macOS projects."
The system targets the gap between LLM-based coding assistants and the day-to-day mechanics of building, testing, and inspecting Apple platform apps. It wraps Xcode build/test/launch flows, simulator lifecycle, UI automation, log capture, Swift Package Manager operations, and project discovery behind a uniform tool surface that is reachable from both an MCP host (e.g., Claude Desktop, Cursor) and a shell xcodebuildmcp binary.
Runtime requirements are stated in package.json: Node.js >= 18.x, macOS as the host platform, and Xcode 16. The license is MIT.
2. High-Level Architecture
XcodeBuildMCP is organized around three runtimes and a manifest-driven tool catalog. The three runtime kinds are declared in src/runtime/types.ts:
export type RuntimeKind = 'cli' | 'daemon' | 'mcp';
mcp– the long-lived stdio MCP server registered with a coding assistant.daemon– a background process used by the CLI to amortize startup cost and share state.cli– the user-facingxcodebuildmcpcommand, which lazily spawns or reuses the daemon.
The MCP server is created in src/server/server.ts using @modelcontextprotocol/sdk/server/mcp.js and StdioServerTransport. The server advertises a multi-paragraph instructions payload summarizing its capabilities (session defaults, project discovery, simulator workflows, etc.) so MCP hosts can reason about when to delegate work to it.
flowchart LR
A[MCP Host<br/>Claude / Cursor] -->|stdio JSON-RPC| B[server.ts<br/>McpServer]
B --> C[Tool Catalog<br/>tool-catalog.ts]
C --> D[Manifest<br/>YAML tool defs]
B --> E[Handlers]
E --> F[xcodebuild / simctl<br/>AXe / xcrun]
G[CLI: xcodebuildmcp] --> H[cli-tool-catalog.ts]
H --> I[daemon-control.ts]
I --> J[daemon-server.ts]
J --> C
B -.->|shutdown| K[mcp-shutdown.ts]The CLI does not duplicate tool definitions. It reuses the same manifest and tool catalog that the MCP server uses, and routes calls through a daemon process. The daemon in turn loads the manifest via src/runtime/tool-catalog.ts:
export async function buildCliToolCatalogFromManifest(opts?: {
excludeWorkflows?: string[];
}): Promise<ToolCatalog> { ... }
This shared catalog is what allows a single tool to be invoked as either an MCP tool or a CLI subcommand without re-implementation.
3. Tool Catalog and Manifest System
Tools are not registered through ad-hoc code. They are loaded from a workflow manifest, then materialized into typed ToolDefinition records. The ToolDefinition interface in src/runtime/types.ts carries everything needed for both runtimes:
| Field | Purpose |
|---|---|
cliName | Stable kebab-case command name for the CLI |
mcpName | Original MCP tool name as declared |
workflow | Workflow directory (e.g. simulator, device, logging) |
cliSchema / mcpSchema | Schema shapes for flag parsing and MCP registration |
outputSchema | Reference to a structured-output schema |
nextStepTemplates | Suggested follow-up tool invocations |
stateful | Whether the tool mutates session state |
handler | The actual tool implementation |
src/runtime/tool-catalog.ts builds several lookup maps (byCliName, byMcpName, byToolId, byMcpKebab) and explicitly deduplicates by lowercase mcpName so that a single tool exposed under multiple workflows does not produce ambiguous resolution.
Visibility is controlled by predicates. The catalog builder consults isWorkflowEnabledForRuntime, isToolAvailableForRuntime, and isToolExposedForRuntime to decide whether a given tool appears in a given runtime context. The CLI predicate context, built in src/cli/commands/tools.ts, hard-codes runningUnderXcode: false because the CLI is never embedded in Xcode.
4. Server Lifecycle and Known Failure Modes
The MCP server has a deliberate shutdown sequence implemented in src/server/mcp-shutdown.ts. It steps through debugger cleanup, Xcode state watcher teardown, the Xcode Tools Bridge shutdown, owned workspace artifact cleanup, video capture session termination, and Swift Package active-process tracking. Each step has explicit timeouts (e.g., DEBUGGER_STEP_BASE_TIMEOUT_MS = 2200, DEFAULT_FLUSH_TIMEOUT_MS = 1500) and is reported as completed | timed_out | failed | skipped in a shutdown summary that is flushed to Sentry.
Several community-reported issues are architectural in nature and worth knowing up front:
- Build output volume and truncation (#68, #177) – LLM context is "blown away" by unfiltered build logs, and tests can be truncated. A
suppressWarningsoption in session defaults exists but is reported not to work in some cases (#447). - Build timeouts (#174) – there is no per-tool timeout parameter, so a stalled
xcodebuildblocks the agent. - Strict mode (#413) – there is no flag that disables per-call "escape hatch" arguments in favor of session defaults, so agents can mutate build settings ad hoc.
- Xcode version coupling (#446) – the bundled AXe tool assumes
Contents/Developer/Library/PrivateFrameworks/SimulatorKit.framework; Xcode 27 moved that framework toContents/SharedFrameworks. - UI automation fragility (#408, #445) –
snapshot_uican return an empty hierarchy before the AX subsystem is ready, and element refs are dropped after a debugger-paused tap. - Security (#291) – build output, warnings, and dependency text are passed back to the LLM and can carry prompt-injection payloads from malicious dependencies.
- Environment configuration (#356) – sandboxed environments like Claude Cowork do not inherit
claude_desktop_settings.jsonconfiguration, and no alternate mechanism is exposed for setting environment variables per session.
These issues are useful context when reading the architecture: the manifest/catalog design is deliberately extensible, and many of the open requests correspond to adding a new tool field or a new predicate rather than a structural rewrite.
See Also
- Tooling and Workflows
- Configuration and Session Defaults
- Build, Test, and Simulator Workflows
- UI Automation and AXe Integration
- Security and Prompt Injection Considerations
- Troubleshooting and Known Issues
Source: https://github.com/getsentry/XcodeBuildMCP / Human Manual
Tool Catalog, Manifests & Workflows
Related topics: Project Overview & System Architecture, UI Automation, Debugging & Simulator Operations, Configuration, Session Management & Extensibility
Continue reading this section for the full explanation and source context.
Related Pages
Related topics: Project Overview & System Architecture, UI Automation, Debugging & Simulator Operations, Configuration, Session Management & Extensibility
Tool Catalog, Manifests & Workflows
Overview and Purpose
XcodeBuildMCP organizes its surface area around three coordinated concepts: tools (atomic actions such as build_sim or launch_app_sim), workflows (logical groupings such as simulator, device, logging, project-discovery), and manifests (YAML files that statically declare each tool's metadata, parameter schema, output schema, and visibility). The tool catalog is the in-memory structure that ties these together at runtime so that both the MCP server and the CLI can resolve, dispatch, and render the same set of capabilities consistently.
The catalog is shared across three runtimes: mcp, cli, and daemon. Each runtime filters the manifest independently based on predicates (platform availability, running-under-Xcode checks, explicit user config, and per-runtime exclusions) so that the same tool definition can be exposed differently to a host agent versus a shell user. Source: src/runtime/types.ts defines the RuntimeKind union and the central ToolDefinition shape; src/server/server.ts shows how the MCP server advertises a broad capability surface — sessions, project discovery, simulator/device workflows, signing, and more — to the host agent.
Manifest-Driven Architecture
Tools are not registered imperatively in TypeScript. Each tool ships with a YAML manifest under manifests/tools/ that describes its name, description, parameter schema, output schema, workflow membership, next-step templates, and any routing metadata. At startup, the catalog loader reads the manifest, dynamically imports the tool's TypeScript module through importToolModule, and synthesizes a ToolDefinition. The shared builder buildToolCatalogFromManifest accepts a RuntimeKind and a PredicateContext, then applies the predicates in src/visibility/exposure.ts — isWorkflowEnabledForRuntime, isToolAvailableForRuntime, and isToolExposedForRuntime — to filter what each runtime sees. Source: src/runtime/tool-catalog.ts.
The CLI applies an additional, runtime-level filter on top of the predicate layer. CLI_EXCLUDED_WORKFLOWS removes internal-only workflows (session-management, workflow-discovery) from the CLI surface so that end users are not exposed to plumbing they do not need. The CLI predicate context is pinned to runningUnderXcode: false and runtime: 'cli', which is what blocks the Xcode-only tools from the binary. Source: src/cli/commands/tools.ts.
The following diagram summarizes the build pipeline from a manifest on disk to a tool the agent can invoke:
flowchart LR YAML[manifests/tools/*.yaml] --> Loader[loadManifest] Loader --> Predicates[exposure predicates] Predicates -->|cli| CLI[buildCliToolCatalogFromManifest] Predicates -->|mcp| MCP[buildMcpToolCatalogFromManifest] Predicates -->|daemon| Daemon[buildDaemonToolCatalog] CLI --> Yargs[register-tool-commands.ts] MCP --> Server[McpServer registration] Daemon --> DaemonSock[Unix socket dispatcher] Yargs --> Dispatch[DefaultToolInvoker] Server --> Dispatch DaemonSock --> Dispatch
Tool Catalog Construction and Resolution
createToolCatalog is the in-memory index. It walks the resolved tool list once and builds four lookup maps keyed by cliName, mcpName (lowercased for case-insensitive lookup), id (the stable manifest id), and mcpKebab (the kebab-cased MCP form, which can map to multiple tools when disambiguation is required). A seenMcpNames set enforces deduplication so that a tool re-exported across multiple workflows does not produce ambiguous resolution. Source: src/runtime/tool-catalog.ts.
The ToolDefinition contract that flows through these maps is centralized in src/runtime/types.ts. The relevant fields are:
| Field | Purpose |
|---|---|
id | Stable manifest id for static YAML tools |
cliName | Kebab-case CLI command name (already disambiguated) |
mcpName | Original MCP tool name as declared |
workflow | Owning workflow directory (e.g., simulator, logging) |
cliSchema / mcpSchema | Separate ToolSchemaShape instances for yargs and MCP registration |
nextStepTemplates | Static suggested follow-up actions surfaced to the agent |
outputSchema | Reference into the structured-output schema registry |
annotations | MCP ToolAnnotations (read-only, destructive, idempotent, etc.) |
stateful | Driven by routing.stateful in the manifest |
handler | The actual tool implementation resolved at load time |
Source: src/runtime/types.ts.
For the CLI, the catalog builder is augmented with daemon plumbing. BuildCliToolCatalogOptions carries a socketPath, workspaceRoot, the set of cliExposedWorkflowIds, and an optional discoveryMode (none or quick). The CLI may route invocations through a background daemon process instead of executing handlers in-process, which lets multiple invocations share derived state. Source: src/cli/cli-tool-catalog.ts. The actual yargs registration, parameter coercion, session-default merging, and structured-output emission live in register-tool-commands.ts, which is what produces the xcodebuildmcp.output.* envelopes observed in the snapshot fixtures. Source: src/cli/register-tool-commands.ts.
Workflows and Runtime Visibility
Workflows are first-class entities in the manifest. Each workflow groups related tools, declares predicate-based availability, and may expose shared metadata such as a description or default enabled state. The CLI's tools command surfaces this grouping to users: --flat produces a single list, the default groups by workflow, --verbose adds full descriptions, and --json emits machine-readable output including a canonicalWorkflow field for tools that are re-exported from a non-owning workflow. The isToolCanonicalInWorkflow and getCanonicalWorkflow helpers determine ownership by inspecting the tool's module path of the form mcp/tools/<workflow>/<tool>. Source: src/cli/commands/tools.ts.
At runtime, the catalog is consulted by both surfaces. The MCP server, constructed in createBaseServerInstance, registers tools with McpServer and exposes them over StdioServerTransport, with Sentry-instrumented request lifecycles. Source: src/server/server.ts. The CLI registers the same set of tools as yargs commands, converts argv into typed tool parameters, merges session defaults, and emits the structured JSON envelopes used by the agent harness. Source: src/cli/register-tool-commands.ts. Build-time artifacts (the tsup-bundled output in build/) are produced by the build wireit pipeline declared in package.json, and the project itself is positioned by README.md as a Model Context Protocol server plus a companion CLI for Apple platform work.
A few community-driven behaviors hinge on this catalog. Issue #174 (custom build-sim timeout) and issue #447 (suppressWarnings not flowing through sessionDefaults) both surface as parameters on individual manifest entries, which means changes must flow through ToolSchemaShape rather than ad-hoc CLI flags. Issue #413 (strict mode) proposes a runtime-level toggle that would disable escape-hatch arguments and rely solely on session defaults — that would naturally be implemented as a predicate in exposure.ts that strips tools exposing such parameters, exactly the same hook the catalog already uses to vary per-runtime exposure.
See Also
- Server lifecycle and Sentry instrumentation: src/server/server.ts
- Tool catalog indexing and resolution: src/runtime/tool-catalog.ts
ToolDefinitionand runtime types: src/runtime/types.ts- CLI tool listing and grouping: src/cli/commands/tools.ts
- Yargs command registration and output envelopes: src/cli/register-tool-commands.ts
Source: https://github.com/getsentry/XcodeBuildMCP / Human Manual
UI Automation, Debugging & Simulator Operations
Related topics: Project Overview & System Architecture, Tool Catalog, Manifests & Workflows, Configuration, Session Management & Extensibility
Continue reading this section for the full explanation and source context.
Continue reading this section for the full explanation and source context.
Continue reading this section for the full explanation and source context.
Continue reading this section for the full explanation and source context.
Related Pages
Related topics: Project Overview & System Architecture, Tool Catalog, Manifests & Workflows, Configuration, Session Management & Extensibility
UI Automation, Debugging & Simulator Operations
Purpose and Scope
XcodeBuildMCP exposes a coordinated set of Model Context Protocol (MCP) tools and CLI commands that allow AI agents to drive the full iOS development loop on macOS: build, launch on a simulator, inspect the on-screen UI, interact with that UI, run XCTest suites, and call into the host Xcode IDE for documentation and debugging assistance. The surface area covered here spans three layers:
- UI Automation — querying the runtime accessibility hierarchy and dispatching taps, touches, gestures, swipes, text entry, and key presses against a booted simulator.
- Simulator / Device Operations — building schemes, running tests, resolving the built
.apppath, installing and launching on simulators, and analogous flows for tethered iOS devices. - Debugging Integration — invoking remote Xcode IDE tools (e.g.
DocumentationSearch) and reasoning about the AX (accessibility) and element-ref cache lifecycle that UI actions depend on.
Tool registration for both MCP and CLI runtimes is centralized in src/runtime/tool-catalog.ts, where each tool module exports a manifest entry that supplies the schema, handler, next-step templates, and runtime-specific predicate context. Source: src/runtime/tool-catalog.ts
UI Automation Tools
The ui-automation workflow is built around a snapshot-then-act pattern. An agent must first call snapshot_ui to capture the live accessibility tree of a simulator, then reference the returned elementRef identifiers in subsequent actions such as tap, touch, long_press, swipe, gesture, type_text, and key_press. A batch tool lets multiple same-screen actions be queued in one call.
Snapshot Cache Contract
All action results are emitted under the structured schema xcodebuildmcp.output.ui-action-result (version 2), which carries summary.status, action.type, artifacts.simulatorId, and an optional uiError block. When an action is requested without a current snapshot, the response fails with:
{
"didError": true,
"error": "No runtime UI snapshot is available for this simulator.",
"data": {
"uiError": {
"code": "SNAPSHOT_MISSING",
"recoveryHint": "Run snapshot_ui for this simulator, then retry with an elementRef from that snapshot."
}
}
}
Source: src/snapshot-tests/__fixtures__/cli/json/ui-automation/tap--error-no-simulator.json, src/snapshot-tests/__fixtures__/cli/json/ui-automation/type-text--error-no-simulator.json, src/snapshot-tests/__fixtures__/cli/json/ui-automation/touch--error-no-simulator.json, src/snapshot-tests/__fixtures__/cli/json/ui-automation/long-press--error-no-simulator.json
sequenceDiagram
participant Agent
participant snapshot_ui
participant Sim as iOS Simulator
participant tap
Agent->>snapshot_ui: snapshot_ui(simulatorId)
snapshot_ui->>Sim: read AX hierarchy via AXe
Sim-->>snapshot_ui: elements + refs
snapshot_ui-->>Agent: <REF>|tap|button|±|...|
Agent->>tap: tap(simulatorId, elementRef=<REF>)
tap->>Sim: validate ref against cached snapshot
Sim-->>tap: action result
tap-->>Agent: ui-action-result (SUCCEEDED)The snapshot cache is runtime-scoped to a simulator UDID. Because the cache is populated lazily, callers that attempt an action before any snapshot see SNAPSHOT_MISSING. The cache is also sensitive to AX readiness: when snapshot_ui returns the known empty-hierarchy shape on a freshly launched simulator, follow-up calls are currently expected to be re-issued by the agent (see issue #408, which requests polling AX readiness before giving up).
Snapshot Lifecycle Edge Cases
- Debugger-paused tap: Issue #445 reports that
ui-automation tap --element-refactions that trigger an LLDB breakpoint drop the runtime snapshot cache; a follow-up tap on the same screen fails with the sameSNAPSHOT_MISSINGsemantics until a freshsnapshot_uiis taken. - Xcode 27 framework relocation: Issue #446 reports that the bundled AXe binary fails to load
SimulatorKit.frameworkon Xcode 27 beta because Apple moved it toContents/SharedFrameworks. The fix path is expected in the UI automation layer that loads AXe. - Action grammar: Each action type carries its own required fields in
data.action— e.g.touchrequiresevent(touch down+up),type-textcarriestextLength,long-presscarriesdurationMs. Source: src/snapshot-tests/__fixtures__/cli/json/ui-automation/gesture--success.json, src/snapshot-tests/__fixtures__/cli/json/ui-automation/long-press--error-no-simulator.json
Simulator & Device Operations
The simulator and device workflows compose xcodebuild invocations with simulator lifecycle steps. They share a common output shape:
- A header listing scheme, workspace/configuration, platform, and target device or simulator UDID.
- A status banner (
✅ Build succeeded.,❌ Build failed.) with elapsed duration. - A
Filesblock surfacing the build log, result bundle (for tests), runtime log, and OSLog capture paths under~/Library/Developer/XcodeBuildMCP/workspaces/XcodeBuildMCP-<HASH>/.
Build, Test, and Build-and-Run
build_sim produces only a build, while build_run_sim chains build → resolve app path → boot simulator → install → launch, and captures an OSLog stream filtered by the bundle identifier. Source: src/snapshot-tests/__fixtures__/cli/text/simulator/build--success.txt, src/snapshot-tests/__fixtures__/cli/text/simulator/build-and-run--success.txt
test_sim (and test_device) emit per-test progress lines such as Running tests (9 completed, 1 failure, 0 skipped) and a final summary, then place an .xcresult bundle next to the build log. Selective testing surfaces the -only-testing: paths in the header. Source: src/snapshot-tests/__fixtures__/cli/text/simulator/test--success.txt, src/snapshot-tests/__fixtures__/cli/text/device/test--success.txt, src/snapshot-tests/__fixtures__/cli/text/simulator/test--failure.txt
Compiler Diagnostics in Output
When the build fails on a Swift compile error, the banner still reports ❌ Build failed. followed by a structured Compiler Errors (N) block with file:line:column references, rather than dumping the full raw xcodebuild log. This is part of the same output filtering story as suppressWarnings, which is currently broken (see issue #447). Source: src/snapshot-tests/__fixtures__/cli/text/simulator/build--error-compiler.txt, src/snapshot-tests/__fixtures__/cli/text/simulator/build-and-run--error-compiler.txt
Known Community Pain Points
| Concern | Issue | Impact |
|---|---|---|
| Custom build timeout | #174 | Stalled xcodebuild runs cannot be killed by the agent |
Output verbosity (build_sim_id_ws) | #68 | Single invocation blows LLM context |
suppressWarnings not respected | #447 | Legacy project warnings still flood responses |
| Truncated test output | #177 | Full xcodebuild log never reaches the agent |
| Configurable OSLog subsystem filter | #409 | build_run_sim / launch_app_sim use a fixed subsystem == "<bundleId>" predicate |
| Concurrent simulator reuse | #414 | No automatic clone when multiple workspaces race for the same simulator |
| Strict mode for build settings | #413 | No way to disable escape-hatch extraArgs |
| Prompt injection via build output | #291 | Malicious dependency strings reach the agent verbatim |
Debugging Integration
Beyond simulator-side automation, XcodeBuildMCP bridges to the host Xcode IDE through the xcode-ide workflow. The call_tool tool dispatches a named remote tool (e.g. DocumentationSearch) and writes the raw response JSON to an artifact under ~/Library/Developer/XcodeBuildMCP/workspaces/XcodeBuildMCP-<HASH>/state/xcode-ide/call-tool/. Source: src/snapshot-tests/__fixtures__/cli/text/xcode-ide/documentation-search--success.txt
The xcode-ide surface is what allows agents to ask Xcode for symbol lookups and documentation context without leaving the MCP loop, complementing the per-tool next-step suggestions that the catalog emits from toolManifest.nextSteps (src/runtime/tool-catalog.ts).
See Also
- Tool Catalog & Manifest System — how UI automation and simulator tools are registered for MCP and CLI runtimes
- Session Defaults & Configuration — covers
suppressWarnings, strict mode (#413), and Claude Cowork config (#356) - Build Output & Diagnostics — filtering rules,
Compiler Errorsextraction, and the OSLog subsystem filter limitation (#409) - Homebrew & npm Installation —
brew tap getsentry/xcodebuildmcpandbrew install xcodebuildmcpper Release v2.6.2
Source: https://github.com/getsentry/XcodeBuildMCP / Human Manual
Configuration, Session Management & Extensibility
Related topics: Project Overview & System Architecture, Tool Catalog, Manifests & Workflows, UI Automation, Debugging & Simulator Operations
Continue reading this section for the full explanation and source context.
Related Pages
Related topics: Project Overview & System Architecture, Tool Catalog, Manifests & Workflows, UI Automation, Debugging & Simulator Operations
Configuration, Session Management & Extensibility
XcodeBuildMCP exposes Apple-platform tooling (Xcode builds, simulator control, UI automation, Swift package workflows) to AI agents via the Model Context Protocol (MCP) and a companion CLI. The configuration, session, and extensibility layers sit between the AI client and the underlying tool implementations: they decide *which* tools are visible, *what defaults* the user has set, and *how* a single request flows from invocation to handler. The README frames XcodeBuildMCP as a way to "prefer XcodeBuildMCP tools over shell commands for Apple platform tasks," and session defaults are the mechanism that makes that preference practical by avoiding repetitive parameters on every call (Source: src/server/server.ts:25-30).
Project Configuration & Setup
Project-level configuration lives in a per-workspace YAML file at .xcodebuildmcp/config.yaml. The file is created and edited by the interactive xcodebuildmcp setup wizard (Source: src/cli/commands/setup.ts:1-30). The wizard walks the user through target platforms, workflows, a project/workspace, scheme selection, and simulator/device defaults required by the enabled workflows, then writes the result to disk. Running the wizard is idempotent: previous choices are pre-loaded, and a re-run can be used to revise the configuration.
The same wizard supports an MCP-config emission mode that prints a ready-to-paste JSON block for clients such as Windsurf (mcp_config.json), VS Code (.vscode/mcp.json), or Claude Desktop (claude_desktop_config.json) (Source: src/cli/commands/setup.ts:35-50). Reference configs are shipped under example_projects/ for iOS, macOS, Swift Package, and iOS Calculator projects, giving users a concrete starting point for typical targets (Source: example_projects/iOS/.xcodebuildmcp/config.yaml).
At server boot, bootstrapServer accepts a BootstrapOptions object that carries enabledWorkflows, configOverrides, an optional filesystem executor, and a working directory. Runtime overrides are applied on top of the on-disk config so that MCP clients and tests can pin specific defaults without touching the user's file (Source: src/server/bootstrap.ts:18-40).
Session Defaults & Per-Invocation Overrides
Session defaults are the values the agent is allowed to omit when calling a tool — project path, scheme, simulator UDID, device, derived-data location, and so on. They are resolved during runtime bootstrap and are exposed to the rest of the system through a hydration result that's logged at startup (Source: src/runtime/bootstrap-runtime.ts:1-25).
Two CLI escape hatches let a user override defaults for a single invocation without editing the project config:
--profile <name>selects a named defaults profile for that one command only (Source: src/cli/register-tool-commands.ts:50-60).--json '<object>'passes a JSON object of tool arguments, useful for complex payloads likeextraArgsarrays that don't map cleanly to yargs flags (Source: src/cli/register-tool-commands.ts:62-72).
A --profile-style mechanism on the MCP side corresponds to session defaults set by the AI client; community issue #413 ("Strict mode") requests a configuration switch that disables these escape hatches so an agent can only use session defaults and cannot change build settings ad hoc. Related concerns surface in #447, where suppressWarnings in session defaults reportedly does not filter compiler warnings from MCP/CLI responses, and in #356, where Claude Cowork sessions cannot inherit claude_desktop_settings.json env variables — both touch the same defaults-hydration path described in bootstrap-runtime.ts.
Manifest-Driven Tool Extensibility
Tools are not hard-coded; they are loaded from a manifest. buildToolCatalogFromManifest walks manifest.workflows, filters by runtime predicate context, and resolves each entry to a ToolDefinition with CLI and MCP schemas, an outputSchema, and a list of nextStepTemplates (Source: src/runtime/tool-catalog.ts:1-40). Three runtime kinds share the same manifest but apply different predicates:
| Runtime | Constant | Predicate context | Purpose |
|---|---|---|---|
| CLI | 'cli' | runningUnderXcode: false | Local command-line use; never sees Xcode-bridge tools |
| Daemon | 'daemon' | Server-side | Long-lived background process serving CLI clients |
| MCP | 'mcp' | runningUnderXcode: true/false | The stdio MCP server, possibly launched from inside Xcode |
Source: src/runtime/types.ts:1-20 and src/cli/commands/tools.ts:60-75 define and consume this RuntimeKind. The CLI list command filters workflows through CLI_EXCLUDED_WORKFLOWS and an isWorkflowEnabledForRuntime predicate, so a single manifest powers three different surfaces (Source: src/cli/commands/tools.ts:80-95).
The MCP path also adds an Xcode IDE tool bridge: XcodeIdeToolService and a registry that turns Apple documentation/SwiftUI tool schemas into Zod-backed tool definitions via jsonSchemaToZod, making them first-class tools in the catalog when the daemon or MCP process is running under Xcode (Source: src/cli/cli-tool-catalog.ts:1-35). Catalog resolution deduplicates by lowercase MCP name so the same tool exposed by multiple workflows resolves to a single entry, avoiding ambiguity in tool lookup (Source: src/runtime/tool-catalog.ts:60-80).
Runtime Lifecycle & Bootstrap
Server creation is centralized in createBaseServerInstance, which builds an McpServer named xcodebuildmcp, pins its version from src/version.ts, and attaches a multi-paragraph instructions string that summarizes capabilities to the AI client (Source: src/server/server.ts:25-45). Lifecycle management wires the SDK's StdioServerTransport, registers SetLevelRequestSchema for client-driven log-level changes, and instruments every MCP request through instrumentMcpRequestLifecycle so that latency and errors are observable via Sentry (Source: src/server/server.ts:55-70).
A deferred-initialization handle is returned by bootstrapServer, allowing heavy work (manifest loading, workspace sweeps) to happen after the server is connected. runStartupFilesystemLifecycleSweep clears stale workspaces and logs how many were stopped or deleted — important because simulators and derived-data directories are per-workspace and can leak across runs if not pruned (Source: src/server/bootstrap.ts:25-45).
flowchart LR
A[Agent / CLI invocation] --> B[xcodebuildmcp entrypoint]
B --> C[bootstrap-runtime<br/>load .xcodebuildmcp/config.yaml]
C --> D[Hydrate session defaults]
D --> E[buildToolCatalogFromManifest]
E --> F{Predicate filter}
F -->|mcp| G[McpServer + Stdio transport]
F -->|cli| H[yargs command tree]
F -->|daemon| I[Background daemon + DaemonClient]
G --> J[Tool handler]
H --> J
I --> J
J --> K[StructuredToolOutput + nextSteps]Operational extras round out the layer: xcodebuildmcp doctor (npm run doctor in package.json) validates the environment, xcodebuildmcp upgrade follows GitHub releases rather than package-manager metadata (Release v2.6.2), and snapshot fixtures under src/snapshot-tests/__fixtures__/cli/text/ and …/json/ lock the formatted output that agents see (Source: src/snapshot-tests/__fixtures__/cli/text/simulator/build--success.txt). Together, the manifest system, session defaults, and runtime lifecycle make XcodeBuildMCP extensible: adding a workflow means adding a manifest entry plus a handler, not editing a central registry.
See Also
- README.md — installation, MCP client configuration, and high-level capabilities
- config.example.yaml — annotated reference for
.xcodebuildmcp/config.yaml - src/runtime/types.ts —
ToolDefinition,NextStepTemplate, andRuntimeKinddefinitions - src/cli/commands/setup.ts — the interactive setup wizard
- Issue #413 "Strict mode", #447 "suppressWarnings doesn't work", #356 "Compatibility with Claude Cowork" — open configuration-pain points
Source: https://github.com/getsentry/XcodeBuildMCP / Human Manual
Doramagic Pitfall Log
Source-linked risks stay visible on the manual page so the preview does not read like a recommendation.
May increase setup, validation, or first-run risk for the user.
May increase setup, validation, or first-run risk for the user.
May increase setup, validation, or first-run risk for the user.
May increase setup, validation, or first-run risk for the user.
Doramagic Pitfall Log
Found 23 structured pitfall item(s), including 2 high/blocking item(s). Top priority: Installation risk - Installation risk requires verification.
1. Installation risk: Installation risk requires verification
- Severity: high
- Finding: Project evidence flags a installation risk. Review the linked source before relying on this workflow.
- User impact: May increase setup, validation, or first-run risk for the user.
- Recommended check: Reproduce the official install and quickstart path in an isolated environment.
- Evidence: community_evidence:github | https://github.com/getsentry/XcodeBuildMCP/issues/414
2. Installation risk: Installation risk requires verification
- Severity: high
- Finding: Project evidence flags a installation risk. Review the linked source before relying on this workflow.
- User impact: May increase setup, validation, or first-run risk for the user.
- Recommended check: Reproduce the official install and quickstart path in an isolated environment.
- Evidence: community_evidence:github | https://github.com/getsentry/XcodeBuildMCP/issues/413
3. Installation risk: Installation risk requires verification
- Severity: medium
- Finding: Project evidence flags a installation risk. Review the linked source before relying on this workflow.
- User impact: May increase setup, validation, or first-run risk for the user.
- Recommended check: Reproduce the official install and quickstart path in an isolated environment.
- Evidence: community_evidence:github | https://github.com/getsentry/XcodeBuildMCP/issues/408
4. Installation risk: Installation risk requires verification
- Severity: medium
- Finding: Project evidence flags a installation risk. Review the linked source before relying on this workflow.
- User impact: May increase setup, validation, or first-run risk for the user.
- Recommended check: Reproduce the official install and quickstart path in an isolated environment.
- Evidence: community_evidence:github | https://github.com/getsentry/XcodeBuildMCP/issues/368
5. Installation risk: Installation risk requires verification
- Severity: medium
- Finding: Project evidence flags a installation risk. Review the linked source before relying on this workflow.
- User impact: May increase setup, validation, or first-run risk for the user.
- Recommended check: Reproduce the official install and quickstart path in an isolated environment.
- Evidence: community_evidence:github | https://github.com/getsentry/XcodeBuildMCP/issues/369
6. Installation risk: Installation risk requires verification
- Severity: medium
- Finding: Project evidence flags a installation risk. Review the linked source before relying on this workflow.
- User impact: May increase setup, validation, or first-run risk for the user.
- Recommended check: Reproduce the official install and quickstart path in an isolated environment.
- Evidence: community_evidence:github | https://github.com/getsentry/XcodeBuildMCP/issues/436
7. Installation risk: Installation risk requires verification
- Severity: medium
- Finding: Project evidence flags a installation risk. Review the linked source before relying on this workflow.
- User impact: May increase setup, validation, or first-run risk for the user.
- Recommended check: Reproduce the official install and quickstart path in an isolated environment.
- Evidence: community_evidence:github | https://github.com/getsentry/XcodeBuildMCP/issues/177
8. Installation risk: Installation risk requires verification
- Severity: medium
- Finding: Project evidence flags a installation risk. Review the linked source before relying on this workflow.
- User impact: May increase setup, validation, or first-run risk for the user.
- Recommended check: Reproduce the official install and quickstart path in an isolated environment.
- Evidence: community_evidence:github | https://github.com/getsentry/XcodeBuildMCP/issues/447
9. Installation risk: Installation risk requires verification
- Severity: medium
- Finding: Project evidence flags a installation risk. Review the linked source before relying on this workflow.
- User impact: May increase setup, validation, or first-run risk for the user.
- Recommended check: Reproduce the official install and quickstart path in an isolated environment.
- Evidence: community_evidence:github | https://github.com/getsentry/XcodeBuildMCP/issues/445
10. Installation risk: Installation risk requires verification
- Severity: medium
- Finding: Project evidence flags a installation risk. Review the linked source before relying on this workflow.
- User impact: May increase setup, validation, or first-run risk for the user.
- Recommended check: Reproduce the official install and quickstart path in an isolated environment.
- Evidence: community_evidence:github | https://github.com/getsentry/XcodeBuildMCP/issues/356
11. Configuration risk: Configuration risk requires verification
- Severity: medium
- Finding: Project evidence flags a configuration risk. Review the linked source before relying on this workflow.
- User impact: May increase setup, validation, or first-run risk for the user.
- Recommended check: Reproduce the official install and quickstart path in an isolated environment.
- Evidence: capability.host_targets | https://github.com/getsentry/XcodeBuildMCP
12. Capability evidence risk: Capability evidence risk requires verification
- Severity: medium
- Finding: README/documentation is current enough for a first validation pass.
- User impact: May increase setup, validation, or first-run risk for the user.
- Recommended check: Reproduce the official install and quickstart path in an isolated environment.
- Evidence: capability.assumptions | https://github.com/getsentry/XcodeBuildMCP
Source: Doramagic discovery, validation, and Project Pack records
Community Discussion Evidence
These external discussion links are review inputs, not standalone proof that the project is production-ready.
Count of project-level external discussion links exposed on this manual page.
Open the linked issues or discussions before treating the pack as ready for your environment.
Community Discussion Evidence
Doramagic exposes project-level community discussion separately from official documentation. Review these links before using XcodeBuildMCP with real data or production workflows.
- Restore configurable simulator OSLog subsystem filters - github / github_issue
- Poll AX readiness when snapshot_ui returns an empty hierarchy - github / github_issue
- Warden weekly sweep - github / github_issue
- Clone simulators - github / github_issue
- Strict mode - github / github_issue
- [[Bug]: suppressWarnings doesn't work](https://github.com/getsentry/XcodeBuildMCP/issues/447) - github / github_issue
- [[Bug]: Bundled AXe fails with Xcode 27 because SimulatorKit.framework mo](https://github.com/getsentry/XcodeBuildMCP/issues/446) - github / github_issue
- [[Bug]: ui-automation element refs become unavailable after debugger-paus](https://github.com/getsentry/XcodeBuildMCP/issues/445) - github / github_issue
- Security Advisory: Prompt Injection Risk via Build Output and Dependency - github / github_issue
- [[Feature]: build-sim custom timeout](https://github.com/getsentry/XcodeBuildMCP/issues/174) - github / github_issue
- [[Bug]: Never gives Claude the full output](https://github.com/getsentry/XcodeBuildMCP/issues/177) - github / github_issue
- [[Feature]: Compatibility with Claude Cowork](https://github.com/getsentry/XcodeBuildMCP/issues/356) - github / github_issue
Source: Project Pack community evidence and pitfall evidence