Things to ask it
macos-mcp does not add buttons to your client — it adds verbs an agent can reach for. So the real question is what to say. Here are twenty-four prompts that work, each with the tools that run underneath and what comes back.
On this page
The quoted line is what you type. Below it: what happens, and the tools the agent picks. A toolset marked gated is off by default — the agent turns it on itself with enable_toolset, or you pass --toolsets at launch. New here? Install first — it takes three minutes.
Getting your bearings
Start here. These four are read-only: nothing on your Mac changes, and they work under the readonly profile.
Take a screenshot of my screen and tell me what's on it.
The whole display, downscaled for a vision model rather than sent as a wall of base64. Scope it if you want: a single window, or a rectangle.
- screenshot
What buttons and fields does the frontmost app have right now?
The accessibility tree, not a picture of it: every element with a role, a title, a frame and the actions it accepts — each stamped with an id the other ui_* tools take. Secure fields come back marked secure, with no value.
- ui_snapshot
Find the word ‘Cancel’ on screen and tell me where it is.
OCR plus fuzzy matching, best match first, with clickable centre points. This is the bridge for apps with no accessibility support — Electron, games, remote desktops. No match is an element_not_found carrying the nearest text it actually saw.
- screen_find
Read the text out of the top-right quarter of my screen.
OCR over a rectangle, with per-line confidence and coordinates — for a toast, a status bar or a dialog that no tree exposes.
- ocr
Driving an app
The accessibility path first: an element's own action needs no pointer, no raised window and no stolen focus. Every one of these reads the effect back before it reports success.
Open TextEdit, write my standup notes into a new document, and save it to the desktop as standup.txt.
Launch, snapshot, type into the text area, ⌘S, fill the save sheet, confirm. Typing is read back from the field — if the app took the keystrokes and the value did not change, you get action_unverified rather than a cheerful lie.
- app_launch
- ui_snapshot
- ui_type
- ui_shortcut
- ui_click
In the frontmost app, click Save — don't move my mouse.
Exactly what the accessibility path is for. The result says method: "ax" when the element's own action ran, or "cgevent" when it had to fall back to a synthetic click at the element's centre.
- ui_snapshot
- ui_click
Put Safari on the left half of my screen and Notes on the right.
Move and resize, each verified by reading the frame back. An app that clamps a resize reports the frame the window actually took, not the one it was asked for.
- window_manage
Press ⌘⇧P in VS Code and tell me what the palette offers.
Key positions resolve against the active keyboard layout, so a shortcut is correct on an AZERTY or Dvorak Mac instead of pressing whatever sits where a US key would be.
- ui_shortcut
- ui_snapshot
Scroll to the bottom of this list and tell me the last item.
Scrolls the element, then re-reads. A scroll that could only be a no-op — zero delta, or an element that cannot scroll — is refused up front rather than performed and reported as done.
- ui_scroll
- ui_snapshot
Drag that file from the list onto the Archive folder.
A press-move-release drag between two element frames, for the interactions no accessibility action exposes.
- ui_snapshot
- ui_drag
Files, clipboard, Spotlight
Find every PDF I touched this week and list them by folder.
Spotlight's own index through mdfind — plain text, or full Spotlight query syntax when you want to be precise.
- spotlight_search
Tag those four invoices red and move last month's exports to the Trash.
Finder tags are replaced and read back. trash never hard-deletes: the file goes to the Trash and the result carries the trash path so an undo is one move away. It is destructive, so under the default profile it asks first.
- tags
- trash
- →
- confirmation_required
Copy this error message to my clipboard so I can paste it in Slack.
A type-aware pasteboard: text, a PNG, or file paths — exactly one of the three per write, read back from the pasteboard before it reports success.
- clipboard_write
- clipboard_read
Open the newest screenshot in Preview.
Opens a file or URL with its default app, or a named app, and reports the app that actually took it — name and pid, so the next tool call has a target.
- spotlight_search
- open
System chores
Instead of raw AppleScript, the system toolset ships a catalog of vetted, injection-safe recipes — parameters are substituted as typed values, never concatenated into a script. The agent can list the catalog and pick.
Switch my Mac to dark mode and turn the volume down to 20%.
Two recipes from the catalog, each reading its value back. applescript_recipes lists everything on offer — appearance, volume, notifications, Notes, Finder selection, what Music is playing, the Safari tab.
- applescript_recipes
- applescript_run_recipe
What files are selected in Finder right now?
The finder_selection recipe — the cheapest way to say “this one” to an agent without typing a path.
- applescript_run_recipe
Run git status in my project and summarise what changed.
A real shell with output caps and a timeout, so a runaway command cannot wedge the session or flood the context window.
- shell
Post a notification when the build finishes.
The notification_post recipe. Pair it with a long shell call and the agent tells you across the room.
- shell
- applescript_run_recipe
Calendar, Reminders, Contacts (gated)
EventKit and Contacts through the system's own permission prompts — macOS asks once, the first time. Tool names that apple-mcp users already know.
What's on my calendar this week, and is anything double-booked?
The agent notices the apps toolset is off, switches it on, macOS prompts once, and the search answers. Gating and first-use consent in a single turn.
- enable_toolset
- calendar_list
- calendar_search
Which reminders are overdue, and what's Dana's email address?
Reminders and Contacts, read-only. Nothing is written back to either store.
- reminders_search
- contacts_search
The web (gated)
Where Apple's own Safari MCP server is available — Safari 27, which ships for macOS Sequoia, macOS 26 and macOS 27 alike — its tools are mounted and re-exported verbatim as web_*. Everywhere else the same names are served by an AppleScript fallback, and every result says method: "fallback" so the agent always knows which engine answered.
What's in my open Safari tabs? Pull the text out of the third one.
List tabs, select one, read the page as text — no scraping stack, no headless browser, your real session and your real logins.
- web_tabs
- web_select_tab
- web_page_text
Open the pull request in Safari and summarise the review comments.
Navigate, then read. The gateway hands Apple's result back untouched — never a reimplementation of what Apple already ships.
- web_navigate
- web_page_text
Your iPhone (gated)
Eight tools that drive a real handset through the iPhone Mirroring window. The mirror is an opaque video surface with no accessibility tree, so this is the one place where OCR is the primary locator rather than a fallback — and taps land in the phone's own device points, not screen pixels. Needs iPhone Mirroring itself, which Apple does not offer in the EU. The full story →
Open Settings on my iPhone and tell me how much storage is free.
Find “Settings” by OCR, tap its device centre, screenshot, read. Every mutating call captures the phone before and after: a tap that changed nothing comes back action_unverified, never a false success.
- iphone_find
- iphone_tap
- iphone_screenshot
Go to the home screen on my phone and swipe to the second page.
iphone_key home sends Apple's documented ⌘1 — or presses the window's own Home button when the toolbar happens to be showing — and the result says which path ran.
- iphone_key
- iphone_swipe
A Mac it may destroy
Not a prompt — a command line. macos-mcp vm clones a golden macOS image into a throwaway guest on Apple's Virtualization.framework, proves the clone is actually drivable, and deletes it. Give the agent that one instead of your own Mac when the work is risky.
macos-mcp vm clone golden-27 scratch # APFS clonefile: instant, fresh machine identifier
macos-mcp vm start scratch # a window in this Mac's console session
macos-mcp vm verify scratch # ax_read · keystroke · screencapture · non-black frame
# … the agent does the risky thing in there …
macos-mcp vm destroy scratch # gone
Accessibility and Screen Recording are solved once per golden image and inherited by every clone. Two macOS VMs per Apple Silicon host is a measured kernel quota, not a limit anyone chose. Disposable Macs →
When it says no
Half of using this well is reading the refusals. They are a closed set of typed codes, and each carries what an agent needs to recover — so the agent usually fixes itself without asking you.
| What comes back | What it means | What happens next |
|---|---|---|
confirmation_required | A destructive call under the default standard profile. | The agent shows you the exact call and re-issues it with a one-shot token bound to that call. Nothing else can be done with that token. |
action_unverified | The tool ran, macOS reported success, and the UI did not change. | This is the headline feature, not a bug: macOS lies about this constantly. The agent re-snapshots and tries the other path. |
permission_missing | Accessibility or Screen Recording is not granted to the app hosting the agent. | The error carries the exact System Settings deep-link. Grant it to the client, then restart it. |
element_not_found | The id is stale, or the text is not on screen. | The error lists what is there — the nearest matches — so the next call can be right. |
refused | A hard line: a secure text field, or a request that could only be a no-op. | Permanent. A password field is never read and never typed into; the error names an alternative instead of half-trying. |
element_not_found on a tool name | The tool is real, but its toolset is switched off. | nearest_matches spells out the enable_toolset call to make. A name that exists nowhere stays a protocol error instead, so the two cases never blur. |
Five things that make it work better
-
Name the app.
“Snapshot Mail” beats “snapshot the app”. Every
ui_*tool defaults to the frontmost app, and the frontmost app changes while you are typing. -
Let it look before it acts.
An agent that snapshots first clicks by element id, which needs no pointer and no focus. An agent that guesses coordinates fights whatever window moved.
-
Ask it to check.
“…and confirm the file is on the desktop” turns a claim into a read-back. The tools verify themselves; the plan is yours to make verifiable.
-
Use
readonlywhile you explore.macos-mcp serve --profile readonlyrefuses anything that is not pure observation. A good way to hand someone else's Mac to an agent for five minutes. -
Read the log afterwards.
macos-mcp audit tailreplays what was called andaudit summarytotals it by tool and failure code. Arguments are stored as a digest, never raw — typed text can be a secret.
Next
- Getting started — install, connect your client, grant two permissions.
- Tool reference — all 44 tools, every argument and default.
- Safety model — profiles, confirmation tokens, audit, hard lines.
- The iPhone toolset · Disposable Macs · How it compares