Figment.so
Mac hostingWebsite hostingGuidesHow to usePricing

Run an API-Backed Coding Agent on a Hosted Mac

An API-backed coding agent needs an always-on Mac: a place to keep a cloned repo, run git, call an LLM API, write files, and commit results on a schedule. A laptop that sleeps or an ephemeral CI runner that is torn down after each job cannot hold that state. A hosted Mac can.

This guide gives the direct recommendation, the runtime components to verify, a tool-permission matrix, and a launchd loop you can copy. Start a plan at /mac-hosting/start.

Choose the Right Mac Plan for the Job

The right plan is the smallest one that runs your agent's actual binaries.

Agent workloadPlanWhy
Call LLM API, run git, write files, commitFigment virtual Intel macOS — $29/mo2 vCPU, 8 GiB RAM, 80 GiB disk; browser-console access; Intel toolchain
Cross-compile an arm64 app or a universal binaryVirtual Intel macOS — $29/moXcode 26 or earlier on Intel can cross-compile arm64 and sign supported targets
Execute ARM-only binaries, Xcode 27, or visionOS workPhysical M-series — from $95/mo entryApple silicon required; exact chip/RAM/disk confirmed in the quote
CI setup, backups and monitoring includedManaged Build Mac — $249/moOne M-series Mac, CI setup, backups, monitoring, 30 minutes monthly support
Two Macs, two runners, one hour monthly supportManaged Mac Team — $999/moTwo M-series Macs, two CI runners, team setup, backups, monitoring

Recommendation. For a pure "fetch a task, call an LLM, write a patch, open a PR" agent, the $29 virtual Intel macOS is the right starting plan. It is a real macOS environment that runs compatible Intel Mac toolchains in the VM itself, including supported Xcode 26-or-earlier versions, reached through a browser console. It has no GPU acceleration and no audio, and it will not execute ARM-only binaries. If your agent runs ARM-only tools, Xcode 27, visionOS simulators, or heavy local model inference, request an M-series configuration — the $95 entry is a starting price, and the specific chip, RAM and disk are set in the quote. Physical Intel $49 and physical M-series offers currently collect requests until supply is confirmed.

Entry-price context from a primary source: CloudMac pricing lists an M4 / 16 GB / 256 GB mini at $99.99/month, with 512 GB and 1 TB storage rows marked fully reserved. Per the coordinator check on 2026-11-10, cloudmac.org also publishes a $999/year option, which is $83.25 effective monthly — cheaper than 12 × $95 at Figment's M-series entry. Figment's $95 is an M-series entry price, not a specified M4/16 GB build, so treat this as an entry-price comparison, not equal hardware. What Figment adds at the Managed Build and Team tiers is the specific managed CI work: CI setup, backups, monitoring, and support minutes.

Runtime Bill-of-Materials

Before launching the agent, verify every component is present. Run this once from the browser-console terminal on first login:

#!/usr/bin/env bash
# agent-bom-check.sh — verify runtime components on first login
set -euo pipefail

check() {
  local name="$1" cmd="$2"
  if eval "$cmd" >/dev/null 2>&1; then
    echo "OK       $name"
  else
    echo "MISSING  $name"
    MISSING=1
  fi
}

MISSING=0
check "git"         "git --version"
check "python3"     "python3 --version"
check "node"        "node --version"
check "curl"        "curl --version"
check "jq"          "jq --version"
check "LLM key"     "security find-generic-password -a \"$USER\" -s llm-api-key -w"
check "workspace"   "[ -d \"$HOME/agent-workspace\" ]"

exit "$MISSING"

Any MISSING line stops the agent before it runs a bad cycle. Install the missing tool, re-check, then proceed.

Tool-Permission Matrix

Every tool the agent uses needs an explicit, minimal grant. Over-permissioned agents are harder to audit and easier to exploit.

Tool / capabilityCredentialScopeWhere it lives
git clone / pushMachine-user token or deploy keySingle repo, writeKeychain generic password
LLM API callBearer tokenOne project / one keyKeychain generic password
Task queue fetchBearer tokenRead-only task endpointKeychain generic password
File writesNone special~/agent-workspace/ onlyRun as a non-admin user
Outbound HTTPSNone443 to LLM + git host + queueUpdate your own egress allowlist if you run one
Scheduled executionUser launchd agent~/Library/LaunchAgents/No root; user-only

Store secrets in the login keychain, not in a dotfile:

# one-time, interactive
security add-generic-password -a "$USER" -s llm-api-key -w
# runtime
LLM_API_KEY=$(security find-generic-password -a "$USER" -s llm-api-key -w)
export LLM_API_KEY

Do not export every secret into a plain-text file and source it — that file will be read by every process the agent spawns and backed up by anything that touches the home directory. Transfer secret names between hosts and re-enter values through the keychain on the new host.

Implement the Agent Loop

A minimal loop: fetch a task, call the LLM, apply the patch, commit, push. Run it under launchd so it survives crashes and restarts at login.

#!/usr/bin/env bash
# agent-loop.sh — one iteration; launchd re-runs it on StartInterval
set -euo pipefail

WORKSPACE="$HOME/agent-workspace"
LOG="$WORKSPACE/agent.log"
TASK_API="https://your-task-queue.example.com/tasks/next"

