# m-cli: a terminal front end for macOS system settings

> m-cli wraps dozens of macOS system commands behind a single m command. It is useful if you administer Macs over SSH or in scripts, and unnecessary if you already have a settings workflow you trust.

**rgcr/m-cli** —  Swiss Army Knife for macOS 

- Repository: https://github.com/rgcr/m-cli
- Stars: 9,917 · Forks: 317
- Language: Shell
- License: MIT
- Published: 2026-09-21 · Updated: 2026-09-21 · Language: en
- Canonical page: https://hysenlabs.com/projects/rgcr-m-cli

## What m-cli actually replaces

macOS settings live in System Settings and in a set of command line tools that Apple ships but does not present as one interface. Changing the dock behaviour, toggling the firewall, or reading battery state each means a different command with different flags. m-cli collects these under one executable named m, with subcommands such as dock, wifi, firewall, battery, and volume. The README lists roughly forty of them, from airdrop and appearance through vpn and wallpaper.

The audience is narrow and specific: people who administer Macs without a graphical session, or who want these settings to be reproducible. If you configure a build machine over SSH, or you keep a setup script for a new laptop, the value is that you write m dock ... instead of remembering which defaults domain and key control the dock. If you click through System Settings once and move on, the tool adds a layer you will not use.

## How the m command is put together

The repository is a Shell project. The top level holds a single executable file named m, an install.sh script, a completions directory, a plugins directory, and a tests directory. There is no compiled binary and no runtime dependency to install, which matches the README claim of no third-party dependencies.

The dispatch model follows from that layout. You invoke m with a subcommand, and the m script routes to the code for that subcommand. The README describes two entry points for discovery: running m with no arguments displays all available commands, and running m <command> --help shows the options for one command. Autocompletion is a first-class part of the design rather than an afterthought: the completions directory carries separate files for Bash, Zsh, and Fish, and the README notes that version 2 introduced a standardized syntax alongside improved shell autocompletion. That combination explains the breaking change notice at the top of the README. A tool whose commands are typed by hand benefits from completion, and standardizing the syntax is what makes consistent completion files possible.

Several subcommands call macOS tools that need elevated privileges. The README states plainly that some macos commands need to be executed with sudo internally and recommends having sudo privileges.

## Installing m-cli with Homebrew or the install script

Homebrew is the shortest path and the one the README lists first. The formula installs the m executable and, according to the README, configures autocompletion for Bash, Zsh, and Fish automatically, so there is no separate completion step.

```bash
brew install m-cli
```

If you want the newest code rather than the released formula, the README gives a tap-based variant:

```bash
brew install rgcr/formulae/m-cli
```

The manual route runs the project's install script from the repository. This places files under your home directory rather than in a system location.

```bash
curl -fsSL https://raw.githubusercontent.com/rgcr/m-cli/main/install.sh | bash
```

After a manual install, the README says to ensure ${HOME}/.local/bin is on your PATH. Add it in your shell config so it persists:

```bash
export PATH="${HOME}/.local/bin:$PATH"
```

For a first real use, pick a read-only command before you change anything. Running m with no arguments prints the command list, which is the quickest way to confirm the install worked. From there, m dock --help shows the options for the dock subcommand and confirms that per-command help is wired up.

Manual installs do not get completion for free. The README documents sourcing the file for your shell, for example for Zsh:

```bash
source ~/.local/opt/m-cli/completions/zsh/_m
```

The equivalent files live under completions/bash/m and completions/fish/m.fish. Add the matching line to your shell config to keep it across sessions. Uninstalling is symmetric: brew uninstall m-cli for the Homebrew install, or m --uninstall for the manual one.

## Where m-cli runs into trouble

The trash command is the clearest documented failure mode. The README states it will not work unless your terminal application has permission to access the Trash folder, and points to System Preferences > Security & Privacy > Privacy > Full Disk Access to grant it. That is a macOS privacy boundary, not a bug in m-cli, but it means a command that looks like it should just work can fail silently or with an error until you change a system setting. Anything you script around trash needs to account for that.

The sudo requirement is the second constraint. Commands that change protected settings need elevation, so unattended runs depend on how sudo is configured on that machine. A non-interactive script that hits a password prompt will stall.

The README does not document rollback for the settings commands. There is no described mechanism to undo a change you made through m, so the practical safety net is knowing the previous value before you set a new one. The repository has a tests directory, but the README does not describe what those tests cover or whether they exercise the settings-changing commands.

