Skip to content

Apple Development with Claude

The complete code → build → run → see → iterate workflow for iOS, macOS, watchOS, and tvOS. Claude in Xcode handles code editing and building. XcodeBuildMCP adds the simulator run loop and visual feedback so Claude can see and fix what it ships.

When to use

When building Apple platform apps with Claude as a co-developer — from initial feature to production polish.

The pattern

Prerequisites

  • macOS with Xcode 26+ and simulators installed
  • Claude Pro, Max, or Team/Enterprise plan (for Claude in Xcode)
  • Node.js v18+ (for XcodeBuildMCP)
  • Claude Code CLI installed

Part 1: Claude in Xcode — code editing and building

Claude in Xcode embeds Claude directly into Xcode 26's coding agent. Claude can read and modify Swift source files, generate new files, build the project and fix compiler errors, look up Apple documentation, and generate SwiftUI previews — all without leaving Xcode.

Set up: Xcode → Settings → Intelligence → Sign in to Claude. Requires Xcode 26 and a Claude Pro, Max, or premium Team/Enterprise seat.

Once logged in, open the Coding Assistant panel and describe what you want. Claude will plan the work, create files, build, fix errors, and deliver a buildable implementation. You stay in Xcode reviewing and testing; Claude handles the implementation detail.

What Claude in Xcode does not do: It cannot run the app, take screenshots, or automate UI gestures. The "build succeeds" step is as far as it goes on its own. XcodeBuildMCP closes that gap.

Part 2: XcodeBuildMCP — run, see, and interact

XcodeBuildMCP (maintained by Sentry, MIT licensed) gives Claude the ability to launch the simulator, screenshot what's running, traverse the accessibility tree, and send taps, swipes, and keystrokes. This is what lets Claude verify its own work visually and iterate without human intervention.

Register the MCP server:

sh
claude mcp add \
  --transport stdio XcodeBuildMCP \
  npx -y xcodebuildmcp@latest mcp

Restart Claude Code after adding. Verify with claude mcp list — look for XcodeBuildMCP connected.

Create .xcodebuildmcp/config.yaml in the project root so Claude knows the scheme and simulator without being told each time:

yaml
schemaVersion: 1
enabledWorkflows:
  - simulator
  - ui-automation
sessionDefaults:
  scheme: MyApp
  projectPath: ./MyApp.xcodeproj
  simulatorName: iPhone 16

Enable only what you need to keep context usage low:

  • simulator — Build, run, test, screenshot
  • ui-automation — Tap, swipe, type, describe UI elements
  • debugging — LLDB attach, breakpoints, variable inspection
  • device — Build and deploy to physical devices over USB or Wi-Fi

For most development, simulator and ui-automation cover all needs.

Wiring XcodeBuildMCP into Xcode's coding agent: XcodeBuildMCP can also extend Claude in Xcode with the same run/screenshot/interact tools. Create a launcher script (needed because Xcode's agent has a restricted PATH):

sh
# ~/bin/xcodebuildmcp-run.sh
#!/bin/zsh
export PATH=/opt/homebrew/bin:/usr/local/bin:$PATH
export NVM_DIR="$HOME/.nvm"
[ -s "$NVM_DIR/nvm.sh" ] && . "$NVM_DIR/nvm.sh"
nvm use --silent >/dev/null 2>&1 || true
exec npx -y xcodebuildmcp@latest mcp

Make it executable: chmod +x ~/bin/xcodebuildmcp-run.sh

Then register it in ~/Library/Developer/Xcode/CodingAssistant/ClaudeAgentConfig/.claude.json:

json
{
  "mcpServers": {
    "XcodeBuildMCP": {
      "command": "/Users/you/bin/xcodebuildmcp-run.sh"
    }
  }
}

Part 3: The complete loop

With both tools in place, the workflow is:

1. Write. Claude edits Swift files in response to your description or a plan it generates. Claude in Xcode does this natively inside the IDE; Claude Code CLI does it from the terminal.

2. Build. simulator/build-and-run compiles and launches the app in the simulator. Compiler errors appear directly in the tool response — Claude can fix them and rebuild immediately.

3. See. simulator/screenshot captures the running UI. Claude sees the image and assesses layout, spacing, color, and content.

4. Inspect. ui-automation/describe-all returns the full accessibility tree — element types, labels, and positions. More reliable than coordinates guessed from a screenshot.

5. Interact. For multi-step flows, UI automation simulates real input: ui-automation/tap, ui-automation/type, ui-automation/swipe. Claude can walk a complete user flow, screenshotting at each step.

6. Fix and repeat. Claude modifies the code based on what it saw and loops back to step 2. The cycle continues until the feature works correctly.

Example prompt

Build and run MyApp on iPhone 16. Take a screenshot. Navigate to the Settings tab, toggle the dark mode switch, and take another screenshot. Then switch to iPad Pro 13-inch and screenshot the same screens so I can compare the layouts.

Testing across platforms

Change simulatorName in .xcodebuildmcp/config.yaml to test on different targets: iPhone 16, iPad Pro 13-inch (M4), Apple Watch Series 10 - 46mm. For macOS, build natively without a simulator. SwiftUI layout adapts automatically, but screenshot each platform target to catch sidebar behavior on iPad, navigation differences, and form factor edge cases.

Handling compiler errors

Swift's type checker is strict. Complex SwiftUI view bodies can trigger "expression too complex" errors. When that happens:

  • Break large view bodies into smaller extracted sub-views
  • Add explicit type annotations on intermediate values
  • Move complex logic into computed properties or helper methods

Claude is generally good at reading Swift errors and iterating — feed the full error output back and let it resolve.

Trade-offs

  • Claude in Xcode requires Xcode 26 and a Claude Pro/Max plan. Projects on older Xcode can use Claude Code CLI + XcodeBuildMCP alone (same loop, no IDE integration)
  • Claude in Xcode builds but does not run or screenshot — XcodeBuildMCP is still needed for the visual feedback step
  • XcodeBuildMCP requires Node.js alongside Xcode; the two tools are independent installs
  • UI automation uses coordinates — always run describe-all first to find current element positions rather than hardcoding them
  • Screenshots come from the simulator, not a physical device; use the device workflow for on-device validation