CLI reference
miditool <command>
run Run an effect graph between an input port and an output port new Write a starter file: a config or a Luau script ports List MIDI input and output ports monitor Print incoming MIDI events from an input port effects List the built-in effects and their parameters hide Hide a MIDI source from other apps until Ctrl-C (macOS only) unhide Restore sources hidden by a crashed run (macOS only) bench Measure round-trip latency through a pass-through engine doctor Check the environment: ports, config, hidden sources, DAW statemiditool run
Section titled “miditool run”miditool run [CONFIG]Runs the effect graph. Without CONFIG, the file is resolved in order: MIDITOOL_CONFIG, ./miditool.kdl, then ~/.miditool/config.kdl (created as a pass-through starter on first run; see config files). The command prints which config won, holds the ports open, watches the config for live edits, and winds down on Ctrl-C by releasing every held note.
miditool: Roland -> miditool Out (virtual). Ctrl-C to stop.If the config sets hide=true, the input is hidden after connecting and restored on exit; see the GarageBand guide.
miditool new
Section titled “miditool new”miditool new config [NAME]miditool new script <NAME>Writes a starter file into the current directory and prints the next step. new config writes NAME.kdl (default miditool.kdl), a minimal commented config; new script writes NAME.lua, a runnable Luau script to edit from. Extensions are appended for you, and existing files are never overwritten.
wrote wedge.luanext: add `script "wedge.lua" seed=1` to your config, then `miditool run`.miditool ports
Section titled “miditool ports”miditool portsLists every MIDI input and output the system offers, one per line:
inputs: Roland FP-30 MIDI INoutputs: Roland FP-30 MIDI OUT IAC Driver Bus 1miditool monitor
Section titled “miditool monitor”miditool monitor [--input <SUBSTRING>]Prints incoming events from an input port. --input matches a substring of the port name; without it the first non-miditool port is used. Timestamps are seconds since the first event.
monitoring. Ctrl-C to stop. 0.000 ch1 note-on C4 (60) vel 96 0.412 ch1 note-off C4 (60) vel 0 1.003 ch1 cc64 = 127 2.741 ch1 bend +2048miditool effects
Section titled “miditool effects”miditool effectsPrints the built-in effects reference: every effect with its parameters and defaults, the routing nodes, and the config file shape. It is the offline, always-current version of the Effects section.
miditool hide
Section titled “miditool hide”miditool hide <NAME>Hides the MIDI source matching NAME from every other app, until Ctrl-C restores it. macOS only. Mostly useful for testing; miditool run hides and restores by itself when the config says input "..." hide=true.
Roland FP-30 MIDI IN is hidden from other apps; restart any app that was already listening. Ctrl-C to restore.miditool unhide
Section titled “miditool unhide”miditool unhide [NAME]Restores sources hidden by a run that was killed hard. macOS only. Without NAME it restores every hidden source:
restored Roland FP-30 MIDI INmiditool bench
Section titled “miditool bench”miditool bench [--rounds <N>]Measures round-trip latency by sending N note pairs (default 500) through a live pass-through engine: a virtual source, the whole decode-process-encode path, a virtual sink, and back through the OS MIDI service to a listener. The numbers cover the entire stack, not just miditool’s pipeline.
bench: 500 note pairs, miditool bench in -> engine -> miditool bench out events min p50 p90 p99 max lost 1000 212.4us 341.7us 498.2us 772.9us 1103.5us 0Read p50 as the typical added latency and p99 as the bad case; both are normally well under a millisecond, far below the few milliseconds a key press takes to travel over USB. A nonzero lost column means another app grabbed the bench ports; close it and rerun. Needs virtual ports, so it runs on macOS and Linux but not Windows.
miditool doctor
Section titled “miditool doctor”miditool doctor [CONFIG]Runs every environment check and prints one verdict line per check: ok, warn, or fail. All checks run even when one fails, so a single report shows everything that needs attention. Exit status is nonzero only for hard failures (no MIDI backend, a config that does not parse).
ok midi backend: 1 input (Roland FP-30 MIDI IN), 2 outputs (Roland FP-30 MIDI OUT, IAC Driver Bus 1)ok config miditool.kdl: parses, 2 sceneswarn possibly hidden or simply offline: Arturia KeyLab; `miditool unhide` clears the hidden casewarn GarageBand is running; apps started before miditool keep hearing the raw keyboard until relaunchedok Logic Pro is not runningThe platform-specific checks: hidden sources and running DAWs on macOS, the ALSA sequencer on Linux, loopMIDI on Windows.