Headless Xcode: From Prompt to Simulator with MCP Apple's Xcode 27 beta 5 introduces `xcrun mcp-server`, a headless MCP server that exposes Xcode's build, preview, and simulator tools to external coding agents without opening the Xcode UI. Combined with Apple's exportable agent skills, it enables an agent like Claude Code to create, build, and verify a project entirely from the command line, with permissions gated by per-agent approval and `sudo`-enabled settings. Xcode's MCP server lets a coding agent create files, build, render previews, and drive the simulator. Until now, those tools disappeared when you quit Xcode. Xcode 27 beta 5 adds xcrun mcp-server , which exposes the same tools without opening the Xcode UI. Combined with Apple's exportable agent skills, it lets an external agent create a project, build it, render previews, and verify interactions in the simulator. I'll use Claude Code to do exactly that with a small reading list app. Everything here was run on Xcode 27.0 beta 5 build 27A5237l with Claude Code as the MCP client. You need that Xcode build, Claude Code, and an administrator account to enable the service. This is beta software and the CLI surface may change. Quit Xcode. We're getting started. Starting the server without the Xcode UI Headless mode is off until you turn it on, and every command that changes permissions needs sudo : enable flips the switch; start launches the service and is a no-op if it is already up. unsafeAlwaysAllowAllAgents is the one thing enable lets you change, and false — the default — means every agent gets approved individually. More on that later. xcrun mcp-server status reports where things stand: Wiring the project: MCP server and Apple's skills Two things have to be in place before an agent is any use here, and both belong in the project repo rather than in your machine's global config: the server registration, which is how the agent reaches Xcode at all, and Apple's skills, which are how it knows what to do once it gets there. Registering the MCP server in the repo The MCP server itself is a stdio bridge. Pinning DEVELOPER DIR in the registration keeps the beta scoped to the agent and leaves the stable Xcode selected for day-to-day work: Everything after -- is the command the bridge runs, so the flags belong to claude rather than to xcrun . --scope project writes a .mcp.json at the repository root. The registration travels with the repository, but every developer still approves it locally. The resulting file is small enough to hand-edit later: Point DEVELOPER DIR at wherever the beta actually lives. You can omit the variable entirely to use the Xcode selected by xcode-select . When set, DEVELOPER DIR takes precedence without changing the selection for other terminals. Exporting Apple's skills into the repo Tools are verbs: build this, render that. Skills tell the agent when to use them and how Apple expects SwiftUI code to be structured. One command copies Apple's skills next to .mcp.json : Xcode launches and shows its window while exporting the skills — its only on-screen appearance in this entire headless workflow. The skills live inside Xcode rather than the CLI, which is why the command prints Launching Xcode... . Existing skills are skipped rather than overwritten, so pass --replace-existing when you re-export after an update. Pass --output-dir an absolute path. The export is performed by Xcode over XPC Apple's system for communication between processes , not by your shell, so a relative path may resolve outside your project and fail. Each skill is a plain SKILL.md with name and description frontmatter, most with a references/ directory of deeper material and occasionally a scripts/ directory: Putting them under .claude/skills/ is what makes Claude Code discover them automatically, and discovery is relative to the directory the agent was started in — so the agent has to be started in the project, the same place the server registration lives. Understanding the two permission gates After you start an agent, its first request to the MCP server waits while the headless service authorizes two things independently. The first gate is the agent itself. This prompt appears: The prompt comes from the headless service, not from Claude Code. The grant is keyed to the code signature rather than the app name, which is why the dialog says agents from Anthropic PBC . Approving it gives the agent every tool the server exposes: build, test, and modify your code , as the dialog says. An Xcode icon appears in the menu bar as the only visible trace of the setup. Click it to open the Background Activity window: It lists approved agents, their current activity, and any open workspaces. Quit shuts down the service, just like xcrun mcp-server stop . A folder grant is the second gate, and it gets its own prompt the moment the agent tries to open or create something: The phrase Any Xcode project inside this folder matters. The grant is recursive and does not expire unless you pick Allow for 24 Hours . status shows both gates now: Both grants carry an id, and that id is how you revoke them later. Skipping the prompts One unsafe flag skips both prompts: The Xcode item in the menu bar normally collapses to a hammer with no background. When an agent connects, it briefly expands into a colored badge: blue for individual approvals and red for unsafe mode. The red badge is a security warning, not an error. While Xcode is handling an agent request, the hammer changes into rotating arrows — for example, while building and launching the app on a simulator. The color still reflects the permission mode; the animation is the activity indicator. The flag is named after agents, but it bypasses the folder gate too. It trusts every process on the machine with every Xcode project it can reach, leaving no individual grant in status to revoke. Disable and re-enable the service without the flag to return to individual prompts. To remove any stored grants, run: The next connection asks for approval again. Creating the project from a prompt With the setup complete, describe the project: Create a new multiplatform SwiftUI app called ReadingListExample in a subfolder, no storage, Swift Testing. The agent discovers what the templates actually offer instead of guessing at identifiers. The XcodeListTemplates tool with kind: "project" returns each template along with its option schema — for the standard App template that is storageType , hostInCloudKit , and testingSystem . Then the XcodeNewProject tool instantiates it: That JSON is the tool call, not something you write. Claude Code collapses tool calls to a one-line summary; ⌃ + O shows the parameters and response. destinationPath is the parent directory. Asking for a subfolder keeps .mcp.json and the skills at the repository root while Xcode creates