win-computer-use
Click on "Deploy Server".
Wait a few minutes for the server to deploy. Once ready, it will show a "Started" state.
In the chat, type
@followed by the MCP server name and your instructions, e.g., "@win-computer-useTake a screenshot and list the windows currently open."
That's it! The server will respond to your query, and you can continue using it as needed.
Here is a step-by-step guide with screenshots.
win-computer-use
An MCP server that gives Claude Code computer use on Windows — screenshots, mouse, keyboard, window and display enumeration — which the CLI officially ships on macOS only:
createCliExecutor called on win32. Computer control is macOS-only.It does not reimplement anything at a low level. It reuses the native binding that the Claude
desktop app installs (@ant/claude-native), which loads fine in plain Node, and adds screen
capture on top through GDI (the desktop app captures with Electron's desktopCapturer, which does
not exist outside Electron).
By default this gives a model unrestricted control of your desktop. Keystrokes and clicks go to whatever window currently has focus, and a screenshot captures the entire screen — password managers, private messages, anything else you have open.
An allowlist can restrict input to named applications, but it is opt-in and it does not restrict what the screenshot sees. Of the four safeguards the Claude desktop app has, this implements one: there is no screenshot masking, no on-screen indicator while computer use is active, and no panic key. Run it only on a machine where that is acceptable to you — and since the install below registers it for every session on that machine, decide deliberately whether to pair it with an allowlist.
Unofficial, unsupported, and not affiliated with Anthropic. It depends on internals of the desktop app: if the binding or the MSIX package layout changes, this breaks.
Requirements
Windows 10 or 11. Windows-only by construction; the server exits with an error elsewhere.
The Claude desktop app, installed (the MSIX package from the Microsoft Store or the official installer). It is where the native binding comes from — the app does not have to be running, it has to be installed.
Node.js 18+.
Windows PowerShell 5.1 (the built-in
powershell.exe), used for screen capture.
No npm dependencies.
Related MCP server: windows-computer-use-mcp
Install
Clone it anywhere, then register it with the Claude Code CLI:
git clone https://github.com/Regigicas/win-computer-use.git
cd win-computer-use
claude mcp add win-computer-use --scope user -- node "$PWD\server.js"Restart the session for the tools (mcp__win-computer-use__*) to appear. Check it with
claude mcp list; remove it with claude mcp remove win-computer-use.
--scope user registers it once for every session on the machine, which is usually what you want
from a tool that drives the desktop rather than a project. It also means any session can reach
your desktop, so it is the case where an
allowlist earns its keep. Use --scope local
instead to keep it to the project you are in.
For any other MCP client, the equivalent config entry is:
{
"mcpServers": {
"win-computer-use": {
"command": "node",
"args": ["C:\\path\\to\\win-computer-use\\server.js"]
}
}
}Tools
Screen |
|
Windows |
|
Mouse |
|
Keyboard |
|
Composite |
|
Policy |
|
Coordinates are screen pixels (display origin + offset), never pixels of the returned image;
every capture states the scale it used and how to convert. batch chains several actions and ends
with a screenshot, so a click-type-check cycle costs one round-trip instead of three.
Limits and defaults
| Auto-fits the width to ~1400 px; override with |
| 1 (native pixels); values above 1 are not supported |
JPEG quality | 80 |
| 2000 characters per call, ~8 ms per character |
| 30 actions per call; |
Capture timeout | 15 s |
Restricting which applications it can touch
With no allowlist configured — the default — input reaches whatever window has focus. Configure one
and the tools that inject input (click, drag, scroll, type_text, key) refuse to act unless
the foreground window belongs to an allowed application, and focus_window refuses to bring a
non-allowed one forward.
Set it with an environment variable, which wins over everything else:
claude mcp add win-computer-use --scope user `
-e WIN_COMPUTER_USE_ALLOWLIST="notepad.exe,*brave*" -- node "$PWD\server.js"or in %LOCALAPPDATA%\win-computer-use\allowlist.json (point WIN_COMPUTER_USE_ALLOWLIST_FILE
elsewhere if you prefer):
{ "allow": ["notepad.exe", "Microsoft.WindowsNotepad_8wekyb3d8bbwe!App", "*brave*"] }The file is re-read whenever it changes on disk, so you can widen or narrow the policy in the middle of a session without restarting the server or the client.
Value | Meaning |
unset, and no file | every application allowed — the behaviour before the allowlist existed |
| every application allowed, said explicitly |
| nothing allowed: enumeration and screenshots only |
a list of patterns | only those applications |
Patterns are case-insensitive and take * and ?. Each one is matched against the full bundleId
(c:\windows\system32\notepad.exe, or an MSIX identifier such as
Microsoft.WindowsNotepad_8wekyb3d8bbwe!App), its file name with and without .exe, the package
family and package name of an MSIX identifier, and the friendly display name — so notepad.exe,
*notepad* and the full identifier all work. list_windows gains an allowed flag while a policy
is in force, and allowlist_status reports the policy and whether the app in front right now is on
it.
No tool can change the allowlist. A model able to grant itself applications would not be constrained by one; only the environment variable and the file decide. If the file cannot be parsed the server fails closed and refuses input until it is fixed.
Each action is checked on its own — including every action inside a batch — against:
the application owning the foreground window;
the application under the target coordinates of a
click,dragorscroll, so a background window or the desktop behind everything is not a valid target;for
type_text, that focus has not moved elsewhere mid-string; if it does, typing stops and reports how many characters were delivered.
What it does not cover
Captures. screenshot and zoom return the whole display whether or not an allowlist is set.
The desktop app masks non-allowlisted windows out of the image (cuMaskedWindowRects is right there
in the binding); that is not implemented here. An allowlist limits what can be done, not what can
be seen.
How the desktop app differs
Worth knowing if you expect identical behaviour. With an allowlist active the desktop app hides
every non-allowed application before acting (cuHideApps, then up to five more rounds against
whatever is still frontmost) and masks them out of the screenshot, and it grants each application a
tier: read (visible in screenshots, no input), click (plain left click only) or full. This
server does neither — it refuses the action instead of rearranging your desktop, and every allowed
application is at the equivalent of full.
Files
File | What it is |
| The MCP server (JSON-RPC over stdio, no dependencies). |
| Persistent capture helper (PowerShell 5.1 + System.Drawing). |
| Test client: |
How the binding is resolved
C:\Program Files\WindowsApps cannot be listed from an ordinary process, and the .node cannot be
loaded in place (Acceso denegado / access denied) — but it can be read and copied. So the server:
Resolves the registered package with
Get-AppxPackage -Name Claude.Copies
claude-native-binding.nodeinto%LOCALAPPDATA%\win-computer-use\and loads that copy, re-copying whenever the original's size or mtime changes.
Set CLAUDE_NATIVE_BINDING=<path> to skip all of that and load a specific file.
Nothing from the desktop app is redistributed by this repository. The binding is copied at runtime, on your machine, out of your own installation.
What it writes to disk
%LOCALAPPDATA%\win-computer-use\— the copy of the native binding, plus asource.jsonstamp recording where it came from. Persistent; safe to delete, it is re-copied on the next run. The optionalallowlist.jsonlives here too, and is only ever read.%TEMP%\win-computer-use\— each screenshot is written here as a JPEG before being read back and sent, then deleted immediately. Deletion is best-effort: if the server is killed mid-capture, an image of your screen can be left behind in your temp directory.
Nothing is sent anywhere by this server itself; it only answers the MCP client that spawned it.
Things learned the hard way
typeTextandtypeTextPacedbreak on long strings when driven from outside the desktop app: the first characters land and the rest come out as the last character repeated, or nothing at all. That is whytype_textsends one character per call. It costs about a second per 100 characters, but it is exact. Do not "optimise" it back.Shortcuts mean whatever the target app makes them mean, in its own language. On a Spanish Windows,
ctrl+ain Notepad is Abrir (open) and select-all isctrl+e. The binding maps keys correctly; the app on the other end is what differs.Key names are lowercase:
ctrl,alt,shift,win,return,escape,tab,space,backspace,delete, arrows,home,end,pageup,pagedown,f1–f12, and single characters. The internal enum names (Num1, …) throw. Chords go throughkeys([...]), which is the same API the desktop app uses forctrl+v.GDI capture looks correct in SDR; on an HDR display it can come out washed out. That is a
CopyFromScreenlimitation, not the state of your screen.The GDI capture does not draw the mouse cursor.
Troubleshooting
the Claude desktop app does not appear to be installed — Get-AppxPackage -Name Claude
returned nothing. Install the desktop app, or point CLAUDE_NATIVE_BINDING at a copy of the binding.
binding not found at ... — the package layout changed. Look for
claude-native-binding.node under the install location and set CLAUDE_NATIVE_BINDING.
Behaviour that does not match the installed version — Get-AppxPackage returns the registered
package, which is not necessarily the newest one staged on disk. If the app has updated but the
binding behaves like an older build, that mismatch is the first place to look.
capture helper could not start — powershell.exe could not be spawned: check that Windows
PowerShell 5.1 is present and not blocked by policy.
blocked by the allowlist: ... — an allowlist is configured and the app in front (or under the
click) is not on it. allowlist_status prints the policy, where it came from, and what is in front;
the allowlist section covers how to change it.
Nothing happens in the target app — elevated windows (running as administrator) will not accept injected input from a non-elevated process, and the UAC prompt runs on an isolated desktop that cannot be automated at all. Fullscreen games generally reject the injection too.
Limitations and what is untested
See docs/limitations.md for what has actually been exercised and what has
only been written.
License
MIT — see LICENSE.
This server cannot be deployed
Maintenance
Related MCP Connectors
Eyes and hands on real Windows PCs — observe, click, type via Glasswarp API.
- SimSenseOAuthai.simsense
Deploy sims to any screen. Control your displays with Claude.
Deploy sims to any screen. Control your displays with Claude.
Securely control computers you explicitly pair through files, terminals, processes, screenshots, desktop UI/input, clipboard, browser automation, diagnostics, and document tools.
Related MCP Servers
- FlicenseNot gradedqualityCmaintenanceEnables control of Windows PC through Claude Desktop, including executing shell commands, managing system resources, controlling audio/power, launching applications, taking screenshots, and managing windows and processes.-
- AlicenseNot gradedqualityDmaintenanceEnables Claude to fully control a Windows desktop with native screen capture, low-level input injection, game-grade input, and play-testing capabilities.MIT
- AlicenseNot gradedqualityDmaintenanceEnables Claude to control the local desktop via screenshot, mouse, keyboard, and clipboard operations.MIT
- AlicenseNot gradedqualityDmaintenanceEnables Claude Desktop to control mouse, keyboard, and clipboard on Windows, allowing AI-driven computer interaction tasks like clicking, typing, scrolling, and screenshotting.MIT