Introduction¶
When developing macOS / iOS within DSH (DeepSeek Harness), there is a practical problem: building projects, running unit tests, viewing SwiftUI Previews, and operating the simulator are tasks typically completed within the Xcode UI, where the agent cannot intervene. DSH’s philosophy is “everything is a plugin,” and such capability gaps are usually filled by plugins.
Starting with Xcode 27, the system includes a built-in headless MCP service (xcrun mcp-server / xcrun mcpbridge), exposing these capabilities as MCP tools. However, to use them within DSH, a layer of bridging is required to convert these MCP tools into native DSH tools. dsh-mcp-xcode, introduced in this article, is such a plugin.
What is it¶
dsh-mcp-xcode is a DSH plugin maintained by nanshanyi. Its positioning in one sentence: bridging Xcode Headless MCP (xcrun mcpbridge) to native DSH tools. Once installed, the DSH agent can directly invoke all of Xcode’s headless capabilities without opening the Xcode UI.
In implementation, the plugin starts /usr/bin/xcrun mcpbridge via subprocess, implements an MCP (JSON-RPC 2.0) client on stdio itself, and registers each tool returned by tools/list as a DSH tool once the connection is established. Runtime environment requires Node >= 20, with zero runtime dependencies.
Core Features¶
After bridging, the capabilities available to the agent include:
- Create / Open projects, build, and test;
- Render SwiftUI Previews to PNG;
- Start the simulator and interact (tap / type / swipe);
- Read screenshots and accessibility hierarchies;
- Read OSLog.
As tested in Xcode 27, there are a total of 54 tools. The plugin registers them uniformly as DSH tools in the format xcode_<original_name>. Screenshots during tool invocation are automatically saved to an attachment and injected into the next round of model context via deferContext.
The plugin comes with a control tool xcode_mcp_status for checking connection status, forcing a reconnect, and viewing bridge stderr.
Additionally, there is a bridge self-healing mechanism: after the xcrun mcpbridge process crashes or is terminated, the xcode_* tools remain registered. The next invocation will automatically reconnect and re-register (checked by name reconciliation, preventing already registered errors), requiring no manual intervention.
Installation and Activation¶
First, confirm prerequisites: macOS + Xcode 27 or later (headless MCP has been built-in since Xcode 27 beta 5; earlier versions lack these commands; this project was developed and verified on 27.0 27A5237l), and ensure the headless service is enabled and running:
xcrun mcp-server status # Permission: enabled / mcp-server: running
sudo xcrun mcp-server enable # If not enabled
xcrun mcp-server start # If not running
Then, install with a single command:
# Install from GitHub (Recommended)
dsh plugin --profile web add "github:nanshanyi/dsh-mcp-xcode#v1.0.0"
# Or from a local path
dsh plugin --profile web add file:/path/to/dsh-mcp-xcode
This package uses self-describing mounting via dsh.bundle.patch: after installation, no need to edit any profile files; it takes effect after restarting DSH, is visible in the plugin list, and xcode_* tools are available for all sessions. If you previously manually wrote a line for this plugin in cordis.patch.yml, please remove it first to avoid double mounting.
The first connection will pop up an Xcode agent authorization dialog; granting permission once is sufficient. DSH is a signed app, so the authorization is permanent; unsigned clients expire in about 24 hours. When a build reports Operation not permitted, you need to authorize the folder containing the project for the headless service:
sudo xcrun mcp-server allow-folder /path/to/your/projects
Configuration (Optional)¶
All configuration is written under config in the patch line:
config:
clientName: deepseek-harness # Client name shown in the Xcode authorization dialog
bridgePath: /usr/bin/xcrun # Bridge executable
bridgeArgs: ['mcpbridge'] # Bridge arguments
includeTools: ['BuildProject', 'XcodeList*'] # Only register matching tools
excludeTools: ['StringCatalog*'] # Exclude matching tools
includeTools / excludeTools perform anchored matching based on the original Xcode tool names, supporting * and ? wildcards, case-sensitive, with excludeTools taking precedence. xcode_mcp_status is the control channel, not affected by filtering, and always registered. The common use of filtering is to slim down the model—the schema descriptions of 54 tools would occupy a significant amount of context.
Typical Usage¶
After the above steps, the tools are fully available. Simply describe the task in natural language, for example:
Open /path/to/Project.xcodeproj, run unit tests, and list the failing cases.
If connection issues arise, instruct the agent to call xcode_mcp_status (optionally with reconnect: true) to troubleshoot.
Use Cases and Notes¶
Suitable for developers building macOS / iOS agent workflows in DSH: tasks requiring Xcode capabilities such as build verification, batch test runs, viewing Preview render results, and simulator interaction.
Note a few points before use:
- Like all third-party plugins,
dsh-mcp-xcoderuns with the permissions of the current DSH process; it is recommended to check the source code and license (MIT, noted in README and package.json) before installing; - The connection uses Xcode’s official headless permission model; authorization is permanent once granted for signed apps;
- The plugin does not publish any services and does not modify Xcode permission storage; stopping or disabling the plugin will terminate the
mcpbridgesubprocess it holds.
Summary¶
dsh-mcp-xcode does things in a restrained manner: it ingests the 54 tools exposed by xcrun mcpbridge directly into DSH, paired with authorization guidance, bridge self-healing, and status troubleshooting tools, allowing the agent to complete builds, tests, and simulator operations without opening the Xcode UI.
- Community Directory: https://www.skillhub.cn/plugins/nanshanyi/dsh-mcp-xcode
- GitHub Repository: https://github.com/nanshanyi/dsh-mcp-xcode