# xcode-mcp
MCP server for Xcode developer tools.
## Installation
```bash
npm install
npm run build
```
## Usage
### Claude Desktop Configuration
Add to your Claude Desktop config (`~/Library/Application Support/Claude/claude_desktop_config.json`):
```json
{
"mcpServers": {
"xcode": {
"command": "node",
"args": ["/Users/YOUR_USERNAME/Projects/xcode-mcp/dist/index.js"]
}
}
}
```
## Available Tools
### iOS Simulator (`simctl`)
Control iOS Simulators via `xcrun simctl`.
| Tool | Description |
|------|-------------|
| `simctl_list` | List available simulators, device types, runtimes, or device pairs |
| `simctl_boot` | Boot a simulator device |
| `simctl_shutdown` | Shutdown a simulator device or all simulators |
| `simctl_install` | Install an app bundle on a simulator |
| `simctl_launch` | Launch an app on a simulator |
| `simctl_terminate` | Terminate a running app without shutting down the simulator |
| `simctl_uninstall` | Uninstall an app from a simulator |
| `simctl_openurl` | Open a URL or deep link on a simulator |
| `simctl_push` | Send a push notification to an app |
| `simctl_location` | Set or clear the simulated GPS location |
| `simctl_privacy` | Grant, revoke, or reset privacy permissions for an app |
| `simctl_io_screenshot` | Capture a screenshot from a simulator |
#### Device Identification
All simulator tools that require a device accept:
- Device UDID (e.g., `"3A8C9B5F-1234-5678-9ABC-DEF012345678"`)
- Device name (e.g., `"iPhone 16 Pro"`)
- Special value `"booted"` for the currently booted simulator
#### Examples
**List all devices:**
```json
{"name": "simctl_list", "arguments": {"filter": "devices"}}
```
**Boot a simulator:**
```json
{"name": "simctl_boot", "arguments": {"device": "iPhone 16 Pro"}}
```
**Take a screenshot:**
```json
{"name": "simctl_io_screenshot", "arguments": {"device": "booted"}}
```
**Send a push notification:**
```json
{
"name": "simctl_push",
"arguments": {
"device": "booted",
"bundle_id": "com.example.app",
"payload": {
"aps": {
"alert": {
"title": "Test",
"body": "Hello from MCP!"
}
}
}
}
}
```
**Set location:**
```json
{
"name": "simctl_location",
"arguments": {
"device": "booted",
"action": "set",
"latitude": 37.7749,
"longitude": -122.4194
}
}
```
**Grant camera permission:**
```json
{
"name": "simctl_privacy",
"arguments": {
"device": "booted",
"action": "grant",
"service": "camera",
"bundle_id": "com.example.app"
}
}
```
### WebDriverAgent (`wda`)
UI automation for iOS Simulator apps via WebDriverAgent. Enables tapping, swiping, typing, and finding UI elements.
| Tool | Description |
|------|-------------|
| `wda_status` | Check WebDriverAgent server connectivity |
| `wda_tap` | Tap at coordinates, by accessibility ID, or element ID |
| `wda_type` | Type text into the currently focused text field |
| `wda_swipe` | Perform a swipe gesture from start to end coordinates |
| `wda_find` | Find UI elements by accessibility ID, class name, or predicate |
| `wda_source` | Get the UI hierarchy (accessibility tree) as XML |
| `wda_home` | Press the home button |
| `wda_alert` | Accept or dismiss system alerts |
#### Prerequisites
1. **Clone WebDriverAgent** (one-time):
```bash
git clone https://github.com/appium/WebDriverAgent.git
cd WebDriverAgent
```
2. **Start WDA on a simulator** (keep running in a terminal):
```bash
xcodebuild test -project WebDriverAgent.xcodeproj \
-scheme WebDriverAgentRunner \
-destination 'platform=iOS Simulator,name=iPhone 16 Pro'
```
3. **Verify WDA is running**:
```bash
curl http://localhost:8100/status
```
#### Coordinate System
All coordinates are in **points** (logical pixels), not physical pixels. Use `wda_source` to see element positions in the UI hierarchy XML.
#### Common Parameters
All WDA tools accept these optional parameters:
- `bundle_id`: Activate a specific app before the action
- `port`: WDA server port (default: 8100)
#### Examples
**Check WDA status:**
```json
{"name": "wda_status", "arguments": {}}
```
**Tap at coordinates:**
```json
{"name": "wda_tap", "arguments": {"x": 200, "y": 400}}
```
**Tap by accessibility ID:**
```json
{"name": "wda_tap", "arguments": {"accessibility_id": "login_button"}}
```
**Tap with app activation:**
```json
{"name": "wda_tap", "arguments": {"accessibility_id": "login", "bundle_id": "com.example.app"}}
```
**Type text:**
```json
{"name": "wda_type", "arguments": {"text": "hello@example.com"}}
```
**Swipe down (scroll up):**
```json
{
"name": "wda_swipe",
"arguments": {
"start_x": 200,
"start_y": 400,
"end_x": 200,
"end_y": 200,
"duration": 500
}
}
```
**Find elements:**
```json
{"name": "wda_find", "arguments": {"strategy": "accessibility id", "value": "submit_button"}}
```
**Get UI hierarchy:**
```json
{"name": "wda_source", "arguments": {}}
```
**Handle alert:**
```json
{"name": "wda_alert", "arguments": {"action": "accept"}}
```
### Xcode Build (`xcodebuild`)
Build, test, and manage Xcode projects via `xcodebuild`.
| Tool | Description |
|------|-------------|
| `xcodebuild_list` | List schemes, targets, and configurations for a project or workspace |
| `xcodebuild_build` | Build a scheme for a destination with structured result parsing |
| `xcodebuild_test` | Run tests and return structured results with pass/fail counts |
| `xcodebuild_clean` | Clean build artifacts for a scheme |
| `xcodebuild_show_build_settings` | Show build configuration settings |
#### Project Auto-Detection
All xcodebuild tools can automatically detect the project or workspace in the current directory. They prefer `.xcworkspace` over `.xcodeproj`. You can also specify explicit paths:
- `workspace`: Path to a `.xcworkspace` file
- `project`: Path to a `.xcodeproj` file
- `directory`: Directory to search for projects (defaults to cwd)
#### Destination Handling
The `destination` parameter accepts:
- Device names (e.g., `"iPhone 16 Pro"`) - automatically resolved to simulator UDID
- Full destination strings (e.g., `"platform=iOS Simulator,name=iPhone 16 Pro"`)
#### Examples
**List schemes:**
```json
{"name": "xcodebuild_list", "arguments": {}}
```
**Build a scheme:**
```json
{
"name": "xcodebuild_build",
"arguments": {
"scheme": "MyApp",
"destination": "iPhone 16 Pro",
"configuration": "Debug"
}
}
```
**Run tests:**
```json
{
"name": "xcodebuild_test",
"arguments": {
"scheme": "MyApp",
"destination": "iPhone 16 Pro",
"only_testing": ["MyAppTests/testLogin"]
}
}
```
**Clean build:**
```json
{
"name": "xcodebuild_clean",
"arguments": {
"scheme": "MyApp"
}
}
```
**Show build settings:**
```json
{
"name": "xcodebuild_show_build_settings",
"arguments": {
"scheme": "MyApp",
"configuration": "Release"
}
}
```
## Development
```bash
# Run in development mode
npm run dev
# Build
npm run build
# Test
npm test
```
## License
MIT