MD View CLI reference

The mdview command — open files, pipe stdin, export PDF/DOCX, verify links. Subcommand-based CLI for the markdown viewer for Windows.

Last updated

mdview is the command-line shim that ships with MD View. It’s a small console binary (mdview.exe) installed on PATH alongside the GUI binary (md-view.exe). The shim parses arguments and stdin, then hands off to a running primary instance via Tauri’s single-instance plugin.

This page is the canonical user-facing reference. The implementation contract lives in web/doc/spec/cli-v1.md inside the MD View repo; this page is generated from it. If the two ever disagree, the spec wins.

Invocation grammar

mdview [GLOBAL_FLAGS] [SUBCOMMAND [SUBCOMMAND_ARGS]] [FILE...]

Two operating modes:

  • Viewer mode — no subcommand. The first positional argument is a file path. Example: mdview README.md.
  • Subcommand mode — the first positional argument is one of seven subcommand names. Example: mdview export pdf README.md.

The parser tells subcommand from file by one rule: the first argument is treated as a subcommand only if it’s a bare word that exactly matches a known subcommand name. Anything containing ., /, \, or a drive letter is a path. So mdview verify is the subcommand, mdview ./verify is a file.

Subcommands

The whole CLI is seven operations:

CommandDescription
mdview FILEOpen in viewer (no subcommand)
mdview diff FILE_A FILE_BSide-by-side diff (Pro)
mdview export pdf FILEExport to PDF
mdview export docx FILEExport to DOCX (Pro)
mdview verify FILERun the verification layer (Pro)
mdview watch FILEOpen viewer with the file watcher
mdview workspace DIROpen a folder as a workspace (Pro)

export is the only nested subcommand — it has two children (pdf and docx). Everything else is flat.

Examples

Open a single file

mdview README.md
mdview "C:\notes\plan.md"
mdview .\CLAUDE.md

Relative and absolute paths both work. UNC paths (\\server\share\...) are supported. WSL paths under /mnt/<letter>/ translate automatically — see Path handling. If MD View is already running, the file opens in the existing window.

Open a folder as a workspace

mdview docs\
mdview .              # current directory — equivalent to mdview workspace .
mdview C:\projects\my-rfcs
mdview workspace .    # explicit form

Bare mdview FOLDER is shorthand for mdview workspace FOLDER. Invoking the CLI to open a workspace requires Pro; the in-app trial unlocks shell access for 14 days. Once the workspace is open, the file tree (Ctrl+Shift+O) and workspace search (Ctrl+Shift+F) stay available regardless of how you opened it — they’re free Reader features. The recent-workspaces CLI list is a Pro convenience tied to the shell entry point.

Pipe stdin

git log --pretty=format:"# %h%n%n%s%n%n%b" -n 20 | mdview
git diff main..HEAD | mdview
gh pr view 42 --json body --jq .body | mdview
cat plan.md | mdview

Piped content opens as an ephemeral document with the sentinel path <stdin> — no watcher, no recents entry. To be explicit:

type plan.md | mdview -

The - token is the conventional Unix marker for “read from stdin.” With no FILE argument and no piped data (stdin is a TTY), mdview prints the help text and exits.

Export to PDF

mdview export pdf README.md
mdview export pdf README.md -o release-notes.pdf
mdview export pdf README.md --theme dark
mdview export pdf README.md -o - > release-notes.pdf
cat plan.md | mdview export pdf - -o plan.pdf

-o (or --output) sets the output path. Without it, MD View writes to the input filename with .pdf extension in the same directory. -o - writes the PDF bytes to stdout — useful for piping into another tool, but you must opt in explicitly. We don’t auto-detect that stdout is redirected; that would make the same command behave differently in interactive shells vs CI.

FlagDescription
-o, --output PATHWrite to PATH. Default: derived from input filename.
--theme NAMERender with named theme. Default: current app theme.
--no-bookmarksSkip nested-bookmark generation (flat PDF).

Export to DOCX (Pro)

mdview export docx plan.md
mdview export docx plan.md -o for-review.docx
mdview export docx plan.md --reference-doc .\company-style.docx

Pandoc must be installed (winget install pandoc); the export uses it under the hood. The optional --reference-doc lets you control Word styles — see DOCX export for the details.

FlagDescription
-o, --output PATHWrite to PATH. Default: derived from input filename.
--reference-doc PATHPandoc reference DOCX (controls Word styles).

Verify (Pro) — coming in MD View 1.0

Coming in MD View 1.0. The mdview verify subcommand is specified in cli-v1.md and ships with the 1.0 release. The current 2.5.x binary exposes the verification layer through the GUI only — toggle it with Ctrl+Shift+V. Once 1.0 ships, the invocations below run the same checks headlessly for CI.

# Coming in MD View 1.0
mdview verify CLAUDE.md
mdview verify CLAUDE.md --strict
mdview verify CLAUDE.md --json > findings.json

mdview verify will run the verification layer over the file and report findings. Designed for CI: exit 0 on success, exit 3 when findings are present.

--json writes a structured findings document to stdout, leaving human messages (progress, internal errors) on stderr. --strict treats warnings as errors.

