Tiny CLI for MX Master 4 status and settings.
cargo install mx4Cargo builds mx4 from source. It requires a current stable Rust toolchain, a C build toolchain, pkg-config, and the libudev development files on Linux. On Debian or Ubuntu, install the native build dependencies with:
sudo apt install build-essential pkg-config libudev-devCargo places the binary in ~/.cargo/bin. Make sure that directory is included in PATH.
Download the amd64 .deb from the GitHub release you want to install, then run:
sudo apt install ./mx4_*_amd64.debThe package contains a prebuilt binary and the udev access rule. APT installs its runtime dependencies automatically, so Rust, build-essential, pkg-config, and libudev-dev are not required.
To uninstall, remove the opt-in per-user daemon before purging the package:
mx4 daemon --uninstall
sudo apt purge mx4APT does not remove files generated in a user's home directory. If the package was purged before the daemon was uninstalled, clean up the remaining user service with:
systemctl --user disable --now mx4.service
rm -f ~/.config/systemd/user/mx4.service
systemctl --user daemon-reload
systemctl --user reset-failed mx4.servicegit clone https://github.com/EriksRemess/mx4.git
cd mx4
cargo install --path .cargo run --release -- --help
cargo run --release -- status
cargo run --release -- firmware --jsonThe first -- separates Cargo's arguments from arguments passed to mx4. To build once and run the resulting binary directly:
cargo build --release
./target/release/mx4 --helpThis crate can also be used as a Rust library:
use mx4::features;
fn main() -> mx4::Result<()> {
let battery = features::battery::read_status()?;
println!("{} {}", battery.pct, battery.charging);
Ok(())
}mx4 status
mx4 status --json
mx4 status battery
mx4 status battery --json
mx4 status dpi
mx4 status dpi --json
mx4 status wheel
mx4 status wheel --json
mx4 status thumb-wheel
mx4 status thumb-wheel --json
mx4 status force-button
mx4 status force-button --json
mx4 status haptic
mx4 status haptic --json
mx4 set host 2
mx4 set dpi 2500
mx4 set strength 100
mx4 set strength off
mx4 set wheel ratchet free
mx4 set wheel ratchet-speed 10
mx4 set wheel force 75
mx4 set wheel invert on
mx4 set wheel resolution off
mx4 set wheel divert off
mx4 set thumb-wheel invert off
mx4 set thumb-wheel divert on
mx4 set force-button 4310
mx4 daemon
mx4 daemon --install
mx4 daemon --once
mx4 daemon --uninstall
mx4 haptic 14
mx4 haptic 0..3
mx4 haptic '{0..14}'
mx4 battery
mx4 battery --json
mx4 firmware
mx4 firmware --jsonHaptic strength presets:
off=0subtle=15low=45medium=60high=100
The daemon is opt-in. Normal status and setting commands never install or start a background service.
Install the binary first, then install and start the per-user service:
mx4 daemon --installThis creates a user systemd service on Linux or a user launchd agent on macOS. It watches for reconnects and reapplies saved settings. No sudo is needed.
Other daemon modes:
mx4 daemon # run in the foreground
mx4 daemon --once # apply saved settings once and exit
mx4 daemon --uninstall # stop and remove the background serviceThe Debian package installs and reloads the udev access rule automatically. For Cargo or source installations, if mx4 status reports a /dev/hidraw... Permission denied error, install the rule once and reconnect the mouse or Logi Bolt receiver:
sudo install -Dm644 contrib/udev/99-mx4.rules /etc/udev/rules.d/99-mx4.rules
sudo udevadm control --reload-rules
sudo udevadm triggerThe source checkout already contains that rule. A Cargo installation only installs the binary, so download the rule first if you do not have the source tree:
curl -fLO https://raw.githubusercontent.com/EriksRemess/mx4/main/contrib/udev/99-mx4.rules
sudo install -Dm644 99-mx4.rules /etc/udev/rules.d/99-mx4.rules
sudo udevadm control --reload-rules
sudo udevadm triggersudo mx4 status can confirm that the HID++ device is readable, but it is only a diagnostic. Normal use should not need sudo after the udev rule is active.
Notes:
mx4 statusprints battery, DPI, wheel, thumb-wheel, force-button, and haptic state when available.mx4 status --jsonprints all readable status values as one JSON object, usingnullfor unavailable features.mx4 status hapticprints the configured haptic level when the device exposes it.mx4 batteryremains as a shorter alias for battery status.mx4 firmwareprints the mouse firmware entities and Bolt receiver firmware when available.- Persistent
mx4 set ...commands save the applied value to a local config file so it can be restored later. mx4 set host ...andmx4 haptic ...do not persist anything.mx4 daemonpolls for reconnects and reapplies saved settings when the mouse comes back.- The background service is only installed when
mx4 daemon --installis run explicitly. - The saved config file lives at:
- Linux:
~/.config/mx4/config.tomlunlessXDG_CONFIG_HOMEis set - macOS:
~/Library/Application Support/mx4/config.toml
- Linux: