Skip to main content
Glama

NexusWindows for Claude

This repository is archived. NexusWindows for Claude now lives in the single NexusWindows repository, folder claude/, with the common engine and the other profiles: https://github.com/pironjulien/NexusWindows. Install it through NexusSystem. This copy is kept read-only for earlier installs.

Release PyPI Tests OpenSSF Scorecard License: MIT Python 3.14 MCP Windows 10/11

NexusWindows: Windows computer use for AI agents, in the background. Works with Claude, Codex and Antigravity.

NexusWindows: an AI agent fills and submits a form in a window that stays behind another one, then reports five verified steps

Windows computer use for Claude, in the background. An MCP server (nexus-windows-claude) that lets Claude Desktop and Claude Code see and operate Windows desktop applications while the user keeps their mouse, keyboard and foreground window.

Version 3.7.4 · Windows 10/11 · Python 3.14 · MIT licence

Part of the Nexus family: NexusWindows (Claude · Codex · Antigravity), NexusBrowser (repo), NexusAndroid (repo). Project page: julienpiron.fr/nexuswindows.

Why

Anthropic's own computer use (in Cowork and Claude Code inside Claude Desktop) is a beta for Pro and Max subscribers: "Team and Enterprise plans don't have access to computer use at this time" (Claude Help Center). NexusWindows for Claude is a local MCP server, so it works with Claude Desktop and Claude Code on any plan that allows local MCP servers, Team and Enterprise included.

Screenshot-and-click computer use moves the real cursor and brings windows to the front, so the person at the PC has to stop working while the agent acts. Most Windows applications can be driven without that: native controls accept window messages, modern frameworks expose UI Automation, and Chromium can be reached through its accessibility tree. This server picks, per UI family, a technique that was measured not to steal focus, reads the effect back, and only falls back to the real mouse or keyboard when the user explicitly allows it.

Related MCP server: win-computer-use

NexusWindows family

Three MCP servers, one per agent, built separately because each model needs its tools shaped for it, with the same promise: the user keeps their mouse, keyboard and foreground window, and every action is read back.

Claude

Codex

Antigravity

Install

uvx --python 3.14 nexus-windows-claude

npx -y nexus-windows-codex

uvx --python 3.14 nexus-windows-antigravity

Package

PyPI

npm

PyPI

Tools

windows look act launch window, plus notifications and logs

windows look act launch window

windows look act launch window

Repository

NexusWindows-Claude

NexusWindows-Codex

NexusWindows-Antigravity

Every step reports ✓ verified, = already done, ~ unknown (never replayed) or ✗ failed or refused. The three share the guardrail policy, the foreground token, the emergency stop (Ctrl+Alt+Shift+Esc), a common journal format and a common bench.

Installation

Windows 10 or 11. You do not need Python: uv downloads Python 3.14 by itself.

