Mercury CLI
Documentation

Start

Install and update

Mercury installs release archives into a directory for the current user and supplies a mercury command. Updates check the download's signature and SHA-256 checksum and keep the previous version on disk so you can roll back.

A release installation requires git. Its archive carries its own Node runtime (24.22.1, the October 2026 security release fixing CVE-2026-111497 in Node's Brotli decoder) and ripgrep; a launcher selects Node in this order: the explicit MERCURY_NODE binary, the bundled runtime, then a compatible Node installation on PATH. Archives are built for Apple silicon and Intel Macs (macos-arm64, macos-x64), Linux x64 and arm64 (linux-x64, linux-arm64), and Windows x64 and arm64 (windows-x64, windows-arm64). Any other machine builds from source; mercury update states that directly instead of guessing an archive. Building a copy is covered below and in the repository's install and source-build guide. Mercury CLI, the TypeScript and Python SDKs in sdk/ and sdk-py/ (mercury-cli-sdk on npm and PyPI), and the VS Code extension are open source under the Apache License 2.0 (Apache-2.0, LICENSE.md and NOTICE).

Release archives also include Mercury's bash-compatible shell engine (brush). On Windows, the Bash tool runs on the bundled brush engine by default whenever its pack is present: a long-lived brush process serves the main conversation and a separate process serves each crewmate so variables, functions, aliases and options persist between calls for their owner, and on Windows it resolves .cmd and .bat programs such as npm or npx by their bare name through PATHEXT, passes %VAR% and ^ to batch files unchanged, and runs a program named by a relative path after cd, without requiring Git for Windows. Calls that a long-lived brush process cannot take (Monitor watches, run_in_background commands and commands with inherit_session_env) run in a process of their own: the system shell on macOS and Linux, installed Git for Windows bash.exe when present on Windows, and a per-command brush engine process on Windows machines without bash.exe, so every Bash call works without Git for Windows. When Git for Windows is installed, setting MERCURY_SHELL_ENGINE=system ($env:MERCURY_SHELL_ENGINE = "system" in PowerShell) or setting shell.engine to system in /config under Shell engine keeps the Bash tool on Git for Windows' bash.exe alone. On macOS and Linux, the system shell (bash or zsh) is the default, and MERCURY_SHELL_ENGINE=brush or brush in /config under Shell engine runs the Bash tool on the bundled engine with persistent shell state. Without either shell on Windows (in a source build without the engine pack and without Git for Windows), Mercury starts with the PowerShell tool while the Bash tool leaves the roster, and /health's Bash tool shell row (shell) reports which shell is active and why.

Install with curl

On macOS or Linux (x64 and arm64), run the shell installer to download the newest archive and run its installer:

curl -fsSL https://mercury-cli.ai/install | sh     # macOS and Linux (x64 and arm64)

Install with PowerShell

On Windows (x64 and arm64) in PowerShell 7, run the PowerShell installer to download the newest Windows archive and run its installer:

irm https://mercury-cli.ai/install.ps1 | iex        # Windows (x64 and arm64), in PowerShell 7

Install with Homebrew

Install the release pinned by the Homebrew formula:

brew install Whq02/mercury/mercury                 # Homebrew: macOS and Linux x64

Install with npm

Install the global npm launcher package (which downloads the release named by its package from MercuryCLI):

npm install -g mercury-tech-cli                    # npm; `bun install -g mercury-tech-cli` is the same package

Install with mise

Install Mercury through the npm package with mise:

mise use -g npm:mercury-tech-cli                   # mise, through the npm package

The curl and PowerShell scripts check the archive against the release's SHA256SUMS.txt. Homebrew commands use the full tap name Whq02/mercury/mercury (bare mercury in homebrew-core is a different program). On Windows, the npm launcher package (mercury-tech-cli) unpacks downloaded .zip archives using the system tar (System32\tar.exe) and falls back to Windows PowerShell's Expand-Archive, never Git for Windows' tar. Homebrew and npm packages can trail the newest release until they are republished. To remove the installed release, command shim and the PATH entry it added while keeping your configuration and sessions, run mercury install --uninstall (and npm uninstall -g mercury-tech-cli if you installed the npm launcher). All channels install without administrator access, and an installation command is safe to run again.

Installation locations

  • Release payloads: ~/.mercury/versions/<version>, or %USERPROFILE%\.mercury\versions on Windows, holds one complete release payload per version under the config home.
  • Command directory: ~/.local/bin on macOS and Linux, or %LOCALAPPDATA%\Mercury\bin on Windows, holds the command. The installer adds that directory to PATH once.
  • Active release: <config-home>/versions/current.txt names the active payload, and previous.txt names the previous one. Updates and rollbacks switch the pointer file by atomic rename; on Windows, a rename refused because another program holds the file is replaced by a write into the file in place.
  • Deployed source copy: Each build has its own folder under <config-home>/runtime/builds/<tree>-<bundle>. runtime/current points to the active build, and runtime/dist is kept as the older link to the same build. The launcher is at <config-home>/bin/mercury. A pre-existing runtime/dist directory stays in place while a daemon still runs from it.

Configuration and sessions live in the config home outside the versioned payload directory. Installation, update, rollback and uninstall leave them in place. A config home that belongs to another coding tool is treated as that tool's: Mercury signs in through none of its logins and writes no identity into it, and the accounts board shows it for information only.

Set up an unpacked release archive

To run a Windows archive without installing it, extract it and run mercury\mercury.exe from PowerShell or Command Prompt. mercury.cmd and mercury.ps1 are also in that folder.

If you unpacked a release archive yourself, run ./mercury/mercury install (or .\mercury\mercury.cmd install on Windows) from the folder you unpacked it into, then open a new terminal (or run the printed PATH line) and run mercury --version to check the managed installation.

The installation options are:

  • --dry-run: Previews the installation, names the runtime the archive carries and shows the change it would make to PATH.
  • --uninstall: Removes the installed release, command shim and the PATH entry it added, while keeping your configuration and sessions.
  • --force: Replaces an existing mercury file in the command directory and backs up the old file as mercury.bak. Without --force, an existing file from another program is refused.
  • --json: Prints the result as JSON.

Update a managed installation

Run mercury update (mercury upgrade is the same command) to update any installation.

The installed version selects the release channel. A full release updates to the newest full release. A beta or release candidate updates to the newest release, full or pre-release. The updater downloads the archive and checksums from that same release.

mercury update is the one update command on every channel. Inside a Homebrew installation it asks once whether to run brew upgrade Whq02/mercury/mercury, runs that command on y with its output as it comes, and reads the installed version back; --yes skips the question, --json needs --yes there, and --rollback declines there because Homebrew keeps its own versions. For an npm or mise installation, mercury-tech-cli downloads the Mercury release into ~/.mercury/versions/ on its first run and launches it from there: mercury update updates that installed release directly in place, while npm update -g mercury-tech-cli or mise upgrade npm:mercury-tech-cli updates only the launcher package. A source checkout is not an installation the channel manages: --check and --status say so and name the rebuild, and the bare update and --rollback refuse there before anything is downloaded or written.

Mercury downloads the release, checks its checksum and signature, stages it beside the active version and switches the active pointer. A failed smoke check after the switch restores the previous pointer. The previous version stays on disk for rollback. Versions older than that are removed when an update completes, and the update names them.

On Windows, an update run from a PowerShell window completes while another program holds the version file open: when the rename of the pointer is refused, the new value is written into the file in place, and a swap that stays refused ends after a few seconds with one line naming the file and the way out, the active installation unchanged and nothing left behind. Earlier launchers held that file open for as long as their PowerShell window lived, so an update run from that window was refused at the pointer stage. From one of those installations, run the one update from Command Prompt: open cmd.exe and run mercury update. After it, updates complete from PowerShell too.

The updater reads the public release list anonymously and consults a signed-in GitHub CLI, gh, only when that request is refused. A checksum match and a signature under the Mercury release key are required before activation. --allow-unsigned accepts an unsigned payload and still rejects an unknown key, a malformed signing block or tampered bytes, and the result and the local receipt name the exception. A signed installation starts without a signature notice, and mercury health names the signing key on its Artifact signature row. From an extracted archive, node mercury/verify-artifact.mjs --deep prints the verdict and exits 0 for signed, 3 for unsigned, 4 for an unrecognized key, 5 for tampered and 6 for malformed.

An update ends with the background daemon. The daemon that hosts sessions runs the build it was started from, so after the pointer moves the update asks it to move to the installed build and reports the outcome on its background daemon: line: moved, with new sessions running on it; the installed build taking new sessions while the old daemon keeps its live sessions until they finish; moving once its live sessions finish; already on the installed build; none running; or could not be moved, with the reason and the mercury daemon stop remedy. A live session keeps the build its runner started on; within a minute of an install, a live chat on an older build shows a one-time unfolded notice between turns (preserved across /clear): A newer Mercury build is installed (<tree>). This chat still uses <tree>. /restart switches to it; watches and background shells will stop and be listed. Entering /restart lists the Monitor watches and background shells that will stop, stops the session's own runner before daemon handover, moves the background daemon to the installed build if needed, and resumes the session on that build with a receipt naming the build and every watch and background shell the restart ended (/restart checks the runner's build info first, leaves an already-current session unchanged, tells you to wait when a turn is running, and refuses a source run with no runtime manifest). mercury daemon restart makes the daemon move from a plain shell. A deployed source build's folder is never moved while a daemon or session runs from it.

