wastech-mdlint
Deterministic linting for the Markdown your agents read.
wastech-mdlint is a TypeScript CLI and library that lints the Markdown context in your repository, from AGENTS.md and CLAUDE.md to the docs tree. Every check runs locally, with no network calls and no model in the loop, so the same files always get the same result.
Why it’s here
Part of getting good work from agents is keeping the files they read in order, and I wrote this tool for that. It runs in CI on the docs of this site and of wastech-orchestrator, whose config you can open in its public repository.
Problem
The files your agents read change along with the code, and unless something checks them, links stop resolving after a file moves and context files grow past the size a model reads well. No test fails when that happens, so the first sign may be an agent doing worse work, and it is easy to put that down to the model.
Solution
wastech-mdlint treats agent-facing Markdown like source code. It ships 22 built-in rules, from link targets to required table columns, plus budget rules that put a ceiling on context size. Custom rules are written as configuration from a closed set of assertions, so nothing arbitrary runs in your CI.
- Once a config turns the rules on, broken internal links and drifting tables fail a check in CI or in a local run.
- A token budget for context becomes a limit that CI can check.
- Custom rules are plain data, so running them in someone else’s CI executes no code.
Key features
- 22 built-in rulesCategories for tables, sections and structure, references, content quality and graph integrity.
- LLM context hygieneByte, line and token budgets plus an eager-import budget for context files.
- Declarative custom rulesA closed vocabulary of assertions composed from config – no rebuild, no code execution in your CI.
Sample runs
wastech-mdlint lint .broken.md 3:11 error Link target "missing.md" does not resolve to a file. REF-001✖ 1 problem (1 error, 0 warnings)wastech-mdlint graph .nodes: 8edges: 7cycles: 1entry points (3): design.md index.md orphan.mdtop hubs: (none: no document has 3 or more incoming references)cycles: cycle-a.md -> cycle-b.md -> cycle-a.mdclusters: cluster 1 (5 files): design.md glossary.md guide.md index.md requirements.md cluster 2 (2 files): cycle-a.md cycle-b.md cluster 3 (1 files): orphan.mdreading order (6): design.md index.md glossary.md guide.md orphan.md requirements.mdall 2 documents below sit in a cycle.excluded from reading order (2): cycle-a.md cycle-b.mdcoverage: nodes: 8 edges: 7 files outside corpus (1): appendix.mdWho it is for
- Teams maintaining a large body of documentation and agent-facing context.
- Anyone keeping CLAUDE.md / AGENTS.md / SKILL.md in a repository.
Stack
- Language
- TypeScript
- Runtime
- Node.js 24 LTS
- Structure
- npm workspaces monorepo
- TypeScript project references
- AI integration
- Model Context Protocol (stdio)
Install
npm install --save-dev @wastech-mdlint/clinpx wastech-mdlint initnpx wastech-mdlint lint .Limitations
- External HTTP links are not checked, which keeps every run local and deterministic.
- Custom rules are data only, with no TypeScript or JavaScript configs and no user-code plugins.
- The context graph is rebuilt on every run, with no incremental cache yet.
