Skip to content

CLI Reference

docvet provides ten subcommands. Global options are generally placed before the subcommand; discovery flags and check-specific options are placed after it.

docvet [GLOBAL OPTIONS] COMMAND [COMMAND OPTIONS]

Global Options

Option Type Default Description
--verbose flag off Show file count, per-check timing, and active checks
-q / --quiet flag off Suppress non-finding output (summary, timing, verbose details). Config warnings are always shown.
--summary flag off Print per-check quality percentages after findings
--format terminal | markdown | json terminal Output format
--output PATH stdout Write report to file
--config PATH auto-detected Path to pyproject.toml
--version flag Show version and exit

When --output is specified without --format, the format defaults to markdown. When --format json is used, output is always a JSON object (even when no findings exist).

JSON Output

The --format json option produces a structured JSON object for programmatic consumption. The schema includes a findings array and a summary object:

{
  "findings": [
    {
      "file": "src/app/utils.py",
      "line": 12,
      "symbol": "my_func",
      "rule": "missing-raises",
      "message": "Function 'my_func' raises ValueError but...",
      "category": "required",
      "severity": "high"
    }
  ],
  "suppressed": [
    {
      "file": "src/app/utils.py",
      "line": 30,
      "symbol": "internal_helper",
      "rule": "missing-examples",
      "message": "Public symbol lacks an Examples section",
      "category": "recommended",
      "severity": "low"
    }
  ],
  "summary": {
    "total": 1,
    "by_category": { "required": 1, "recommended": 0, "scaffold": 0 },
    "files_checked": 42
  }
}
  • Each finding has seven fields: file, line, symbol, rule, message, category, severity.
  • The severity field is derived from category: "required" maps to "high", "scaffold" maps to "medium", "recommended" maps to "low". It is a convenience alias, not a separate signal.
  • The summary object includes total, by_category (with required, recommended, and scaffold counts), and files_checked.
  • A suppressed array is included containing findings that were suppressed by inline # docvet: ignore comments. Each entry has the same seven fields as a finding.
  • Whitespace and indentation are not part of the schema contract — always parse with a JSON parser.
  • Exit codes: 0 when no active (non-suppressed) findings match a fail_on check, 1 when active findings exist in a fail_on check.

Quality Summary (--summary)

The --summary flag prints per-check quality percentages to stderr after findings:

docvet check --all --summary
  enrichment      96%  (8 findings)
  freshness      100%  (0 findings)
  coverage        92%  (1 findings)
  griffe         100%  (0 findings)

Only checks that actually ran appear in the output. When combined with --format json, a quality object is added to the JSON output:

docvet check --all --summary --format json
{
  "findings": [...],
  "summary": {...},
  "quality": {
    "enrichment": {"items_checked": 200, "items_with_findings": 8, "percentage": 96, "unit": "symbols"},
    "freshness": {"items_checked": 200, "items_with_findings": 0, "percentage": 100, "unit": "symbols"},
    "coverage": {"items_checked": 12, "items_with_findings": 1, "percentage": 92, "unit": "packages"},
    "griffe": {"items_checked": 15, "items_with_findings": 0, "percentage": 100, "unit": "files"}
  }
}

When --quiet and --summary are both set, the terminal summary is suppressed (--quiet wins). The machine-readable path is --format json --summary.

--verbose and --quiet can be placed before or after the subcommand name (dual-registered). Both positions are equivalent:

docvet --verbose check --all      # before subcommand
docvet check --all --verbose      # after subcommand — also valid
docvet check --all -q             # quiet after subcommand

When both --quiet and --verbose are specified, --quiet wins.

Output Tiers

docvet uses a three-tier output model. Findings always go to stdout; metadata goes to stderr.

Tier Trigger stderr stdout
Quiet -q / --quiet (nothing) Findings only
Default (no flags) Summary line Findings only
Verbose --verbose File count + per-check timing + summary Findings only

Parse and availability warnings always appear regardless of output tier.

Default output (zero findings):

Vetted 42 files [enrichment, freshness, coverage, griffe] — no findings. (0.3s)

Default output (with findings):

src/app/utils.py:12: missing-raises Raises section missing for ValueError [required]
src/app/utils.py:30: stale-signature Docstring may be stale (signature changed) [required]
Vetted 42 files [enrichment, freshness, coverage] — 2 findings (2 required, 0 recommended). (0.4s)

The summary line uses the brand verb "Vetted" and always includes the elapsed time and list of checks that ran. When griffe is not installed, it is omitted from the check list.

