> axiom-xcode-mcp-setup
Xcode MCP setup — enable mcpbridge, per-client config, permission handling, multi-Xcode targeting, troubleshooting
curl "https://skillshub.wtf/CharlesWiltgen/Axiom/axiom-xcode-mcp-setup?format=md"Xcode MCP Setup
Prerequisites
- Xcode 26.3+ with MCP support
- macOS with Xcode installed and running
- At least one project/workspace open in Xcode
Step 1: Enable MCP in Xcode
- Open Xcode Settings (Cmd+,)
- Go to Intelligence tab
- Check Enable Model Context Protocol
- Ensure Xcode Tools toggle is ON
Without this toggle, xcrun mcpbridge connects but returns no tools.
Step 2: Connect Your MCP Client
Claude Code
claude mcp add --transport stdio xcode -- xcrun mcpbridge
Verify: claude mcp list should show xcode server.
Codex
codex mcp add xcode -- xcrun mcpbridge
Cursor
Create or edit .cursor/mcp.json in your project root:
{
"mcpServers": {
"xcode": {
"command": "xcrun",
"args": ["mcpbridge"]
}
}
}
Cursor-specific note: Cursor is a strict MCP client. Xcode's mcpbridge omits structuredContent when tools declare outputSchema, which violates the MCP spec. If Cursor rejects responses, use XcodeMCPWrapper as a proxy:
{
"mcpServers": {
"xcode": {
"command": "/path/to/XcodeMCPWrapper",
"args": []
}
}
}
VS Code + GitHub Copilot
Create or edit .vscode/mcp.json:
{
"servers": {
"xcode": {
"type": "stdio",
"command": "xcrun",
"args": ["mcpbridge"]
}
}
}
Gemini CLI
gemini mcp add xcode -- xcrun mcpbridge
Step 3: Verify Connection
After configuration, call XcodeListWindows (no parameters). You should see:
tabIdentifier: <uuid>, workspacePath: /path/to/YourProject.xcodeproj
If you see an empty list, ensure a project is open in Xcode.
Permission Dialog
When an MCP client first connects, Xcode shows a permission dialog:
- Identifies the connecting process by PID
- Asks to allow MCP tool access
- Must be approved in Xcode's UI (not terminal)
PID-based approval: Permission is granted per-process. If the client restarts (new PID), you'll see the dialog again. This is expected behavior.
Multi-Xcode Targeting
When multiple Xcode instances are running:
Auto-Detection (default)
mcpbridge auto-selects using this fallback:
- If exactly one Xcode process is running → uses that
- If multiple → uses the one matching
xcode-select - If none → exits with error
Manual PID Selection
Set MCP_XCODE_PID to target a specific instance:
# Find Xcode PIDs
pgrep -x Xcode
# Claude Code with specific PID
claude mcp add --transport stdio xcode -- env MCP_XCODE_PID=12345 xcrun mcpbridge
Session ID (optional)
MCP_XCODE_SESSION_ID provides a stable UUID for tool sessions, useful when tracking interactions across reconnections.
Troubleshooting
digraph troubleshoot {
rankdir=TB;
"Connection failed?" [shape=diamond];
"tools/list empty?" [shape=diamond];
"Wrong project?" [shape=diamond];
"Repeated permission prompts?" [shape=diamond];
"Client rejects responses?" [shape=diamond];
"Check Xcode running + toggle on" [shape=box];
"Open a project in Xcode" [shape=box];
"Use MCP_XCODE_PID or check tab targeting" [shape=box];
"Expected: PID changes on restart" [shape=box];
"Use XcodeMCPWrapper proxy" [shape=box];
"Connection failed?" -> "Check Xcode running + toggle on" [label="refused/timeout"];
"Connection failed?" -> "tools/list empty?" [label="connects OK"];
"tools/list empty?" -> "Open a project in Xcode" [label="no tools"];
"tools/list empty?" -> "Wrong project?" [label="tools listed"];
"Wrong project?" -> "Use MCP_XCODE_PID or check tab targeting" [label="yes"];
"Wrong project?" -> "Repeated permission prompts?" [label="no"];
"Repeated permission prompts?" -> "Expected: PID changes on restart" [label="yes"];
"Repeated permission prompts?" -> "Client rejects responses?" [label="no"];
"Client rejects responses?" -> "Use XcodeMCPWrapper proxy" [label="strict client (Cursor)"];
}
Common Issues
| Symptom | Cause | Fix |
|---|---|---|
| "Connection refused" | Xcode not running or MCP toggle off | Launch Xcode, enable MCP in Settings > Intelligence |
| tools/list returns empty | No project open, or permission not granted | Open a project, check for permission dialog in Xcode |
| Tools target wrong project | Multiple Xcode windows, wrong tab | Call XcodeListWindows, use correct tabIdentifier |
| Repeated permission prompts | Client restarted (new PID) | Expected behavior — approve each time |
| Cursor/strict client errors | Missing structuredContent in response | Use XcodeMCPWrapper as proxy |
| "No such command: mcpbridge" | Xcode < 26.3 | Update to Xcode 26.3+ |
| Slow/hanging tool calls | Large project indexing | Wait for Xcode indexing to complete |
Xcode Built-in Assistant Config
Xcode also supports MCP servers for its built-in assistants. Config files live at:
~/Library/Developer/Xcode/CodingAssistant/codex
~/Library/Developer/Xcode/CodingAssistant/ClaudeAgentConfig
These are for configuring Xcode's internal assistant, separate from external MCP client setup.
Resources
Docs: /xcode/mcp-server
Skills: axiom-xcode-mcp-tools, axiom-xcode-mcp-ref
> related_skills --same-repo
> axiom-eventkit
Use when working with ANY calendar event, reminder, EventKit permission, or EventKitUI controller. Covers access tiers (no-access, write-only, full), permission migration from pre-iOS 17, store lifecycle, reminder patterns, EventKitUI controller selection, Siri Event Suggestions, virtual conference extensions.
> axiom-eventkit-ref
Use when needing EventKit API details — EKEventStore, EKEvent, EKReminder, EventKitUI view controllers, EKCalendarChooser, authorization methods, predicate-based fetching, recurrence rules, Siri Event Suggestions donation, EKVirtualConferenceProvider, location-based reminders, and EKErrorDomain codes
> axiom-contacts
Use when accessing ANY contact data, requesting Contacts permissions, choosing between picker and store access, implementing Contact Access Button, or migrating to iOS 18 limited access. Covers authorization levels, CNContactStore, ContactProvider, key fetching, incremental sync.
> axiom-contacts-ref
Use when needing Contacts API details — CNContactStore, CNMutableContact, CNSaveRequest, CNContactFormatter, CNContactVCardSerialization, CNContactPickerViewController, ContactAccessButton, contactAccessPicker, ContactProvider extension, CNChangeHistoryFetchRequest, contact key descriptors, and CNError codes