Tool reference
thirty tools. fourteen look, sixteen touch. The useful part of this page is not the parameter lists - it is knowing which tool to reach for when the obvious one is the wrong one.
What you get today, honestly. npx @agent360/computer-mcp currently serves 0.1.0, which has 12 tools. The 30 tools described here are the source: they are built and tested, but not published yet. Building from source takes about thirty-five seconds if you want them now.
The one habit that matters. Find things by name, not by pixel. computer_inspect and computer_find return the frame of every element, so the agent can act on "the Log in button" rather than on a coordinate that stops being true the moment a window moves. Reach for computer_click only when there is no accessibility element to aim at: a canvas, a map, an image.
Looking
computer_permissionsread
Which macOS permissions are granted. Call it first whenever anything fails for no obvious reason - a missing permission looks like a broken tool.
{ "accessibility": true, "screenRecording": true,
"macos": "Version 26.4.1", "mode": "ask",
"auditLog": "~/.local/state/computer-mcp/audit.jsonl" }
computer_appsread
Running applications with their bundle IDs and which one is frontmost. The bundle ID is what every other tool wants when you target an app.
computer_windowsread
Open windows with titles and screen frames. Optional app narrows it to one.
An app can be running with no window, and a window on another Space is not on screen. If a window you expect is missing here, check whether your editor is full-screen: a full-screen app gets its own Space, and everything else sits on another one.
computer_set_valuewrite
Write a value straight into a field through the accessibility API: no focus change, no keystrokes, no cursor movement. It reaches a field in a window sitting behind another one, which typing cannot.
It refuses on a secure field, every time. We removed that check once on purpose to see what happened: the modified build wrote into the password box. It is the only thing standing there.
computer_ask_userwrite
Ask the person to do something themselves, and wait. Use it for anything the model must not see: a password, a 2FA code, a CAPTCHA, an OAuth consent.
The agent puts the cursor in the right field first, then calls this. A native dialog names the app and the window it is about to land in - written by the server, not by the model - and the person types on their own keyboard.
It returns true or false, never text. There is deliberately no route through this server for a secret to reach a model. That is the whole design of the tool, not a limitation of it.
computer_pastewrite
Put text on the clipboard, press Cmd+V, then put your own clipboard back. Better than typing for anything long or awkward: a paragraph, a URL, an emoji, text in a script your keyboard layout cannot produce.
There is deliberately no tool that READS the clipboard. A person copies a password out of their password manager, and one read would hand it to the model past every other guard here.
To put your previous clipboard back, this does read it - in memory only, for the few milliseconds the paste takes. That value is never returned and never logged. Pass restore: false to skip the read entirely, at the cost of leaving the pasted text on your clipboard.
computer_launchwrite
Open an application, by bundle ID or by its plain name. computer_activate can only bring forward something already running; this starts what is closed. Already running, it just comes forward, and the answer says which of the two happened.
Launching cannot lose anything, so it is not on the always-ask list the way quitting is - but it is still a write, and it goes through the same gate as every other write: refused in read-only mode, and in ask mode the first one asks for the session. Quitting is separate because it can lose work, and it asks every single time.
computer_quitwrite
Ask an application to quit, the same way Cmd+Q does. It never kills a process: the app still gets to ask you about unsaved work, and an agent should trigger that question rather than route around it.
Quitting can lose work, so this asks every time, in every mode - like closing a window, and like a menu item that looks destructive.
computer_pendingread
The actions that were refused because they needed a human, and there was no way to ask without taking over the screen.
In background mode a dialog is itself an interruption, so a write that would need one is refused rather than raised - and that refusal only reaches you if you happen to read the right conversation. This is where it becomes visible: what was asked for, when, and why it stopped. It is a list, not a button. Nothing here can be approved from here: a consent granted without a human is exactly what the gate exists to prevent. To allow the work, change the mode.
computer_dragwrite
Drag from one point to another: a file into a folder, a row into a new position, a slider to a value. Coordinates are in points, the same as computer_click - and computer_find hands you a center for every element it returns.
Like clicking, this moves the real cursor, so it is not the quiet route. Where an app publishes an accessibility tree, computer_press and computer_set_value do more without touching the pointer. And it reports that the drag was sent, never that it was accepted - only a screenshot or a fresh look at the tree can tell you that.
computer_spacewrite
Switch to the desktop to the left or right, the way Control+Arrow does. This is how you reach a full-screen app: macOS gives every full-screen window its own desktop, so a window the agent cannot find is often simply on another one.
Switching desktops moves what you are looking at, so this asks every time, in every mode - the same rule as quitting an app. If the system shortcut for switching desktops is turned off on this machine, it says so and sends nothing, rather than pressing a key that does nothing. And it tells the agent whether the desktop actually changed, measured from which windows are on screen before and after - it will not claim a switch it cannot prove.
computer_windowwrite
Move, resize, close or minimise a window. Coordinates are global points, the same space clicks use, so a negative x is a screen to the left - this is how you put a window on another display.
computer_window app="Google Chrome" title="Report" x=-1780 y=100 width=1500 height=900
This reaches where scripting often does not. Measured: Chrome's own AppleScript refused to move a window off the main display and reported success anyway; setting the accessibility position moved it from (11, 54) to (-3700, 100) and it stayed there.
Closing a window can lose unsaved work, so button: "close" asks for consent every time, in every mode. Moving and resizing cannot lose anything and do not ask.
computer_menusread
An app's whole menu bar, flattened to paths: every item, whether it is enabled right now, and its keyboard shortcut. This is often the only way to reach an action at all: a large part of macOS has no button on screen, only a menu.
{ "count": 301, "items": [
{ "path": "File > Print…", "enabled": true, "shortcut": "P" },
{ "path": "Edit > Copy", "enabled": true, "shortcut": "C" },
{ "path": "Chrome > Clear Browsing Data…", "enabled": true } ] }
The titles come back in the system language, which is the whole reason to read the menu instead of guessing at it. On a Danish Mac the path is Arkiv > Udskriv…, not File > Print…, and an English guess simply misses.
computer_menuwrite
Choose a menu item by its full path. Like computer_press, it goes through the accessibility API rather than the pointer: it reaches a window sitting behind another one, and nothing moves on your screen.
computer_menu app="Google Chrome" path="File > Print…"
Always give the whole path. "Delete" exists in several menus, and hitting the wrong one is not a detail. A path that does not exist is refused with a pointer back to computer_menus, and a greyed-out item is refused as greyed-out rather than clicked into nothing.
Items that look destructive ask every time, in every mode, including allow - anything whose name contains delete, clear, erase, reset, trash or quit, in English or in the system language. That is a word match, so it can be wrong in both directions: the dialog therefore shows you the full path and says so. You decide, not the word list.
computer_displaysread
The displays, with a stable id for each, where it sits on the desktop and how big it is. Call it when a window is not where you expect: on a machine with several screens it is almost always on another one.
{ "count": 3, "displays": [
{ "index": 0, "id": 3, "x": -3840, "y": 27, "width": 1920, "height": 1080 },
{ "index": 1, "id": 1, "x": 0, "y": 0, "width": 1710, "height": 1107, "main": true },
{ "index": 2, "id": 2, "x": -1920, "y": 27, "width": 1920, "height": 1080 } ] }
Use id, never index. The order is not stable between calls. We measured it changing inside a single run, seconds apart: index 0 meant one monitor and then another. An index you read a moment ago may already point somewhere else; the id does not move.
computer_screenshotread
| app | Bundle ID or name. Omit for the whole screen. |
|---|---|
| redact | Default true. Secure fields and password-manager windows are painted out before the image is written. |
| maxWidth | Scale down. Default 1400, which is plenty for a model to read and a lot cheaper than full resolution. |
Takes about 0.4 seconds. The result says how many regions were redacted, so "0 redacted" tells you there was nothing sensitive on screen rather than that redaction was off.
computer_recordread
| action | start, stop or status. |
|---|---|
| maxSeconds | start only. It stops by itself after this long. Default 600, at most 3600. |
| displayId | start only. Which display, by the id from computer_displays. Default: the main one. |
Records one display to a video file, for a person to watch afterwards - a tutorial, a demo, proof of what was done. Starting asks you every time: it is your screen, for minutes. In read-only mode it is refused. Stopping and asking for the status never ask. Only password managers are left out of the recording, including ones opened while it runs (the list is checked about four times a second, so one opened mid-recording can be visible for a moment; if the check cannot be made for two seconds, or a password manager cannot be kept out, the recording stops rather than keep filming). Everything else is recorded as it looks: password fields are not blacked out the way they are in screenshots, and anything typed into an ordinary field is visible. The answer is the file's path - this server never reads the file back and never sends it to the model. It stops on its own at maxSeconds, and when the server that started it ends - if your MCP client quits, that can take up to about half a minute. A server that hangs rather than ends does not count: the recording then runs to maxSeconds, and macOS's own recording indicator is what shows it. Needs macOS 15, and macOS shows its own recording indicator in the menu bar while it runs.
computer_wait_forread
Wait until an element appears, then return. The alternative is a screenshot loop, and the arithmetic is stark: twenty polls cost one tool call here and twenty images the other way - twenty pictures of a progress bar, in the model's context.
computer_wait_for role="AXSheet" timeout=300
It gives up rather than hanging. A timeout comes back as an error you can act on, not as silence.
computer_focusedread
What has keyboard focus right now: its role, its title, its frame, the app it belongs to, and whether it is a secure field. Call it before typing if you care where the characters will land.
The value of a secure field is never returned here either - only the fact that it is one.
computer_inspectread
The accessibility tree: role, title, description, value and frame per element. This is the tool that replaces guessing.
| app | Strongly recommended. Without it you walk every app on screen. |
|---|---|
| depth | Default 12. Web content sits deep; native UI rarely does. |
| limit | Max nodes, default 400. Raise it for large apps, but read the next line first. |
Values of secure fields are never returned, not even to the agent. A node marked "secure": true comes back with its frame and no value.
computer_findread
The same tree as computer_inspect, narrowed to what you are looking for: pass any of role, title or contains and get back the matches with their frame, their centre point and whether they can be pressed.
| app | Bundle ID or app name. Omit to search every app on screen, which is slower and rarely what you want. |
|---|---|
| role | AXButton, AXTextField, AXCheckBox and so on. |
| title / contains | Exact label, or a substring of it. |
| depth / limit | Default 24 and 25. |
Frames come back in points, which is the unit computer_click takes - so a coordinate from here needs no conversion, unlike one read off a screenshot.
computer_auditread
The last N entries of a log that only grows: every call, what it targeted, and whether it was allowed or refused with the reason. Ask for this when you want to know what an agent actually did rather than what it says it did.
computer_learningread
Writes down what the agent learned while driving the Mac - a step that said ok and did nothing, the route that worked instead, a refusal, a missing capability - as one line in learnings.jsonl next to the audit log. Numbers and email addresses are removed first, and nothing is sent anywhere; the answer holds a pre-filled GitHub issue link the person can use to share it.
Touching
computer_presswrite
Presses an element through its own accessibility action instead of simulating a click on a coordinate. Takes the same search arguments as computer_find, with app required.
This is the one that does not take over your screen. It works while the window sits behind another one, and it never moves the pointer you are using. Everything else on this list goes through the system input tap, which means it lands wherever the keyboard focus happens to be and drags your real cursor along with it.
Two or more matches is a refusal, not a guess. The agent gets the candidates back and has to narrow the search, or pass first: true and mean it. Pressing the first plausible button is the kind of almost-right action nobody notices until much later.
app is required because it is also what the consent gate judges. Press something in 1Password and the always-ask rule fires, even if 1Password is nowhere near the front window.
computer_clickwrite
x, y, optional button (left/right/middle) and count (2 for double-click).
Pixels are not points. A full-resolution screenshot of a 1710-point-wide screen is 3420 pixels wide. computer_click takes points. Read a coordinate off the image and click it unchanged, and you land at half the intended position - with no error, because the click succeeds, just somewhere else. Every screenshot reply now carries pixelsPerPoint; divide by it before you click.
Better still: prefer the accessibility tree. Coordinates are correct for exactly as long as nothing moves.
computer_movewrite
Moves the pointer without clicking. Use it to trigger a hover state before screenshotting a menu that only appears on hover.
computer_scrollwrite
dx and dy in pixels at the current pointer position. Move first, then scroll, or you scroll whatever happens to be under the cursor.
computer_typewrite
Types text into the focused field as Unicode, so it works on any keyboard layout rather than only a US one. cps sets characters per second, default 240.
The text reaches the helper over stdin, never as a command-line argument, because ps is readable by every process on the machine. In the audit log it appears as a length and a hash, never in clear.
computer_keywrite
A key combination: cmd+s, escape, cmd+shift+4. Modifiers are cmd, shift, alt, ctrl, fn.
computer_activatewrite
Brings an app to the front by bundle ID or name. Worth knowing: this switches Space if the target app is full-screen, which is usually what you want and occasionally a surprise.
What is not here
There is no tool to run a shell command, open an arbitrary file, or fetch a URL. Each would be a few lines of code and all three are absent deliberately: a computer-control server with a shell inside it is remote access under a friendlier name. If you want a shell, install a shell MCP server, and then the choice is yours and it is visible in your config.
Several agents at once
Each MCP client starts its own server, so a second chat is simply a second process. They share one audit log, and every line carries a per-server session mark. Set CMCP_CLIENT to a name and the line carries that as well, so the log answers which conversation did it rather than only what was done.
What is not solved yet: two servers driving coordinates at the same time still share one pointer and one focused window, and nothing locks between them. Give the background work to computer_press, and keep computer_click for the session you are actually watching.
A working order
computer_permissions # is anything missing?
computer_apps # what is running, what is its bundle ID
computer_find --app X --role .. # the element, by name, with its frame
computer_press / click / type # act on what you found, not on a guess
computer_screenshot # confirm it did what you meant
computer_audit # what actually happened
The last two are the ones agents skip and humans miss.