log() { printf '[%s] %s\n' "$(date -u +%FT%TZ)" "$*" >> "$LOG"; }

LLM_API_KEY=$(security find-generic-password -a "$USER" -s llm-api-key -w)
TASK_TOKEN=$(security find-generic-password -a "$USER" -s task-token -w)
export LLM_API_KEY TASK_TOKEN

cd "$WORKSPACE"
git fetch --quiet origin
git checkout --quiet main
git reset --quiet --hard origin/main

TASK=$(curl --silent --show-error --fail --max-time 15 \
  -H "Authorization: Bearer $TASK_TOKEN" "$TASK_API") \
  || { log "task fetch failed"; exit 1; }

[ -z "$TASK" ] && { log "queue empty"; exit 0; }

TASK_ID=$(printf '%s' "$TASK" | jq -r '.id')
PROMPT=$(printf '%s' "$TASK" | jq -r '.prompt')
log "start $TASK_ID"

PATCH=$(python3 agent_client.py --prompt "$PROMPT") \
  || { log "llm failed $TASK_ID"; exit 1; }

printf '%s' "$PATCH" | git apply - \
  || { log "patch failed $TASK_ID"; exit 1; }

git add -A
git commit -m "agent: task $TASK_ID"
git push origin HEAD:refs/heads/agent/"$TASK_ID"
log "done $TASK_ID"

Install as a user launchd agent — see Apple's launchd agent guide and the launchd.plist(5) reference:

<!-- ~/Library/LaunchAgents/com.yourteam.agent.plist -->
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN"
  "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
  <key>Label</key><string>com.yourteam.agent</string>
  <key>ProgramArguments</key>
  <array>
    <string>/bin/bash</string>
    <string>/Users/agent/agent-workspace/agent-loop.sh</string>
  </array>
  <key>StartInterval</key><integer>60</integer>
  <key>KeepAlive</key>
  <dict>
    <key>SuccessfulExit</key><false/>
  </dict>
  <key>StandardOutPath</key>
  <string>/Users/agent/agent-workspace/agent.log</string>
  <key>StandardErrorPath</key>
  <string>/Users/agent/agent-workspace/agent-err.log</string>
</dict>
</plist>

KeepAlive with SuccessfulExit: false restarts the script only on non-zero exit, so a clean "queue empty" exit stays quiet. StartInterval: 60 schedules a fresh poll each minute regardless. Load it with launchctl bootstrap gui/$UID ~/Library/LaunchAgents/com.yourteam.agent.plist.

Failure and Recovery Checks

Before leaving the agent unattended, verify each of these:

  • agent-bom-check.sh prints OK for every line.
  • Push one known task through the queue and confirm a commit appears on agent/<id>.
  • pkill -f agent-loop.sh; within 60 seconds confirm launchctl list | grep yourteam.agent shows a new PID.
  • After the first 30 minutes, grep -Ei 'fail|error|denied' agent.log agent-err.log returns nothing unexpected.
  • Rotate the deploy key, re-add it via security add-generic-password, and run one task to prove rotation.
  • Confirm your egress allowlist (if any) covers the LLM endpoint, the task queue, and your git host.

Cost and Operating Limits

The $29/month virtual Intel macOS is the entry price for one continuously-running agent. It is a monthly plan — a two-week run still costs the full month; there is no published daily rate at this tier. Plan around these limits:

  • Concurrency. One loop per plist. Add a second plist with its own workspace and label for a parallel agent on the same VM.
  • Disk. 80 GiB included. Large monorepos and accumulated patch files will fill it; add a git gc --aggressive and workspace-cleanup step.
  • Memory. 8 GiB RAM is enough for API-driven agents and git. Local model inference, Xcode device builds, or large simulator runs want an M-series plan.
  • Architecture. ARM-only binaries will not run on the Intel VM. If any step shells out to an ARM-only tool, catch its exit code — do not count a failed invocation as a successful loop.
  • Tax and fees. Taxes, card fees, and any setup charges are as shown in your actual Figment offer at checkout; nothing is pre-assumed here.

When the job grows into multi-step compilation, signing, or simulator testing, move to an M-series plan (from $95/mo entry) or the Managed Build Mac ($249/mo) if you want CI setup, backups, and monitoring handled.

Start or Migrate the Workload

To start fresh, request your hosted Mac, log in via the browser console, and run agent-bom-check.sh. To migrate an existing agent:

  1. On the old host, list the keychain entry names the agent uses (llm-api-key, task-token, deploy key passphrase). Do not export values to a file.
  2. Push the current working branch so no state is left locally.
  3. On the new host, security add-generic-password each entry interactively. Clone the repo into ~/agent-workspace.
  4. Copy the launchd plist, update the absolute paths for the new user, and launchctl bootstrap gui/$UID it.
  5. Send one test task and confirm the commit appears before you decommission the old machine.

More in this cluster: Mac agent API polling · Mac agent signed webhooks · GitHub Actions self-hosted runner on Mac. Full plan details and the start form are at /mac-hosting.


Subscribe for Figma design and website publishing guides.


Figment.so

Contact

Twitter

Website pricing

Compute index

About

Privacy

Terms