Mercury CLI
Documentation

Extend

Extensions

An extension is a folder with one manifest, mercury-extension.json, that names it, versions it, and says what it adds to Mercury and what it needs from the machine. Mercury reads only what the manifest declares. Extensions come from sources you add (empty at start) or the bundled @mercury set.

An extension's id is <name>@<source label>. The board is /extensions, and the command-line verbs are mercury extensions <verb>.

Extension sources

A source is a git repository on any host, a local folder or an archive. Its root carries one of two files:

  • mercury-extensions.json: A catalogue of several extensions, each named with its version, a line of description, and either path inside the source or git plus an optional ref. An entry that disagrees with the fetched manifest refuses the install.
  • mercury-extension.json: A single extension. The repository is the source.

Contributions

  • Skills: Directories whose child folders each hold a SKILL.md, registered as /<name>:<skill>.
  • Commands: Directories of <cmd>.md prompt files, registered as /<name>:<cmd>.
  • Agents: Directories of <agent>.md definitions, registered as agent type <name>:<agent>. Privilege-raising front matter is ignored with a health note, and an extension agent runs under the session's permission mode.
  • Hooks: run entries in the manifest's contributes.hooks, the same map as a settings file's events.hooks, each named extension:<name> in the session, with ${MERCURY_EXTENSION_ROOT}, ${MERCURY_EXTENSION_DATA} and ${option.KEY} substituted. A faulty entry is named and dropped; the rest loads, and a failing hook leaves the session running.
  • Servers: MCP servers over stdio, http or sse, connected as ext:<name>:<server>. Their tools pass the permission engine like any MCP tool.
  • Language: Language servers in Mercury's own configuration shape, started as ext:<name>:<server>.
  • Channels: The extension's servers allowed to post channel messages into the session after approval. Posts from an undeclared server are dropped.
  • Keybindings: Default chords for the extension's own commands and skills, applied only where your keybindings leave the chord free.

Manifest fields

  • name: Required. Lowercase letters, digits and hyphens, 1 to 40 characters, starting with a letter or digit.
  • version: Required. Any non-empty string without whitespace. It keys updates and approval.
  • description: Required. One line of at most 200 characters.
  • mercury: Optional. A version floor, >=x.y.z. Unmet, the extension is broken with the reason.
  • contributes: Optional. What the extension adds, in the kinds above.
  • needs: Optional. binaries on PATH, env variables, network hosts and configurable options. A missing binary or unset variable makes the extension partial with the reason.
  • author, homepage and license: Optional. Shown in the detail pane.
  • module: Reserved. This build loads declarative extensions.

Every path in the manifest stays inside the extension root. An unknown top-level key is a warning at load and an error under mercury extensions inspect. An unknown key inside contributes or needs is an error at load. A sensitive option lives in the secure store, appears as a placeholder in prose the model reads, and reaches only hook and server environments. An extension's name is lowercase letters, digits and hyphens, its id everywhere is <name>@<source label>, and the labels project, session and mercury are reserved. In command lines, arguments, environment values and prompt bodies, ${MERCURY_EXTENSION_ROOT}, ${MERCURY_EXTENSION_DATA} and ${option.KEY} are substituted and every other ${…} stays literal; hooks and servers receive MERCURY_EXTENSION_ROOT, MERCURY_EXTENSION_DATA and one MERCURY_EXTENSION_OPTION_<KEY> per option.

Add an extension source

Run mercury extensions add <url|path|archive>, or press a on the sources tab of /extensions. Mercury checks the blocklist, fetches, validates, labels and records the source without installing anything yet.

Install an extension

To install an extension:

  1. Open /extensions.
  2. Select the extension in its source.
  3. Press i.
  4. Read the approval card: what the extension runs, adds and needs.
  5. Approve.

Mercury fetches the copy, records the approval and turns the extension on.

mercury extensions install <name>[@label] does the same from the command line, and --yes is the only scripted approval. Approval is tied to a hash of contributes, needs and the delivered files, including skill, command and agent bodies and hook and server scripts. A version-only bump carries approval over, but a changed delivered file requires approval again even when the manifest’s contributions are unchanged.

Refresh and apply an update

To refresh and apply an update:

  1. Select the source on the /extensions board.
  2. Press u to refresh it.
  3. Select the extension with an update.
  4. Press U.
  5. Approve the changed contributions, if the card asks again.

