Skip to content

CLI reference

docmeta exposes four subcommands: validate (the default), get, fill, and schemas. validate, get, and fill share an input model and several flags with identical semantics.

Terminal window
docmeta [global options] [command] [command options] [arguments]

Global options are accepted before the subcommand.

Option Description
-V, --version Print the docmeta version and exit.
--no-color Disable colored output. See color behavior.
-h, --help Print help for the program or a subcommand.

validate is the default command, so docmeta <paths...> runs validation without naming the subcommand.

Validate the metadata in the given files, directories, or globs against the resolved schema set for each file. This is the default command.

Terminal window
docmeta validate [paths...] [options]
docmeta [paths...] [options]
Argument Description
[paths...] Files, directories, or globs to validate. Use - to read from stdin. Optional — falls back to config paths:. See the shared input model.
Option Argument Default Description
-s, --schema <ref> Schema to validate against. Repeatable. When given, it overrides $schema and config for every file. See reference kinds.
--ext <list> supported extensions Comma-separated extensions used when expanding directories and globs.
--exclude <glob> Glob to exclude from directory and glob walks. Repeatable. Merged with config exclude: and the default ignores.
--as <format> Force an input format (extractor name, e.g. markdown). Required when reading from stdin.
-f, --format <pretty|json|github> pretty Output format. An unknown value is an error (exit 2).
-c, --config <path> discovered Path to a config file. When set, the file must exist or docmeta exits 2.
-q, --quiet off In pretty output, hide passing files. Has no effect on json or github.
Terminal window
docmeta validate docs/ # walk a directory
docmeta validate "**/*.md" -f github # CI annotations
docmeta validate page.md -s google:okf:0.1 -s ./my.schema.json
cat page.md | docmeta validate - --as markdown # read from stdin

Print the values of one or more metadata fields from each file. Useful for scripted extraction. get reads and reports values; it does not validate.

Terminal window
docmeta get <fields> [paths...] [options]
Argument Description
<fields> Comma-separated metadata field references to print. Each is a top-level key (title), a dot-notation path into nested objects and arrays (author.name, tags.0), or a JSON Pointer when prefixed with / (/author/name, /tags/0). Required.
[paths...] Files, directories, or globs to read. Use - to read from stdin. Optional — falls back to config paths:. See the shared input model.

A requested field that is absent from a file is reported as unset rather than as an error.

A field reference descends into nested objects and arrays. Two syntaxes are accepted:

  • Dot-notation: author.name, tags.0. Concise, but a key containing a literal . cannot be addressed this way.
  • JSON Pointer (RFC 6901): any reference beginning with /, e.g. /author/name or /tags/0. This is the same pointer validate prints in error locations, so a path copied from a validation failure works verbatim. Use it to address keys that contain dots (/odd.key) or slashes (/a~1b for the key a/b).

Requesting a parent key (author) returns the whole nested value. A path that descends into a scalar, or whose segment is missing, is reported as unset. Only a key’s own properties resolve; inherited members such as toString or __proto__ are treated as missing.

On Git Bash/MSYS2 (Windows), quote a leading-slash pointer, '/author/name', so the shell does not rewrite it as a filesystem path. Other shells are unaffected.

Option Argument Default Description
--ext <list> supported extensions Comma-separated extensions used when expanding directories and globs.
--exclude <glob> Glob to exclude from directory and glob walks. Repeatable. Merged with config exclude: and the default ignores.
--as <format> Force an input format (extractor name). Required when reading from stdin.
-f, --format <pretty|json> pretty Output format. get has no github format. An unknown value is an error (exit 2).
-c, --config <path> discovered Path to a config file. When set, the file must exist or docmeta exits 2.

In pretty format, get prints one <file>: <field>=<value> line per requested field per file. Unset fields print as (unset). In json format it prints an array of { file, present, values } objects, where values maps each requested field to its value; a requested field that is unset is omitted from values. present reports whether the file had a metadata block at all.

Terminal window
docmeta get title,type docs/intro.md
docmeta get author.name,/author/email docs/intro.md
docmeta get type "**/*.md" -f json
cat page.md | docmeta get title - --as markdown

Infer values for the metadata properties that are missing or invalid, and write back the ones the model is confident about. fill resolves the same schema set as validate, so the schema you already maintain is what determines which properties get proposed.

Terminal window
docmeta fill [paths...] [options]

fill sends the page and its schema to an LLM provider. By default it detects one, taking the first of these that your machine can actually use:

  1. anthropicANTHROPIC_API_KEY is set
  2. openaiOPENAI_API_KEY is set
  3. claude-cli — a signed-in claude CLI is on your PATH
  4. llama-cpp — a local model, needing no key and costing nothing

Pass --provider to pin one instead. fill reports which provider and model it used, in both output formats.

