Windows desktop automation that re-reads only what changed: 7x fewer tokens per task.
Copy the AI prompt to install this server into Claude Code, Cursor, or another agent β or use 1-click editor setup below.
π‘ Paste the JSON block into your client's configuration file under mcpServers, then restart the application.
Desktop automation for AI agents, without paying for a screenshot every step.
mcp-name: io.github.Ask-812/oswright
An MCP server that lets an LLM drive real desktop applications β the desktop equivalent of Playwright MCP. It keeps a model of the screen between actions and re-reads only the parts that changed, so the same work costs an order of magnitude fewer tokens.

Eight fields read off an invoice and typed into an expense form, verified by the
application itself. Same task, same result, 7.4Γ less context than returning
a screenshot after every action. Every number on screen is measured during the
run β regenerate the whole thing with python benchmarks/record_demo.py.
Most GUI agents re-perceive the entire screen on every step: screenshot, OCR, hand the model an image, repeat. Measured on a live desktop, the median observation changes 0.012% of the screen's pixels. Re-reading everything does far more work than the change warrants, and charges ~2,800 image tokens whether anything happened or not.
OSWright asks the compositor what changed, rescans only that, and answers
element lookups from the cheapest source that can. The claims below are measured
on this machine and reproducible from benchmarks/ β including
the ones that did not come out in its favour.
wait_for_change.surprise report when the interface does something unexpected.First, install the OSWright MCP server with your client.
Standard config works in most tools:
Note: If you don't have
uvx, you can usepip install oswrightand then set"command": "oswright"directly.
Follow the MCP install guide, use the standard config above.
Add to your user or workspace settings.json under mcp.servers:
Or use the VS Code CLI:
Go to Cursor Settings -> MCP -> Add new MCP Server. Name it oswright, use command type with the command uvx oswright.
Follow Windsurf MCP documentation. Use the standard config above.
Add to your cline_mcp_settings.json:
Go to Advanced settings -> Extensions -> Add custom extension. Name it oswright, use type STDIO, and set the command to uvx oswright.
If you prefer a standard pip install:
Then use this config:
Or run directly:
Most GUI agents re-perceive the entire screen on every step: full screenshot, full OCR, then hand the model a fresh image. Measured on a live desktop, the median observation changes 0.012% of pixels β so a full rescan does roughly 240Γ more work than the change warrants, and the screenshot it returns costs ~2,800 image tokens whether anything happened or not.
OSWright keeps a model of the screen between observations and rescans only the regions that actually moved.
Measured on this machine over a 14-step agent loop:
| v0.4.0 (full OCR + screenshot) | incremental | |
|---|---|---|
| Median latency per step | 212 ms | 33 ms |
| Tokens per observation | ~2,764 | ~49 |
| Tokens over 14 steps | 38,696 | 1,025 |
| Screen re-read | 100% | 16% |
The busier the screen, the larger the gap: full OCR scales with how much text is
on screen, whereas the incremental path scales with how much changed. The same
comparison measures 6.5Γ on a quiet desktop and 14.3Γ with a dense web page
open. Re-measure with benchmarks/ rather than trusting these.
Cost is a proxy, though, and a cheaper perception path that quietly degraded accuracy would be worse than none. So it is checked against task completion: scripted tasks driving the real tool surface across four applications, graded against each application's own state β UI Automation for Calculator and Explorer, the window title for Chrome and VS Code β never against OCR.
| configuration | Calculator | File Explorer | Chrome | tokens |
|---|---|---|---|---|
| v0.4-style (full screenshot) | 9/9 | 3/3 | 3/3 | 118,858 |
| delta only | 9/9 | 3/3 | 3/3 | 5,252 |
| delta + memory | 9/9 | 3/3 | 3/3 | 5,099 |
| delta + memory + prediction | 9/9 | 3/3 | 3/3 | 7,981 |
Accuracy is identical across every configuration while token cost falls 23Γ.
Run it with python benchmarks/bench_tasks.py.
The design bets that neither perception path wins everywhere. Turning each half off measures that rather than asserting it:
| configuration | Calculator | File Explorer | Chrome |
|---|---|---|---|
| full cascade | 9/9 | 3/3 | 3/3 |
| accessibility only | 9/9 | 0/3 | 0/3 |
| pixels only | 6/9 | 3/3 | 3/3 |
Accessibility-only β the posture most Windows GUI agents take β is perfect on
XAML and blind on a Win32 list view and on web content. Probed against VS Code
it sees 18 elements, the entire IDE being a single node named Chrome Legacy Window, while OCR reads 94 including every filename.
Pixels-only fails Calculator's buttons, because the button a human reads as 7
is named Seven, and Windows OCR returns no digits from Calculator at all.
The cascade is the only configuration that passes everywhere.
find_element and click_element stop at the first method that can answer,
so cost tracks how novel the request is rather than how large the screen is:
| Rung | Method | Typical cost |
|---|---|---|
| 0 | Already in the screen model | ~0.05 ms |
| 1 | Rescan only what changed | ~70 ms |
| 2 | Accessibility tree (knows a Button is a button) | ~40 ms |
| 3 | App's own text buffer via UIA TextPattern β exact characters | ~400 ms |
| 4 | Full-screen OCR | ~250 ms |
Looking up text the model already knows is ~5,000Γ cheaper than the v0.4.0 path (0.05 ms versus 244 ms). The response reports which rung answered, so you can see what a task is actually costing.
No reviews yet β be the first to share how this listing worked for you.
Showcase your server listing on GitHub or your project documentation. Embed this dynamic SVG badge to highlight official listing status and live engagement.
[](https://allmcps.com/mcp/oswright)<a href="https://allmcps.com/mcp/oswright"><img src="https://allmcps.com/api/badge/oswright?style=directory" alt="Oswright on AllMCPs" /></a>