mdtodo
mdtodo is a command-line todo manager that keeps everything in one plain markdown file.
Headings are projects and checkbox items are tasks. You can edit the file in any editor, or
use the mdtodo commands. Either way, it stays readable markdown.
- [ ] Call the bank due:2026-10-20
## Website
- [ ] Write landing copy @active due:2026-10-18
- [ ] Pick a color palette @next
- [ ] Shortlist 3 palettes
- [x] Buy domain
[ ]means open, and[x]means completed.@activemarks a task you're working on now.@nextadds a task to the pool of tasks you plan to pick up next.due:YYYY-MM-DDsets a deadline. Open tasks are flagged as overdue, or as due soon (today through the next 3 days).- Tasks above the first heading go into the
Inboxproject. Prose, notes, and code blocks are ignored.
Listings show each task with its reference. A subtask is labelled with its parent's name, as
<parent>: <task>, so you can tell which task it belongs to:
$ mdtodo list --project Website
## Website
bbdb3a OVERDUE ACTIVE Write landing copy (2 days overdue, 2026-10-18)
b1b77f NEXT Pick a color palette
aa0d81 Pick a color palette: Shortlist 3 palettes
Each task line starts with its ref, then a marker for how urgent it is: OVERDUE,
DUE SOON, ACTIVE, or NEXT. Deadlines read relative to today ("due tomorrow",
"2 days overdue") next to the date. The summary lists Overdue, Due soon, Active, then Next,
and shows each task only once, in its most urgent section.
The full syntax is in specs/001-markdown-todo-manager/contracts/file-format.md.
Install
With uv installed:
uv tool install mdtodo # puts `mdtodo` on your PATH (~/.local/bin)
mdtodo --version
If you don't have a suitable Python, uv downloads one for you.
uv tool install mdtodo==X.Y.Z # install a specific version
uv tool upgrade mdtodo # move to the latest release
uv tool uninstall mdtodo # remove the command
Uninstalling removes only the command. Your todo file (~/tracker.md, or whatever --file
or MDTODO_FILE points at) is left untouched.
Switching from an editable install: if you installed with uv tool install --editable .,
run uv tool uninstall mdtodo first, or replace it in one step with
uv tool install --force mdtodo.
Which file is used
The first match wins:
--file PATH, which can go before or after the command;- the
MDTODO_FILEenvironment variable; ~/tracker.md.
If you used an earlier version that read ~/TODO.md, rename that file to ~/tracker.md, or
point --file or MDTODO_FILE at it.
mdtodo init creates a starter file. Nothing else ever creates the file.
Colour
On a terminal, urgent tasks are coloured: overdue in bold red, due soon in bold magenta, active in bold green, and next in green. Titles are bold, and everything else is normal text. Only bold and the terminal's standard named colours are used, so your theme picks the exact shades and the output stays readable on light and dark backgrounds. Colour only repeats what the text already says, so nothing is lost without it.
--color auto|always|never (before or after the command) chooses when to use it. With
auto, the default, colour is off when output is piped or redirected, when NO_COLOR is set,
or when TERM=dumb. FORCE_COLOR is not read; use --color always to force colour, for
example mdtodo --color always | less -R.
Commands
| Command | What it does |
|---|---|
mdtodo / mdtodo summary |
Overdue, Due soon, Active, and Next tasks (each listed once), plus counts per project |
mdtodo list [--all] [--project NAME] |
Tasks grouped by project, each with its reference |
mdtodo next |
The next pool, ordered by deadline |
mdtodo due |
Open tasks ordered by deadline |
mdtodo start REF / mdtodo stop REF |
Add or remove @active |
mdtodo next add REF / mdtodo next rm REF |
Add or remove @next |
mdtodo done REF |
Check the box, and remove @active and @next |
mdtodo init |
Create a starter file |
REF is the 6-character reference shown in every listing. It stays the same when markers
change. If you edit a task's text, its reference changes, and the old one is refused rather
than applied to the wrong task. Each command changes only the task's own line. If the file
changed while the command was running, nothing is written.
Details, including output formats and exit codes, are in contracts/cli.md.
Development
uv sync
uv tool install --editable . # installs this working tree as the `mdtodo` command
scripts/check.sh # format, lint, mypy --strict, tests (coverage ≥ 80%)
uv run pytest -m perf --no-cov # timing checks (SC-002), kept out of the default run
The design documents are in specs/001-markdown-todo-manager/, and the project principles are in .specify/memory/constitution.md.
Releasing
Releases go to PyPI with scripts/release.sh. See docs/releasing.md.
Metadata
Release files for mdtodo 0.4.0
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | Provenance | |
|---|---|---|---|---|
| mdtodo-0.4.0.tar.gz | 15.0 kB | Without provenance | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| mdtodo-0.4.0-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 34.2 kB
Release files / mdtodo-0.4.0.tar.gz
| Download URL | mdtodo-0.4.0.tar.gz |
|---|---|
| Size | 15.0 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
ffb9b2746af1ed58bbfe262ad2d7f849a62a447f0e62fdaf66f5f085ae48d585
|
|
BLAKE2b-256 checksum How to use checksums |
6637b04160fcc3cf2a304d843c03351ed26e41c078492fa072c81245c300b17a
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
uv/0.9.16 {"installer":{"name":"uv","version":"0.9.16","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"macOS","version":null,"id":null,"libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":null}
|
Release files / mdtodo-0.4.0-py3-none-any.whl
| Download URL | mdtodo-0.4.0-py3-none-any.whl |
|---|---|
| Size | 19.2 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
4c880be1ca559e0861484141238f7e4c05182954b80f9d16e03ebdabfb517879
|
|
BLAKE2b-256 checksum How to use checksums |
7dd40c1c57421c7bdab3c7edfbbd174fbc79d521c0b069e0a350617909cce722
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
uv/0.9.16 {"installer":{"name":"uv","version":"0.9.16","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"macOS","version":null,"id":null,"libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":null}
|
Security for mdtodo 0.4.0
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
No provenance found
None of the files in this release were uploaded with provenance metadata.
A note on package security
PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.