Nova MCP server
Commit Oct 31, 2026Enables AI agents to control macOS and Windows desktops through screenshots, OCR, keyboard/mouse input, and accessibility controls.
Also known as bigduu/Nova
- Stars
- 23
- Tools
- 12
- Downloads, 30 days
- —
- Latest version
- —
- Last commit
- Oct 31, 2026
- License
- MIT
What is Nova MCP?
Nova enables AI agents to control macOS and Windows desktops through screenshots, OCR, keyboard/mouse input, and accessibility controls. It exposes 12 tools, such as ax_read, read_ui, ax_activate.
Summary generated from the project's README
About Nova MCP server
Nova provides AI agents with direct control over macOS and Windows desktops. Instead of relying on virtual machines, it allows clients like Claude Desktop, Cursor, and Claude Code to interact with real applications through screenshots, native OCR, and accessibility controls. The server is distributed as a single Rust binary, which avoids the need for a Python runtime on the host machine.
Users can perform complex tasks using tools such as ax_read, ax_activate, and batch_actions, which are subject to a 64-step limit. The system supports full Unicode keyboard input, including various Asian languages and emojis, and provides mouse and keyboard control. On macOS, users can run the server in a managed mode using Nova.app to handle permissions, or use the standard stdio mode by granting Screen Recording and Accessibility access to the host application.
Developers can also launch an optional Chrome DevTools sidecar for advanced browser automation. The server works on macOS 14+ and Windows x64 or ARM64 architectures, ensuring that agents can see and manipulate the actual user interface of the operating system.
What you can do with it
- 1Visual interface inspectionAn AI agent can take a screenshot of the active window to identify visible buttons and UI elements.
- 2Automated UI interactionThe agent can use accessibility controls to read and activate specific interface components.
- 3Multilingual text entryAn agent can type complex characters including Chinese, Japanese, or Korean directly into desktop applications.
- 4Batch desktop automationA developer can instruct an agent to perform a sequence of up to 64 coordinated desktop actions.
Written from the project's README. Every use case is checked against a quote from it.
Nova MCP tools 12
Detected from the READMEax_readread_uiax_activatescreenshotzoom_regionocrclick_markcursor_positioninspect_appdump_axbatch_actionswait
| ax_read | — | |
| read_ui | — | |
| ax_activate | — | |
| screenshot | — | |
| zoom_region | — | |
| ocr | — | |
| click_mark | — | |
| cursor_position | — | |
| inspect_app | — | |
| dump_ax | — | |
| batch_actions | — | |
| wait | — |
Automated checks
Ran Nov 14, 2026Full report →Not verified yet. A server needs a score of 80, no serious finding, and enough data for us to check. How checks work · What to fix for more points
- Source repository linked and reachablebigduu/nova is public and reachablegithub.com/bigduu/nova ↗Pass
- Package names this repository as its sourceNot checked
- Build provenance (Sigstore attestation)Not checked
- Open source license (OSI)MITspdx.org/licenses/MIT.html ↗Pass
- Commit or release in the last yearLast commit or release 2026-10-31github.com/bigduu/nova ↗Pass
- OpenSSF ScorecardNot checked
- Package name not close to a popular packageNot checked
- No critical advisory in the package or its dependenciesNot checked
- No hidden instructions to the model12 tool descriptions and the README read; no override phrases, credential paths or hidden charactersPass
- Destructive tools are labelledNo tool named like delete, drop or execPass
- Remote endpoint answers the MCP handshakeNot checked
README
View on GitHubNova
Let any MCP agent use your real Mac or Windows apps. Nova is a single Rust binary, with no Python runtime, that gives Claude Desktop, Cursor, Codex, Claude Code and other MCP clients screenshots, native OCR, keyboard and mouse input, clipboard access, window/app control and Accessibility/UIA actions on macOS and Windows.
Releases · Part of Bodhi · Bodhi desktop app · MIT
- Your real desktop, not a VM: macOS 14+ (Apple Silicon and Intel) and Windows x64/ARM64.
- Reads before it clicks: Accessibility/UIA controls, Apple Vision or Windows OCR, and per-window screenshots with zoom. Clicks are given in the screenshot's pixel space and mapped back to the screen.
- Types any text: full Unicode keyboard input, including Chinese, Japanese, Korean and emoji.
- Accessibility-first control (v0.3.0): AX-first
ax_read/ax_activatethat reject stale snapshots, a 64-stepbatch_actionslimit with structured failure reports, the Nova.app permission owner (development preview) and an optional Chrome DevTools sidecar. Latest release: v0.3.0 — Releases.
Static image · Reproduce and inspect MCP evidence
This recording shows Nova's browser tool path (fixture page and real MCP
navigation/click calls). It was captured on Linux, so it does not show native
macOS/Windows desktop control or model reasoning. The reproduction notes explain
the --npx adapter and isolated browser.
Install
| Platform | Published v0.3.0 |
|---|---|
| macOS 14+ (Homebrew) | brew install bigduu/tap/nova |
| macOS 14+ (manual) | nova-v0.3.0-universal-apple-darwin.tar.gz from Releases |
| Windows x86_64 | nova-v0.3.0-x86_64-pc-windows-msvc.zip |
| Windows ARM64 | nova-v0.3.0-aarch64-pc-windows-msvc.zip |
| Linux | Desktop control is not supported (headless protocol checks only) |
Homebrew (macOS):
brew tap bigduu/tap
brew install bigduu/tap/nova
nova --version
The formula installs the CLI from the release archive. It does not configure an
MCP client or grant macOS permissions. Run which nova to find the path to use
below: usually /opt/homebrew/bin/nova on Apple Silicon and
/usr/local/bin/nova on Intel Macs.
npm (macOS and Windows): Homebrew stays the recommended macOS install.
@bigduu/nova (package version 0.3.1) is a Node launcher that downloads the
matching v0.3.1 GitHub
Release binary: universal macOS, or Windows x64 / ARM64. It does not install a
Linux desktop binary. The MCP Registry name is io.github.bigduu/nova.
npx @bigduu/nova --version
npm i -g @bigduu/nova
An MCP client that cannot answer an install prompt should call npx with -y:
{
"mcpServers": {
"nova": { "command": "npx", "args": ["-y", "@bigduu/nova"] }
}
}
The launcher checks the release archive's .sha256 before writing nova or
nova.exe. The macOS binary is ad-hoc signed, not notarized. Windows binaries
are not Authenticode-signed, so SmartScreen may warn on first run.
Manual download: download the matching .sha256 file from the same release
and verify the archive before extracting it. On macOS:
tar -xzf nova-v*-universal-apple-darwin.tar.gz
xattr -dr com.apple.quarantine ./nova # only if Gatekeeper blocks the download
sudo install -m 0755 nova /usr/local/bin/nova
On Windows, extract the archive for the machine's architecture and invoke
nova.exe directly or place its directory on PATH. The Windows binaries are
not Authenticode-signed, so SmartScreen may warn on first run. The macOS binary
is ad-hoc signed, not notarized.
Published release assets never change. Every consumer pins these files by
SHA-256 — Homebrew and npm formulas, Bamboo's plugin catalogue (bundle, manifest,
per-platform executable and app archive digests), and any manual --sha256
install. Re-uploading a same-named asset to an existing release would silently
break all of them, so the release workflow refuses to publish when the tag
already has assets:
error: v0.3.1 was already published with 2 asset(s); refusing to replace them.
A re-cut ships a new version tag (bump the patch version) rather than
replacing bytes under the old one. Deliberately replacing an existing release's
assets requires scripts/verify-release-immutable.sh <tag> --allow-asset-replace, which warns that every pinned consumer is now broken.
Because a tag's assets are immutable, an already-published release can no longer
be re-run to add missing files: if a partial publish happened, ship the next
patch version. Draft releases are exempt, since a draft is not published yet.
Build from source:
git clone https://github.com/bigduu/Nova.git
cd Nova
cargo build --release --locked
The result is target/release/nova on macOS or target/release/nova.exe on
Windows. Do not use cargo install nova: that crates.io name belongs to an
unrelated project. The npm package is @bigduu/nova (see above).
Choose a version
| Path | What you get |
|---|---|
| Published v0.3.0 (Homebrew and release archives) | Screenshots, zoom_region, OCR, numbered marks with click_mark, mouse/keyboard input, AX/UIA actions including ax_read / read_ui / ax_activate, inspect_app, managed nova mcp, Nova.app development preview, optional Chrome DevTools sidecar, consent-based Chrome bridge, windows/apps, clipboard, batch_actions (64-step limit + structured failure), wait. |
master (tip of development) |
Whatever lands after v0.3.0 — build from source for unreleased work. |
Nova.app remains a development preview (ad-hoc signed, not notarized). Menu-bar status and virtual cursor are labelled Preview pending live-device acceptance (#34, #70). Audit evidence.
Use it from an MCP client
These snippets use direct stdio (no arguments). They work with the v0.3.0
release and with a master build. Replace the path with your own which nova
output, the extracted binary or target/release/nova. GUI clients do not
always inherit your shell PATH, so use an absolute path.
Claude Desktop: edit
~/Library/Application Support/Claude/claude_desktop_config.json on macOS or
%APPDATA%\Claude\claude_desktop_config.json on Windows.
Cursor: edit ~/.cursor/mcp.json (all projects) or .cursor/mcp.json in
one project.
{
"mcpServers": {
"nova": { "command": "/opt/homebrew/bin/nova", "args": [] }
}
}
Claude Code:
claude mcp add --scope user nova -- /opt/homebrew/bin/nova
Codex: add to ~/.codex/config.toml, or run
codex mcp add nova -- /opt/homebrew/bin/nova:
[mcp_servers.nova]
command = "/opt/homebrew/bin/nova"
args = []
On Windows, use the full path to nova.exe, escaped in JSON
("C:\\Tools\\nova\\nova.exe") or as a TOML literal string
('C:\Tools\nova\nova.exe').
macOS permissions: in direct stdio mode, macOS usually attributes Nova to the
app that launches it. Grant Accessibility (input and UI control) and
Screen Recording (screenshot, ocr, list_windows) to Claude Desktop,
Cursor, or the terminal/IDE that runs Claude Code or Codex. If that does not
work, add the nova binary itself. Then restart or reconnect the MCP server.
You can instead let Nova.app own the
permissions; see Managed mode.
Try: "Use Nova to list my open windows, take a screenshot of the frontmost one and tell me which buttons you can see."
Managed mode with Nova.app
nova mcp is the cross-platform managed entrypoint used by the Bamboo plugin
(v0.3.0+):
{
"mcpServers": {
"nova": { "command": "/absolute/path/to/nova", "args": ["mcp"] }
}
}
Windows and Linux headless builds serve ordinary stdio MCP. On macOS, mcp
only connects to the independent Nova.app, launching it through LaunchServices
when needed. Install the app separately, open it once, and grant
Accessibility to Nova; Screen Recording is needed for capture, OCR, and
list_windows (the app menu requests it only when you explicitly choose that
action). The bundled executable can also be used as the connector:
{
"mcpServers": {
"nova": {
"command": "/Applications/Nova.app/Contents/MacOS/nova",
"args": ["mcp"]
}
}
}
The explicit --connect command remains supported and uses the same transport
as macOS mcp. It carries MCP bytes over a private per-user Unix socket. The
connector does not call desktop APIs or request macOS permissions;
the app process owns the MCP handlers and TCC responsibility. The socket lives
under /tmp/nova-app-<uid>/ with a mode-0700 directory, mode-0600 socket, and a
same-UID peer check.
If Nova.app is unavailable, the managed command exits with installation and
reconnection guidance. It never falls back to desktop operations inside the MCP
host. NOVA_APP_SOCKET is for isolated development/tests; when set it disables
automatic app launch. Unset it for the normal installed-app setup. Unbundled
nova with no arguments still offers the legacy direct stdio mode.
When the app service closes its connection, the CLI connector finishes forwarding responses and exits even if the host keeps its stdin pipe open. Closing host stdin normally still half-closes the request stream and drains the service's final response, including its last buffered bytes. Standard stdout backpressure still applies: the host must keep reading responses. Reconnect only the Nova MCP server after replacing/restarting the service; Bodhi can stay open. No interrupted request is replayed and no replacement MCP session is created automatically.
This exit behavior is specific to the terminating CLI connector process.
Its dedicated runtime is released after forwarding completes, and process
exit reclaims an outstanding blocking stdin read. It does not make the
connect_stdio library function's stdin cancellable inside a resident or
embedded runtime.
Chrome DevTools MCP sidecar
For advanced Chrome page automation and debugging, Nova can launch the official
Chrome DevTools MCP
next to the desktop server. This is a transparent stdio sidecar, not a second
browser implementation inside Nova. It requires npm/npx, Node.js
^20.19.0, ^22.12.0, or >=23, and current stable Chrome (or newer). Nova
pins the reviewed upstream package to chrome-devtools-mcp@1.8.0.
Application-level integrations should accept an app selector (name or bundle ID)
and use inspect_app discovery internally. Discovery alone does not grant CDP
control; automatic app-to-provider routing remains a separate integration slice.
Endpoint copying and the separate MCP configuration below are advanced transport
compatibility. On macOS:
{
"mcpServers": {
"nova": {
"command": "/Applications/Nova.app/Contents/MacOS/nova",
"args": ["--connect"]
},
"nova-chrome-devtools": {
"command": "/Applications/Nova.app/Contents/MacOS/nova",
"args": ["chrome-devtools"]
}
}
}
For a standalone binary from the v0.3.0 release or current source, use its absolute path and
["chrome-devtools"]. If a GUI client cannot find npx, add
"--npx", "/absolute/path/to/npx" after the subcommand.
The default launches a new temporary, isolated Chrome profile. Usage
statistics, package update checks, CrUX URL lookups, and sensitive network
headers are disabled/redacted by default. Requests made by attached DevTools
targets can be guarded by repeating --allowed-url-pattern, for example:
"args": [
"chrome-devtools",
"--allowed-url-pattern", "https://example.com/*",
"--allowed-url-pattern", "https://*.example.net/*"
]
URL allow patterns require Chrome 149+. They apply only to DevTools targets while the MCP server is attached and are not a complete network sandbox; use an OS/VM sandbox when full network isolation is required, as described by the upstream security policy.
To work with an already running signed-in Chrome profile instead, first open
chrome://inspect/#remote-debugging in Chrome and enable remote debugging,
then configure:
"args": ["chrome-devtools", "--profile", "existing"]
Automatic connection requires Chrome 144+. If several Chrome profiles are active, Chrome chooses the profile it considers the default; select and verify the connected pages before acting.
[!WARNING] Existing-profile mode can inspect and control every open window in the selected Chrome profile, including authenticated pages. Enable it only for a trusted local MCP client, and disable remote debugging when finished.
An internal consumer or advanced caller can attach to an explicitly selected, already-running browser instead of relying on stable Chrome's default profile:
nova chrome-devtools --browser-url http://127.0.0.1:9222
nova chrome-devtools --ws-endpoint 'ws://[::1]:9222/devtools/browser/<id>'
Use one endpoint, without --profile (including explicit isolated) or
--headless. --browser-url accepts HTTP(S) at the browser root, with an optional
trailing /; --ws-endpoint accepts WS(S) at /devtools/browser/<id>, where the
ID uses letters, digits, hyphen or underscore. Both require an original literal
loopback IP and explicit port 1–65535. Hostnames, abbreviated/integer/hex IPs,
credentials, query strings and fragments are rejected before starting npx.
Nova forwards the selected address literally and adds no Chrome launch flags
or automatic connection fallback. HTTPS/WSS use upstream's certificate checks.
These inputs are trusted local endpoints, not network confinement. Pinned
Puppeteer HTTP discovery
uses the returned webSocketDebuggerUrl, and its
WebSocket transport follows redirects.
A local service can therefore lead the connection to another address. The
pinned options
and ownership cleanup
distinguish attachment from launch: disconnect, stdin EOF or SIGTERM detach from
an attached browser, while upstream closes a browser it launched itself.
After connecting, call list_pages and choose by the expected title/URL. Use the
returned pageId explicitly on every page-scoped read/action. For two windows,
if the intended pages have IDs 7 and 12, first take_snapshot({pageId: 7}) and
fill({pageId: 7, uid: "<field from that snapshot>", value: "example"}); then
take_snapshot({pageId: 12}) and click({pageId: 12, uid: "<button from that snapshot>"}).
Obtain fresh page IDs and element UIDs after pages close or change; do not rely
on whichever window is focused.
The endpoint must expose browser-level CDP, covering the app's pages/windows.
The WS path check excludes renderer-only /devtools/page/... sockets and Node/V8
main-process inspector WebSocket URLs. HTTP root syntax alone cannot establish
the advertised service's identity. Upstream officially targets
Chrome/Chrome for Testing; Electron/CEF attachment is experimental and unverified
for each runtime until reads/actions are tested in its own windows. A successful
MCP tools/list alone does not establish application compatibility. On setup or
connection failure, check the selected app's supported debugging setup and
refresh its discovery metadata before retrying this transport. Keep Bodhi open;
Nova's native AX and separately paired extension capabilities remain available.
Use --enable-webmcp to expose upstream's experimental WebMCP tools. Nova adds
Chrome's required --enable-features=WebMCP launch argument in isolated mode;
for an existing profile or endpoint, the browser must already have started with that
feature enabled. WebMCP requires Chrome 150+. --expose-network-headers and
--enable-performance-crux are explicit privacy opt-ins. The pinned 1.8.0
package does not support a
--disable-javascript-evaluation option, so Nova does not advertise or pass it.
The sidecar and Nova's optional Secure Chrome Bridge serve different trust models: DevTools MCP is the broad, full-featured choice for normal browser automation, DOM/network inspection, and performance debugging; the Secure Chrome Bridge requires explicit per-page pairing and is preferable when least-privilege page scoping matters. Nova's desktop tools remain the path for browser chrome, native dialogs, and non-web UI.
Use the absolute path to the extracted release binary or the source-build
output. On Windows, use an escaped executable path such as
"C:\\absolute\\path\\nova.exe". Use the source-build output for the
AX-first workflow below. If its directory is already on PATH, the command can
be "nova".
Reconnect/reload the Nova MCP server in the client; Bodhi's main window can stay open. See Permissions & code signing for legacy direct-stdio and development-binary cases.
HTTP clients — run Nova as a server and connect over Streamable HTTP:
nova --http # 127.0.0.1:3100/mcp
nova --http --addr 127.0.0.1:8080 # custom loopback port
HTTP mode is currently a local transport: it keeps rmcp's default loopback Host allowlist and does not configure remote-access authentication. Binding all interfaces is not a supported LAN setup.
First calls (current source build). Call ax_read (optionally
ax_read(window="<name>", mode="all")) for semantic content and controls, then
ax_activate(snapshot_id, node_id) on an exact actionable node. Re-run
ax_read after the action to verify semantic state. If AX/UIA coverage is
absent or partial, use focused-window ocr for rendered text; use
screenshot(window=...) / zoom_region only when pixels are necessary
(layout, icon, color, image, canvas, or visual verification). All pointer tools
use the pixel space of the most recent screenshot; cursor_position instead
reports OS-global logical coordinates.
Semantic reads (ax_read and its read_ui alias) include supported control
state and identify scroll containers with scrollable=true in all/content
mode, including unnamed containers. Containers alone receive no action mark.
The target includes its window title and, when the selected macOS window
exposes AXDocument/AXURL, an optional url. Unsupported URL/state attributes
are omitted; Windows uses supported cached UIA states and ScrollPattern metadata.
Windows reads preserve cached ValuePattern text, including Unicode and multiline values, for controls that expose the pattern. Empty, unsupported, failed, or non-string values are absent; password fields and unknown password status stay redacted. Controls exposing only TextPattern have no value fallback.
Native text writes (type_text, write_clipboard, batch typing, and
ax_set_value) omit the submitted text from tracing and acknowledgements.
Write diagnostics retain character/UTF-8 byte counts and native operation
details without echoing the value. Explicit reads such as read_clipboard
and ax_read still return the requested content.
Requirements
- Linux: the source builds a headless MCP server for protocol checks; native desktop actions return an unsupported/headless error. This is not Linux desktop automation.
- macOS 14+ for the macOS desktop backend. The release archive is universal and runs on Apple Silicon and Intel Macs.
- Windows x86_64 or ARM64 for the Windows desktop backend. GitHub Releases provide a native archive for each architecture.
- On Windows,
ocruses installed Windows OCR language packs. Usenova --ocr-langsto inspect available languages; install the needed pack if recognition reports that it is unavailable. - Building on macOS requires the macOS 15 SDK / Xcode 16+ because of a
transitive
apple-metalbuild dependency; that is a build-time requirement, not Nova's minimum macOS runtime version. - On macOS, Screen Recording permission is required for
screenshot,ocr, andlist_windows; Accessibility is required forax_read, semantic activation, and input.
macOS grants these permissions to the process it identifies as responsible for Nova. The managed
nova mcpentrypoint and Bamboo plugin use the independent Nova.app on macOS. Direct stdio/HTTP can use the host app, terminal, or directly launched binary as the permission subject. See Permissions & code signing.
Nova MCP questions
What tools does Nova MCP provide?
It exposes 12 tools, including ax_read, read_ui, ax_activate, screenshot, zoom_region.
What operating systems does Nova support?
Nova supports macOS 14+ (both Apple Silicon and Intel) and Windows x64/ARM64.
Can Nova control my computer without a virtual machine?
Yes, Nova operates on your actual desktop rather than a VM.
Does Nova support non-English text input?
Yes, it supports full Unicode keyboard input, including Chinese, Japanese, Korean, and emojis.
How do I install Nova on macOS?
You can install it via Homebrew using brew install bigduu/tap/nova or by downloading the universal Apple Darwin tarball from the releases page.