mercury update --json puts the result on stdout, including the daemon's state and openWindows, and the progress on stderr. Exit 0 includes already current, 1 is an operational failure and 2 is a usage error.

Update controls

  • mercury update --check: Reports the newest release against the version running. The notice in the chat shows only a version newer than the one running.
  • mercury update --status: Names where this Mercury came from and the runtime in use.
  • mercury update --rollback: Restores the previous managed release.
  • /restart: Moves the live chat onto a newly installed Mercury build, listing the Monitor watches and background shells that will stop, switching the background daemon if needed, and resuming the chat on the installed build.
  • Update notice: Once a day, an interactive boot reads the release list. When a newer release exists, the home screen says so once in its bottom-right corner and the chat shows the same notice until you update. MERCURY_UPDATE_NOTICE=0 turns both off.

--check reads one release list in every channel and ends with the update path that applies, and --status names an npm-made installation for what it is. If another mercury appears earlier on PATH, the last lines of an update and the health check's Command on PATH row report the mismatch and its remedy. An interactive boot that fails three or more times in a row is reported by mercury health and by mercury update, which name the recovery, mercury update --rollback.

Build from source

Building from source requires Node 24 LTS (>=24.20.0 <25, with .node-version pinning the patch included in release archives; below 24.20.0 headless run commands that call a tool abort on exit on Windows), Bun 1.4.4 for the build, and git (on Windows, PowerShell 7 inside Windows Terminal or the VS Code terminal). In a clone of the repository:

bun run setup                      # once; bun install + the vendored packs
bun run build.ts                   # writes dist/mercury.mjs + dist/manifest.json
node dist/mercury.mjs --version

setup fetches the bundled capability packs (pyright, debugpy, js-debug, extra grammars, the platform's Node and Python runtimes, and brush). With Rust installed, setup also builds the voice capture addon (native/voice), the desktop driver addon (native/desktop) for the Computer tool, and the local embedding addon (native/embed) with the 118 MB BGE model; adding cmake beside Rust builds the on-device transcriber (native/whisper). If a download or native build tool is missing, setup skips that pack and /health reports the missing component. To install a clean-tree source build as your daily mercury command, run scripts/ops/deploy-runtime.sh and scripts/ops/deploy-launcher.sh, then add <config-home>/bin to PATH.