wastech-mdlint

Deterministic linting for the Markdown your agents read.

  • Open source
  • Actively developed
  • MIT

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.

View repositoryView on npm

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)
Output of wastech-mdlint 0.2.2 on the broken-link fixture from its own test suite.
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.md
Output of wastech-mdlint 0.2.2 on the graph fixture from its own test suite, which plants a reference cycle for the report to catch.

Who 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 .
Requires Node.js 24.17 or later. With no config the linter runs no rules, so the init command comes first. It scans your documents, drafts a rule set and writes it once you confirm.

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.

Want the same checks in your team’s repository?

Write to me