One step (installs uv if missing, downloads and checks the server, registers it with Claude Code and declares it in Claude Desktop's configuration, merged after a backup; an entry of your own is kept, and with the Claude Code plugin enabled no second server is added): open Windows PowerShell (Start menu, type powershell) and paste:

irm https://raw.githubusercontent.com/pironjulien/NexusWindows-Claude/main/setup.ps1 | iex

Then close Claude completely and open it again. setup.ps1 is short and can be read first; running it again only does what is missing.

Claude Code plugin (the same server, plus a skill; uv required):

/plugin marketplace add pironjulien/nexus-plugins
/plugin install nexus-windows@nexus-plugins

Claude Desktop extension (uv required): download nexus-windows-claude-<version>.mcpb from the latest release, then in Claude Desktop open Settings → Extensions and drop the file there (or Advanced settings → Install extension), and click Install. With the Microsoft Store version of Claude Desktop, double-clicking the file does not open it: Windows has no app for .mcpb.

By hand. Install uv (official package):

winget install --id=astral-sh.uv -e

then restart Claude so that it sees uv, and register the server from PyPI. Claude Code:

claude mcp add --scope user -e PYTHONUTF8=1 --transport stdio nexus-windows -- uvx --python 3.14 nexus-windows-claude

Claude Desktop: Settings → Developer → Edit Config, add this to claude_desktop_config.json (inside the existing mcpServers if there is one), save, then quit Claude completely and reopen it:

{
  "mcpServers": {
    "nexus-windows": {
      "command": "uvx",
      "args": ["--python", "3.14", "nexus-windows-claude"],
      "env": { "PYTHONUTF8": "1" }
    }
  }
}

The first start downloads about 100 MB (Python 3.14 and the server's dependencies); later starts take under a second. Until 3.0.0 the package was named nexus-windows; that name still works and installs nexus-windows-claude.

From a clone (development):

git clone https://github.com/pironjulien/NexusWindows-Claude.git
cd NexusWindows-Claude
$env:UV_PROJECT_ENVIRONMENT = "$env:LOCALAPPDATA\claude-windows-computer-use\venv"   # optional: venv outside the clone
uv sync --frozen

Register it with Claude Code (user scope):

claude mcp add --scope user `
  -e "UV_PROJECT_ENVIRONMENT=$env:LOCALAPPDATA\claude-windows-computer-use\venv" -e PYTHONUTF8=1 `
  --transport stdio nexus-windows '--' uv run --project "$PWD" --frozen python -m nexus_windows

For Claude Desktop from a clone:

{
  "mcpServers": {
    "nexus-windows": {
      "command": "uv",
      "args": ["run", "--project", "C:/path/to/NexusWindows-Claude", "--frozen", "python", "-m", "nexus_windows"],
      "env": { "PYTHONUTF8": "1" }
    }
  }
}

Local state (logs, routines) lives in %USERPROFILE%\.claude\nexus-claude\; set NEXUS_WINDOWS_HOME to use another folder.

Tools

Tool

Purpose

windows(filter)

Application windows, front to back: hwnd, title, process, UI family, size; [hidden] Store apps launched in the background (never shown, still drivable); then the taskbar and the desktop

look(window, show, query, region, detail, marks)

Numbered [N] elements (role, name, value, state, position), without bringing the window forward; text first: the image only when the tree is too thin or after an unverified step (show="both" always attaches it); also window="taskbar", "desktop", and "screen" (the whole screen with each window's place)

act(steps, window, then, foreground, remember, routine, params)

Several steps in one call, each read back, then the updated state; Windows panels "quick settings", "notifications", "start" with foreground=true

launch(app, args, devtools, restart)

Start an application (Start menu name, Store app, executable), a folder, a document or an address (ms-settings:<page>, mailto:, https:) without giving it focus; the opening is verified

window(action, ...)

Restore behind, minimize, maximize, close, move, resize

notifications(limit, app)

Windows notifications read from their database (read-only), nothing opened on screen; security codes masked

logs(count, errors_only)

Debug log: techniques tried, durations, errors, server state

Step actions: click, double_click, right_click, type, set, clear, key, select, check, uncheck, toggle, expand, collapse, scroll, focus, menu, wait, drag, hover. A target is an [N] from the last look, a visible name ("OK"), a role-qualified name ("button:OK", "edit:Name", "checkbox:Subscribe") or an x,y point in the last image.

windows, notifications and logs also return structured content (MCP outputSchema and structuredContent: window rows, notifications, log records) beside the same text, for clients that read data rather than prose.

Usage

Typical flow: look(window="Notepad"), then one act with all the steps, then read the per-step report.

act(window="Settings form", steps=[
  {"do": "set",   "target": "edit:Name", "text": "Ada",
   "check": {"target": "Name", "value": "Ada"}},
  {"do": "check", "target": "Subscribe"},
  {"do": "click", "target": "button:Save", "expect": "Saved"}
], remember="save-form")

Later: act(window="Settings form", routine="save-form").

What it does

Only what changed (then="changes", show="changes")

After an action, act(then="changes") (or look(show="changes")) returns only what changed since the last list shown for that window: + added, ~ changed (text, state or moved), - removed; every other element keeps its [N]. A common scroll of many elements is one line naming them as ranges ([2-21]), not a full list. Comparison is made in the window's own frame, so moving the window is not a change. A removed [N] is never given again, and an element whose change was cut from a long report loses its [N] until the next look. When almost everything changed (60 %), the full list is returned. Measured: 2 to 2.6 times shorter than the full list after a click.

Text read from the image (OCR fallback)

When a window publishes almost no UI Automation elements (fewer than 6: Tk, canvases) or a Chromium page stops publishing its content, the text of the window image is read with the Windows built-in OCR engine (Windows.Media.Ocr, local, offline) and listed as [N] Text "…" (OCR) with its position; such an element can be targeted by number or by name (click at its position, recomputed if the window moved). Measured on the lab apps: 10 to 21 ms per window; text correct 16/16 (WPF), 20/23 (Edge), 6/7 (Tk).

Four outcomes per step

Each step is reported as one of:

  • ✓ the effect was read back (value, state, window, image). A click or menu choice with no expect or check is also proven on its own, by the clicked element only: its own state read back (checked, expanded, selected), or the UI Automation "Invoked" event the application raises when the control receives the click (WPF, Chromium, Electron; not WinForms or Win32, whose buttons stay ~). "Invoked" says the click arrived, not what it produced: expect checks that. A click the control acknowledged is never sent again by another technique;

  • = the state requested by the step's check was already true, so nothing was sent;

  • ~ the input was sent but its effect could not be read (never counted as a success);

  • ✗ failure, refusal, or postcondition not met; the batch stops there.

A batch ends with a tally of the four counts.

Postconditions (check)

A step may carry check: one element and the state it must reach (value, contains, checked, selected, expanded, focused, enabled, exists). Already true before the step: the step is skipped (=). True after: ✓. False after: ✗ and the batch stops. A state the element does not publish stays unknown, never false.

Routines

act(remember="name") saves a batch only if every step ended ✓ or = and every target is a visible name (never an [N] or a point). {{x}} marks variable text, filled at replay with params. act(routine="name") finds each target again by name and re-verifies every step; an application update is reported and a failed replay marks the routine for review. Routines are stored per executable under %USERPROFILE%\.claude\nexus-claude\routines. An optional mirror folder (NEXUS_ROUTINES_MIRROR) can share definitions between PCs; typed text is never mirrored in clear (a routine whose text is not a {{x}} template stays local).

Verified opening of paths

launch(app=<folder or document>) opens through the file association (ShellExecuteEx, no activation requested), then checks what actually opened: the folder shown in File Explorer (read through Shell.Application) or a window titled with the file name. Scripts, shortcuts and installers are refused.

Per UI family

  • Native Win32: direct messages to controls (BN_CLICKED, CB_SETCURSEL/LB_SETCURSEL with their notification, EM_REPLACESEL, menu WM_COMMAND, TCM_SETCURFOCUS), read back. UI Automation is avoided where it was measured to steal focus (button Invoke) or to fail silently (list Select).

  • Win32 and WinForms drop-down lists: opened and closed with CB_SHOWDROPDOWN, read back with CB_GETDROPPEDSTATE (expand, collapse, or click on the list). Choosing in an open list closes it first (Windows treats that close as a cancel and would drop a choice made before it), then sends CB_SETCURSEL, CBN_SELCHANGE and CBN_SELENDOK to the parent and reads the application back (index and label); an empty or other value is ✗. While a list is open its UI Automation tree is not walked (it chains to every top-level window of the desktop): the options are read from the ComboLBox pop-up itself.

  • WinForms, WPF, UWP, WinUI: UI Automation with AutoSetFocus disabled and bounded timeouts. A WPF drop-down list left open by a choice is closed and the choice read back.

  • Chromium and Electron, without activation: for an app already open without DevTools, multiline fields, rich editors, <select>, keys and Ctrl/Alt shortcuts go through a simulated activation: WM_NCACTIVATE and WM_ACTIVATE are sent to that window only (Chromium takes its activation state from these messages; Windows does not change the foreground), DOM focus is set with MSAA accSelect(SELFLAG_TAKEFOCUS) and read back, characters go as WM_CHAR, and the deactivation is posted so it is processed after them. The page receives trusted keydown and input events. One caveat was measured: an app launched a moment ago may use its launch-time foreground right once (about 10 ms, handed back by the guard), so the first simulated activation per process is treated like a brief activation. Apps started with launch(devtools=true) are driven through the DevTools protocol instead.

  • Steam (CEF in an SDL frame): recognised as Chromium; launch(app="Steam") adds Steam's own -cef-disable-occlusion -cef-force-accessibility switches so the UI stays readable while covered.

  • Tk: no UI Automation; its text is found by the OCR fallback. Clicks are sent with the mouse button marked pressed for Tk's thread only (Tk reads it with GetKeyState), keys and shortcuts get a simulated focus (WM_SETFOCUS to that window only, never WM_ACTIVATE), lists scroll through their native scroll bar; all read back. A wheel on a covered Tk canvas would be lost (Tk routes it to the window visible at the point): a Tk window that is entirely covered is moved beyond the desktop for the gesture (no activation), the wheel is posted to the same control there, and the window comes back to its place, read back to the pixel; a partly visible, maximized or minimized window is never moved (refused).

  • Scrolling a covered Chromium page without DevTools: the wheel is dropped by Chromium when another window is on top, and scrolling areas expose no ScrollPattern; the next hidden line of the area is brought into view (UI Automation ScrollItem) and the line's offset inside its area is read back.

Capture

PrintWindow (10 to 26 ms, covered windows included), Windows.Graphics.Capture only as a fallback. Images follow the common Nexus image rule: at most 2000 px and 2.56 MP, so that neither Claude Code nor the model downscales them (coordinates stay exact); lossless WebP up to 500 KB, then lossy until the image fits 500 KB, same size (a 2560×1440 screen is sent as 2000×1125, about 110 KB lossless). To read small text, zoom with region rather than a larger image. An image identical to the last one sent for that window (or zoomed area) is not attached again; the reply says so, and show="image" always attaches it. Coordinates are bound to the window: followed if it moves, refused if it was resized.

Agent at work

While an action runs (act, launch, window; never the reads), a small logo spins on itself in the bottom-right corner of the driven window's screen, like a game loading screen, with a breathing blue halo. It goes away 1.6 s after the last action. The overlay is always on top, borderless, click-through, never activated, absent from the taskbar and excluded from screen captures (the model never sees it in look). NEXUS_WINDOWS_INDICATOR=0 turns it off.

Real mouse and keyboard

Only with act(foreground=true), which the user must approve. The window then stays in front for the whole batch; cursor and foreground are handed back at the end; any physical input from the user during the batch stops it.

Working alongside other agents

The server cooperates with other desktop agents on the same PC (it is used next to a Codex layer, NexusWindows for Codex, and an Antigravity layer) through two small file-based protocols. Any agent can implement them.

Foreground token (%USERPROFILE%\.nexus\foreground.lock): taken only while really holding the mouse or the foreground (real input, brief activation, window put in front), never for background actions. Holding it means an exclusive LockFileEx on 1 byte at offset 2^32, opened with read, write and delete sharing; Windows releases it when the handle closes, including when the process dies, so there is no stale token. The holder writes {"owner", "pid", "since", "purpose"} at the start of the file for diagnostics only. Waiters wait at most a few seconds (8 s here), then do nothing and say who holds it. A foreground guard that sees another agent holding the token follows that agent's window instead of taking the foreground back.

Emergency stop (Ctrl+Alt+Shift+Esc, files in %USERPROFILE%\.nexus\): every agent tries RegisterHotKey(MOD_NOREPEAT); one gets it, the others retry every 3 s. The holder writes a heartbeat to stop.owner every 3 s. On a press it rewrites stop with {"by", "pid", "at", "hold_s": 120, "nonce"}. Every agent watches stop at least every 0.2 s and before each action: a new version younger than 120 s blocks all desktop actions for the remaining time (reads stay allowed). The stop is latched in memory on a monotonic clock: deleting the file or changing the clock does not lift it, a new press re-arms it.

Architecture

flowchart LR
    Claude["Claude Code or Claude Desktop"] -->|"MCP stdio"| Server["server.py MCP tools"]
    Server --> Worker["COM worker thread with hard timeout"]
    Worker --> Snapshot["snapshot and capture"]
    Worker --> Actions["actions per UI family"]
    Actions --> Win32["Win32 messages"]
    Actions --> UIA["UI Automation"]
    Actions --> Chromium["Chromium simulated activation and DevTools"]
    Actions --> Real["real input only with foreground true"]
    Server --> Safety["policy, emergency stop, foreground guard"]
    Safety --> Shared["shared files in USERPROFILE nexus"]
    Real --> Shared
src/nexus_windows/
  reloader.py      stdio supervisor: restarts the server on new code and replays the client handshake
  server.py        MCP tools, dedicated COM thread, per-call log
  actions.py       executor facade, assembled from the act_*.py modules
  act_base.py      targets read back live, technique chains, outcomes, shared refusals
  act_win32.py     Win32 messages
  act_uia.py       UI Automation (WinForms, WPF, UWP/WinUI) and dispatch per family
  act_chromium.py  Chromium/Electron/CEF: verified click, DevTools, simulated activation, <select>
  act_pointer.py   points, message clicks, scrolling, drag, hover
  act_wait.py      text presence and waiting
  snapshot.py      window + popups, [N] elements, image, coordinates, changes since the last list
  ocr.py           Windows built-in OCR (Windows.Media.Ocr) for windows without UI Automation
  uia.py           UI Automation with a single cross-process cache request
  methods.py       Win32 message techniques
  cdp.py           minimal Chrome DevTools Protocol client
  capture.py       PrintWindow / Windows.Graphics.Capture
  foreground.py    foreground monitoring and restoration, brief activation
  agentlock.py     shared foreground token
  postcond.py      step postconditions (check)
  routines.py      verified routines per application
  physical.py      the user's physical input (Raw Input, no hook), told apart from injected input
  launch.py        background launch, DevTools, throwaway browser profiles
  steam.py         Steam switches, clean restart, DevTools port
  realinput.py     real mouse/keyboard (SendInput), only when authorised
  policy.py        where to act and what to launch (hard blocks of the shared policy, launch switches)
  act_confirm.py   confirmation of irreversible gestures (confirm: true), whatever key or click triggers them
  shared/          the guard-rail policy shared with NexusWindows for Antigravity (garde-fous.json)
  packages.py      resumes Store apps that Windows suspended in the background
  offwindows.py    outside Windows: the server starts and lists its tools, every desktop tool says Windows is required
  stop.py          shared emergency stop
  freshness.py     detects a server whose code changed on disk
  codeprint.py     code fingerprint and location of the shared policy (no dependencies)
  worker.py        COM thread with a hard timeout
  log.py           JSONL log, 14 days
lab/     test applications (Win32, WinForms, WPF, Tk, a web page for Electron/Edge)
bench/   technique benchmarks and raw results
tests/   unit tests (pytest) and end-to-end tests (pytest -m live)

Measurements

All figures come from bench/RESULTS.md and the raw files in bench/results/ (measured on one PC, October 2026; the notes in RESULTS.md are in French).

What

Result

Capture, PrintWindow

10 to 26 ms, covered windows included

Real MCP server, 73 actions on the lab apps (0.4.0 to 0.5.0)

69 succeeded, 5 explicit refusals, 0 false success, 0 cursor move, clipboard never touched; median 78 ms, p90 321 ms

2,000 characters with 20 line breaks

Win32 38 ms, WinForms 66 ms, WPF 141 ms, Electron/Edge with DevTools 82 to 108 ms

Chromium simulated activation, scenario of 18 steps (0.7.0)

Electron 18/18, 1 foreground take of 9 ms (launch right, first time); Edge 18/18, 0 foreground take

Same, Electron without switches, hidden

17/18; the failure is a page that rebuilds 1,500 elements per keystroke, reported as ✗

Typing 700 characters on 6 lines, simulated activation

0.85 to 1.1 s (Electron, Edge), 1.9 to 2 s when occluded

Final render of an act (0.7.0 vs 0.6.1)

Win32 418 → 221 ms, Electron 341 → 205 ms (window-settle detection replaces a fixed 300 ms wait)

Open drop-down list, choose in it (WinForms and WPF forms, real MCP server)

8/8 scenarios, the application received the choice every time; select in an open WinForms list 113 ms (was 22 s and a failure); 0 foreground take sampled every 5 ms, cursor never moved

Cross-agent parity bench (October 26, 2026)

The three NexusWindows editions (this one, for Codex and for Antigravity) ran the same 33 tasks, 3 rounds each, on the Electron, WinForms and WPF lab windows, placed at the bottom of the z-order under an opaque cover, nobody at the PC (the bench stops the moment the user touches the mouse or keyboard). The effect is judged by the application (event received or value read back), never by the tool's report. Raw results: bench/results/2026-10-26_1045-parity.json (summary in French next to it).

Exact effect

Without intrusion

False success

Median

p95

nexus-windows for Claude 3.3.0

84/99

83/99

0

957 ms

5.6 s

NexusWindows for Codex

84/99

82/99

0

691 ms

3.8 s

NexusWindows for Antigravity

84/99

80/99

0

817 ms

3.4 s

Gap between the three: 0. Every Electron task 3/3 for all three. The 15 failures are the same for all three and are background limits refused honestly, not false successes: WPF raw click, Ctrl+K in WPF, WPF context menu, and double click in WinForms and WPF (the cover sits over the point; WinForms ignores a double click posted to a covered point). "Intrusion" means the foreground was taken, the cursor moved or the clipboard was written during the attempt.

Offline test suite: see the Tests badge (test.ps1 on Windows, plus a startup check on Linux).

Side by side with Cua Driver and Windows-MCP (October 26, 2026)

Cua Driver 0.38.0 is the closest other tool: it also works in the background by default. Windows-MCP 0.8.8 is the most used Windows MCP server; it has no background mode. All three were driven through their real MCP servers (bench/cua_vs_nexus.py) on the same lab windows, covered by an opaque window, nobody at the PC (the bench refuses to start before 2 minutes without physical input and stops at the first one); each was used the way its own guide tells an agent (Cua: background first, then clicks, then its foreground fallback; Windows-MCP: bring the window forward with App switch, then act on the screen). The effect is judged by the application (event received or value read back), never by the tool's report. Foreground changes are sampled every millisecond, the real cursor before and after each attempt. 51 tasks across Win32, WinForms, WPF, Tk, Electron and Edge (bench/tally_cua.py, raw results in bench/results/2026-10-26_1210-cua-vs-nexus.json). To reproduce: python bench/cua_vs_nexus.py on an idle Windows PC, with Cua Driver and Windows-MCP installed as described at the top of the script.

All 51 tasks, target covered

nexus-windows 3.3.0

Cua Driver 0.38.0

Windows-MCP 0.8.8

Effect proven in the background

44

26 (+1 by clicks, +6 after taking the foreground)

0 (no background mode; 10 effects in the foreground)

False success (reported done, the app got nothing)

0

4

not comparable, see below

Scrolling a covered list (Tk, Electron, Edge)

3/3

0/3

0/3

Foreground taken

0

3

15 (never given back)

Real cursor moved

0

0

34

Median time of a successful action

598 ms

728 ms

1,478 ms

Windows-MCP reached the effect on all 9 Win32 tasks once its App switch brought the window forward. On the WinForms, WPF, Tk, Electron and Edge windows the switch left the window behind 30 times, and its click or typing then landed on the window on top (here the bench's cover; in real use, the user's own window) while it reported the click: 36 "done" answers with no effect, which says more about the absence of a background mode than about its reporting, so they are not counted as false successes in the table. 5 more attempts failed in the bench adapter (an item of an open list or menu was not found on screen).

Misses of this server in this run: WPF raw click, wheel and Ctrl+K, a wheel on a covered canvas (Tk, Electron, Edge), and Win32 Ctrl+K this time; each was reported as refused or as an unknown outcome (~), never as done.

History, from 3.0.1 (35 of 45 covered rows) to 3.0.2 (October 23, 44 of 51 against Cua's 28, details in bench/RESULTS.md): Tk clicks and shortcuts, Win32 Ctrl+K, and scrolling covered lists. Still refused, with the cause read in each toolkit's source and measured: WPF clicks, wheel and shortcuts, a wheel on a covered canvas, input at a point of a hidden Electron page. Taken from Cua: reading only what changed (then="changes"). Not taken: its injected WPF click (moves the user's real cursor), CDP clicks in an already open Chrome (turns on remote debugging in the user's real profile). Tried and dropped: simulated activation for WPF shortcuts (WPF takes the foreground), WM_POINTERWHEEL (Windows refuses to post it), WM_VSCROLL to the Chromium renderer (no effect), InjectSyntheticPointerInput (goes to the window on top).

Cross-agent bench (October 16, 2026)

The same task was run by the three Windows desktop agents used on this PC (this server, the Codex layer and the Antigravity layer) on WinForms and WPF forms created without activation at the bottom of the z-order, while the user kept working: fill three fields, tick a box, open the "Formule" drop-down list, choose "Bravo" in the open list, validate. Proof is the result label read back in the application. Physical input was forbidden and counted.

Morning

After fixes

Measured

This server (0.7.0 + drop-down fixes)

17/20

19/20

open list read back on both families; select in an open WinForms list 113 ms instead of 22 s; application received Formule=Bravo;Envois=1; 0 foreground take over 1,371 and 773 samples (20 ms), 0 cursor move, 0 physical input

NexusWindows for Codex 1.4.0

16/20

19/20

every step verified on both families; observe + batch 1.2 to 1.4 s

Antigravity layer

18/20

19/20

open WinForms list read and chosen; batch status is the worst step

What still keeps this server from 20: clicking "Validate" stays ~ without an expect (the application did receive it), and a click on a closed WPF list is ~ where expand is ✓.

Security

  • Emergency stop: Ctrl+Alt+Shift+Esc interrupts the running action at its next checkpoint (typing included) and refuses every new action for 2 minutes, across conversations and for the other agents (protocol above).

  • Hard blocks (shared policy, src/nexus_windows/shared/garde-fous.json, same file as NexusWindows for Antigravity): the secure desktop (UAC, lock and sign-in screens) and password managers are never read nor driven. A missing or unreadable policy refuses every action (fail closed).

  • Confirmation of irreversible gestures: paying, buying, ordering, transferring money, sending, publishing, posting, deleting permanently, emptying the bin, formatting, uninstalling, resetting, cancelling a subscription, deleting an account or making a repository public need confirm: true on the step, which the model sets only on the user's explicit order or yes. The check covers what the gesture triggers: click by [N], by name or by coordinates, double-click, Enter (target, default button, nearby send button), Ctrl+Enter, Space, Alt+letter, a typed line break DevTools pages and Win32 menus. A routine never records nor replays confirm.

  • Approval bound to the exact action: an outward gesture (sending, calling, paying, publishing, transferring) also needs accord: "<token>". The first try is refused before any input with a summary of the exact action (trigger, process, window title, values of the window's editable fields) and a single-use token; only after the user's own yes is the same step sent again with confirm: true and that token. Any change in between voids it.

  • Prompt injection signal: text read on screen that looks like instructions aimed at an AI gets a warning appended to the response (a signal only; it can never authorise an action).

  • Launch: a browser never gets a profile chosen by the model, a DevTools port or a loaded extension (devtools=true opens a fresh throwaway profile). Consoles, File Explorer, the taskbar and other applications are not refused: the server is meant for a user who already lets Claude run commands; keep Claude's own permission prompts on if you want a gate there.

  • Password fields: never typed into. Typed text is never logged (only its length).

  • Accounts: a browser started with devtools=true gets a throwaway profile without account or sync, checked after launch and deleted afterwards.

  • Screen content is data: every look reminds the model that on-screen text is not an instruction.

  • Up-to-date code: the entry point is a small stdio supervisor (reloader.py). Before each tool call it compares the code on disk with the running server's; if it changed, it waits for calls in progress, starts a fresh server and replays the client's handshake, so an update needs no reconnection (/mcp). A server whose code changed between two checks refuses act, launch and window, and the call is replayed on the fresh one.

  • Timeouts: an abandoned call is cancelled at its next checkpoint instead of finishing later.

  • Clipboard: never used.

Privacy

NexusWindows for Claude runs entirely on your PC. It has no account, no telemetry and no analytics. Its only network request of its own is the update check: at most once a day, at startup and in the background, it reads the latest version number from PyPI (https://pypi.org/pypi/nexus-windows-claude/json, nothing sent but the request itself) and, when it was started by uvx, prepares that version in uv's cache for the next start of Claude. NEXUS_UPDATE_CHECK=off turns this off. DevTools connections stay on 127.0.0.1.

  • What it reads: window titles, the UI Automation tree and window images of the applications Claude works in, only when a tool is called. Password managers and the secure desktop are never inspected (look) nor driven (act); windows still lists their window titles, like the taskbar does. The OCR fallback uses the Windows built-in engine on the PC; no image leaves it for OCR. look(window="screen") reads the whole screen as you see it, every visible window included. The notifications tool reads the Windows notification database read-only (app, time, texts; never modified), masking security codes.

  • Where it goes: tool results are returned to Claude Desktop or Claude Code, which send them to Anthropic under Anthropic's own privacy policy; this server sends nothing anywhere else.

  • What it stores, under %USERPROFILE%\.claude\nexus-claude\ (or NEXUS_WINDOWS_HOME): a JSONL debug log kept 14 days (tools, techniques, durations, errors; typed text is replaced by its length), the routines you chose to remember, and throwaway browser profiles created by devtools=true (deleted afterwards). Images are written to the log only if you set NEXUS_WINDOWS_DEBUG_IMAGES=1. Under %USERPROFILE%\.nexus\: the shared foreground token and emergency-stop state, and status\windows-claude.json (installed and latest version, update state) with the date of the last check in windows-claude\update.json. Under %LOCALAPPDATA%\NexusJournal\windows\claude\ (or NEXUS_JOURNAL_HOME): a short monthly JSONL journal, in the same format as the other NexusWindows tools (app executable name, framework, action, technique, outcome, duration, whether the foreground was used, and the first words of an error, cut before any quote, colon or bracket); never typed text, screen text, labels, titles or paths. The server never deletes it.

  • Removing it: remove the server from Claude (claude mcp remove nexus-windows), then delete those folders (and %LOCALAPPDATA%\NexusJournal).

Questions or concerns: open an issue on this repository.

Limits

  • Code comments are in French. Everything an MCP client receives (instructions, tool descriptions, step reports, refusal messages) is in English.

  • Windows only. Tested on Windows 11 with the lab apps and a handful of real applications; not every application has been checked.

  • Applications without UI Automation that ignore posted input (some games, canvases) need real input, so the user's approval and the foreground; the OCR fallback finds their text but does not make background input possible.

  • WPF: raw clicks on a point, the mouse wheel and keyboard shortcuts are refused in the background (WPF drops a click while the real cursor is not over its window, and takes the foreground when given focus); controls with UI Automation patterns work.

  • A mouse wheel on a covered Chromium canvas has no effect (Chromium routes it to the window on top); it is refused or reported as ~, never as a success. On Tk, it works only when the window is entirely covered (see Per UI family). Lists and scrolling areas scroll without the wheel (see Per UI family).

  • A covered Electron page that has gone hidden (it had the foreground once, then lost it) stops rendering: clicks at a point are reported as ~.

  • Store apps that Windows suspends in the background are resumed (IPackageDebugSettings.Resume, no foreground); one that Windows still does not render can only be shown by taking the foreground; this is reported.

  • In Chromium, a page that reacts very slowly to each keystroke can exceed the read-back time and is reported as ✗.

  • An effect with nothing readable (a file written by a button, for example) stays ~; add a check that observes it.

  • The end-to-end suite (pytest -m live) drives real windows and refuses to start if the PC was used less than 2 minutes ago.

Development

pwsh -NoProfile -File test.ps1         # unit tests, ruff check and format; venv and caches outside the clone
pwsh -NoProfile -File test.ps1 -Full   # also the end-to-end tests on the lab windows
uv run python bench/bench.py           # technique benchmark (when nobody is using the PC)

Licence

MIT, see LICENSE. Copyright (c) 2026 Julien Piron.

Available Tools

7 tools
actA
Destructive

Act in the background: steps run in order (stops at the first error or unknown outcome), then the updated state (then: auto = list + image if a step is not verified; both, image, elements, changes, none). Per-step report: ✓ invoked or effect read, = already done (nothing sent), ~ unknown outcome (batch stopped: inspect the state), ✗ failed or not reached; then the summary. Steps (do): click, double_click, right_click, type (appends text; no target = focused element), set (replaces the text), clear, key (keys "ctrl+s", "enter", "alt+f4"), select (option in a list), check, uncheck, toggle, expand, collapse, scroll (direction, amount), focus, menu (path "File > Open"), wait (text appeared, or gone=true; timeout), drag (target → to), hover. expect: text expected after the step. check: wanted state of an element ({"target":"Name","value":"Alice"}; also contains, checked, selected, expanded, focused, enabled, exists): already true → step skipped, read back after → ✓, otherwise ✗ not reached. confirm=true: paying, sending, publishing, permanent deletion… (refused otherwise, before any input); only on the user's explicit order or "yes" for THIS action. Outward ones (send, pay, publish…) also need accord: the token from the refusal, after the user's own yes. target: [N] from the last look, visible name ("Save", "button:OK", "edit:Name") or "x,y" in image pixels. Example: steps=[{"do":"set","target":"Name","text":"Alice"},{"do":"click","target":"OK"}]. Routines: remember="name" saves the batch if it is verified (✓/=, targets by name; {{x}} = variable text, only in text and check.value/contains; typed text made only of {{x}}); routine="name" (without steps) replays it, params={"x": "…"}; remember="name" with steps=[] forgets it; look lists them. foreground=true: window kept in front for the whole batch, real mouse/keyboard when the background is impossible or ignored (drag, hover, WPF/UWP/Chromium shortcuts, Tk); only with the user's consent. Panels window="quick settings", "notifications", "start": foreground=true only.

NameRequiredDescriptionDefault
thenNoauto
stepsNo
paramsNo
windowNo
routineNo
rememberNo
settle_msNo
foregroundNo

TDQS

A4.3/5.0
Behavior5/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

The description adds extensive behavioral detail beyond annotations: batch stop conditions, per-step symbols, then-mode outputs, confirm/accord safety gating, foreground escalation rules, and routine save/replay behavior. This is consistent with destructiveHint=true, openWorldHint=true, and readOnlyHint=false.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is long but appropriately dense for a highly parameterized automation tool, and it front-loads the core batch model before details. Some sections are packed into terse run-on text, but nearly every sentence carries operational meaning.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a complex UI automation tool with no output schema, the description is complete enough: it explains execution order, failure semantics, report symbols, returned state modes, confirmation safety, routines, and foreground constraints. Only minor details such as settle_ms are absent.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is low at the top level, and the description compensates well by explaining then modes, steps, expect, confirm, accord, target formats, routine/remember/params, foreground, and panel windows. It still leaves settle_ms unexplained and does not fully cover every top-level nuance.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description clarifies that this tool executes an ordered batch of UI actions in the background and explains the state/report returned afterward. It is specific about the verb and resource, but it does not clearly differentiate the tool from siblings like window, launch, or look beyond a brief mention of look listing routines.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

It gives clear usage conditions for confirm=true, accord tokens, foreground=true, and routines, including safety exclusions such as refusing confirm without explicit user instruction. However, it does not explicitly state when to choose act over sibling tools such as look, window, or launch.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

launchA

Open an application in the background (without giving it the foreground) and see it. app: Start menu name ("Calculator", "Notepad"), executable ("notepad.exe") or path. args: arguments. app = path of a FOLDER or a DOCUMENT: opened by its file association (Explorer, default application), opening verified (displayed folder read back, or title carrying the file name). app = ADDRESS: ms-settings: opens that Settings page behind the user's window (Windows flashes it ~1 s; foreground given back); any other scheme (mailto:, https:, tel:…) by its app. Calling or sending stays a click, guarded in act (confirm + accord). devtools=true (Chromium/Electron/Edge only, application not already open): opens a local DevTools port for more reliable clicks, typing and shortcuts. The window becomes the current window. Steam: always launched readable even when covered; devtools=true opens its DevTools port (127.0.0.1:8080, its own session); when already open, restart=true closes and relaunches it (refused while a game runs). Both: only with the user's consent.

NameRequiredDescriptionDefault
appYes
argsNo
thenNoauto
wait_sNo
restartNo
devtoolsNo

TDQS

A3.7/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Beyond the annotations, it discloses important behavior: launching in the background, Windows briefly flashing Settings pages, returning foreground, verification of folder/document opening, DevTools port exposure, Steam readability, and restart refusal while a game runs. It does not explain the effects of then or wait_s, leaving some behavioral gaps.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness3/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The information is dense and mostly relevant, but it is delivered as a run-on block with nested parentheticals and inconsistent structure. It starts with the main purpose, yet later details about Steam and DevTools are hard to scan and would be clearer as separated sections.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness3/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a six-parameter, behaviorally complex tool with no output schema, the description covers the critical app argument and many special cases well. However, then and wait_s are unexplained, args is under-specified, and the result of 'see it' is not fully clear.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is 0%, so the description must carry parameter meaning. It thoroughly documents app formats and adds useful semantics for devtools and restart, but args is described only as 'arguments,' and then and wait_s are not mentioned at all despite being part of the six-parameter schema.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description states a specific action and resource: opening an application in the background and seeing it, with explicit support for apps, folders, documents, and address schemes. It is clearly distinct from act, look, and window, though it does not explicitly route against those siblings.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

It gives concrete conditional guidance: devtools only for Chromium/Electron/Edge and only when the application is not already open, restart only when already open and refused during games, and address schemes opened by their associated app. It lacks broad guidance on when to use launch instead of act, window, or look.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

logsB
Read-onlyIdempotent

Log of the latest calls (debugging): tool, arguments, techniques tried per step, durations, errors. Full files: ~/.claude/nexus-claude/logs/YYYY-MM-DD.jsonl.

NameRequiredDescriptionDefault
countNo
errors_onlyNo

Output Schema

NameRequiredDescription
pidYes
statusYes
recordsYes
versionYes

TDQS

B3.2/5.0
Behavior3/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare readOnlyHint, idempotentHint, destructiveHint=false, so safety is covered structurally. The description usefully discloses the returned fields and the on-disk location of the full logs, implying this is a bounded recent-window read. It does not state the actual recency/volume limits or how the count default behaves.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Two tight sentences, front-loaded with what the log contains, followed by where the full files live. No filler; the location sentence earns its place by routing the agent for deeper queries. Slightly terse given the undocumented parameters, but structurally sound.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness3/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

An output schema exists, so return shape needn't be explained, yet the description still helpfully lists the logged fields. The gap is on the input side—two parameters with zero coverage are left undefined, which for a low-complexity tool is the main missing piece.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters2/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 0% for both parameters, so the description must compensate and largely does not: 'count' (default 15) and 'errors_only' (default false) are never explained. The word 'errors' in the content list weakly hints at errors_only, but nothing clarifies count's meaning or bounds.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description names a concrete resource (the log of the latest calls) and enumerates its contents—tool, arguments, techniques per step, durations, errors—which is far more specific than the bare name 'logs'. It's clearly distinguishable from the sibling action tools (act, launch, window), which mutate or drive things rather than read a log.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines3/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The parenthetical '(debugging)' implies the use case, and the pointer to the full JSONL files tells the agent this is the recent/partial view. But there is no explicit when-to-use/when-not guidance and no naming of an alternative for full historical data beyond the file path.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

lookA
Read-onlyIdempotent

See a window without bringing it to the front: numbered elements [N] (role, name, value, states, position @x,y), and an image when the text is not enough. window: title (part of it), process ("notepad"), hwnd, or Windows itself: "taskbar" (buttons, tray, clock), "desktop" (icons), "screen" (whole screen as the user sees it, with the windows' places: overview only); omitted = current window. show: auto (default: the list, plus the image only when the tree is too thin to act on — canvas, game, page that publishes nothing — or after an unverified action), both (list and image), image, elements, changes (only what changed since the last list: added "+", changed "~", removed "-", the others keep their [N]), text (text of documents, no image), none. query: list only the elements containing this text. region [x1,y1,x2,y2]: zoom on an area of the image (fine reading; coordinates stay those of the full image). Images: WebP, at most 2000 px and 2.56 Mpx (detail=high gives the same size: zoom with region to read small text); an image identical to the last one sent for this window is not attached again (show=image always attaches it). marks: numbers drawn on the image (auto = unnamed elements; all; none).

NameRequiredDescriptionDefault
showNoauto
marksNoauto
queryNo
detailNonormal
regionNo
windowNo
max_elementsNo

TDQS

A4/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Beyond the read-only annotation, it discloses important behavior: it does not bring the window forward, describes the numbered-element output, explains image attachment rules, and notes that an identical image is not reattached. However, it omits behavior around max_elements truncation, which matters for interpreting element lists.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness3/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The purpose is front-loaded, but the remainder is a dense run-on block with semicolons, parentheses, and nested asides that make it hard to scan. Most information is relevant, but the structure sacrifices readability for compression.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a complex seven-parameter tool with no output schema, it explains the return format reasonably well and covers most modes. It still leaves gaps: max_elements behavior is unmentioned and detail semantics are only partially explained.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 0%, so the description must carry parameter meaning; it does this well for show, marks, query, region, window, and partly detail. It completely omits max_elements, leaving one of the seven parameters with no semantic guidance beyond its default.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description opens with a specific verb and resource: 'See a window without bringing it to the front,' then specifies that it returns numbered elements and optionally an image. This distinguishes it from action-oriented siblings like act and from window enumeration tools like windows.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines3/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

It gives useful context such as 'omitted = current window' and explains when 'show=auto' includes an image, but it never explicitly names when to use look instead of act, windows, or window. The alternatives are only implied by the read-only inspection focus.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

notificationsA
Read-onlyIdempotent

Notifications shown by Windows (notification center), most recent first: app, time, texts; read without opening anything on screen; security codes masked. app: part of the app name.

NameRequiredDescriptionDefault
appNo
limitNo

Output Schema

NameRequiredDescription
notificationsYes

TDQS

A3.5/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare this as read-only, idempotent, non-destructive, and closed-world. Beyond that, the description adds useful behavior: results are ordered most recent first, entries expose app/time/texts, security codes are masked, and no screen interaction is required. It does not explain limit/pagination behavior, but the additions are substantial.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is compact and front-loaded with the core resource and ordering. The semicolon-separated details are efficient, though the shorthand 'texts' is slightly vague.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a simple read-only notification listing tool with an output schema and rich annotations, the description covers what is returned, ordering, filtering by app, and privacy masking. The main omission is limit behavior, but overall it is sufficiently complete.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 0%, so the description must compensate. It does explain the app parameter as 'part of the app name', which is meaningful, but it does not explain the limit parameter beyond the schema's default value of 20.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description clearly states the resource (Windows notification center notifications), what each entry contains (app, time, texts), and ordering (most recent first). It is distinguishable from screen-interaction siblings by saying it reads without opening anything on screen, though it does not explicitly name an alternative.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines2/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

There is no explicit guidance on when to use this tool versus siblings like windows, look, or logs. The phrase 'read without opening anything on screen' hints at a use case, but it does not state when-not-to-use or name alternatives.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

windowA
Idempotent

Manage a window without bringing it to the front: restore (restore behind the others), minimize, maximize, close (polite request: the application may offer to save), bottom (bottom of the z-order), move (x, y) / resize (width, height) in screen pixels. front: bring it to the front (foreground=true, only with the user's consent).

NameRequiredDescriptionDefault
xNo
yNo
widthNo
actionYes
heightNo
windowNo
foregroundNo

TDQS

A3.8/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare this as a non-readonly, non-destructive, idempotent, closed-world tool. The description adds meaningful behavior beyond those annotations: restore places the window behind others, bottom moves it to the bottom of the z-order, close is a polite request that may trigger save prompts, and front requires consent.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is dense but front-loaded with the core constraint, `without bringing it to the front`, followed by action definitions. It avoids filler and covers many actions in few sentences, though the single long paragraph is less scannable than a short action table would be.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a 7-parameter tool with no output schema and no schema descriptions, the description provides enough behavioral and action semantics to call most actions correctly, and annotations cover safety traits. It is incomplete mainly around how to identify the target window and what happens on invalid or missing window identifiers.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 0%, so the description carries the burden and largely succeeds: it explains the action enum values, maps `x`/`y` to move, `width`/`height` to resize in screen pixels, and ties `foreground=true` to the `front` action. The notable gap is that the `window` target parameter, despite being central to invocation, is not described.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description states a specific verb and resource: manage a window, with an explicit action list covering restore, minimize, maximize, close, bottom, front, move, and resize. It is clearly distinguishable from a generic UI tool, though it does not explicitly contrast itself with the sibling `windows` or `act` tools.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines3/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

It gives useful action-specific context, especially that `front` requires `foreground=true` and the user's consent, while the default is to manage without bringing the window to the front. However, it does not say when to use this tool instead of siblings like `windows` for enumeration or `act` for broader interaction.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

windowsA
Read-onlyIdempotent

List application windows (front to back): hwnd, title, process, UI framework (Win32, WPF, Chromium…), size; [dialog of N "title"] = dialog or other window owned by window N (file picker, "Open", "Save as"); [hidden] = Store app Windows never shows (launched in the background), readable and drivable all the same. Then Windows itself: window="taskbar" and window="desktop" (icons). filter: part of a title or process name.

NameRequiredDescriptionDefault
filterNo

Output Schema

NameRequiredDescription
windowsYes

TDQS

A3.8/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already cover the safety profile (readOnly, idempotent, non-destructive), so the bar is lower; the description still adds substantial behavioral context: the front-to-back ordering, the '[dialog of N]' ownership notation for file pickers, and the '[hidden]' semantic that Store apps launched in the background are still readable and drivable. It stops short of describing pagination or volume limits, but the added semantics are meaningful.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

A single tightly packed passage that is front-loaded with the core purpose before examples. Density is high and the 'Then Windows itself' transition is slightly cryptic, but no clause is filler — each defines an output field, a notation, or a special-case window.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

Given one optional parameter, an output schema, and full annotation coverage, the description supplies what structured data doesn't: what the list represents, how owned dialogs and hidden windows appear, and what the filter matches. An agent can call this correctly without further information.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is 0% and the schema only names 'filter' with a null default, so the description carries the burden and does so: 'filter: part of a title or process name' tells the agent it is a substring match over two distinct fields, which the schema does not convey. It doesn't say whether matching is case-insensitive, which is a minor gap.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

Opens with a specific verb+resource ('List application windows') and immediately defines the scope and ordering ('front to back') plus the fields returned, so the agent knows exactly what this produces. It doesn't explicitly contrast itself with the sibling 'window' tool (likely for acting on a single window), so it falls short of full sibling differentiation.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines3/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Gives real usage context: how to reach the taskbar and desktop via window="taskbar"/"desktop", and how the filter argument matches. However, there is no explicit statement of when to prefer this over the sibling 'window' tool or how it relates to 'act'/'look' in a typical workflow.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

Tool Schema Changelog

Recent tool additions, removals, and schema changes observed during successful MCP inspections.

  1. 3 tool updatesv3.7.4
    • Changedlogs1 field changed
      • changedOutput schema / (root)
        Previous value: -nullNew value: +{
        +  "$defs": {
        +    "LogRecord": {
        +      "properties": {
        +        "args": {
        +          "additionalProperties": true,
        +          "title": "Args",
        +          "type": "object"
        +        },
        +        "error": {
        +          "anyOf": [
        +            {
        +              "type": "string"
        +            },
        +            {
        +              "type": "null"
        +            }
        +          ],
        +          "default": null,
        +          "title": "Error"
        +        },
        +        "ms": {
        +          "anyOf": [
        +            {
        +              "type": "number"
        +            },
        +            {
        +              "type": "null"
        +            }
        +          ],
        +          "default": null,
        +          "title": "Ms"
        +        },
        +        "ok": {
        +          "title": "Ok",
        +          "type": "boolean"
        +        },
        +        "steps": {
        +          "items": {
        +            "additionalProperties": true,
        +            "type": "object"
        +          },
        +          "title": "Steps",
        +          "type": "array"
        +        },
        +        "tool": {
        +          "title": "Tool",
        +          "type": "string"
        +        },
        +        "ts": {
        +          "title": "Ts",
        +          "type": "string"
        +        }
        +      },
        +      "required": [
        +        "ts",
        +        "tool",
        +        "ok"
        +      ],
        +      "title": "LogRecord",
        +      "type": "object"
        +    }
        +  },
        +  "properties": {
        +    "pid": {
        +      "title": "Pid",
        +      "type": "integer"
        +    },
        +    "records": {
        +      "items": {
        +        "$ref": "#/$defs/LogRecord"
        +      },
        +      "title": "Records",
        +      "type": "array"
        +    },
        +    "status": {
        +      "items": {
        +        "type": "string"
        +      },
        +      "title": "Status",
        +      "type": "array"
        +    },
        +    "version": {
        +      "title": "Version",
        +      "type": "string"
        +    }
        +  },
        +  "required": [
        +    "version",
        +    "pid",
        +    "status",
        +    "records"
        +  ],
        +  "title": "LogsOutput",
        +  "type": "object"
        +}
    • Changednotifications1 field changed
      • changedOutput schema / (root)
        Previous value: -nullNew value: +{
        +  "$defs": {
        +    "NotificationRow": {
        +      "properties": {
        +        "app": {
        +          "title": "App",
        +          "type": "string"
        +        },
        +        "arrived": {
        +          "description": "ISO 8601 local time",
        +          "title": "Arrived",
        +          "type": "string"
        +        },
        +        "texts": {
        +          "description": "Security codes masked",
        +          "items": {
        +            "type": "string"
        +          },
        +          "title": "Texts",
        +          "type": "array"
        +        }
        +      },
        +      "required": [
        +        "app",
        +        "arrived",
        +        "texts"
        +      ],
        +      "title": "NotificationRow",
        +      "type": "object"
        +    }
        +  },
        +  "properties": {
        +    "notifications": {
        +      "items": {
        +        "$ref": "#/$defs/NotificationRow"
        +      },
        +      "title": "Notifications",
        +      "type": "array"
        +    }
        +  },
        +  "required": [
        +    "notifications"
        +  ],
        +  "title": "NotificationsOutput",
        +  "type": "object"
        +}
    • Changedwindows1 field changed
      • changedOutput schema / (root)
        Previous value: -nullNew value: +{
        +  "$defs": {
        +    "WindowRow": {
        +      "properties": {
        +        "foreground": {
        +          "title": "Foreground",
        +          "type": "boolean"
        +        },
        +        "framework": {
        +          "title": "Framework",
        +          "type": "string"
        +        },
        +        "height": {
        +          "title": "Height",
        +          "type": "integer"
        +        },
        +        "hidden": {
        +          "description": "Store app never shown by Windows, drivable all the same",
        +          "title": "Hidden",
        +          "type": "boolean"
        +        },
        +        "hwnd": {
        +          "title": "Hwnd",
        +          "type": "integer"
        +        },
        +        "maximized": {
        +          "title": "Maximized",
        +          "type": "boolean"
        +        },
        +        "minimized": {
        +          "title": "Minimized",
        +          "type": "boolean"
        +        },
        +        "owner": {
        +          "description": "hwnd of the owner window for a dialog, 0 otherwise",
        +          "title": "Owner",
        +          "type": "integer"
        +        },
        +        "process": {
        +          "title": "Process",
        +          "type": "string"
        +        },
        +        "surface": {
        +          "description": "Windows surface (\"taskbar\", \"desktop\"...), empty for an application window",
        +          "title": "Surface",
        +          "type": "string"
        +        },
        +        "title": {
        +          "title": "Title",
        +          "type": "string"
        +        },
        +        "width": {
        +          "title": "Width",
        +          "type": "integer"
        +        }
        +      },
        +      "required": [
        +        "hwnd",
        +        "title",
        +        "process",
        +        "framework",
        +        "width",
        +        "height",
        +        "minimized",
        +        "maximized",
        +        "foreground",
        +        "hidden",
        +        "owner",
        +        "surface"
        +      ],
        +      "title": "WindowRow",
        +      "type": "object"
        +    }
        +  },
        +  "properties": {
        +    "windows": {
        +      "items": {
        +        "$ref": "#/$defs/WindowRow"
        +      },
        +      "title": "Windows",
        +      "type": "array"
        +    }
        +  },
        +  "required": [
        +    "windows"
        +  ],
        +  "title": "WindowsOutput",
        +  "type": "object"
        +}
  2. 7 tool updatesv3.3.1
    • First observedact
    • First observedlaunch
    • First observedlogs
    • First observedlook
    • First observednotifications
    • First observedwindow
    • First observedwindows

TDQS

A3.7/5.0

Scored across 7 tools

Disambiguation4/5

The set is mostly distinct: launch opens apps, look inspects contents, act performs UI steps, window manages a window, notifications and logs are separate. The main confusion is between 'windows' (list windows) and 'window' (manage a window), plus some overlap between look and windows for inspection/listing.

Naming Consistency3/5

Names are all lowercase single words, but conventions are mixed: some are verbs (act, look, launch), others are nouns (windows, notifications, logs, window). The singular/plural pair 'window'/'windows' is particularly easy to misread, though the set remains readable.

Tool Count5/5

Seven tools are well scoped for a desktop automation server. Each tool has a clear role and the count is comfortably within a practical range.

Completeness4/5

The surface covers the core desktop automation lifecycle: launch, list windows, inspect, act, manage window state, read notifications, and debug via logs. Minor gaps like clipboard operations or explicit process management are not central, so agents can work around them.

Maintenance

ActivityNo data
ResponsivenessSyncing

Related MCP Connectors

Related MCP Servers

  • A
    license
    Not graded
    quality
    F
    maintenance
    Enables Claude Code to control a Windows desktop via screenshots, mouse, keyboard, and window/display enumeration, reusing the native binding from the Claude desktop app.
    MIT
  • A
    license
    Not graded
    quality
    C
    maintenance
    Enables Claude Code on Windows to read the foreground window's UI Automation tree as structured text and then act on it with real, human-like SendInput mouse and keyboard events. It drives desktop apps through a perceive-decide-act loop without screenshots, a vision model, or any locally hosted LLM.
    MIT