Mercury applies the update and keeps the previous version until the first clean load.

Refreshing a source, with u or mercury extensions refresh, is the only act that discovers a newer version. mercury extensions update <id> applies one, update --all applies every known update, and mercury extensions update <id> --previous swaps back to the previous version.

Other controls

  • list and sources: The installed roster and the sources, each with state. list --json prints it as JSON, and list --source <label> shows a source's offer.
  • remove <label>: Removes a source. Its installed copies keep working unless --and-extensions removes them too.
  • trust <id>: The approval card for an installed-off or found extension.
  • enable <id> and disable <id>: The switch, everywhere or with --project. On the board, Space is the switch.
  • fence and unfence: The blocklist, by id, source label or URL. On the board, b blocks.
  • uninstall <id>: Removes everything, or keeps the data with --keep-data. On the board, x does the same.
  • inspect <path>: The maker's linter.
  • scaffold <name>: Scaffolds an extension, or a source root with --source.

Make an extension

To make an extension:

  1. Run mercury extensions scaffold <name>, which writes the folder with a manifest, an empty skills/ directory and a README.
  2. Put the folder in the project at .mercury/extensions/<name>/ and open Mercury there. /extensions shows the extension as found.
  3. Press i, read the approval card and approve.
  4. Edit a skill and press r, or enter /extensions reload. The change is live; when the manifest's contributions changed, the row says it needs approving again and the card shows the diff.
  5. Run mercury extensions inspect .mercury/extensions/<name> to lint everything the runtime tolerates.

Publish it by pushing the folder as its own repository, a single-extension source, or by adding it to a catalogue; others add the URL.

In settings, extensions.enabled holds extension ids and their enabled state, extensions.wanted the requested extensions, extensions.blocked the blocklist, extensions.options the non-secret option values, and extensions.exclusive, a managed lock, true for every customization surface or a list drawn from skills, agents, hooks and mcp.

The MCPs & Skills menu on the home screen adds a per-repository master switch, and a session is served an extension only when both switches agree.

Each row on /extensions states its health (● on, ◑ partial with ↵ details, or ✕ broken) and what to do next (◐ reload, ○ off, ◇ found, r reloads, i approves or i installs). /health has one extensions row.

Bundled extensions

Mercury bundles three desktop-application extensions in /extensions with a shared installer and MCP bootstrap: filmcraft (FilmCraft 0.12.0), photocraft (PhotoCraft 0.14.0) and lightcraft (LightCraft 0.13.0). Only the extension manifests, skills and bootstrap scripts ship in Mercury; application binaries download only when you approve an installation.

Each bundled Craft extension contributes its skill (/filmcraft:filmcraft, /photocraft:photocraft, /lightcraft:lightcraft) and an app MCP server (ext:filmcraft:app, ext:photocraft:app, ext:lightcraft:app) with three bootstrap tools:

  • craft_status: Inspects the local installation in ${MERCURY_EXTENSION_DATA}/runtime/<version>-<platform> without downloading or opening the app, checking .vendor-manifest.json, the file count and tree digest, and the GUI and CLI executable SHA-256 digests and licence files.
  • craft_install: Plans the platform download from the extension's lockfiles, asks for confirmation naming the application, version, byte size and destination directory, and after approval downloads the application and CLI archives from GitHub release storage (github.com, release-assets.githubusercontent.com, objects.githubusercontent.com), checks every archive's byte count and SHA-256 digest, extracts them into the runtime directory, and writes .vendor-manifest.json without opening the app.
  • craft_connect: Connects to the installed application in one of three modes: mode: "attach" (default) checks that the loopback control listener (127.0.0.1:<port>) belongs to the current user's installed executable (matching its SHA-256 digest and process identity) and that the open project, document or library matches before forwarding the CLI's MCP tools; mode: "launch" launches the desktop window with control enabled (refusing if a window is already open so unsaved work is untouched) and attaches once ready; and mode: "headless" starts a separate headless CLI session without touching an open window. On Windows, PhotoCraft and LightCraft apply the per-user control-folder ACL once with a sanitised PowerShell environment.

Mercury also bundles mercury-media (mercury-media@mercury, 0.1.0), off by default, which contributes ext:mercury-media:engine for local image and video generation and is configured through /config (Local media, media.enabled and media.root) and /imagesetup; see Local images and video.