Sentry’s XcodeBuildMCP wraps Xcode’s command-line toolchain in a Model Context Protocol server so AI agents can build, test, and inspect iOS and macOS projects without reinventing Apple’s build system. The package ships as both a CLI and an MCP server from a single install, includes optional skill files to prime agents, and exposes the same tools whether you call them from a terminal or from Cursor.
This is the first platform-specific build toolchain MCP to hit GitHub Trending (rank #3 for TypeScript). It represents a pattern: instead of building custom build orchestrators for agents, wrap the existing platform toolchain and handle the impedance mismatch at the MCP boundary.
Why This Matters
Most MCP servers expose general-purpose tools (filesystem, HTTP, database). XcodeBuildMCP exposes a stateful, GUI-heavy IDE toolchain that expects schemes, provisioning profiles, and signing certificates. The challenge is not running xcodebuild. The challenge is translating an agent’s intent (“build this project for TestFlight”) into the correct sequence of xcodebuild flags, then parsing the output into structured tool results.
The dual-mode packaging solves a different problem: developers want to test tools manually before handing them to agents. Shipping a CLI and an MCP server in one package means you can run xcodebuildmcp build --scheme MyApp in your terminal, verify the output, then expose the same logic to Claude Desktop or Cursor without changing code.
Architecture
Dual-Mode Entry Points
The package exports two binaries:
xcodebuildmcp(CLI mode): parses argv, calls tool functions, prints to stdout.xcodebuildmcp mcp(MCP server mode): starts stdio transport, registers tools, waits for JSON-RPC calls.
Both modes share the same tool implementation layer. The CLI wraps each tool in a command-line parser. The MCP server wraps each tool in a JSON-RPC handler. The actual logic (invoke xcodebuild, parse output, return structured result) lives in shared modules.
// Simplified structure
class XcodeTool {
async build(params: BuildParams): Promise<BuildResult> {
const args = this.buildArgs(params);
const proc = spawn('xcodebuild', args);
const output = await this.captureOutput(proc);
return this.parseResult(output);
}
}
// CLI mode
program
.command('build')
.action(async (opts) => {
const tool = new XcodeTool();
const result = await tool.build(opts);
console.log(JSON.stringify(result, null, 2));
});
// MCP mode
server.setRequestHandler(CallToolRequestSchema, async (request) => {
if (request.params.name === 'build') {
const tool = new XcodeTool();
const result = await tool.build(request.params.arguments);
return { content: [{ type: 'text', text: JSON.stringify(result) }] };
}
});
This pattern keeps tool logic testable and reusable. You can unit-test the XcodeTool class without spinning up an MCP server or parsing CLI flags.
Tool Inventory
XcodeBuildMCP exposes tools for:
- Project inspection: list schemes, targets, configurations.
- Build orchestration: build for simulator, device, or archive.
- Test execution: run unit tests, UI tests, or specific test plans.
- Artifact management: export IPA, locate build products, read logs.
Each tool accepts structured parameters (scheme name, configuration, destination) and returns structured results (exit code, stdout, stderr, parsed warnings/errors).
The MCP server does not attempt to parse Xcode’s full build log into a semantic graph. It returns raw output plus a success/failure flag. Agents must parse warnings and errors themselves or ask for clarification.
Skill-Based Priming
XcodeBuildMCP ships two optional skill files:
- MCP Skill: instructions for using the MCP server’s tools (when to call
build, how to interpret results). - CLI Skill: instructions for using the CLI directly (when to run
xcodebuildmcp build, how to chain commands).
Skills are plain text files you paste into your agent’s system prompt or project context. They do not change the MCP server’s behavior. They prime the agent with examples and guardrails.
Example MCP skill snippet:
When building an iOS project:
1. Call list_schemes to discover available schemes.
2. Call build with scheme and destination (e.g., "platform=iOS Simulator,name=iPhone 15").
3. If build fails, call show_build_log to retrieve full output.
4. Do not assume scheme names. Always list first.
This is instruction-based priming, not tool-based enforcement. The agent can still call build without calling list_schemes first. The skill reduces trial-and-error by front-loading common patterns.
State Management Boundary
Xcode maintains state in:
- Derived data: incremental build artifacts, indexes, module caches.
- Provisioning profiles: installed in
~/Library/MobileDevice/Provisioning Profiles. - Keychains: code-signing identities, certificates.
- Simulators: booted devices, installed apps.
XcodeBuildMCP does not manage this state. It assumes Xcode and the macOS environment are already configured. If an agent calls build and the provisioning profile is missing, xcodebuild fails and the MCP server returns the raw error. The agent must interpret the error and either ask the user to fix it or call a different tool.
This is a deliberate boundary. Wrapping Xcode’s signing and provisioning workflows would require reimplementing Apple’s entire certificate management system. Instead, XcodeBuildMCP exposes the build tools and lets agents handle failures by asking for human intervention.
Deployment Shape
Installation Paths
| Method | Binary Location | MCP Server Invocation |
|---|---|---|
| Homebrew | /opt/homebrew/bin/xcodebuildmcp | xcodebuildmcp mcp |
| npm global | ~/.npm-global/bin/xcodebuildmcp | xcodebuildmcp mcp |
| npx on-demand | (none, runs in temp dir) | npx -y xcodebuildmcp@latest mcp |
Homebrew bundles Node.js runtime with the package. npm requires Node.js 18+ already installed. npx downloads and caches the package on first run.
Most MCP clients (Cursor, Claude Desktop) expect a command they can spawn. You configure them with:
{
"mcpServers": {
"xcodebuild": {
"command": "xcodebuildmcp",
"args": ["mcp"]
}
}
}
Or for npx:
{
"mcpServers": {
"xcodebuild": {
"command": "npx",
"args": ["-y", "xcodebuildmcp@latest", "mcp"]
}
}
}
The MCP server runs as a child process. The client sends JSON-RPC requests over stdin, reads responses from stdout. Logs go to stderr.
Security Boundaries
XcodeBuildMCP shells out to xcodebuild, which can execute arbitrary build scripts embedded in Xcode projects. If an agent opens a malicious project and calls build, the build scripts run with the user’s permissions.
Mitigations:
- Sandboxing: run the MCP server in a macOS sandbox or container (not implemented by default).
- Approval prompts: configure your MCP client to require human approval before calling
buildortest. - Read-only mode: use inspection tools (
list_schemes,show_build_settings) without calling build tools.
The package does not implement tool-level permission checks. If the MCP server is running, all tools are callable. You enforce boundaries at the client level (approval prompts, tool allowlists).
Failure Modes
Invalid Parameters
If an agent calls build with a nonexistent scheme, xcodebuild exits with code 65 and writes an error to stderr. The MCP server captures this and returns:
{
"success": false,
"exitCode": 65,
"stderr": "xcodebuild: error: Scheme 'NonExistent' is not currently configured for the build action."
}
The agent must parse the error text. There is no structured error schema. This is a limitation of wrapping xcodebuild, which does not emit machine-readable error codes.
Provisioning and Signing Failures
If the agent calls build for a device destination and the provisioning profile is missing, xcodebuild fails during the code-signing phase. The error appears deep in the build log. The MCP server returns the full log as a text blob. The agent must either parse it or call show_build_log and ask the user to fix signing.
This is the most common failure mode. Agents cannot fix provisioning issues programmatically. They can only surface the error and request human intervention.
Simulator State
If the agent calls test and the target simulator is not booted, xcodebuild may hang or fail with a timeout. XcodeBuildMCP does not manage simulator lifecycle. You must boot simulators manually or configure Xcode to boot them automatically.
A future version could expose xcrun simctl tools to boot, shutdown, and reset simulators. For now, simulator management is out of scope.
Observability
The MCP server logs to stderr. Most MCP clients capture stderr and display it in a debug panel. Logs include:
- Tool calls (name, parameters).
xcodebuildinvocations (full command line).- Exit codes and output sizes.
There is no structured telemetry. If you want metrics (tool call latency, failure rates), you must wrap the MCP server in a proxy that logs to your observability stack.
The CLI mode prints results to stdout as JSON. You can pipe this to jq or a log aggregator.
Trade-Offs
| Aspect | XcodeBuildMCP Approach | Alternative |
|---|---|---|
| Tool boundary | Wrap xcodebuild CLI | Reimplement build logic in TypeScript |
| Error handling | Pass raw stderr to agent | Parse errors into structured schema |
| State management | Assume Xcode is configured | Manage provisioning, signing, simulators |
| Packaging | Single binary, dual mode | Separate CLI and MCP packages |
| Skill priming | Optional text files | Hardcoded tool descriptions |
The core trade-off is fidelity vs. abstraction. Wrapping xcodebuild gives you full fidelity (every flag, every option) but zero abstraction (agents must understand Xcode’s quirks). Reimplementing build logic gives you abstraction (simplified tool calls) but incomplete fidelity (you will never cover every Xcode feature).
Sentry chose fidelity. This makes XcodeBuildMCP a thin adapter, not a build system.
Technical Verdict
Use XcodeBuildMCP when:
- You want agents to build, test, or inspect iOS/macOS projects without leaving the MCP ecosystem.
- You already have Xcode configured (schemes, signing, provisioning) and need agents to automate repetitive tasks.
- You want a single install that works as both a CLI (for manual testing) and an MCP server (for agents).
- You are comfortable with agents receiving raw
xcodebuilderrors and asking for clarification.
Avoid XcodeBuildMCP when:
- You need agents to configure Xcode from scratch (provisioning, signing, scheme creation). This tool assumes Xcode is ready.
- You want structured error schemas. Errors are raw text from
xcodebuild. - You need cross-platform build automation. This is macOS-only.
- You want the MCP server to manage simulator lifecycle. Simulator tools are not yet exposed.
The dual-mode packaging pattern is worth stealing. Shipping a CLI and an MCP server from the same codebase reduces maintenance burden and makes tools easier to test. The skill-based priming pattern is less proven. It works if your agents read system prompts carefully, but it does not enforce guardrails at the tool level.