XcodeBuildMCPdocs
Install

Contributing

How to set up, build, and submit changes to XcodeBuildMCP.

XcodeBuildMCP lives at getsentry/XcodeBuildMCP. Use the issue tracker for bugs, proposals, and larger changes that need design discussion before code.

Prerequisites#

RequirementNotes
macOSXcodeBuildMCP shells out to Apple developer tools, so development is macOS-only.
XcodeInstall Xcode and make sure Command Line Tools point at the Xcode you use for testing.
Node.js 18+The package targets Node 18 and later.
npmUsed for install, build, test, and local scripts.
AXe (optional)Required only if you work on UI automation or simulator capture tools. Bundle it locally with npm run bundle:axe. The script downloads pre-built artifacts into bundled/axe, which the server resolves automatically at runtime.
shell
npm run bundle:axe

If you prefer a system-wide install on PATH, brew tap cameroncooke/axe && brew install axe also works, the resolver falls back to PATH after checking bundled/.

Clone, install, build#

shell
git clone https://github.com/getsentry/XcodeBuildMCP.git
cd XcodeBuildMCP
npm install
npm run hooks:install
npm run build

# Verify the build via the CLI
node build/cli.js --help

# Or start the MCP server (stdio)
node build/cli.js mcp

npm run hooks:install configures the repository-managed git hooks from .githooks/.

Point your MCP client at the dev build#

Use the built cli.js directly while developing. Replace the path with your checkout path.

json
{
  "mcpServers": {
    "XcodeBuildMCP": {
      "command": "node",
      "args": ["/path/to/XcodeBuildMCP/build/cli.js", "mcp"],
      "env": {
        "XCODEBUILDMCP_DEBUG": "true"
      }
    }
  }
}

Iterating#

Most XcodeBuildMCP code is shared between the CLI and MCP server: the tools themselves, the manifests that describe them, the runtime layer that receives a request, and the rendering layer that turns its output into text or JSON. That means most tool behavior is testable through the CLI without an MCP client in the loop:

shell
node build/cli.js simulator list
node build/cli.js simulator build --scheme MyApp --project-path ./MyApp.xcodeproj

Reach for the tools below only when you are validating MCP-specific behavior: tool advertising in tools/list, the structured content envelope, annotations, the server lifecycle, or anything the CLI surface does not exercise.

Testing the MCP layer#

When an MCP client launches the server, it spawns the server as a long-lived subprocess at startup. The running Node process holds the build that was on disk when it spawned, so rebuilding does not affect it. To pick up changes you have to kill and respawn the server, which drops the client's MCP connection and forces a reconnect (a manual click or a full editor restart, depending on the client). Three patterns avoid that loop:

Run npm run inspect for the MCP Inspector interactive UI. Browser-based MCP client where you can list tools, call them with form inputs, view structured responses, and (importantly) see the server's stderr logs that real MCP clients usually hide.

Best for human exploration and debugging when you want the full server-side picture.

shell
npm run inspect

Run npm run dev:tsup in your terminal so the build rebuilds on save. The Inspector flows pick up the latest build on the next call (fresh subprocess); Reloaderoo needs an explicit restart_server call after each rebuild.

Pre-commit checks#

If you ran npm run hooks:install, the git pre-commit hook automatically runs npm run format:check, npm run lint, npm run build, and npm run docs:check when you commit. That is a safety net, not a substitute for development-time checks. Catching problems while you iterate is faster than catching them at commit time, and the hook does not run typecheck, lint:fix, or test.

Full checklist to run yourself during development:

shell
npm run lint:fix
npm run typecheck
npm run format
npm run build
npm run docs:check
npm test
Type errors block changes

Do not commit TypeScript errors. Fix the type issue instead of suppressing it with unsafe casts, any, @ts-ignore, or @ts-nocheck.

Making a change#

Start from an up-to-date main branch and create a focused branch:

shell
git checkout main
git pull origin main
git checkout -b feature/issue-123-add-simulator-filter

Common branch prefixes:

PrefixUse it for
feature/issue-123-descriptionNew behavior.
bugfix/issue-456-descriptionBug fixes.
hotfix/critical-descriptionUrgent production fixes.
docs/update-topicDocumentation-only work.
refactor/improve-topicInternal restructuring without behavior changes.

Keep commits atomic. Each commit should explain one logical change. If your change affects users, add a CHANGELOG.md entry under ## [Unreleased] in the correct section: Added, Changed, Fixed, or Removed.

Follow the existing TypeScript patterns:

  • Use Zod schemas for runtime validation.
  • Keep tool logic testable through injected executors when it orchestrates external commands.
  • Test logic functions, not handler functions.
  • Do not add formatted output by hand. Use the domain result and rendering model described in Architecture.

Submitting#

Open a pull request from your branch and include:

SectionWhat reviewers need
SummaryWhat changed and why.
Background or detailsContext, issue links, and important constraints.
SolutionThe implementation approach and key tradeoffs.
TestingCommands you ran and any manual validation.
NotesRisk, follow-up work, or reviewer focus areas.

Link related issues. For major features or risky behavior changes, open an issue first and get alignment before spending time on implementation.

Project templates#

The scaffolding tools pull iOS and macOS templates from separate repositories:

Use local template overrides when developing template changes:

shell
export XCODEBUILDMCP_IOS_TEMPLATE_PATH=/path/to/XcodeBuildMCP-iOS-Template
export XCODEBUILDMCP_MACOS_TEMPLATE_PATH=/path/to/XcodeBuildMCP-macOS-Template

Optional version overrides:

Env varScope
XCODEBUILD_MCP_TEMPLATE_VERSIONShared fallback for both templates.
XCODEBUILD_MCP_IOS_TEMPLATE_VERSIONiOS template only.
XCODEBUILD_MCP_MACOS_TEMPLATE_VERSIONmacOS template only.

When testing through an MCP client, put the same env vars in that client's mcpServers.XcodeBuildMCP.env block.