Headless mode
README · Tool reference · Headless mode · Agent tooling · Schemas · Changelog
Xcode 27 adds xcrun mcp-server, a preview of an MCP server that runs without an open Xcode workspace, and that can grant code-signed agents access to a directory tree for a longer period instead of asking every time. Apple flags it as an early preview: some commands may not work in every configuration, and some settings or permissions may need an Xcode relaunch or a reboot to take effect.
sudo xcrun mcp-server enable
| Command | Description |
|---|---|
open <paths> | Launch if needed, then open workspaces/projects |
stop | Terminate the running server (no-op if not running) |
enable / disable | Turn headless mode on/off (sudo) |
status | Report permissions and, when running, the open workspaces |
approve <id> | Approve a pending agent or folder request (sudo). --always (signed agents and folders only) or --for-24-hours |
allow-folder <path> | Permit workspaces under a folder without waiting for a request (sudo). --always or --for-24-hours |
deny <id> | Deny a pending request, permitted agent, or permitted folder (sudo); denying an agent also stops the server |
clear-permissions | Remove all granted agent and folder permissions (sudo) |
reset-all | Delete all permission state and kill the server immediately (sudo); next use shows onboarding again |
show-logs | Dump the agent activity log to a file and print its path. Without a running server it collects the last 24 hours |
Every subcommand takes --format text\|json. There is no start — open launches the server.
show-logs is the audit trail: one line per agent connection, with the binary path, PID, signing team, and a summary on disconnect.
Xcode Service[850]: agent: Xcode/copilot-xcode [9d474085] | connected | binary: … | pid: 735 | signed by: VEKTX9H2N7 | version: 27.0/0.51.0
Xcode Service[55388]: agent: Claude Code [11bcb302] | disconnected | 25 tool calls over 15h 57m 48s
Request and permission ids come from mcp-server status. For unattended environments, sudo xcrun mcp-server enable --unsafe-always-allow-all-agents approves every agent upfront — Apple does not recommend it for at-desk use.
What actually runs
xcrun mcp-server is only a launcher, and so is xcrun mcpbridge — with headless mode on it launches or reuses the headless service through LaunchServices, so no Xcode window is needed. The server itself is Xcode Service.app, shipped inside Xcode at Xcode.app/Contents/Developer/Library/Xcode/Agents/Xcode Service.app with bundle identifier com.apple.dt.mcp-server and LSUIElement, so it has no Dock icon and no menu bar. It is started as a RunningBoard-managed application job — launchctl print gui/$(id -u)/application.com.apple.dt.mcp-server.<n>.<n> shows the job with managed_by = com.apple.runningboard. It is the same Xcode engine, not a separate reimplementation, and it can attach a UI later, so headless is a mode rather than a different product.
Permissions
Granted permissions are stored in a JSON file inside Xcode’s secure settings group container, readable only by the user:
~/Library/Group Containers/group.com.apple.dt.Xcode.SecureSettingsContainer/CodingAssistant/HeadlessPermissions/mcp-server.json
{
"version": 1,
"enabled": true,
"agentPermissions": [
{ "id": "1B162114-…", "trust": { "signed": { "signingIdentifier": "com.anthropic.claude-code", "teamIdentifier": "Q6L2SF6YDW" } } }
],
"folderPermissions": [
{ "id": "B9BAFD34-…", "subtreeRoot": "/Users/username/Developer/MyApp" }
]
}
Agent trust is a code-signing identity — team identifier plus signing identifier — not a filesystem path, so moving or renaming an approved agent binary does not invalidate its grant, but re-signing it does. Unsigned agents are recorded by path and a content hash, and can only be approved with --for-24-hours; --always is rejected for them.
Two things are worth knowing before enabling this:
- The identity that gets recorded is the process that launched
mcpbridge, notmcpbridgeitself. Wrapping the command (for exampletimeout xcrun mcpbridge) registers the wrapper as the agent. - An already-approved agent can widen its own reach: calling
XcodeOpenWorkspaceon a project outside every permitted folder adds that folder tofolderPermissionswithout a prompt, and launchingmcpbridgefrom an approved agent’s process tree grants the launcher a 24-hour agent permission of its own.
Tool surface in headless mode
Every tool that takes a tabIdentifier in a window takes a workspaceIdentifier instead: “Identifies the target workspace directly (used in headless mode): its workspace identifier (e.g. workspace1) or its absolute path.” It accepts either the identifier returned by XcodeOpenWorkspace/XcodeListWorkspaces (in practice something like workspace-LKfjPJCMBL) or the absolute path of the project. Prompts, skills, and scripts that hardcode tabIdentifier need updating for headless mode.
DocumentationSearch behaves the same in both modes: listed once its documentation asset is installed, absent from tools/list while it isn’t.