This document explains how to use the lightweight build and log capture wrapper scripts instead of the heavy XcodeBuildMCP server.
This approach replaces XcodeBuildMCP's 84+ tools with simple bash wrappers that:
- ✅ Just work reliably
- ✅ Capture output to files (token-efficient)
- ✅ Follow Igor Makarov's proven pattern
- ✅ Let you search/grep results instead of loading everything
Wraps standard xcodebuild commands and captures output to timestamped files.
./claude/scripts/xcodebuild -workspace XXX.xcworkspace -scheme YYY <action> [options]Build for visionOS Simulator:
./claude/scripts/xcodebuild -workspace MyApp.xcworkspace -scheme MyApp build -destination 'generic/platform=visionOS Simulator'Run unit tests:
./claude/scripts/xcodebuild -workspace MyApp.xcworkspace -scheme MyApp test -destination 'generic/platform=visionOS Simulator'Build for device:
./claude/scripts/xcodebuild -workspace MyApp.xcworkspace -scheme MyApp build -destination generic/platform=visionOSArchive for distribution:
./claude/scripts/xcodebuild -workspace MyApp.xcworkspace -scheme MyApp archive -archivePath ./build/MyApp.xcarchive- ✅ Builds to:
./build/xcodebuild/build-YYYYMMDD-HHMMSS.txt - ✅ Reports: Exit code, file size
- ✅ Searchable via grep
- ❌ NEVER use
-clean- Not needed, slows down builds - ✅ Use existing build cache between builds
- ✅ Search output files with grep instead of loading entire contents
Captures app console output (print statements, NSLog, os_log) to timestamped files.
Step 1: Start log capture
./claude/scripts/capture-logs com.example.myappStep 2: Launch your app in Xcode (Cmd+R)
- Your app runs normally
- Logs are captured in background
Step 3: Interact with the app
- Reproduce the issue
- Trigger the feature you're testing
Step 4: Stop log capture
./claude/scripts/stop-logsStep 5: Search the logs
grep -i error ./build/logs/logs-*.txt
grep -i "ViewModel" ./build/logs/logs-*.txtThe capture-logs script filters by subsystem/bundle ID to reduce noise.
Examples:
# Capture logs from your app's main subsystem
./claude/scripts/capture-logs com.mycompany.myapp
# Capture logs from a specific subsystem
./claude/scripts/capture-logs com.mycompany.myapp.CoreData
# If you're not sure about the subsystem, use a prefix:
# (Note: simctl's predicate syntax might require exact matches)
./claude/scripts/capture-logs com.exampleThe script captures logs at all levels including Debug, Info, and Error:
--level debugflag ensures Debug-level logs are captured--style compactformats output in readable compact style- Most visionOS apps log heavily at Debug level
Without --level debug, you'll only see Info and Error logs, which may result in very small/empty log files.
- ✅ Logs to:
./build/logs/logs-YYYYMMDD-HHMMSS.txt - ✅ Stores PID for cleanup
- ✅ Independent of xcodebuild builds
Always stop logs after testing:
./claude/scripts/stop-logsThis kills the background log capture process.
./build/
├── xcodebuild/ # Build outputs
│ └── build-*.txt # One per build
└── logs/ # App logs
├── logs-*.txt # One per capture session
└── .last-capture-pid # PID of active capture (temporary)
grep -i "error:" ./build/xcodebuild/build-*.txtgrep -i "warning:" ./build/xcodebuild/build-*.txtgrep -i "failed" ./build/xcodebuild/build-*.txtgrep "ViewController" ./build/logs/logs-*.txt
grep -i "crash" ./build/logs/logs-*.txt
grep "ERROR" ./build/logs/logs-*.txtgrep -c "MyClass" ./build/logs/logs-*.txtgrep -C 3 "error" ./build/logs/logs-*.txt # 3 lines before/after- Start logs:
./claude/scripts/capture-logs com.myapp.vision - Launch app: Cmd+R in Xcode
- Reproduce crash
- Stop logs:
./claude/scripts/stop-logs - Search:
grep -i "crash\|exception\|error" ./build/logs/logs-*.txt
- Build:
./claude/scripts/xcodebuild -workspace MyApp.xcworkspace -scheme MyApp build -destination 'generic/platform=visionOS Simulator' - Search:
grep -i "error" ./build/xcodebuild/build-*.txt - Show context:
grep -C 5 "error" ./build/xcodebuild/build-*.txt
- Start logs:
./claude/scripts/capture-logs com.myapp.vision - Launch app: Cmd+R
- Run performance test
- Stop logs:
./claude/scripts/stop-logs - Search for performance markers:
grep "duration\|elapsed\|ms" ./build/logs/logs-*.txt
| Aspect | XcodeBuildMCP | These Scripts |
|---|---|---|
| Complexity | 84+ tools, TypeScript server | 3 bash scripts, ~100 lines total |
| Reliability | ❌ Often fails | ✅ Just wraps Apple's tools |
| Token Efficiency | ❌ Large responses | ✅ File-based, search what you need |
| Setup Time | ⏱️ Complex configuration | ⚡ Works immediately |
| Maintenance | 🔧 Requires debugging | 🔒 Stable, no dependencies |
| Features | 🌟 Many tools | 📍 Focused, what you need |
- File-based outputs - Save to timestamped files, not memory
- Search, don't load - Use grep/head/tail to find what you need
- Simple tools - Bash wrappers, not complex protocols
- Independent - Log capture and builds don't interfere
- Reliable - Built on Apple's battle-tested tools
- Check simulator is running:
xcrun simctl list - Use correct simulator ID or "booted" for active simulator
- Example:
./claude/scripts/capture-logs com.myapp.vision booted
- The script now includes
--level debugto capture all log levels - If logs are still empty, verify subsystem name matches your app's logging setup
- Check how your app logs:
grep -r "Logger\|os_log" YourApp/ - Example in Swift:
Logger(subsystem: "com.myapp", category: "APP") - Verify correct subsystem: Look for
[com.yourapp.*]in process logs
- Check that your app is actually writing logs with that subsystem
- Verify simulator is running:
xcrun simctl list | grep Booted - Try broader capture to test:
xcrun simctl spawn booted log stream --predicate 'process == "YourApp"'
- Verify path:
ls -la XXX.xcworkspace - Must be relative to where you run the script
- Example:
./claude/scripts/xcodebuild -workspace ./MyApp.xcworkspace ...
- Check file exists:
ls -la ./build/logs/ ./build/xcodebuild/ - Try without wildcards:
grep error ./build/logs/logs-20251020-*.txt - Use
-rfor recursive:grep -r error ./build/
When working with Claude Code:
-
Ask Claude to run builds: "Build the visionOS app"
- Claude will call:
./claude/scripts/xcodebuild ... - Results saved to file
- Claude reads file with grep
- Claude will call:
-
Ask Claude to capture logs: "Capture logs from my app"
- Claude will call:
./claude/scripts/capture-logs com.yourapp - Launch app manually in Xcode
- Ask Claude to read logs after stopping
- Claude will call:
-
Ask Claude to analyze: "Find errors in the build"
- Claude greps the build output file
- Shows only relevant errors
- No token waste from full output
- Review scripts in
./.claude/scripts/ - Start with:
./claude/scripts/xcodebuild -h(for xcodebuild help) - Try a build:
./claude/scripts/xcodebuild -workspace MyApp.xcworkspace -scheme MyApp build - Test log capture with your app