Discovery Modes

All subcommands accept the same set of discovery modes. These are mutually exclusive — use only one at a time.

Mode Description
(default) Files from git diff (unstaged changes)
--staged Files from git diff --cached (staged changes)
--all All Python files in the project
(positional) Specific files as positional arguments
--files Specific files (repeatable alternative)

Pass files as positional arguments (preferred) or with the --files flag:

docvet check src/app/utils.py src/app/models.py
docvet check --files src/app/utils.py --files src/app/models.py  # equivalent

Commands

docvet check

Run all enabled checks.

docvet check                          # unstaged changes (default)
docvet check --staged                 # staged files
docvet check --all                    # entire codebase
docvet check src/foo.py src/bar.py    # specific files

This runs presence, enrichment, freshness, coverage, and griffe (if installed) in sequence and produces a unified report.

docvet presence

Check for missing docstrings and report coverage.

docvet presence --all

Detects public symbols (modules, classes, functions, methods) that lack a docstring. Reports per-file findings and aggregate coverage statistics.

Default output (with findings):

src/myapp/utils.py:12: missing-docstring Public function has no docstring [required]
src/myapp/models.py:5: missing-docstring Public class has no docstring [required]
Vetted 10 files [presence] — 2 findings (2 required, 0 recommended), 98.0% coverage. (0.2s)

Verbose output (with coverage detail):

src/myapp/utils.py:12: missing-docstring Public function has no docstring [required]
Docstring coverage: 99/100 symbols (99.0%) — below 100.0% threshold
Vetted 10 files [presence] — 1 finding (1 required, 0 recommended), 99.0% coverage. (0.2s)

The verbose summary shows documented/total symbols, percentage, and threshold comparison when min-coverage is set.

docvet enrichment

Check for missing docstring sections.

docvet enrichment --all

Analyzes Python AST to detect missing Raises, Yields, Attributes, Examples, and other sections that should be present based on the code's behavior. 10 rules covering functions, classes, modules, and format conventions.

docvet freshness

Detect stale docstrings.

docvet freshness --all                # diff mode (default)
docvet freshness --all --mode drift   # drift mode
Option Type Default Description
--mode diff | drift diff Freshness check strategy

Diff mode maps git diff hunks to AST symbols and flags code changes without matching docstring updates. Fast, targeted feedback.

Drift mode uses git blame timestamps to find docstrings that haven't been updated relative to their code. Sweeps the entire codebase for long-stale documentation.

docvet coverage

Find files invisible to mkdocs.

docvet coverage --all

Walks the directory tree from each discovered file up to the source root, checking for missing __init__.py files that would make packages invisible to documentation generators.

docvet griffe

Check mkdocs rendering compatibility.

docvet griffe --all

Loads packages with the griffe parser and captures warnings that would cause broken rendering in mkdocs-material sites. Detects unknown parameters, missing type annotations, and docstring format issues.

Note

Requires the optional griffe extra: pip install docvet[griffe]

docvet fix

Scaffold missing docstring sections. Runs enrichment to find missing sections, inserts placeholder content, and writes modified files. Use --dry-run to preview changes as a unified diff without modifying any files.

docvet fix                        # Fix files in git diff (default)
docvet fix --all                  # Fix entire codebase
docvet fix --staged               # Fix staged files only
docvet fix src/app.py             # Fix a specific file
docvet fix --dry-run --all        # Preview changes without writing

Unique options:

Option Description
--dry-run Show unified diff of changes without writing files

All standard discovery modes are supported (--all, --staged, positional files, --files).

Workflow: After running docvet fix, run docvet check to see scaffold-incomplete findings for each [TODO: ...] placeholder. Fill in the placeholders with real descriptions, then docvet check produces zero findings.

# Typical fix workflow
docvet fix --all                  # Insert scaffolded sections
docvet check --all                # See scaffold-incomplete findings
# ... fill in [TODO: ...] markers ...
docvet check --all                # Zero findings

docvet config

Show effective configuration with source annotations.

docvet config                     # TOML output (default)
docvet --format json config       # JSON output
docvet config --show-defaults     # same as plain `docvet config`

Prints the merged config (user values + built-in defaults) so you can see exactly which settings are active and where they come from. Each value is annotated with # (user) or # (default).

TOML output (default):

[tool.docvet]
src-root = "src"  # (default)
exclude = ["tests", "scripts"]  # (default)
fail-on = ["enrichment"]  # (user)
warn-on = ["presence", "freshness", "griffe", "coverage"]  # (default)

