Setting up a self-hosted agent on macOS is a great way to gain control over your build environment, especially for iOS or macOS-specific tasks (like Xcode builds) that require specific versions or tools.
As of 2026, the v3.x agent is the standard, supporting both Intel (x64) and Apple Silicon (ARM64) Macs.
Before touching your Mac, ensure you have the following:
- A Mac running macOS 11.0 (Big Sur) or later.
- Azure DevOps Permissions: You must be an Agent Pool Administrator in your organization.
- A Personal Access Token (PAT):
- In Azure DevOps, go to User Settings (top right) > Personal access tokens.
- Click + New Token.
- Click Show all scopes at the bottom.
- Select the scope: Agent Pools (Read & Manage).
- Copy the token immediately - you won't see it again.
- Log in to your Azure DevOps organization (
https://dev.azure.com/{your-org}). - Go to Organization Settings (bottom left) > Agent pools.
- Select the Default pool (or create a new one).
- Click the Agents tab and then click New agent.
- Select macOS and choose your architecture:
- x64: For Intel Macs.
- ARM64: For Apple Silicon (M1, M2, M3, M4) Macs.
- Click Download.
Open your Terminal on the Mac and run these commands:
xattr -c ~/Downloads/vsts-agent-osx-x64-4.266.2.tar.gzmkdir my-agent && cd my-agentReplace the filename below with the one you actually downloaded:
tar zxvf ~/Downloads/vsts-agent-osx-x64-4.266.2.tar.gzRun the config script. It will ask you for details interactively:
./config.shWhat to enter when prompted:
- Server URL:
https://dev.azure.com/{your-organization} - Authentication type: Press
Enter(defaults to PAT). - Personal access token: Paste the PAT you created earlier.
- Agent pool: Press
Enter(defaults to "Default"). - Agent name: Give it a friendly name (e.g.,
Mac-Mini-01). - Work folder: Press
Enter(defaults to_work).
You can run the agent in two ways:
This runs the agent directly in your terminal. If you close the terminal, the agent stops.
./run.shThis ensures the agent starts automatically when the Mac boots and runs in the background.
# Install the service
./svc.sh install
# Start the service
./svc.sh start- Stay Updated: Agents usually auto-update, but you can manually trigger an update by right-clicking the pool in Azure DevOps and selecting Update all agents.
- Xcode Versions: If you are building iOS apps, ensure you have the correct version of Xcode installed on the Mac. The agent will automatically detect it as a "Capability."
- Security: If you get a "Developer cannot be verified" popup on macOS, run:
xattr -rd com.apple.quarantine ~/my-agent
When running MAUI or Android pipelines, you may encounter an error:
##[error]No agent found in pool Default satisfies both of the following demands: MSBuild, JDK
On macOS (especially Apple Silicon), the agent doesn't always automatically register these capabilities even if the tools are installed.
- MSBuild Demand: Modern .NET (MAUI) uses the
dotnetCLI. TheMSBuilddemand is often a legacy check that macOS agents don't "claim" by default. - JDK Demand: Tasks like
AndroidSigning@3automatically add a hidden demand forJDK.
Satisfy these demands in the Azure DevOps portal without changing your code:
- In Azure DevOps, go to Project Settings > Agent pools.
- Select your pool (e.g.,
Default) and click the Agents tab. - Select your agent (e.g.,
Mac-M3-Build-01) and go to the Capabilities tab. - Click Add capability and add the following:
| Key | Value (Example) |
|---|---|
| MSBuild | /usr/local/share/dotnet/dotnet |
| JDK | /Library/Java/JavaVirtualMachines/zulu-17.jdk/Contents/Home |
Note: You can usually just use True as the value if you aren't using the capability to define a path.
| Action | Command |
|---|---|
| Check Status | ./svc.sh status |
| Stop Agent | ./svc.sh stop |
| Start Agent | ./svc.sh start |
| Remove Agent | ./svc.sh uninstall then ./config.sh remove |
In your azure-pipelines.yml file, ensure your pool block matches the name of the pool where you registered the Mac:
pool:
name: 'Default'
demands:
- Agent.Name -equals Mac-M3-Build-01 # Targets your specific machine