A Python Markdown linter that checks files for style and formatting violations.
- 50+ built-in rules covering headings, lists, whitespace, links, code blocks, and more
- Configurable via
.mdlint.tomlorpyproject.tomlwith per-rule settings - Multiple output formats including human-readable terminal output and JSON
- Gitignore-aware file discovery that respects
.gitignorepatterns - Auto-fix support via
--fixto automatically correct fixable violations - stdin support for integration with editors and CI pipelines
- Built-in rule documentation accessible from the CLI
- Online playground to try mdlint directly in the browser β no installation needed
- Compatible with existing
markdownlintrule sets (Ruby and JavaScript implementations)
uv tool install --from git+https://github.com/mprpic/mdlint mdlint
# OR
pip install --user git+https://github.com/mprpic/mdlint
# OR run directly
uvx --from git+https://github.com/mprpic/mdlint mdlint -hRequires Python 3.10 or later.
# Lint current directory
mdlint check
# Lint specific files
mdlint check README.md docs/guide.md
# Lint a directory recursively
mdlint check docs/
# Lint from stdin
cat README.md | mdlint check -# Human-readable output (default)
mdlint check docs/
# JSON output
mdlint check --format json docs/# Fix violations in-place
mdlint check --fix docs/
# Fix stdin and output result to stdout
cat README.md | mdlint check --fix -Not all rules support auto-fixing. When --fix is used, fixable violations are corrected automatically and any
remaining unfixable violations are still reported. The rules index in the documentation indicates which rules are
fixable.
# List all rules
mdlint rule
# View specific rule details
mdlint rule MD001
# Include valid/invalid examples
mdlint rule MD003 --show-examplesThe following table shows rule availability across mdlint and the
Ruby and
JavaScript markdownlint implementations. The rule behavior is mostly
consistent with that of the markdownlint projects (slight preference to the JavaScript implementation), but may differ
slightly over time as the project evolves.
| Rule(s) | mdlint | Ruby markdownlint | JS markdownlint | Notes |
|---|---|---|---|---|
| MD001 | β | β | β | |
| MD002 | β | β | β | Not implemented (use MD041) |
| MD003βMD005 | β | β | β | |
| MD006 | β | β | β | Not implemented (use MD007) |
| MD007 | β | β | β | |
| MD008 | β | β | β | Not implemented |
| MD009βMD014 | β | β | β | |
| MD015βMD017 | β | β | β | Not implemented |
| MD018βMD041 | β | β | β | |
| MD042βMD045 | β | β | β | |
| MD046βMD047 | β | β | β | |
| MD048βMD056 | β | β | β | |
| MD057 | β | β | β | Not implemented |
| MD058βMD060 | β | β | β |
Create .mdlint.toml in your project root:
# Select specific rules to run (default: all rules)
select = ["MD001", "MD003", "MD041"]
# Ignore specific rules (subtracted from select)
ignore = ["MD041"]
# Rule-specific configuration
[rules.MD041]
level = 2 # Expect first heading to be h2
[rules.MD003]
style = "atx" # atx | atx_closed | setext | setext_with_atx | consistent
[rules.MD013]
line_length = 120
code_blocks = falseOr add to pyproject.toml:
[tool.mdlint]
ignore = ["MD041"]
[tool.mdlint.rules.MD003]
style = "atx"The select and ignore options work together:
selectestablishes the baseline set of rules (defaults to all rules if omitted)ignoresubtracts from the select set
Examples:
# Run all rules except MD041
ignore = ["MD041"]# Run only MD001 and MD003
select = ["MD001", "MD003"]# Run MD001, MD003-MD005, but skip MD004
select = ["MD001", "MD003", "MD004", "MD005"]
ignore = ["MD004"] # Alternatively, omit from select list# Use a specific config file
mdlint check --config path/to/config.toml
# Inline configuration
mdlint check --config "MD003.style='atx'"
# Select specific rules (replaces config select list)
mdlint check --select MD001 --select MD003
# Ignore specific rules (replaces config ignore list)
mdlint check --ignore MD002
# Add to existing select/ignore lists
mdlint check --extend-select MD004 --extend-ignore MD005
# Disable .gitignore and .ignore patterns
mdlint check --no-ignore
# Verbose output (show files being processed)
mdlint check --verbose| Code | Meaning |
|---|---|
| 0 | No violations found |
| 1 | Violations found |
| 2 | Error occurred (file not found, invalid config, etc.) |
- Parallel processing of files (if many are being checked)
- More rules with auto-fix support
MIT