[tool.docvet.freshness]
drift-threshold = 30  # (default)
age-threshold = 90  # (default)

[tool.docvet.enrichment]
require-raises = false  # (user)
require-yields = true  # (default)
...

The TOML output is copy-paste-ready — you can paste it directly into your pyproject.toml.

JSON output (--format json):

{
  "config": {
    "src-root": "src",
    "exclude": ["tests", "scripts"],
    "fail-on": ["enrichment"],
    "warn-on": ["presence", "freshness", "griffe", "coverage"],
    "freshness": { "drift-threshold": 30, "age-threshold": 90 },
    "enrichment": { "require-raises": false, "require-yields": true }
  },
  "user_configured": ["fail-on", "enrichment.require-raises"]
}

The user_configured array lists which keys were explicitly set in your pyproject.toml.

When no pyproject.toml is found, a note is printed to stderr and all built-in defaults are shown.

docvet lsp

Start the LSP server for real-time diagnostics.

docvet lsp

Launches a Language Server Protocol server on stdio that publishes docstring quality diagnostics on file open and save events.

Note

Requires the optional lsp extra: pip install docvet[lsp]

docvet mcp

Start the MCP server for agentic integration.

docvet mcp

Launches a Model Context Protocol server on stdio that exposes docstring quality checks as MCP tools for AI agents. Agents can call docvet_check to run checks on files or directories, and docvet_rules to retrieve the full rule catalog.

Note

Requires the optional mcp extra: pip install docvet[mcp]

Configuration

docvet reads configuration from the [tool.docvet] section in pyproject.toml. If the section is missing, sensible defaults are used.

Specify a custom config path with:

docvet --config path/to/pyproject.toml check --all

Exit Codes

Code Meaning
0 No findings (or no findings in fail_on checks)
1 Findings detected in fail_on checks
2 Usage error (invalid arguments or options)

Inline Suppression

Suppress specific findings with inline comments. Suppression operates as a post-filter — all checks run normally, then matching findings are partitioned into suppressed.

Line-Level Suppression

Place a # docvet: ignore[rule] comment on the def or class keyword line:

def connect(host, port):  # docvet: ignore[missing-raises]
    """Connect to the server."""
    ...

Suppress multiple rules with comma separation:

def connect(host, port):  # docvet: ignore[missing-raises,missing-returns]
    """Connect to the server."""
    ...

Suppress all rules on a symbol with a blanket ignore:

def connect(host, port):  # docvet: ignore
    """Connect to the server."""
    ...

Note

The comment must be on the def/class keyword line itself — not on a decorator line. For multi-line signatures, place it on the def line: def long_name( # docvet: ignore[rule].

File-Level Suppression

Place a # docvet: ignore-file[rule] comment before the first def or class:

# docvet: ignore-file[missing-examples]

def foo():
    """Does something."""
    ...

Suppress all rules for the entire file:

# docvet: ignore-file

def foo():
    """Does something."""
    ...

Behavior

  • Exit code: Suppressed findings do NOT count toward the exit code. Only active findings determine pass/fail.
  • Verbose mode: When --verbose is active, suppressed findings are listed separately on stderr with a [suppressed] tag.
  • JSON output: --format json includes a "suppressed" array alongside "findings".
  • Invalid rules: If a suppression comment specifies a non-existent rule ID, a warning is emitted to stderr. The directive is recorded for forward-compatibility, but only matching rule IDs suppress findings — a typo will not hide anything.
  • Always active: Suppression requires no configuration toggle — it is always available.

Cross-Tool Syntax Reference

Tool Syntax Scope
ruff # noqa: E501 Line
pylint # pylint: disable=C0114 Line/block
mypy # type: ignore[attr-defined] Line
docvet # docvet: ignore[rule] Line (symbol)
docvet # docvet: ignore-file[rule] File

Examples

Check staged files before committing:

docvet check --staged

Generate a markdown report for CI:

docvet --format markdown --output report.md check --all

Produce structured JSON output for agents or CI pipelines:

docvet --format json check --all

Write JSON findings to a file:

docvet --format json --output report.json check --all

Run only the freshness drift sweep with verbose output:

docvet freshness --all --mode drift --verbose

Suppress all non-finding output (useful in scripts and CI):

docvet check --all -q

Check specific files:

docvet enrichment src/myapp/utils.py src/myapp/models.py