Guide · · 7 min read

Headless Mac Virtual Display for AI Agents — No Dummy Plug Required

Running an AI agent on a headless Mac — a Mac mini sitting in a rack with no monitor attached — sounds straightforward until you try to take a screenshot or drive a browser. Without a display, macOS collapses the window server and most screen-capture tools return blank frames or refuse to launch entirely. The traditional fix is a dummy HDMI plug. Mirage is the software fix: a Swift daemon that uses the CGVirtualDisplay macOS API to create a persistent 4K virtual display that the OS treats as real hardware.

Why Headless Macs Break AI Agent Workflows

The problem isn't just aesthetics. Tools like Claude Computer Use, Peekaboo, and Playwright depend on a live display connection to function correctly. On a mac mini no monitor setup, macOS typically falls back to a 1024×768 framebuffer — if it renders anything at all. Screen-capture APIs return empty buffers. Accessibility APIs can silently fail. Browser automation that works perfectly on a developer laptop will produce blank screenshots in CI or on a server Mac.

Dummy plugs work around this at the hardware layer by lying to the GPU — they present a fake EDID telling macOS a 4K monitor is connected. But they're a physical device you have to ship to wherever the Mac lives, they can fall out, and they cap you at whatever resolution the plug was programmed with. They're also unnecessary since macOS 12.4, which shipped CGVirtualDisplay — a private-but-stable API for creating virtual displays entirely in software.

CGVirtualDisplay is the same API Apple uses internally for virtual displays in Sidecar and Universal Control. Mirage wraps it in a persistent daemon with a clean CLI, so you don't have to reverse-engineer the entitlements or manage the process lifecycle yourself.

How Mirage Works

Mirage is a Swift daemon that registers a virtual display with CGVirtualDisplayDescriptor, holds the CGVirtualDisplay handle open for the lifetime of the process, and exposes a simple CLI for status, resolution changes, and teardown. On launch it creates a 3840×2160 (4K) display at 60 Hz. macOS immediately treats it as a primary display — the window server comes fully online, screenshot APIs return real frames, and browser windows render at full resolution.

Because Mirage runs as a background daemon (managed via launchd or a simple brew services wrapper), the virtual display persists across SSH sessions, survives screensaver lock, and comes back automatically after a reboot. No babysitting required.

# Install Mirage via Homebrew
brew tap jkjoplin/mirage
brew install mirage

# Start the daemon (creates the virtual display immediately)
mirage start

# Confirm the display is live
mirage status

After mirage start, running system_profiler SPDisplaysDataType will show a new 3840×2160 display in the output — indistinguishable from a physically connected monitor from the OS's perspective.

AI Agent macOS Integration — Claude, OpenAI, Gemini, and More

The real value of a reliable headless Mac virtual display shows up when you wire AI agents into your infrastructure. Here's how Mirage integrates with the tools developers are actually using:

Claude Computer Use (headless Mac): Anthropic's computer-use capability drives the Mac desktop via screenshot + action loops. Without a display, the screenshot step fails silently and the agent has nothing to act on. With Mirage running, Claude sees a full 4K desktop and can click, type, and navigate normally — even on a Mac mini with zero physical peripherals.

OpenClaw: OpenClaw's browser control and Peekaboo integration both depend on Quartz window server APIs. Mirage gives OpenClaw a stable rendering target, which means browser automation, screen snapshots, and UI tree inspection all work without modification.

Peekaboo: Peekaboo uses ScreenCaptureKit to capture screenshots and perform UI automation. SCShareableContent requires a live display. Mirage satisfies that requirement so Peekaboo can run in fully unattended server environments.

Playwright / browser automation: Playwright's headed browser mode (useful for anti-bot evasion or visual regression testing) needs a display. With Mirage active:

# Playwright headed mode on a headless Mac — works with Mirage running
npx playwright test --headed

Browsers launch, render, and close cleanly. No DISPLAY environment variable hacks, no XQuartz, no virtual framebuffer workarounds — just a Mac that thinks it has a monitor.

OpenAI Operator: OpenAI's computer use agent (released January 2025) navigates web UIs to complete tasks autonomously. It renders and interacts with browser windows — which means it has the same display dependency as every other agent. A Mac mini running Operator jobs headlessly needs Mirage to give those browser windows somewhere to exist.

Google Project Mariner: DeepMind's Project Mariner controls Chrome to browse and complete tasks. Like Operator, it depends on a real rendering surface. Running Mariner unattended on a Mac means Mirage is the difference between a functional agent pipeline and a process that silently stalls waiting for a display that never appears.

browser-use and Open Interpreter: The open-source ecosystem is catching up fast. browser-use drives Chromium via LLM instructions; Open Interpreter executes code and controls the desktop. Both need a real display context on macOS. The same two-command Mirage install makes both work on a headless Mac.

Practical Setup: AI Agent Server on a Mac Mini

The typical production setup is a Mac mini acting as a dedicated AI agent host — running Claude agents, browser automation jobs, or computer-use workflows 24/7 with no monitor attached. Here's the minimal configuration:

# 1. Install and start Mirage
brew tap jkjoplin/mirage && brew install mirage
mirage start

# 2. Enable auto-start on login
brew services start mirage

# 3. Verify display resolution (should show 3840x2160)
system_profiler SPDisplaysDataType | grep Resolution

# 4. Optional: lock to a specific resolution
mirage set-resolution 2560x1440

From this point, any tool that needs a display — Claude Computer Use sessions, Peekaboo captures, Playwright tests, or OpenClaw browser automation — will find a stable 4K display waiting for it. The Mac behaves exactly like a workstation with a monitor plugged in, because as far as macOS is concerned, it does.

Note on entitlements: CGVirtualDisplay requires the com.apple.developer.cgvirtualdisplay.mojo entitlement. Mirage ships with this entitlement already configured in the signed binary — you don't need an Apple Developer account or custom entitlements to use it.

Get Mirage Running in Two Commands

One tap, one install, one mirage start. Your headless Mac gets a 4K display and your AI agents get a stable environment to work in.