FlagDescription
--strictTreat warning-level findings as errors (affects exit code).
--jsonEmit machine-readable JSON to stdout.

Diff (Pro)

mdview diff plan.md plan-v2.md
mdview diff CLAUDE.md.bak CLAUDE.md

Opens the desktop split-view window with the two files side-by-side and the git-diff overlay on by default. No flags in 1.0 — the subcommand exists to declare intent and to give us a stable place for --base COMMIT in 1.1+ if user demand surfaces.

Watch

mdview watch RELEASE.md
mdview watch .\docs\architecture.md

Opens the viewer with the file watcher active. The implicit viewer already watches files; mdview watch exists so scripts can declare the intent explicitly and so we have a stable place to add --no-open (1.1+) without changing default viewer behavior.

Show help and version

mdview --help
mdview export --help          # parent command help, lists pdf/docx
mdview export pdf --help      # subcommand-specific help
mdview --version

--help is context-sensitive: the parser shows top-level help if no subcommand precedes, and subcommand-specific help when one does.

Global flags

These work on every subcommand and on the implicit viewer.

ShortLongDescription
-h--helpShow help. Subcommand-specific if it follows a subcommand.
-v--versionPrint version and exit.
--quietSuppress non-error output.
-V--verboseVerbose stderr output (debug logging).
--no-colorDisable ANSI colors.

-v is bound to --version (the docker / git / hugo convention), not --verbose. -V (capital) is the documented short form for --verbose.

Path handling

MD View accepts paths in any of these forms without configuration:

FormExample
Windows nativeC:\Users\Ivan\file.md
Forward-slash WindowsC:/Users/Ivan/file.md
Relative./file.md, ..\docs\file.md
UNC\\server\share\file.md
UNC into WSL\\wsl$\Ubuntu\home\ivan\file.md
WSL /mnt/<letter>/ path/mnt/c/Users/Ivan/file.md

URL-encoded paths (file%20name.md) are rejected — they aren’t a Windows convention. Tilde expansion (~/notes/) happens in your shell before MD View sees it; if your shell doesn’t expand it, MD View treats ~ as a literal character.

WSL bash users

mdview.exe is a Windows binary. From WSL bash, call it by name and pass a Linux path under /mnt/<letter>/:

mdview.exe README.md                    # relative path resolves against CWD
mdview.exe /mnt/c/Users/Ivan/plan.md
git diff | mdview.exe

MD View translates /mnt/<letter>/... to <LETTER>:\... automatically. You don’t need wslpath -w. Other absolute Linux paths (e.g. /home/ivan/file.md) are rejected — use \\wsl$\<distro>\home\... or a /mnt/... path instead.

If you’d rather not type .exe, alias it in your shell config:

alias mdview='mdview.exe'

File extensions

The viewer and the export / verify / watch subcommands require FILE to end in one of:

.md  .markdown  .mdx  .mdown  .mkd

Anything else exits 1 with mdview: ERROR: not a markdown file: <path>. There is no --force flag — if you have markdown in a .txt, rename it or pipe it: cat notes.txt | mdview.

Stdin / stdout / stderr

StreamWhat goes there
stdinInput markdown (when piped, or with explicit -).
stdoutBinary export bytes when -o - is set; JSON when verify --json; --version text.
stderrAll errors, warnings, progress, info messages, and auto-displayed help (after misuse).

User-requested help (--help) goes to stdout — it’s data, you can pipe it into less. Auto-displayed help (after a flag mistake) goes to stderr so mdview some-command 2>/dev/null still pipes data correctly.

Exit codes

CI pipelines and shell scripts switch on these. The list is canonical and short.

CodeMeaning
0Success
1Generic failure: file not found, render error, parse error, Pandoc missing, etc.
2Misuse: bad flags, unknown subcommand, missing required argument
3Verification failed — mdview verify only; the file is valid markdown but failed configured checks
4License required — shell-invoked CLI without a valid license (after the trial expired)
5I/O error — permission denied, disk full, stdin requested but TTY, etc.

Which invocations exit 4

The MD View CLI is one of the six Pro features in v1. Any invocation that opens a document or workspace from the shell requires a valid license or an active 14-day trial. Specifically, the following exit 4 if the trial has expired and no license is present:

  • mdview FILE
  • mdview FOLDER / mdview .
  • mdview --stdin and mdview -
  • Auto-detected piping (cat foo.md | mdview)

The following always exit 0 regardless of license state — they’re informational or recovery paths and must work in Reader:

  • mdview --help
  • mdview --version
  • mdview --enter-license <path> (Phase 4 implements the import; v1 reserves the flag and exits 2 with a “not yet implemented” notice)

File-association invocations (double-clicking an .md from Explorer) go through the GUI binary directly and are not gated — Reader mode remains free for opening and reading files. The Pro gate is on the shell entry point only.

Single-instance behavior

mdview reuses a running primary process. The first invocation opens MD View; subsequent invocations route to the running window. This is the behavior you want for “double-click an .md and see it pop up in the same window each time.”

Error messages

Every error message follows one shape:

mdview: ERROR: <human-readable text>

Errors go to stderr. WARNING and INFO follow the same shape with the level swapped. The mdview: prefix makes piped stderr output clearly attributable.

See also