Install Mjolnir
Mjolnir’s controller runs on Linux and macOS. On Windows, use a Linux distribution under WSL2; there is no native Windows controller package.
The release installer is the simplest route. The npm package installs the same native release bundle. Cargo and source builds are useful when you want only the headless controller or are developing Mjolnir itself, but they do not automatically install the portable Linux workers required by managed and remote targets.
Release installer
Section titled “Release installer”curl -fsSL https://raw.githubusercontent.com/BrokkAi/mjolnir/master/install.sh | bashThe installer selects the release for the current Linux or macOS architecture, verifies the downloaded artifacts when checksum sidecars are available, and installs them in ~/.local/bin by default. A release bundle contains:
mj, the terminal controller and CLImj-desktop, used bymj appmj-voice-worker, used for local dictation- static x86_64 and ARM64 Linux session workers for remote and container targets
- on macOS, a native
mj-workerfor local bare sessions
The Linux controller requires glibc 2.28 or newer; only the portable workers are static musl binaries. Alpine and native Windows are not controller release targets.
If ~/.local/bin is not already on PATH, the installer offers to update the detected shell profile. Open a new shell before running mj, or add the directory to PATH yourself. The installer’s last line tells you to run mj; see First run.
Pin a release or choose another destination with environment variables:
curl -fsSL https://raw.githubusercontent.com/BrokkAi/mjolnir/master/install.sh | MJOLNIR_VERSION=vX.Y.Z bashReplace vX.Y.Z with the release tag you want to install.
curl -fsSL https://raw.githubusercontent.com/BrokkAi/mjolnir/master/install.sh | MJOLNIR_INSTALL_DIR="$HOME/bin" bashMJOLNIR_INSTALL_DIR takes precedence over the compatible INSTALL_DIR variable. The script also accepts MJOLNIR_GITHUB_OWNER for a different release owner, GITHUB_TOKEN for authenticated GitHub API requests, and PROFILE to select the shell profile it may update.
Re-run the installer to update or repair an installation. Its checksum cache avoids downloading an unchanged archive again.
Homebrew
Section titled “Homebrew”brew tap brokkai/tapbrew trust brokkai/tapbrew install --formula brokkai/tap/mjolnirName the formula in full. A bare brew install mjolnir installs an unrelated, deprecated Homebrew cask of the same name instead of mj. Recent Homebrew versions refuse to load formulae from a tap until you trust it; that is what brew trust does. The formula installs the same release bundle into Homebrew’s libexec and puts only mj on PATH.
Keeping Mjolnir current
Section titled “Keeping Mjolnir current”On every interactive startup, before starting the daemon, mj asks the channel it was installed from whether a newer release exists. If one does, mj says what it found and asks Upgrade now? [Y/n] before changing anything. Answering y runs the upgrade for your install method and restarts mj into the new version:
- Release installer installs: mj downloads the release archive, verifies its SHA-256 sidecar, updates the CLI and all bundled helper binaries, and restarts mj.
- npm installs: mj runs
npm install -g @brokkai/mjolnir@latestso npm keeps ownership ofnode_modules.npxruns are ephemeral, so mj only prints the command. - Homebrew installs: mj runs
brew update(so the local formula index learns about the release) and thenbrew upgrade --formula brokkai/tap/mjolnir(the bare namemjolniris an unrelated Homebrew cask). - Cargo installs: mj prints
cargo install --locked brokk-mjolnirand leaves the rebuild to you.
When mj finds the daemon running a different build, it replaces the daemon only if its own build is newer: a later release or, within one release, a build from a later commit. An older mj, such as a stale copy earlier on PATH, uses the newer daemon and says so. When mj cannot tell which build is newer, it also keeps the running daemon and says so; mj daemon restart then replaces it.
The check contacts the channel’s own endpoint — GitHub Releases, the npm registry, or the Homebrew tap on GitHub — and it is skipped entirely for non-interactive commands, debug builds, or when MJOLNIR_NO_UPDATE_CHECK is set. Set that variable to disable automatic update checks altogether.
npm or npx
Section titled “npm or npx”The npm package requires Node.js 18 or newer and supports macOS and glibc-based Linux on x86_64 and ARM64. A WSL2 Linux environment is supported when it meets those requirements.
Install it globally:
npm install -g @brokkai/mjolnirOr run it without a global installation:
npx -y @brokkai/mjolnirThe package includes the native bundle for the selected platform; it does not download a binary on first launch. Native Windows is not an npm target.
Mjolnir requires Rust 1.99 or newer. Install the headless controller from crates.io with:
cargo install --locked brokk-mjolnirThis installs only mj. Install brokk-mj-worker beside it to run a bare runtime on this machine; on macOS that worker is native. Container and remote targets need a target-compatible static Linux worker: install an architecture-named worker beside mj, point MJ_WORKER_DIR or MJ_WORKER_BINARY at one, or configure the verified MJ_WORKER_URL and MJ_WORKER_SHA256 fallback. The release installer and npm package supply both supported portable worker architectures automatically, so use one of those complete bundles unless you intend to build and manage workers yourself.
cargo install --locked brokk-mjolnir brokk-mj-workerAdd the local dictation sidecar when voice input is wanted:
cargo install --locked brokk-mjolnir brokk-mj-voice-workerTo use the desktop viewer through mj app, install the desktop crate as well:
cargo install --locked brokk-mjolnir brokk-mj-desktopCargo places the executables in its configured binary directory, normally ~/.cargo/bin. Ensure that directory is on PATH.
Build from source
Section titled “Build from source”Clone the repository, enter it, and build the native headless controller for development:
git clone https://github.com/BrokkAi/mjolnir.gitcd mjolnircargo build --release -p brokk-mjolnir./target/release/mj --versionThe development wrapper builds the correct pair for the host:
scripts/run.sh --release -- --versionOn Linux this builds the controller natively and cross-compiles only
brokk-mj-worker for the matching musl target. On macOS both binaries are
native, enabling a local bare runtime without a Linux cross toolchain. Managed Linux
targets from macOS still need a packaged worker or an explicit override.
To install mj from a checkout together with the worker that container and remote targets need, run:
scripts/install.shThe script builds the static Linux worker for the host architecture, builds mj and the dictation helper with the same cargo build invocations as scripts/run.sh so the two scripts share build caches, and places the worker beside the installed mj as mj-worker-<target-triple>. It builds the release profile unless you pass another, for example scripts/install.sh --profile dev. On macOS it also installs the native worker for a local bare runtime and builds the Linux worker through Docker or Podman when one is running. It installs into ~/.cargo/bin unless CARGO_INSTALL_ROOT or CARGO_HOME names another root. Targets on another architecture still need the release installer or a manually built worker.
To build a portable worker manually, use:
rustup target add x86_64-unknown-linux-muslcargo build --release --target x86_64-unknown-linux-musl \ -p brokk-mj-worker --bin mj-workerOn ARM64 Linux, substitute aarch64-unknown-linux-musl. Place a worker for
another target architecture beside the controller as mj-worker-<target-triple>,
for example mj-worker-aarch64-unknown-linux-musl. The configuration
reference covers the worker path
and verified-download overrides.
To work only on controller commands without launching sessions, use:
cargo run -p brokk-mjolnir -- --instance docs-dev --helpTo build the desktop controller on x86_64 GNU/Linux:
cargo build --release -p brokk-mjolnir -p brokk-mj-desktop \ --target x86_64-unknown-linux-gnu./target/x86_64-unknown-linux-gnu/release/mj appUse the corresponding host target on ARM64 Linux or macOS. Linux desktop builds require the WebKitGTK 4.1 development package, and running mj app requires the distribution’s WebKitGTK 4.1 runtime. These GUI libraries are not required for the headless mj controller. Building the optional voice worker on Linux also requires ALSA development headers.
Verify the installation
Section titled “Verify the installation”mj --versionmj doctormj doctor checks the controller, configuration, harness credentials, targets, and required workers. Resolve reported errors before launching a session; the troubleshooting guide explains the common failures.
First run
Section titled “First run”Mjolnir runs a coding agent you already have (Claude Code, Codex, Kimi Code, Grok Build, Muse Code, OpenCode, MiMo Code, or DSH), so install and sign in to one first. DSH has no sign-in; export DEEPSEEK_API_KEY before starting mj instead. Then go to a project directory and run mj:
cd path/to/your/repositorymjThe first interactive mj automatically discovers installed agents and the current GitHub repository, and every later plain mj launch adds profiles for newly installed agents; mj go, mj workspaces, and the relaunch after an upgrade do not. A brief welcome reports prerequisite errors, and container images download in the background. mj setup reruns discovery from the shell while preserving existing configuration. mj go is a shortcut for later: it remembers each folder’s setup and returns to that folder’s last conversation. The quickstart walks through the first session. For unattended or advanced setup, see configuration, profiles, targets, and the complete CLI reference.
Uninstall
Section titled “Uninstall”Stop your sessions and the daemon first; mj daemon stop alone leaves session workers running. The quickstart lists what each way of stopping leaves running and which files and directories to remove.