Xcode: MCP Bridge Wrapper for Cursor
Python wrapper that makes Xcode's MCP bridge compatible with strict MCP clients like Cursor
★ 17MITother
Install
Config snippet generator goes here (5 client tabs)
README
# XcodeMCPWrapper - mcpbridge-wrapper
<!-- mcp-name: io.github.SoundBlaster/xcode-mcpbridge-wrapper -->
<!-- version-badge:start -->
[](https://github.com/SoundBlaster/XcodeMCPWrapper/releases/tag/v0.4.4)
<!-- version-badge:end -->
[](https://www.python.org/downloads/)
[](https://opensource.org/licenses/MIT)
[](./SPECS/ARCHIVE/P5-T14_Code_Coverage/)
<!-- coverage-sync: keep README and DocC coverage metrics aligned -->
[](https://registry.modelcontextprotocol.io)
A Python wrapper that makes Xcode 26.3's MCP bridge compatible with Cursor and
other strict MCP-spec-compliant clients.
## The Problem
Xcode's `mcpbridge` returns tool responses in the `content` field but omits the required `structuredContent` field when a tool declares an `outputSchema`. According to the MCP specification, when `outputSchema` is declared, responses **must** include `structuredContent`.
- ✅ Claude Code and Codex CLI work (they have special handling for Apple's responses)
- ❌ Cursor strictly follows the spec and rejects non-compliant responses
## The Solution
`mcpbridge-wrapper` intercepts responses from `xcrun mcpbridge` and copies the data from `content` into `structuredContent`, making Xcode's MCP tools fully compatible with all MCP clients.
```
┌─────────────┐ MCP Protocol ┌──────────────────┐ MCP Protocol ┌────────────┐ XPC ┌─────────┐
│ Cursor │ ◄────────────────► │ mcpbridge-wrapper│ ◄──────────────► │ mcpbridge │ ◄───────► │ Xcode │
│ (MCP Client)│ │ (This Project) │ │ (Bridge) │ │ (IDE) │
└─────────────┘ └──────────────────┘ └────────────┘ └─────────┘
```
## Quick Start
### Prerequisites
- macOS with Xcode 26.3+
- Python 3.9+
- **Xcode Tools MCP Server enabled** (see below)
> ⚠️ **Important:** You MUST enable Xcode Tools MCP in Xcode settings:
> 1. Open **Xcode** > **Settings** (⌘,)
> 2. Select **Intelligence** in the sidebar
> 3. Under **Model Context Protocol**, toggle **Xcode Tools** ON
>
> If you see "Found 0 tools" in your MCP client logs, this setting is not enabled.
### Cursor Quick Setup
If you use **Cursor**, no installation is needed — just add this to `~/.cursor/mcp.json`:
**Broker mode (Recommended):**
```json
{
"mcpServers": {
"xcode-tools": {
"command": "uvx",
"args": ["--from", "mcpbridge-wrapper", "mcpbridge-wrapper", "--broker"]
}
}
}
```
With Web UI dashboard (optional — adds real-time monitoring at http://localhost:8080):
```json
{
"mcpServers": {
"xcode-tools": {
"command": "uvx",
"args": [
"--from",
"mcpbridge-wrapper[webui]",
"mcpbridge-wrapper",
"--broker",
"--web-ui",
"--web-ui-config",
"/Users/YOUR_USERNAME/.mcpbridge_wrapper/webui.json"
]
}
}
}
```
**Direct mode (Alternative):**
```json
{
"mcpServers": {
"xcode-tools": {
"command": "uvx",
"args": ["--from", "mcpbridge-wrapper", "mcpbridge-wrapper"]
}
}
}
```
If you upgrade and want to confirm the currently running dashboard process version:
```bash
PORT=8080
PID=$(lsof -tiTCP:$PORT -sTCP:LISTEN | head -n1)
PY=$(ps -p "$PID" -o command= | awk '{print $1}')
"$PY" -c 'import importlib.metadata as m; print(m.version("mcpbridge-wrapper"))'
```
If needed, do a one-time refresh start:
```bash
uvx --refresh --from 'mcpbridge-wrapper[webui]' mcpbridge-wrapper --web-ui --web-ui-port 8080
```
Restart Cursor and you're done. For other clients or installation methods, read on.
### Broker Mode
Broker mode lets multiple short-lived MCP client sessions share one persistent
upstream bridge session.
- **Why this mode exists:** Apple documents a Coding Intelligence known issue in Xcode 26.4 where external development tools may trigger repeated "Allow Connection?" dialogs during normal usage (`170721057`). Reusing one long-lived upstream session via broker mode can reduce reconnect churn that surfaces this prompt pattern. See Apple's official [Xcode 26.4 release notes](https://developer.apple.com/documentation/xcode-release-notes/xcode-26_4-release-notes).
- Use `--broker` to auto-detect — connect if daemon is alive, spawn otherwise (recommended).
- Add `--web-ui` (plus optional `--web-ui-config`) when you want the spawned or daemon host to own one shared dashboard endpoint.
- If you want one explicit daemon owner plus one visible monitoring surface across multiple editors, prefer a dedicated host: start `--broker-daemon --web-ui` once, keep clients on `--broker`, and attach the browser dashboard and/or `--tui