Turn JSON recipes into powerful automation scripts. Write once, run everywhere.
A lightweight, batteries-included CLI that makes command automation effortless. Compose reusable scripts with variables, nested flows, and safe execution—all stored in simple JSON.
| Feature | Description |
|---|---|
| 🎯 Composable scripts | Author commands once in JSON and call them from anywhere. |
| 🔄 Args & vars | Mix positional placeholders ($1, $2) with config vars and optional fragments. Use $$ to escape literal $. |
| 🎲 Nested flows | Navigate nested script structures via space notation: mcl example date utc. Consistent display and execution. |
| 🛡️ Safe execution | Dry-run mode, opt-in environment sharing, structured logging. |
| 📐 Developer-friendly | Strict type hints, comprehensive test coverage, mypy/black enforced in CI. |
| 🔓 Open source | MIT-licensed; fork, adapt, and redistribute freely with attribution. |
The easiest way to get started—pipx manages isolation and PATH for you:
pipx install mcl-toolIf you prefer managing the venv yourself:
- Ensure Python 3.8+ is available (
python3 --version). - Create and activate an isolated environment:
python3 -m venv ~/.venvs/mcl source ~/.venvs/mcl/bin/activate python -m pip install --upgrade pip
- Install the CLI:
pip install mcl-tool
- Initialize a project config
mcl init
- Edit
mcl.json(local overrides global~/.mcl/global-mcl.json):{ "vars": { "project": "mcl", "version": "0.1.0" }, "scripts": { "example": { "hello": "echo Hello, $1!", "deploy": ["echo Deploying $project", "?$1", "echo Version $version"], "date": { "show": "date", "utc": "date -u" } } } } - Run commands
mcl # Shows interactive menu or list: # • example hello # • example deploy # • example date show # • example date utc mcl example hello Alice # Execute with spaces mcl example deploy staging # Optional arg substituted into '?$1' mcl example date utc # Nested command mcl --dry-run example date utc # Dry-run mode
| Command | Description |
|---|---|
mcl init |
Create a stub mcl.json without overwriting existing files. |
mcl edit |
Open the global config (~/.mcl/global-mcl.json) in $EDITOR. |
mcl run <script> [args...] |
Execute a script node; errors bubble as ValueError for clean Click aborts. |
mcl <script> [args...] |
Shorthand for mcl run ..., including nested paths (mcl example date utc). |
--dry-run |
Print rendered commands without executing. |
--share-vars |
Export config vars and args as env vars for shell-based scripts. |
- Scripts accept strings, ordered lists, or nested objects; comment lines starting with
#are ignored. - Nested scripts notation: Scripts are displayed AND executed with space-separated paths (e.g.,
example hello,docker build). Use spaces to invoke nested commands. - Positional placeholders (
$1,$2, …) map to CLI args; optional placeholders (?$3) drop when missing. - Escape syntax: Use
$$to output a literal$without substitution. For example,$$1becomes$1in the output (useful when generating shell scripts that use their own parameters). - Config vars become substitutions (
$project) and, with--share-vars, exported env vars (project,MCL_ARG_1, …). - Global config lives in
~/.mcl/global-mcl.json; localmcl.jsonoverrides keys during merge. - Running
mclwith no args shows an interactive menu (TTY) or text list with available scripts.
When you execute a nested command without specifying a subcommand, mcl shows an interactive menu in TTY environments:
$ mcl docker
? Select a subcommand for 'docker':
❯ build
run
stop
logsNavigate with arrow keys (↑/↓) and select with Enter. Press Ctrl+C to cancel.
Behavior:
- Interactive terminal (TTY): Shows an interactive menu with arrow key navigation
- Non-interactive (pipes, scripts, CI/CD): Falls back to error message with available options
- Graceful cancellation: Ctrl+C exits cleanly with a "cancelled by user" message
This feature improves discoverability while maintaining full backward compatibility for automation workflows.
- Create an environment:
python -m venv .venv && source .venv/bin/activate - Install dev extras:
pip install -e '.[dev]' - Run quality gates:
black --check . mypy src tests pytest --cov=src/mcl - GitHub Actions (
.github/workflows/ci.yml) mirrors these steps.
See docs/architecture.md for a deep dive into the CLI → Config → Executor pipeline, and docs/testing.md for pytest tips. Contribution guidelines live in CONTRIBUTING.md.
- Config schema validation (Pydantic).
- Optional YAML support.
- Multi-platform test matrix via tox.
Have ideas? Open an issue or PR! 🎉


