Published
Setup Claude Code with hierarchical CLAUDE.md files, `xcodebuildmcp` integration, slash commands etc. All in one prompt.
Support & Share
Tip with Lightning, or share to Nostr. Uses the relays wss://relay.damus.io, wss://relay.snort.social.
Omnoster
Connecting…
NIP-07 signer not detected. Please enable your Nostr extension to share.
IMPORTANT: This comprehensive setup will transform any iOS project into a fully automated, context-aware, self-maintaining Claude Code environment. This prompt is designed specifically for Claude Code (claude.ai/code) users.
Before starting, verify these tools are installed:
# Check Xcodexcodebuild -version || echo "ERROR: Xcode not found - install from App Store"
# Check Node.js (required for XcodeBuildMCP)node --version || echo "ERROR: Node.js not found - install from nodejs.org or 'brew install node'"
# Check npmnpm --version || echo "ERROR: npm not found - comes with Node.js"
# Check Gitgit --version || echo "ERROR: Git not found"
# Check if we're in a git repositorygit status || echo "WARNING: Not a git repository - some features won't work"If any tools are missing, document them and provide installation instructions before proceeding.
# Claude Code always runs from the project rootPROJECT_ROOT=$(pwd)echo "Project root: $PROJECT_ROOT"
# Claude Code MCP configuration locationMCP_CONFIG_PATH="$HOME/Library/Application Support/Claude/claude_desktop_config.json"if [ -f "$MCP_CONFIG_PATH" ]; then echo "Claude Desktop config found"else echo "NOTE: Will need to configure MCP manually in Claude Code settings"fiBefore creating anything, perform exhaustive project discovery:
# Find Xcode project filesfind . -name "*.xcodeproj" -o -name "*.xcworkspace" | head -5
# Detect Swift versionif [ -f "Package.swift" ]; then grep "swift-tools-version" Package.swiftfi
# Check for project configurationif ls *.xcodeproj >/dev/null 2>&1; then PROJECT_FILE=$(ls *.xcodeproj | head -1) echo "Found project: $PROJECT_FILE" # Extract key information xcodebuild -list -project "$PROJECT_FILE" 2>/dev/null || truefi
# Detect minimum iOS version from Info.plist or project settingsfind . -name "Info.plist" -exec grep -A1 "MinimumOSVersion" {} \; 2>/dev/null || true# Check for build configuration filesls -la | grep -E "project.yml|project.yaml|Tuist|Package.swift"
# List available schemesif [ -n "$PROJECT_FILE" ]; then xcodebuild -list -project "$PROJECT_FILE" | grep -A20 "Schemes:" || truefi
# Check for dependency managers[ -f "Podfile" ] && echo "Found CocoaPods"[ -f "Cartfile" ] && echo "Found Carthage"[ -f "Package.swift" ] && echo "Found Swift Package Manager"# Find all Swift packagesfind . -name "Package.swift" -not -path "*/.*" | while read pkg; do echo "Package found: $pkg" dirname "$pkg"done
# Find test targetsfind . -name "*Tests" -type d -not -path "*/.*" | head -10# Detect test frameworkgrep -r "@testable import\|import XCTest\|import Testing" --include="*.swift" . | head -5 || true
# Find UI test targetsfind . -name "*UITests" -type d -not -path "*/.*"# Find app extensionsfind . -name "*.appex" -o -name "*Widget*" -o -name "*Extension*" -type d | grep -v ".build" | head -10# Check for linting/formatting tools[ -f ".swiftlint.yml" ] && echo "SwiftLint configured"[ -f ".swiftformat" ] && echo "SwiftFormat configured"# Check for existing build scripts[ -f "Makefile" ] && echo "Makefile found"[ -f "Rakefile" ] && echo "Rakefile found"[ -f "build.sh" ] && echo "Build script found"ls scripts/*.sh 2>/dev/null | head -5Document ALL findings before proceeding. This analysis drives everything that follows.
# Create the Claude configuration directory structuremkdir -p .claude/commandsmkdir -p .claude/hooks mkdir -p .claude/scriptsmkdir -p .claude/imports
# Confirm structuretree .claude || ls -la .claude/Create the main CLAUDE.md at project root. This file will be customized based on your Phase 1 analysis:
# CLAUDE.md
This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
**⚠️ IMPORTANT**: Keep this documentation updated! Run `/update-docs` after significant changes.**Last Updated**: [CURRENT_DATE]
## 📋 Documentation Maintenance
- **When to Update**: After adding features, changing architecture, or modifying workflows- **Update Command**: Use `/update-docs` to refresh all CLAUDE.md files- **Optimize Setup**: Use `/claude-optimize` to analyze and improve configuration- **Review Schedule**: Check documentation accuracy weekly
## Quick Reference
**Project**: [PROJECT_NAME - from analysis]**Language**: Swift [VERSION - from analysis]**Platform**: [iOS/macOS/etc - from analysis]**Architecture**: [Detected pattern - SwiftUI/UIKit/etc]**Key Command**: Build and test via MCP tools
## 🔧 XcodeBuildMCP Integration
**IMPORTANT**: This project uses XcodeBuildMCP for all Xcode operations. The MCP server is automatically available in Claude Code.
### Why XcodeBuildMCP?- Provides intelligent, context-aware Xcode operations- Automatically handles simulator management- Simplifies device deployment- Offers better error handling than raw xcodebuild
### Common MCP Operations```swift// Buildingmcp__xcodebuildmcp__build_sim_name_proj // Build for simulatormcp__xcodebuildmcp__build_dev_proj // Build for device
// Testingmcp__xcodebuildmcp__test_sim_name_proj // Test on simulatormcp__xcodebuildmcp__swift_package_test // Test Swift packages
// Runningmcp__xcodebuildmcp__build_run_sim_name_proj // Build and run on simulatormcp__xcodebuildmcp__launch_app_sim // Launch existing app
// Utilitiesmcp__xcodebuildmcp__clean_proj // Clean build artifactsmcp__xcodebuildmcp__list_sims // List available simulatorsmcp__xcodebuildmcp__screenshot // Take simulator screenshot[This will be filled in based on Phase 1 analysis]
/build - Smart build based on context/test - Run appropriate tests/run - Build and run the app/clean - Clean build artifacts/test-all - Run all tests (app + packages)/test-single [TestName] - Run specific test/device-build - Build and deploy to connected device/device-list - Show connected devices/update-docs - Update all documentation/claude-optimize - Analyze and optimize setup[Document project-specific patterns discovered in Phase 1]
/build to verify project builds/test to ensure tests pass/run to launch in simulator/test-all/update-docs and /claude-optimize
### 2.3 Create Context Detection System
Create `.claude/scripts/detect-context.sh`. This script will be customized based on your project structure:
```bash#!/bin/bash# Context detection for Claude Code XcodeBuildMCP integration# This script analyzes the current context and sets appropriate defaults
# Get absolute project root (Claude Code always runs from project root)PROJECT_ROOT="$(cd "$(dirname "$0")/../.." && pwd)"CURRENT_DIR=$(pwd)
# Function to find project filefind_project_file() { # Look for xcworkspace first (takes precedence) local workspace=$(find "$PROJECT_ROOT" -name "*.xcworkspace" -maxdepth 2 | grep -v xcodeproj | head -1) if [ -n "$workspace" ]; then echo "$workspace" return fi # Fall back to xcodeproj local project=$(find "$PROJECT_ROOT" -name "*.xcodeproj" -maxdepth 2 | head -1) if [ -n "$project" ]; then echo "$project" return fi}
# Function to detect default schemedetect_default_scheme() { local project_file="$1" if [ -n "$project_file" ]; then # Try to extract the main scheme xcodebuild -list -project "$project_file" 2>/dev/null | \ grep -A10 "Schemes:" | \ grep -v "Schemes:" | \ head -1 | \ xargs fi}
# Function to find newest simulatorfind_newest_simulator() { xcrun simctl list devices available | \ grep "iPhone" | \ grep -v "unavailable" | \ tail -1 | \ sed 's/.*(\(.*\)).*/\1/'}
# Detect project configurationPROJECT_FILE=$(find_project_file)DEFAULT_SCHEME=$(detect_default_scheme "$PROJECT_FILE")DEFAULT_SIMULATOR=$(find_newest_simulator)
# Export for MCP toolsexport XCODEBUILDMCP_PROJECT_ROOT="$PROJECT_ROOT"export XCODEBUILDMCP_DEFAULT_PROJECT="$PROJECT_FILE"export XCODEBUILDMCP_DEFAULT_SCHEME="${DEFAULT_SCHEME:-YourApp}"export XCODEBUILDMCP_DEFAULT_SIMULATOR="${DEFAULT_SIMULATOR:-iPhone 15}"
# Detect if we're in a package directoryif [ -f "Package.swift" ]; then export XCODEBUILDMCP_CONTEXT="package" export XCODEBUILDMCP_PACKAGE_PATH="$CURRENT_DIR"elif [[ "$CURRENT_DIR" == *"Tests"* ]]; then export XCODEBUILDMCP_CONTEXT="tests"elif [[ "$CURRENT_DIR" == *"UITests"* ]]; then export XCODEBUILDMCP_CONTEXT="uitests"else export XCODEBUILDMCP_CONTEXT="app"fi
# Check for booted simulatorBOOTED_SIM=$(xcrun simctl list devices | grep "Booted" | head -1 | awk -F'[()]' '{print $2}')if [ -n "$BOOTED_SIM" ]; then export XCODEBUILDMCP_BOOTED_SIMULATOR="$BOOTED_SIM"fi
# Check for connected physical devicesif xcrun devicectl list devices 2>/dev/null | grep -q "iPhone\|iPad"; then export XCODEBUILDMCP_HAS_DEVICE="true"fi
# Output context (useful for debugging)if [ "${DEBUG_CONTEXT}" = "true" ]; then echo "Context Detection Results:" echo " Project: $PROJECT_FILE" echo " Scheme: $DEFAULT_SCHEME" echo " Simulator: $DEFAULT_SIMULATOR" echo " Context: $XCODEBUILDMCP_CONTEXT" echo " Has Device: ${XCODEBUILDMCP_HAS_DEVICE:-false}"fiMake it executable: chmod +x .claude/scripts/detect-context.sh
Claude Code comes with XcodeBuildMCP pre-configured, but you can optimize it for your specific project. The MCP tools are available immediately without additional setup.
Test that MCP tools are available:
# This should return diagnostic informationmcp__xcodebuildmcp__diagnostic
# List available simulatorsmcp__xcodebuildmcp__list_sims
# If these don't work, MCP may need to be enabled in settingsCreate .claude/imports/mcp-best-practices.md:
# XcodeBuildMCP Best Practices
## Always Use MCP ToolsNever use raw xcodebuild commands. Always use the appropriate MCP tool:- Building: `mcp__xcodebuildmcp__build_sim_name_proj`- Testing: `mcp__xcodebuildmcp__test_sim_name_proj`- Running: `mcp__xcodebuildmcp__build_run_sim_name_proj`- Package operations: `mcp__xcodebuildmcp__swift_package_*`
## Context-Aware Tool SelectionThe context detection script automatically determines which tools to use based on your current directory.
## Common Patterns[Document patterns specific to this project]Create these essential slash commands in .claude/commands/:
.claude/commands/build.md:
---description: Build the project intelligently---
# Build the project based on context
First, I'll detect what needs to be built based on the current directory and project structure.
Then I'll use the appropriate MCP tool:- For the main app: `mcp__xcodebuildmcp__build_sim_name_proj`- For packages: `mcp__xcodebuildmcp__swift_package_build`- For specific schemes: Build with the detected scheme
The build will use your project's default simulator and configuration..claude/commands/test.md:
---description: Run all relevant tests---
# Run tests based on context
I'll run the appropriate tests for your current location:- App tests: `mcp__xcodebuildmcp__test_sim_name_proj`- Package tests: `mcp__xcodebuildmcp__swift_package_test`- UI tests if available
Tests will run on the default simulator with proper configuration.
$ARGUMENTS.claude/commands/run.md:
---description: Build and run the app---
# Build and run in simulator
I'll build and launch your app using:`mcp__xcodebuildmcp__build_run_sim_name_proj`
This will:1. Build the latest code2. Install on simulator3. Launch the app4. Show you the simulator
$ARGUMENTS.claude/commands/test-all.md:
---description: Run ALL tests (app + packages)---
# Complete test suite
I'll run your entire test suite:1. App unit tests2. Package tests3. UI tests (if present)
This ensures everything works before committing..claude/commands/test-single.md:
---description: Run a specific test---
# Run specific test
Usage: `/test-single TestClassName` or `/test-single TestClassName/testMethod`
I'll find and run just the test you specify using the appropriate MCP tool with filtering.
$ARGUMENTS.claude/commands/device-list.md:
---description: Show connected devices---
# List physical devices
I'll show all connected iOS devices using:`mcp__xcodebuildmcp__list_devices`
This will display device names, UUIDs, and connection status..claude/commands/device-build.md:
---description: Deploy to physical device---
# Deploy to device
I'll deploy your app to a connected device:1. List available devices2. Build for device architecture3. Install the app4. Launch on device
Requires a device to be connected via USB or WiFi.
$ARGUMENTS.claude/commands/clean.md:
---description: Clean build artifacts---
# Clean build folder
I'll clean all build artifacts using:`mcp__xcodebuildmcp__clean_proj`
This helps resolve build issues and ensures a fresh build..claude/commands/update-docs.md:
---description: Update all documentation---
# Update documentation
I'll refresh all CLAUDE.md files:1. Analyze current project structure2. Update main CLAUDE.md3. Update nested documentation4. Add new discoveries5. Update timestamps
This keeps your Claude Code setup current..claude/commands/claude-optimize.md:
---description: Optimize Claude Code setup---
# Analyze and optimize
I'll review your entire Claude Code configuration:1. Check for missing commands2. Verify MCP is working3. Test all hooks4. Suggest improvements5. Find unused features6. Recommend new tools
This helps you get the most from Claude Code.Based on Phase 1 analysis, create additional commands:
If SwiftLint is found - .claude/commands/lint.md:
---description: Run SwiftLint---
# Lint code
Run SwiftLint to check code style and fix issues.If multiple schemes - .claude/commands/scheme-list.md:
---description: List available schemes---
# Show all schemes
Display all available build schemes for this project.Hooks provide automatic context and validation. Create these in .claude/hooks/:
.claude/hooks/session-start.sh:
#!/bin/bash# Welcome message with project context
PROJECT_NAME=$(basename "$(pwd)")SWIFT_VERSION=$(swift --version 2>/dev/null | head -1 | grep -o '[0-9]\+\.[0-9]\+' | head -1)
echo "🚀 Starting $PROJECT_NAME session" >&2echo "📱 Swift $SWIFT_VERSION | Xcode $(xcodebuild -version | head -1)" >&2
# Check for common issuesif ! command -v node &> /dev/null; then echo "⚠️ Node.js not found - MCP tools may not work" >&2fi
# Show git statusBRANCH=$(git branch --show-current 2>/dev/null)if [ -n "$BRANCH" ]; then echo "🌿 Branch: $BRANCH" >&2fi
exit 0.claude/hooks/pre-build.sh:
#!/bin/bash# Checks before building
# Ensure we're not on main branch with uncommitted changesBRANCH=$(git branch --show-current 2>/dev/null)if [ "$BRANCH" = "main" ] || [ "$BRANCH" = "master" ]; then CHANGES=$(git status --porcelain 2>/dev/null | wc -l | tr -d ' ') if [ "$CHANGES" -gt "0" ]; then echo "⚠️ Warning: Building on main with uncommitted changes" >&2 fifi
exit 0.claude/hooks/post-swift-edit.sh:
#!/bin/bash# Auto-format Swift files after editing
INPUT=$(cat)FILE_PATH=$(echo "$INPUT" | grep -o '"file_path"[[:space:]]*:[[:space:]]*"[^"]*"' | sed 's/.*: *"\(.*\)"/\1/')
if [[ "$FILE_PATH" == *.swift ]]; then # Only run if formatters exist if [ -f ".swiftformat" ] && command -v swiftformat &> /dev/null; then swiftformat "$FILE_PATH" 2>/dev/null || true echo "✨ Formatted $FILE_PATH" >&2 fi if [ -f ".swiftlint.yml" ] && command -v swiftlint &> /dev/null; then swiftlint lint --fix "$FILE_PATH" 2>/dev/null || true fifi
exit 0Make all hooks executable:
chmod +x .claude/hooks/*.shClaude Code settings can enhance your workflow. Create these if you want additional automation:
.claude/settings.json:
{ "env": { "PROJECT_NAME": "[Your project name]", "DEFAULT_SIMULATOR": "iPhone 15", "SWIFT_VERSION": "[From analysis]" }, "hooks": { "SessionStart": [{ "matcher": ".*", "hooks": [{ "type": "command", "command": ".claude/hooks/session-start.sh" }] }], "PostToolUse": [{ "matcher": "Edit.*\\.swift|Write.*\\.swift", "hooks": [{ "type": "command", "command": ".claude/hooks/post-swift-edit.sh" }] }] }}.claude/settings.local.json:
{ "permissions": { "allow": [ "mcp__xcodebuildmcp__*", "Read", "Write", "Edit", "Bash(git*)", "Bash(swift*)", "WebFetch" ] }}Note: These settings files are optional. Claude Code works well with just the CLAUDE.md and commands.
For each major component found in Phase 1, create a CLAUDE.md file:
For Swift Packages - Packages/[PackageName]/CLAUDE.md:
# [Package Name] Package
## Purpose[What this package does]
## Structure- Sources/- Tests/
## TestingRun tests with: `mcp__xcodebuildmcp__swift_package_test`
## Key APIs[List main public interfaces]For App Extensions - [ExtensionName]/CLAUDE.md:
# [Extension Name]
## Type[Widget/Watch/Share/etc]
## BuildingUse scheme: [Scheme name]
## Testing[How to test this extension].claude/CLAUDE.md Overview# Claude Code Configuration
This directory contains all Claude Code setup for this iOS project.
## Quick Command Reference
**Building & Running:**- `/build` - Build the project- `/run` - Build and run in simulator- `/clean` - Clean build artifacts
**Testing:**- `/test` - Run tests- `/test-all` - Run all tests- `/test-single [name]` - Run specific test
**Device:**- `/device-list` - Show connected devices- `/device-build` - Deploy to device
**Maintenance:**- `/update-docs` - Update documentation- `/claude-optimize` - Optimize setup
## Directory Structure.claude/ ├── commands/ # Slash commands ├── hooks/ # Automation scripts ├── scripts/ # Helper utilities └── imports/ # Reusable patterns
## How Commands WorkEach .md file in commands/ becomes a slash command.The filename (without .md) is the command name.
## How Hooks WorkHooks run automatically at specific times:- session-start.sh: When Claude Code starts- post-swift-edit.sh: After editing Swift files# Verify MCP is workingmcp__xcodebuildmcp__diagnostic
# If this fails, MCP may not be enabled# User should check Claude Code settingsTry each command to ensure it works:
/build # Should build the project/test # Should run tests/run # Should launch in simulator/clean # Should clean build artifacts# Test the context scriptDEBUG_CONTEXT=true bash .claude/scripts/detect-context.sh
# Should show:# - Project file path# - Default scheme# - Default simulator# - Current contextIssue: MCP tools not found
# Solution: MCP may not be enabled in Claude Code# The user needs to check their Claude Code settings# Or ensure Node.js is installed:brew install nodeIssue: "Command not found" for slash commands
# Solution: Ensure .claude/commands/ directory exists# and contains .md files with proper frontmatter:---description: Your description here---Issue: Hooks not running
# Solution: Make hooks executablechmod +x .claude/hooks/*.sh
# And ensure paths in settings.json are correctIssue: Build fails with "scheme not found"
# Solution: List available schemesxcodebuild -list -project *.xcodeproj
# Update detect-context.sh with correct schemeIssue: Simulator not found
# Solution: List available simulatorsxcrun simctl list devices
# Update defaults in detect-context.shAfter setup, verify:
✅ Phase 0-1: Analysis Complete
✅ Phase 2: Infrastructure Created
.claude/ directory structure exists✅ Phase 3: MCP Configured
mcp__xcodebuildmcp__diagnostic works)✅ Phase 4: Commands Created
✅ Phase 5-6: Optional Enhancements
✅ Phase 7: Documentation Complete
.claude/CLAUDE.md overview created✅ Phase 8: Everything Tested
/update-docs weekly or after major changes/claude-optimize monthly to find improvementsIf something doesn't work:
mcp__xcodebuildmcp__diagnosticYou'll know the setup is successful when:
/build/test knows what to run/update-docsThe goal is to make iOS development with Claude Code feel magical - where everything just works and Claude understands your project deeply.
Comments (Nostr)
Relays: wss://relay.damus.io, wss://relay.snort.social. NIP-07 signer required to post.
Connecting to relays…
NIP-07 signer not detected. Install/enable a Nostr browser extension (e.g., Alby, nos2x), then refresh to post.