Argument Description
[paths...] Files, directories, or globs to fill. Use - to read from stdin, which prints the filled document to stdout and writes nothing to disk. Optional — falls back to config paths:. See the shared input model.
Option Argument Default Description
-s, --schema <ref> Schema to fill against. Repeatable. When given, it overrides $schema and config for every file.
--ext <list> supported extensions Comma-separated extensions used when expanding directories and globs.
--exclude <glob> Glob to exclude from directory and glob walks. Repeatable.
--as <format> Force an input format. Required when reading from stdin.
--fields <list> all candidates Comma-separated top-level fields to fill. Everything else is left alone.
--confidence <n> 0.7 Minimum self-reported confidence, from 0 to 1, needed to write a value. A non-numeric or out-of-range value is an error (exit 2).
--dry-run off Report proposals without writing them.
--provider <name> auto Inference provider: auto, anthropic, openai, claude-cli, llama-cpp, or mock. auto detects one — see above. An unknown name is an error (exit 2).
--model <model> provider default Model override. Needs a named provider, from either --provider or config fill.provider — a model name does not say which provider owns it, so pairing it with auto (including the default) is an error (exit 2).
--no-cache cache on Bypass the proposal cache in .docmeta/cache.
--max-cost-usd <usd> Stop scheduling new files once this much has been spent.
--concurrency <n> 4 Files inferred in parallel.
-f, --format <pretty|json> pretty Output format. fill has no github format. An unknown value is an error (exit 2).
-c, --config <path> discovered Path to a config file.

A schema property is a candidate when it is missing from the file’s metadata, or present but invalid. A property that is already present and valid is never touched, and neither is $schema, which is schema wiring, not metadata.

Every proposal carries a self-reported confidence between 0 and 1. That number is a weak signal on its own, so it is the last of four gates. Three mechanical checks run first, and a high confidence cannot override any of them:

  1. The value must satisfy the property’s own subschema. fill builds the response schema out of your schema’s property definitions, so a timestamp that is not a valid date-time is rejected before it is ever scored. When several schemas in the set define the same property, every one of their rules applies, so -s order does not change what the model may propose.
  2. The property must be one docmeta asked about. The model cannot introduce keys your schema does not define.
  3. The document must still validate afterwards. Any value that would leave the page failing its own schema is reverted and reported.

Only then is --confidence applied. Values below the threshold are skipped, and reported by name and score so you know what still needs a human. The confidence and the model’s reasoning stay in the report; they never reach your document.

Because the cache stores the proposal before gating, re-running with a different --confidence re-scores the cached proposals and costs nothing. That is the intended way to tune the threshold on a real docset.

The cache lives in .docmeta/cache relative to the working directory. It is machine-local and safe to delete at any time. Add .docmeta/ to your .gitignore. Pass --no-cache to bypass it entirely.

fill can only write formats it can round-trip without disturbing the rest of the document. markdown and mdx are always writable. rst and asciidoc are writable only when the file already has a fenced front matter block, because their native docinfo and header syntax is lossy to read back, and a bare --- means something else in both languages. xml and html are read-only. Run docmeta schemas to see which is which. Targeting a read-only file is reported as a per-file error, not a failed run.

fill exits 1 when a property your schema lists as required could not be filled confidently, or when any file errored, which is work still to do. Skipped optional properties are a normal outcome and leave the exit code at 0. Usage and operational failures exit 2, as elsewhere.

Terminal window
docmeta fill docs/ --dry-run # preview, write nothing
docmeta fill docs/ --confidence 0.9 # only near-certain values
docmeta fill page.md --fields description,tags
cat page.md | docmeta fill - --as markdown # filled document to stdout

List the built-in schemas and the supported input formats. Takes no positional arguments and reads no files.

Terminal window
docmeta schemas [options]
Option Argument Default Description
-f, --format <pretty|json> pretty Output format.

In pretty format, schemas lists each built-in schema by id and title, then each input format with its extensions, whether it is implemented, and whether fill can write to it. In json format it prints { builtins, formats }, where builtins is an array of { id, title, description } and formats is an array of { name, extensions, implemented, writable }.

Terminal window
docmeta schemas
docmeta schemas -f json

validate, get, and fill resolve their inputs the same way.

  • Positional paths are files, directories, or globs. A named file is always read. A directory or glob is expanded and filtered to the extensions in --ext (or, by default, the extensions of the implemented formats).
  • - reads stdin. Stdin requires --as <format> to choose an extractor, because there is no filename extension to detect from. Without --as, docmeta exits 2.
  • Config paths: is the fallback. When no positional paths are given, docmeta uses paths: from the config file. Positional paths, when present, override config paths: entirely.
  • No input and no config is an error. If you pass no paths and no config supplies paths:, docmeta reports an operational error and exits 2. It does not silently produce empty output.

Directory and glob expansion always skips these globs, in addition to anything from --exclude or config exclude::

Glob Skips
**/node_modules/** Dependency directories.
**/.git/** The Git metadata directory.

Dotfiles and dot-directories are also excluded from directory and glob walks by default. An explicitly named file is always read, even if it matches an ignore glob or is a dotfile.