XcodeMCPWrapper - mcpbridge-wrapper
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:
- Open Xcode > Settings (⌘,)
- Select Intelligence in the sidebar
- 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):
{
"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):
{
"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):
{
"mcpServers": {
"xcode-tools": {
"command": "uvx",
"args": ["--from", "mcpbridge-wrapper", "mcpbridge-wrapper"]
}
}
}If you upgrade and want to confirm the currently running dashboard process version:
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:
uvx --refresh --from 'mcpbridge-wrapper[webui]' mcpbridge-wrapper --web-ui --web-ui-port 8080Restart 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. - Use
--brokerto 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-uionce, keep clients on--broker, and attach the browser dashboard and/or--tuito that host.
Quick migration examples:
# Claude Code claude mcp add --transport stdio xcode -- uvx --from mcpbridge-wrapper mcpbridge-wrapper --broker # Codex CLI codex mcp add xcode -- uvx --from mcpbridge-wrapper mcpbridge-wrapper --broker
For full start/stop/status commands, Cursor JSON snippets, troubleshooting, and rollback to direct mode, see Broker Mode Guide.
Multi-Agent Guidance
When you run multiple MCP client processes at the same time:
- Dedicated host frontend workflow (recommended when visibility matters): start one
--broker-daemon --web-uiprocess, keep every editor/client on--broker, and attach the browser dashboard and/ormcpbridge-wrapper --tuito the same host. - Unified single-config auto-spawn: configure each client with
--broker --web-ui --web-ui-config <shared-path>when you want less setup and can accept implicit host ownership. - Runtime expectation: a dedicated host is the clearest way to control lifecycle; in unified auto-spawn, the first client that must spawn the broker starts the broker host and dashboard and later clients reuse it.
- Ownership rule: only one process can bind a given Web UI
host:port(for example127.0.0.1:8080). - Connection behavior: when a broker is already running,
--brokerreuses it and does not retrofit dashboard settings onto that existing host. - Fallback behavior: if dashboard bind fails (port already in use), broker MCP transport continues and only dashboard startup is skipped.
- Verification flow: use
mcpbridge-wrapper --broker-status, the files under~/.mcpbridge_wrapper/, and the shared dashboard/TUI state to verify that both editors are attached to one daemon.
See Broker Mode Guide, Web UI Setup Guide, and Troubleshooting.
Python Environment Setup (Development)
If you plan to run make install, pytest, or other development commands, create and activate a virtual environment first. This avoids Homebrew Python's externally-managed-environment (PEP 668) error.
cd XcodeMCPWrapper python3 -m venv .venv source .venv/bin/activate python3 -m pip install --upgrade pip make install
Quick checks:
Both should point to .venv/bin/... while the environment is active.
Installation
Option 1: Using uvx (Recommended - Easiest)
The fastest way to install is using uvx (requires uv to be installed):
# No manual installation needed - uvx will automatically download and run
uvx --from mcpbridge-wrapper mcpbridge-wrapperOr add to your MCP client configuration directly (see configuration sections below).
Option 2: Via MCP Registry
If your MCP client supports the MCP Registry:
Server name: io.github.SoundBlaster/xcode-mcpbridge-wrapper
# Using mcp-publisher CLI
mcp-publisher install io.github.SoundBlaster/xcode-mcpbridge-wrapperOption 3: Using pip
python3 -m pip install mcpbridge-wrapper
Then use mcpbridge-wrapper or xcodemcpwrapper command.
Option 4: Manual Installation (via install script)
git clone https://github.com/SoundBlaster/XcodeMCPWrapper.git
cd XcodeMCPWrapper
./scripts/install.shThe install script creates a virtual environment, installs the package, and places a wrapper at ~/bin/xcodemcpwrapper.
If you plan to use --web-ui MCP args, install Web UI extras explicitly:
./scripts/install.sh --webui
Add the following to your ~/.bashrc or ~/.zshrc:
export PATH="$HOME/bin:$PATH"
Then reload:
source ~/.zshrc # or . ~/.zshrc
Option 5: Local Development (venv)
For development or if you want to run directly from the cloned repository:
git clone https://github.com/SoundBlaster/XcodeMCPWrapper.git cd XcodeMCPWrapper python3 -m venv .venv source .venv/bin/activate make install # or: make install-webui (for Web UI support)
The entry point is .venv/bin/mcpbridge-wrapper. Use the full absolute path when configuring MCP clients (see configuration sections below).
Uninstallation
To remove xcodemcpwrapper from your system:
Options:
--dry-runor-n: Show what would be removed without removing--yesor-y: Skip confirmation prompt
Configuration
Cursor
Broker setup examples are listed first.
Using uvx in broker mode (Recommended):
{
"mcpServers": {
"xcode-tools": {
"command": "uvx",
"args": ["--from", "mcpbridge-wrapper", "mcpbridge-wrapper", "--broker"]
}
}
}Using uvx in broker mode with Web UI (Optional):
{
"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"
]
}
}
}Using uvx in direct mode:
{
"mcpServers": {
"xcode-tools": {
"command": "uvx",
"args": ["--from", "mcpbridge-wrapper", "mcpbridge-wrapper"]
}
}
}Using uvx in direct mode with Web UI (Optional):
{
"mcpServers": {
"xcode-tools": {
"command": "uvx",
"args": [
"--from",
"mcpbridge-wrapper[webui]",
"mcpbridge-wrapper",
"--web-ui",
"--web-ui-port",
"8080"
]
}
}
}Using manual installation (Direct mode):
{
"mcpServers": {
"xcode-tools": {
"command": "/Users/YOUR_USERNAME/bin/xcodemcpwrapper",
"args": []
}
}
}Using manual installation with Web UI (Direct mode, optional):
Requires installing with
./scripts/install.sh --webui(or equivalent.[webui]dependencies).
{
"mcpServers": {
"xcode-tools": {
"command": "/Users/YOUR_USERNAME/bin/xcodemcpwrapper",
"args": ["--web-ui", "--web-ui-port", "8080"]
}
}
}Using local development (venv, direct mode):
{
"mcpServers": {
"xcode-tools": {
"command": "/path/to/XcodeMCPWrapper/.venv/bin/mcpbridge-wrapper"
}
}
}Using local development with Web UI (Direct mode, optional):
{
"mcpServers": {
"xcode-tools": {
"command": "/path/to/XcodeMCPWrapper/.venv/bin/mcpbridge-wrapper",
"args": ["--web-ui", "--web-ui-port", "8080"]
}
}
}Claude Code
Broker setup examples are listed first.
Using uvx in broker mode (Recommended):
claude mcp add --transport stdio xcode -- uvx --from mcpbridge-wrapper mcpbridge-wrapper --broker
Using uvx in broker mode with Web UI (Optional):
claude mcp add --transport stdio xcode -- uvx --from 'mcpbridge-wrapper[webui]' mcpbridge-wrapper --broker --web-ui --web-ui-config "$HOME/.mcpbridge_wrapper/webui.json"
Using uvx in direct mode:
claude mcp add --transport stdio xcode -- uvx --from mcpbridge-wrapper mcpbridge-wrapper
Using uvx in direct mode with Web UI (Optional):
claude mcp add --transport stdio xcode -- uvx --from 'mcpbridge-wrapper[webui]' mcpbridge-wrapper --web-ui --web-ui-port 8080Using manual installation (Direct mode):
claude mcp add --transport stdio xcode -- ~/bin/xcodemcpwrapperUsing manual installation with Web UI (Direct mode, optional):
Requires installing with ./scripts/install.sh --webui (or equivalent .[webui] dependencies).
claude mcp add --transport stdio xcode -- ~/bin/xcodemcpwrapper --web-ui --web-ui-port 8080Using local development (venv, direct mode):
claude mcp add --transport stdio xcode -- /path/to/XcodeMCPWrapper/.venv/bin/mcpbridge-wrapper
Using local development with Web UI (Direct mode, optional):
claude mcp add --transport stdio xcode -- /path/to/XcodeMCPWrapper/.venv/bin/mcpbridge-wrapper --web-ui --web-ui-port 8080
Codex CLI
Broker setup examples are listed first.
Using uvx in broker mode (Recommended):
codex mcp add xcode -- uvx --from mcpbridge-wrapper mcpbridge-wrapper --broker
Using uvx in broker mode with Web UI (Optional):
codex mcp add xcode -- uvx --from 'mcpbridge-wrapper[webui]' mcpbridge-wrapper --broker --web-ui --web-ui-config "$HOME/.mcpbridge_wrapper/webui.json"
Using uvx in direct mode:
codex mcp add xcode -- uvx --from mcpbridge-wrapper mcpbridge-wrapper
Using uvx in direct mode with Web UI (Optional):
codex mcp add xcode -- uvx --from 'mcpbridge-wrapper[webui]' mcpbridge-wrapper --web-ui --web-ui-port 8080Using manual installation (Direct mode):
codex mcp add xcode -- ~/bin/xcodemcpwrapperUsing manual installation with Web UI (Direct mode, optional):
Requires installing with ./scripts/install.sh --webui (or equivalent .[webui] dependencies).
codex mcp add xcode -- ~/bin/xcodemcpwrapper --web-ui --web-ui-port 8080Using local development (venv, direct mode):
codex mcp add xcode -- /path/to/XcodeMCPWrapper/.venv/bin/mcpbridge-wrapper
Using local development with Web UI (Direct mode, optional):
codex mcp add xcode -- /path/to/XcodeMCPWrapper/.venv/bin/mcpbridge-wrapper --web-ui --web-ui-port 8080
Zed Agent
Using uvx (Recommended):
Edit ~/.zed/settings.json:
{
"xcode-tools": {
"command": "uvx",
"args": ["--from", "mcpbridge-wrapper", "mcpbridge-wrapper"],
"env": {}
}
}Using uvx with Web UI (Optional):
{
"xcode-tools": {
"command": "uvx",
"args": [
"--from",
"mcpbridge-wrapper[webui]",
"mcpbridge-wrapper",
"--web-ui",
"--web-ui-port",
"8080"
],
"env": {}
}
}Using manual installation:
{
"xcode-tools": {
"command": "/Users/YOUR_USERNAME/bin/xcodemcpwrapper",
"args": [],
"env": {}
}
}Using manual installation with Web UI (Optional):
Requires installing with ./scripts/install.sh --webui (or equivalent .[webui] dependencies).
{
"xcode-tools": {
"command": "/Users/YOUR_USERNAME/bin/xcodemcpwrapper",
"args": ["--web-ui", "--web-ui-port", "8080"],
"env": {}
}
}Using local development (venv, direct mode):
{
"xcode-tools": {
"command": "/path/to/XcodeMCPWrapper/.venv/bin/mcpbridge-wrapper",
"args": [],
"env": {}
}
}Using local development with Web UI (Direct mode, optional):
{
"xcode-tools": {
"command": "/path/to/XcodeMCPWrapper/.venv/bin/mcpbridge-wrapper",
"args": ["--web-ui", "--web-ui-port", "8080"],
"env": {}
}
}Kimi CLI
Using uvx (Recommended):
Edit ~/.kimi/mcp.json:
{
"xcode-tools": {
"command": "uvx",
"args": ["--from", "mcpbridge-wrapper", "mcpbridge-wrapper"],
"env": {}
}
}Using manual installation:
{
"xcode-tools": {
"command": "/Users/YOUR_USERNAME/bin/xcodemcpwrapper",
"args": [],
"env": {}
}
}Usage
Once configured, ask your AI assistant to use Xcode tools:
"Build my project"
"Run the tests"
"Find all Swift files in the project"
"Show me the build errors"
Web UI Dashboard (Optional)
The wrapper includes an optional Web UI dashboard for real-time monitoring and audit logging:
# Start with Web UI make webui # Or directly python -m mcpbridge_wrapper --web-ui --web-ui-port 8080
Features:
- Real-time metrics: RPS, latency percentiles (p50, p95, p99), error rates
- Tool usage analytics: Visual charts of most frequently used tools
- Audit logging: Persistent log of all MCP tool calls with export (JSON/CSV)
- Request inspector: Live log stream with filtering
Open http://localhost:8080 in your browser to view the dashboard.
Important for multi-agent setups:
- The dashboard is hosted by one wrapper process, not by Xcode or
mcpbridge. - A single
host:portcan have only one listener; additional processes on the same port skip dashboard startup and continue MCP traffic. - For the explicit Phase 6 operator workflow, run one dedicated broker host with
--broker-daemon --web-ui, then monitor that same host from the browser dashboard and/ormcpbridge-wrapper --tui.
See Web UI Setup Guide for detailed configuration.
Known Issues
- Broker cold-start — Xcode approval timing race (0 tools with green dot): When the broker daemon starts a new
xcrun mcpbridgeprocess (on first launch or after a daemon restart), Xcode shows a per-process "Allow Connection?" dialog. If your MCP client sendstools/listbefore Xcode grants approval, it receives an empty list and caches it permanently — showing 0 tools with a green connected indicator and no error message. Each unique binary path (direct wrapper vs broker daemon) triggers a separate dialog. After approval the permission persists — no re-approval is needed on subsequent sessions. Workaround: watch for the Xcode dialog immediately after enabling broker mode; after clicking Allow, reload the MCP connection in your client (disable → re-enable in settings). See Troubleshooting: 0 tools after first broker connection for client-specific recovery steps and the diagnostic command. - BUG-T5 → FU-P13-T7 (P0): Empty-content tool results can still violate strict
structuredContentexpectations in strict MCP clients. - BUG-T6 → FU-P13-T8 (P0): Web UI port collisions can happen when multiple MCP sessions start with the same
--web-ui-port(for example8080), producingaddress already in use. - BUG-T7 → FU-P13-T9 (P0):
resources/listandresources/templates/listprobing may return non-standard error shapes in some client paths.
Disclaimer (Codex App)
mcpbridge-wrapper normalizes Xcode MCP responses, but it does not control Codex App internals. Codex App transport/session behavior may change independently from Codex CLI and from this wrapper. If App and CLI differ, treat that as client-specific behavior first and verify with exact versions, config, and logs.
Documentation
- Installation Guide
- Broker Mode Guide - Configuration, migration, rollback, and operations
- Web UI Dashboard - Real-time monitoring and audit logging
- Cursor Setup
- Claude Code Setup
- Codex CLI Setup
- Troubleshooting
- Tools Reference
- Architecture
- Contributing - Development guide and quality gates
Development
See CONTRIBUTING.md for development setup and contribution guidelines.
Quick quality gate check:
make test # Run tests with coverage make lint # Run ruff linter make typecheck # Run mypy type checker
Or run all gates:
make test && make lint && make typecheck
Performance
- Overhead: <0.01ms per transformation
- Memory: <10MB footprint
- Coverage: 91.62% test coverage
License
MIT License - see LICENSE for details.
Acknowledgments
- Apple's Xcode team for the MCP bridge functionality
- The MCP protocol specification
- The Cursor, Claude, and Codex teams for AI-powered development tools