macOS Harness: Six Primitives and a Python Process on Your Mac
The simplest, thinnest harness that gives an LLM complete freedom to control a Mac.
At a glance
- What is it?
- browser-use/macos-harness is a thin Python harness that exposes screenshots, keyboard and coordinate input, Apple Accessibility, Apple Events, and a real browser to an LLM. It is early software with a narrow scope, and the design choice that makes it flexible is the same one that makes it risky.
- Who is it for?
- Adopt macOS Harness if you are already driving an agent client such as Codex or Claude Code and you want it to touch real Mac applications without writing a tool per app. Do not adopt it if you need a supported, stable interface, if you cannot grant Accessibility and Screen Recording permissions, or if unattended execution on a machine holding sensitive data is part of the plan.
- Can I use it commercially?
- Yes. MIT is a permissive licence: you can use, modify and sell software built on it, as long as you keep its copyright and licence notices.
- Is it still maintained?
- Yes. The repository last received commits 29 days ago.
- What is it written in?
- Mainly Python, according to GitHub's language statistics.
Answers come from the project's GitHub data, last synced on September 15, 2026, and from our analysis. They are not legal advice.
DEEP OPEN-SOURCE ANALYSIS
What macOS Harness replaces, and what it refuses to replace
Most computer-use agents ship a catalogue of app-specific tools. There is a Spotify tool, a Slack tool, a Finder tool, and when the agent meets an application nobody wrote a tool for, it stops. macOS Harness takes the opposite position. The README states there are no Spotify tools, Slack tools, or Final Cut tools; the model gets raw primitives and writes the rest. The intended user is someone running an agent client that can write and execute Python, who wants that agent to operate real Mac applications, a real logged-in browser, and the local filesystem in one session. The problem it solves is coverage: instead of enumerating every app in advance, the agent composes behaviour at run time from a small fixed vocabulary. The cost of that decision is that nothing is validated in advance, which the rest of this article keeps returning to.
One Python process, six verbs, and a real browser
The architecture is a single persistent Python process. The README's diagram shows three branches hanging off it. The mac.* branch splits into CGWindow screenshots, CGEvent input addressed to a PID, and AX plus Apple Events. A browser.* branch sits on Browser Harness and reaches a real Chrome over CDP. Path and subprocess give the same process ordinary filesystem and shell access. The six primitives are see, key, type, click, ax, and script. The README's example shows mac.see("Spotify") returning a frame, mac.key("cmd+k", app="Spotify") for a shortcut, mac.type with the same app argument, mac.click(640, 420, app="Spotify") for coordinates, mac.ax.at(640, 420, app="Spotify") to read the accessibility tree at a point, and mac.script with an AppleScript tell block. Two behavioural claims stand out. The harness captures background app windows without bringing them forward, and it sends input directly to an app PID rather than to whatever is focused. It also draws an animated, click-through pointer without moving the real cursor. Those three details are what separate this from a screenshot-and-pyzautogui loop, and they are also the parts you should verify yourself, because they depend on macOS permissions that the documentation says doctor reports rather than guarantees.
Installing it by asking an agent to install it
The primary installation path is a prompt. The README tells you to paste a block into Codex or Claude Code that instructs the agent to install or upgrade macOS Harness from the GitHub URL with uv using Python 3.12, register the skill printed by macos-harness skill, run macos-harness doctor, explain any missing macOS permissions and ask before requesting them, then verify by capturing one already-running app without bringing it to the foreground. That last clause is a real acceptance test, not a formality: it exercises background capture and the permission set at once. Manual setup is documented in install.md, which this review has not read. Three CLI entry points appear in the material: macos-harness skill, macos-harness doctor, and macos-harness telemetry disable. The README shows the harness being driven by a heredoc, macos-harness <<'PY' followed by Python and a closing PY, with browser, Path, and subprocess already in scope. Note what the material does not give you: no version pinning advice beyond Python 3.12, no documented configuration file, no list of the specific permission names doctor checks for. If you need a reproducible environment, that gap matters more than the install command itself.
The permission surface is the real dependency
macOS Harness does not run without macOS permissions, and the README is explicit that doctor reports the permissions actually needed rather than that setup grants them. Background window capture implies Screen Recording. Sending keyboard and coordinate input to another process's PID, reading the accessibility tree, and dispatching Apple Events implies Accessibility and Automation consent, with per-application prompts in the Automation case. None of this is unusual for Mac automation, but it concentrates a lot of trust in one process. The harness can see your screen, type into your applications, and read the accessibility tree of whatever is in front of it. The README's privacy section is careful about telemetry and silent about the blast radius of the primitives themselves, which is the right priority for a README and the wrong place to stop if you are the one granting the permissions.
Telemetry is opt-out, and the scope is narrow
Anonymous telemetry is enabled by default. According to the README, it records the CLI command category, success, duration, package version, OS and architecture, and the detected agent client. It does not record prompts, app names, screenshots, UI text, scripts, paths, or window titles. That is a defensible split: the fields collected are the ones you would want for a v0.1.x tool with three releases in a single day, and the fields excluded are the ones that would leak your work. If the default is not acceptable in your environment, macos-harness telemetry disable is a single command and it is documented in the README rather than buried. The honest caveat is that this is a description of intent from the project's own documentation. You are trusting the implementation to match it, and nothing in the supplied material lets you verify that independently.
Where the thin-harness bet goes wrong
The design has a specific failure mode, and it follows directly from the selling point. Because the agent writes missing logic mid-task in ordinary Python, correctness depends on the model's judgement at that moment, not on a tested adapter. A coordinate click at 640, 420 is only meaningful for the window state that produced it; if the layout shifts between the screenshot and the click, the click lands somewhere else, and nothing in the harness will tell you. The same applies to AppleScript fragments generated on the fly and to accessibility queries that assume a particular tree shape. There is no recipe layer to catch a bad assumption. The README labels the project experimental and macOS only, and the release history supports taking that label literally: v0.1.0, v0.1.1, and v0.1.2 all landed within roughly forty minutes on 2026-08-17. It is the wrong tool when you need deterministic, auditable behaviour on a schedule, when the target application changes layout frequently, or when the machine holds data you would not hand to an agent with shell access. It is also the wrong tool on anything that is not a Mac.
Compared with writing your own pyobjc or AppleScript layer
The obvious alternative is not another agent framework. It is the thing macOS Harness is a thin wrapper over: pyobjc for CGWindow, CGEvent, and the Accessibility API, plus AppleScript or osascript for application control, plus Playwright or Selenium for the browser. That stack gives you the same reach with explicit code you reviewed, typed signatures, and no model in the loop at run time. The difference in approach is where the flexibility lives. A hand-written pyobjc layer fixes the operations in advance, exactly like the app-specific tools macOS Harness rejects, and you pay for each new application with new code. macOS Harness moves that work to inference time and accepts the variance. If your task set is stable and small, the hand-written layer is cheaper and far more predictable. If your task set is open-ended and you already have an agent writing Python, the harness removes the per-app tool tax. That is the actual trade, and it is a trade about who writes the code and when, not about which one is more capable.
Maintenance, versions, and the MIT licence
The package is MIT licensed, which permits commercial and closed-source use and requires preserving the copyright notice and licence text. This is not legal advice; read LICENSE and your own obligations. On maintenance, the material shows an active but very young project: the last push recorded is 2026-08-17, the same day as the three releases, and the README itself calls the software experimental. A v0.1.x series that moves this fast can change primitive signatures, and because the agent writes code against those signatures at run time, an upgrade can change behaviour without any change to your own files. The practical consequence is that the version you install is part of your setup, and the README's install prompt does not pin one. If you adopt this, record the version you validated and re-run the background-capture check after each upgrade rather than assuming the primitives stayed put.
Editorial conclusion
Adopt macOS Harness if you are already driving an agent client such as Codex or Claude Code and you want it to touch real Mac applications without writing a tool per app. Do not adopt it if you need a supported, stable interface, if you cannot grant Accessibility and Screen Recording permissions, or if unattended execution on a machine holding sensitive data is part of the plan. Before trusting it, run macos-harness doctor and read what it reports, run macos-harness telemetry disable if the default anonymous telemetry is not acceptable, and verify the background-capture behaviour on one already-running app, which is the exact check the README's install prompt asks the agent to perform.
Community notes