Windows UI automation MCP server exposing uictl capabilities for UI control, element inspection, screenshot capture, OCR, and input simulation
Strong foundation with 29 well-defined tools, all with explicit schemas and descriptions. Tool names follow verb_noun convention (uictl_*). Descriptions are detailed and context-rich (avg ~180 chars), explaining WHAT, WHEN, and prerequisites. Input schemas use proper JSON Schema with typed parameters. However, output schemas are not documented, LLMs cannot predict response structure for chaining. Some parameter descriptions lack format constraints (e.g., 'x,y' format for coordinates is stated but not formalized). Error handling and recovery guidance are absent. No tool annotations (readOnlyHint/destructiveHint) despite clear risk classifications in metadata.
Bring an application (and optionally a specific window) to the front.
List running processes.
Click at a screen point or on a specific element (by id from uictl_elements/uictl_screenshot).
Read the system clipboard text.
Write text to the system clipboard.
List monitors: index (matches screenshot's `screen` arg), bounds in virtual-screen space, the primary-monitor flag, and a DPI-derived scale factor.
Walk a window's UI Automation tree; returns each element's id, role (ControlType), title, value, and frame.
Output schemas not documented. LLMs cannot predict response structure (fields, types, nesting) for downstream tool chaining. E.g., uictl_elements returns element IDs but response format is opaque.
No tool annotations (readOnlyHint, destructiveHint, idempotentHint) despite clear risk classifications in metadata. Metadata shows DESTRUCTIVE (uictl_feedback_delete) and WRITE tools, but MCP protocol annotations are absent.
Parameter format constraints stated in descriptions but not formalized in schema. E.g., 'at' parameter documented as '"x,y" screen point' but no pattern/format constraint in JSON Schema. LLMs may pass invalid formats.
| Scored | Grade | Overall | Spec posture | Rubric |
|---|---|---|---|---|
| 2026-09-23 | D | 55 | 2026-07-28+ | v2 |
Check a local entry's title against existing GitHub issues, without submitting anything. Needs a GitHub token if the repo is private: pass --token, set GITHUB_TOKEN, or have `gh` already authenticated - otherwise this just reports that it couldn't check.
Draft a new local feedback entry.
Delete a local feedback entry.
Show one feedback entry in full.
List all local feedback entries.
Check for an existing duplicate, then open GitHub's new-issue page with this entry's title/body pre-filled. If a likely duplicate is found, the local entry is deleted and nothing is opened. Otherwise opens the URL directly in your default browser - running this command is treated as your confirmation. (The MCP tool uictl_feedback_submit instead asks you to review it first via MCP elicitation, since an agent may call it without you having typed anything yourself.)
Edit a local feedback entry.
Pin uictl to one window - click/move/scroll/type/key will re-activate it first if a human's own input steals foreground status. Requires either app or window.
Stop pinning focus and restore whatever was frontmost right before the hold.
Show what's currently held, if anything, and what release will restore focus to.
Send a keyboard shortcut, e.g. "ctrl+shift+esc".
Export the activity log as JSON.
Open the on-screen activity log window. If it gets buried under other windows, run this again to bring it back to front.
Move the mouse cursor without clicking.
Recognize text in an image file or a window, optionally restricted to a region. Note: confidence is always null on Windows - Windows.Media.Ocr reports no per-result score.
Check elevation status: this process's own, and optionally a target app's. Windows' analog of macOS's Accessibility/Screen Recording permission check - UI Automation and SendInput are blocked by UIPI when the target outranks uictl. Also reports whether the daemon is running in an interactive desktop session - false means UI Automation/SendInput/screen capture will silently fail or no-op, most commonly seen when the daemon gets auto-spawned from a non-interactive channel like an SSH command.
Sample the color of a single screen pixel.
Capture a window, an app's frontmost window, or a display. Set annotate=true to overlay numbered boxes on every UI Automation element and get a legend back - then click/type by element number.
Scroll at a screen point.
Type text into the focused control, or into a specific element by id (tries UI Automation's ValuePattern.SetValue first, falls back to focus + synthesized keystrokes).
Block until an element matching role/title appears in a window, or timeout elapses.
List on-screen windows, optionally filtered to one app.
No error handling or recovery guidance. Tools lack descriptions of failure modes, retryability, or actionable error messages. E.g., uictl_permissions does not explain what to do if elevation is insufficient.
Mutually exclusive parameters not documented. E.g., uictl_screenshot accepts 'window', 'app', or 'screen' but descriptions do not state these are mutually exclusive or which takes precedence.