There is also a maintenance signal worth reading carefully. The repository topics include looking-for-maintainer, and the README links to a Buy Me a Coffee page for supporting development. Neither is a defect, but together they tell you the project is asking for help rather than expanding a team. The last push was on 2026-06-02, and v2.0.9 was released the same day.

## m-cli against scripting the macOS tools yourself

The realistic alternative is not another CLI wrapper. It is writing the underlying macOS commands directly into your own scripts, or using a configuration management tool that already knows how to set macOS defaults. The difference is where the knowledge lives. With m-cli, the mapping from a human-readable subcommand to the right defaults domain, key, and value type is maintained in this repository, and you inherit it by installing. With your own scripts, you own that mapping, which means you also own fixing it when a macOS release changes behaviour.

That trade-off cuts both ways. A wrapper adds a layer between you and the system, and when a command misbehaves you have to read the m script to find out what it actually ran. Direct scripts keep that mapping visible in your own repository, at the cost of writing and maintaining it. m-cli is the better fit when you want breadth quickly and you are willing to accept the abstraction. Hand-written scripts are the better fit when you need to know exactly which system call runs, or when you only care about two or three settings and a wrapper for forty commands is mostly unused surface.

## Licence, upgrade cost, and the v2 break

m-cli is MIT licensed, per the LICENSE.md file and the README footer. MIT is permissive: it allows use, modification, and redistribution with the licence and copyright notice retained. That matters if you plan to vendor the m script into an internal tool or ship it inside a managed image. This is a description of the licence text, not legal advice; if you are redistributing it in a commercial product, have someone qualified read the terms.

The upgrade cost is concentrated in one event. The README opens with a warning that version 2 includes breaking changes because of a new standardized syntax and improved shell autocompletion, and directs readers to CHANGELOG.md. If you have scripts written against version 1 command forms, they need review before you upgrade. If you are installing fresh, the break does not affect you. Beyond that, the project has no dependencies to track and no compilation step, so routine upgrades are a matter of replacing the script and, for manual installs, re-sourcing the completion file. The recurring cost is really the macOS side: as Apple changes the tools underneath, someone has to update the mappings, and the looking-for-maintainer topic is the honest signal about how much spare capacity exists for that.

## Conclusion

Adopt m-cli if you manage Macs from a terminal, in scripts, or over SSH and you want one command vocabulary for dock, wifi, firewall, and similar settings. Skip it if your work stays inside System Settings or if you already script the underlying macOS tools directly. Before installing, open the CHANGELOG for v2 because the README states version 2 introduced breaking syntax changes, and check which of the commands you need require sudo.

## FAQ

### What is m-cli on a Mac?

It is a Shell command line tool for macOS that puts system functions, utilities, and preference changes behind a single m command. The README lists subcommands such as dock, wifi, firewall, battery, and volume, and describes it as having no third-party dependencies.

### How do I install m-cli?

The README gives two routes: brew install m-cli, or the tap variant brew install rgcr/formulae/m-cli for the latest version. There is also a manual install that pipes the repository's install.sh through bash, after which ${HOME}/.local/bin must be on your PATH.

### Does m-cli need sudo?

Some commands do. The README states that some macos commands need to be executed with sudo internally and recommends having sudo privileges, so scripts that change protected settings should plan for elevation.

### Why does the m-cli trash command not work?

The README says trash will not work unless your terminal has permission to access the Trash folder, and points to Full Disk Access under System Preferences > Security & Privacy > Privacy. Grant that permission to the terminal application you run m from.

### Is m-cli the same as the m command in other tools?

No. In this project m is the executable installed by m-cli, and running it with no arguments displays the available subcommands. The name is generic, so check which m is first on your PATH if you have other tools installed.

## Sources

- [Issues](https://github.com/rgcr/m-cli/issues)
- [License: MIT](https://github.com/rgcr/m-cli/blob/main/LICENSE)
- [README](https://github.com/rgcr/m-cli/blob/main/README.md)
- [Releases](https://github.com/rgcr/m-cli/releases)
- [rgcr/m-cli on GitHub](https://github.com/rgcr/m-cli)

---

Hysen Labs editorial analysis, written from the project's own repository and release notes. Cite the canonical page: https://hysenlabs.com/projects/rgcr-m-cli
