Enables secure macOS computer use for AI agents with automatic password redaction, user consent for writes, and comprehensive audit logging.
Also known as Agent360dk/computerMCP, computermcp, @agent360/computer-mcp
- Stars
- 1
- Tools
- —
- Downloads, 30 days
- 201
- Latest version
- 0.1.0
- Last commit
- Nov 11, 2026
- License
- MIT
What is computer MCP?
computer enables secure macOS computer use for AI agents with automatic password redaction, user consent for writes, and comprehensive audit logging.
Summary generated from the project's README
About computer MCP server
Automating macOS desktop tasks through AI agents is made safer with this MCP server, which provides a controlled environment for computer use. It allows agents to interact with windows, click buttons, and fill fields while ensuring the user maintains control. The server works across various MCP clients like Claude Code, Cursor, and VS Code using a single npx command, making it compatible with any agentic workflow without requiring specific vendor plans or accounts.
Security is handled through three distinct layers. It automatically redacts password fields by painting them black in memory before any screenshots are saved, and it refuses access to password managers like 1Password or Keychain by default. To prevent accidental damage, the server requires user consent via a menu bar icon for destructive actions, such as moving files to the Trash or quitting applications. It also manages accessibility trees for Electron apps like Slack and VS Code, and specifically handles Chrome and Edge to ensure web elements are readable and secure.
Every action is recorded in an append-only audit log that uses salted fingerprints to prevent tampering. This allows developers to review exactly what an agent attempted and whether those actions were allowed or refused.
What you can do with it
- 1Secure background automationRun an AI agent to perform desktop tasks for hours while you work on other things without losing control of your pointer.
- 2Protecting sensitive credentialsEnsure that an AI agent cannot see or capture your passwords during screen recordings or screenshots.
- 3Auditing agent behaviorReview a tamper-evident log to see every command an agent attempted and why certain actions were denied.
- 4Controlling destructive actionsPrevent an agent from deleting files or closing windows without your explicit permission through a menu bar prompt.
Written from the project's README. Every use case is checked against a quote from it.
How to install computer MCP
Formats verified 10 Nov 2026Install computer MCP in Claude Code
$ claude mcp add computermcp -- npx -y @agent360/computer-mcpInstall computer MCP in Cursor
~/.cursor/mcp.json
{
"mcpServers": {
"computermcp": {
"command": "npx",
"args": [
"-y",
"@agent360/computer-mcp"
]
}
}
}Install computer MCP in VS Code
.vscode/mcp.json
{
"servers": {
"computermcp": {
"type": "stdio",
"command": "npx",
"args": [
"-y",
"@agent360/computer-mcp"
]
}
}
}Install computer MCP in Claude Desktop
claude_desktop_config.json
{
"mcpServers": {
"computermcp": {
"command": "npx",
"args": [
"-y",
"@agent360/computer-mcp"
]
}
}
}Install computer MCP in Codex
~/.codex/config.toml
[mcp_servers.computermcp] command = "npx" args = ["-y", "@agent360/computer-mcp"]
Install computer MCP in Gemini CLI
~/.gemini/settings.json
{
"mcpServers": {
"computermcp": {
"command": "npx",
"args": [
"-y",
"@agent360/computer-mcp"
]
}
}
}Configuration
CMCP_ASK_TIMEOUTSeconds a consent dialog waits before refusing. Default 60.
CMCP_MODEreadonly | ask (default) | allow
| Name | Description | |
|---|---|---|
| CMCP_ASK_TIMEOUT | Seconds a consent dialog waits before refusing. Default 60. | |
| CMCP_MODE | readonly | ask (default) | allow |
Automated checks
Ran Nov 12, 2026Full report →Passed our automated checks. That is not a security audit: read the code and give the server the narrowest access it needs. How checks work
- Source repository linked and reachablePass
- Open source license (OSI)Pass
- Commit or release in the last yearPass
- Package name not close to a popular packagePass
- Remote endpoint uses HTTPSNot checked
- Destructive tools are labelledNot checked
- No hidden instructions to the modelPass
- No critical advisory in the package or its dependenciesPass
README
View on GitHubComputer MCP
Computer use you can actually leave running.
A macOS computer-use MCP server built for the part everyone skips: what happens in the hours you are not watching.
- It runs in every MCP client, not one app. Claude Code, Cursor, VS Code,
Codex, or your own agent - one
npxline, the same server everywhere. It is not tied to a single vendor's desktop app or plan. - It does not take over your Mac. It presses buttons and fills fields in
windows that stay behind the one you are in, and it leaves your pointer where
you put it. When an app pulls itself to the front as it opens, the front is
handed straight back and the reply says so. In one of 65 measured moments like
it (GitHub's Mac, many agents at once) it could not be, and the reply said that too (
gave_back: false): until you click back, what you type goes to that app. It also leaves the front alone when you clicked, scrolled or pressed a modifier key such as Shift in the last 1.5 seconds - that is taken to be you. - It does not pretend. When something is refused or fails, it says so and says why. The most common complaint about agents driving a computer is that they carry on as if it worked.
- Several can run at once. No session lock, no one-at-a-time limit. Writes to the shared log take a short file lock, so two servers cannot break the chain between them.
- It will not go near your passwords. Keychain, 1Password and five others
are refused in the default mode (in the foreground - while an agent has the screen, or with
CMCP_BACKGROUND=0- they ask every time), and password fields are blacked out while the screenshot is still in memory. A screen recording leaves password managers out, but does not black out password fields. - You can read back what it did. Every call lands in an append-only log, fingerprinted rather than stored in clear.
- Electron apps are not a blind spot. Slack, VS Code, Discord and Notion
build their accessibility tree lazily, so most tools find an empty window.
This one switches the tree on itself before it looks. Measured on a VS Code
fork with two windows open: 0 buttons before, 728 after, same windows,
same moment.
CMCP_INGEN_ELECTRON=1turns it off if you would rather the app did not pay for keeping a tree it otherwise would not build - and it turns off Chrome's switch below too, so Chrome pages are then neither readable nor have their password fields blacked out. - Chrome pages are not a blind spot either. Chrome ignores the Electron
switch - asked for it, it answers that the attribute does not exist - and
has its own: the one a screen reader sets. This server sets that one in
Google Chrome (every channel, Chrome for Testing included) and in Edge,
Brave, Arc, Vivaldi, Opera, Opera GX, Comet, Dia and Chromium (only Google
Chrome is measured; the ids of Opera GX, Comet and Dia are read from Homebrew's
cask data, not from an installed copy). Measured 5 Nov on Chrome 156: a
test page went from 0 page elements to 6, its password field among them
and blacked out; the redaction scan of a heavy everyday Chrome took 0.14 to
0.54 s.
test/chrome-side-live.mjsproves it against a real Chrome.
Honest limits: macOS only. It reads the accessibility tree, so an app that
draws its own controls on a canvas and publishes nothing - some games, some
plotting tools - is still a blind spot. In a browser, Chrome builds a page's
tree in the background the first time it is switched on, which took 3 to 15
seconds in our measurements; until then a search that finds nothing says
tree_building, and that Chrome window is blacked out whole in screenshots,
with the reason in the answer. A page the scan cannot finish - deeper than it
reaches, or a lookup that failed or timed out - is blacked out whole the same way.
A Chrome window that has not been in front since the switch was turned on may
stay unreadable until it is (measured: a page whose window lost focus to a popup
as it loaded was not built in 30 s). Only
Google Chrome is measured. Other Chromium browsers than the ones named above -
Chrome app windows (PWAs) included - are not switched on and not covered, and
Safari and Firefox are not handled. When a browser tool is in the session, let
it do the work inside pages - this server takes over where it is refused (see
the limits below).
No account, no API key, no model inside it. MIT.
npx @agent360/computer-mcp
No Swift needed: the package ships a universal binary for Apple silicon and Intel. It carries the ad-hoc signature macOS needs to run it at all - not a Developer ID signature, and not notarized. Gatekeeper may therefore ask you the first time.
computermcp.dev · Security model
Why
Handing an agent your keyboard, mouse and screen is the most useful thing you
can give it and the least reversible. A screenshot of a working developer's Mac
can contain a password manager mid-unlock, a .env open in the editor, or
customer data. A stray keystroke in a terminal is not a typo - it is a command.
Most desktop-automation MCP servers hand all of that over at once, with no way to say that, but not that. So the careful people don't run them on the machine where the work actually is.
This is the same capability with the dangerous edges answered.
The three gates
1. Passwords never reach the model. Secure text fields and password-manager
windows are painted opaque black on the bitmap in memory, before the PNG is
written. There is no moment where an unredacted picture of your desktop exists
as a file. Native fields expose the role AXSecureTextField; fields in a web
page expose role AXTextField with the subrole AXSecureTextField. Checking
only the role would catch native fields and let every browser password box
through - so both are checked. In a web page the field is only found when the
browser shows its page to the accessibility layer. In Chrome this server switches
that on (above); while a Chrome window's page is not readable yet - the first
seconds after it is switched on, or an empty page - the whole window is blacked
out instead of risking a field it cannot see. Known gaps, not measured: a login
form inside a cross-site frame, or a second step that appears before Chrome has
updated its tree, can be on screen a moment before the field is in the tree. In
a browser it does not switch on (Safari, Firefox, other Chromium browsers, and
any browser with CMCP_INGEN_ELECTRON=1), the field is not painted over; what
it shows is the browser's own dots, unless the page shows the password in plain
text.
2. The dangerous places ask first. By default the agent works without
interrupting you - that is what lets it run while you do something else - and
every write is logged. What never goes through on its own: password managers and
Keychain are refused in the default mode, because the menu bar cannot show what
would be typed (in the foreground - while an agent has the screen, or with
CMCP_BACKGROUND=0 - they ask every single time, even with allow), and that one is not configurable. Terminals and editors, where a keystroke can be a command, ask once
per app per session. Quitting an app, closing a window, switching Space,
and destructive-looking menu items ask every time; an action whose target app
cannot be identified is refused in the default mode. The gate judges the app an action lands in: an
app opened some other way - Spotlight, a shortcut - is guarded by what the
agent then tries to do in it. Want a question before the first write too? Set
CMCP_MODE=ask. If nobody answers, the answer is no.
3. Everything is written down. ~/.local/state/computer-mcp/audit.jsonl,
mode 0600, append-only: every call, its target app, and whether it was allowed
or refused with the reason. Every line carries its call's id, which together
with the server's session id pairs the decision and the outcome of one call,
even with several agents running.
Each line also carries a fingerprint of itself and the line before it, so a
removed or edited line breaks the chain. That is not a signature: whoever can
write the file as you - including an agent with a terminal - can rewrite all of
it. If you need proof against that, copy the log off the machine. If the log cannot be written - a full disk, a
locked file - write actions are refused until it can. Two gaps remain: an action
already under way when the disk fills can lack its outcome line, and typing that
is cut off by the helper's time limit is logged as an error without saying how
many characters arrived. Typed text is stored as a length and a salted
SHA-256 prefix, never in clear - an audit trail full of passwords is its own
breach. The salt is random per run and never written down, because an unsalted
hash of a short password can be guessed offline by whoever holds the log. The
honest cost: two actions can be compared within one run, not across runs.
Here is what that looks like, unedited. In the lines below an agent typed a
sentence into TextEdit behind the window the person was using, asked in the menu
bar to move a file to the Trash and got no answer (the run sets CMCP_ASK_TIMEOUT=1,
so the question ended after a second and is logged as denied; with the default the
call is logged as waiting and the question stays about ten minutes), then was refused
when it tried to type into 1Password. They come from an isolated test run - its own state
folder and stand-ins for the helper and the menu bar icon, so no real screen was
touched and nobody's own log was read - which node scripts/log-uddrag.mjs
repeats. In the presence fields, the idle times come from the stand-in helper
and the icon version from the stand-in icon; the session count comes from the
isolated state, and the surface is derived. Only the box setting was read from
the Mac that made the run. A test checks that every line is byte for byte in
the full log of that run
and that its chain holds.
{"ts":"2026-10-31T22:35:10.230Z","session":"56f00545","call":"02bc741b","tool":"computer_type","tier":"write","args":{"app":{"length":8,"sha256_12":"78743a52a54c","salted":true},"text":{"length":37,"sha256_12":"cdde26c85cca","salted":true}},"target":"com.apple.TextEdit","mode":"allow","asker":"custom","decision":"allowed","asked":false,"reason":"CMCP_MODE=allow","l":1,"kaede":"4fb5f61a6e442962"}
{"ts":"2026-10-31T22:35:10.231Z","session":"56f00545","call":"02bc741b","tool":"computer_type","tier":"write","target":"com.apple.TextEdit","phase":"executing","l":1,"kaede":"13cd03c71bfb3b38"}
{"ts":"2026-10-31T22:35:10.321Z","session":"56f00545","call":"02bc741b","tool":"computer_type","outcome":"ok","effect":"sent","l":1,"kaede":"79696176e8603981"}
{"ts":"2026-10-31T22:35:11.481Z","session":"56f00545","call":"ac33c074","tool":"computer_menu","tier":"write","args":{"app":{"length":6,"sha256_12":"2c65732d0d4e","salted":true},"path":"File > Move to Trash"},"target":"com.apple.finder","mode":"allow","asker":"menubar","presence":{"idle_at_ask":600,"idle_at_end":600,"server":"0.4.1","icon":"0.4.1","box":"on","sessions":1,"surface_derived":"box+menu"},"decision":"denied","asked":true,"reason":"background mode: nobody answered in the menu bar in time","l":1,"kaede":"ad20dddb1195fa7a"}
{"ts":"2026-10-31T22:35:11.578Z","session":"56f00545","call":"5b15b900","tool":"computer_type","tier":"write","args":{"app":{"length":9,"sha256_12":"ac0afc1b1e97","salted":true},"text":{"length":7,"sha256_12":"f0b579393774","salted":true}},"target":"com.1password.1password","mode":"allow","asker":"custom","decision":"denied","asked":false,"reason":"background mode: this would need a dialog, and a dialog takes the screen (a password app can never be approved from the menu bar)","l":1,"kaede":"2332aa9606dd896e"}
Most gates have a test, mutation-checked when it was written: break the code on purpose and the test goes red. Not every rule has one - the CHANGELOG lists the rules without a test of their own and the mutants that survive, and why. See Testing.
Install
# Claude Code
claude mcp add computer -- npx -y @agent360/computer-mcp
Or, inside Claude Code, as a plugin pinned to the version on npm:
/plugin marketplace add Agent360dk/computerMCP
/plugin install computer-mcp@agent360
// Cursor, VS Code, Codex CLI - mcp.json
{
"mcpServers": {
"computer": { "command": "npx", "args": ["-y", "@agent360/computer-mcp"] }
}
}
Then grant two macOS permissions: System Settings → Privacy & Security →
Accessibility, and the same under Screen Recording. Ask your agent to call
computer_permissions and it will tell you what is still missing.
Which app do you grant them to? macOS attributes these to the responsible
process, and which process that is depends on how you launched the server. Run
from a terminal, it is usually the terminal. Run by an MCP client over npx, it
may be the client instead. The honest answer is: grant it to whichever app the
system dialog names, and if no dialog appears, start with the app that launched
the client and check computer_permissions again.
Untested, and we would rather say so: we have not yet measured this from a clean machine with permissions reset, so we cannot tell you with certainty which of the two it will be in your setup. Upgrading is measured for Accessibility (issue #4): the grant belonged to the host app, not to our ad-hoc signed helper - a copy of the helper with a different signature, started from a new path, still had it - so in that setup an upgrade did not send anyone back to System Settings. Screen Recording after an upgrade has not been measured separately. If you see something else, telling us what you saw is a real contribution.
Modes
CMCP_MODE |
Behaviour |
|---|---|
readonly |
Write tools are not even listed. The agent can look and cannot touch. |
ask |
The first write asks in the menu bar icon; if the icon is not running, it is refused in background mode and opens a dialog in the foreground. One yes grants the session. Password managers are refused (in the foreground - while an agent has the screen, or with CMCP_BACKGROUND=0 - they ask every time), terminals and editors ask once per session. |
allow |
Default. Writes proceed without asking, still logged. Password managers are still refused (in the foreground - while an agent has the screen, or with CMCP_BACKGROUND=0 - they ask every time), terminals and editors ask once per session, and in background mode anything that would need a dialog waits in the menu bar instead. |
CMCP_ASK_TIMEOUT (seconds, default 60) controls how long a dialog waits before it refuses. A
consent dialog appears only in the foreground, for a question the menu bar icon may never approve or
when the icon is not running; every other consent question waits in the icon (see The menu bar
icon below), and in background mode with no icon running it is refused. computer_ask_user in the foreground is always a dialog. The same number also bounds
a consent question in the icon: at 45 or less it ends that soon, and above 600 it waits that long.
computer MCP questions
How do I add computer MCP to Claude Code?
Run claude mcp add computermcp -- npx -y @agent360/computer-mcp in your terminal. Add --scope user to make it available in every project.
How do I add computer MCP to Cursor?
Open ~/.cursor/mcp.json and add the server under mcpServers, using the Cursor config shown in the install section above.
Does it protect my passwords?
Yes, secure text fields and password manager windows are painted opaque black in memory before any screenshots are written to disk.
Can I run multiple agents at once?
Yes, the server supports multiple simultaneous sessions without a session lock.
How does it handle Electron apps like VS Code or Slack?
It actively switches on the accessibility tree for Electron apps so they are not seen as empty windows by the agent.
Is there an audit trail of what the agent does?
Every action is recorded in an append-only, fingerprinted log that includes the target app and the decision outcome.