Review a markdown document in your browser and send the verdict straight back to your Claude Code session.
mdview renders a markdown file as a clean web page with Approve and Request changes
buttons pinned to the bottom. Click one, and your decision (and any comment) is reported back
to the waiting Claude Code session — no switching to the terminal to type a reply. Beneath them
sits a scrollable row of curated command buttons — one-click follow-ups like review with a
subagent or verify against the codebase — so you can direct the agent's next step, not just
approve or reject.
It's a single, self-contained, cross-platform Go binary (macOS / Linux / Windows) with no runtime dependencies — the renderer, styles, and diagram support are all baked in.
When an agent wants you to review something it wrote — a spec, a plan, a design doc — the
usual flow is "open this file, then tell me what you think." That means leaving the rendered
view, switching windows, and typing. mdview collapses that into one place: you read the
rendered doc and decide in the same page, and the answer lands back in the session
instantly.
Request changes opens a comment box, and your note comes back with the verdict:
mdview file.mdrenders the doc and serves it on a random127.0.0.1port (localhost only), then opens your browser to it.- It blocks, waiting for you to decide. Run it as a background command and the wait is unbounded — decide in 5 seconds or 40 minutes, it doesn't matter.
- When you click a button, the page POSTs your verdict to the local server, which prints one
line and exits:
MDVIEW_VERDICT {"verdict":"approve"}MDVIEW_VERDICT {"verdict":"changes","comment":"…"}MDVIEW_VERDICT {"verdict":"command","command":"…","prompt":"…"}(you clicked a curated command button)MDVIEW_VERDICT {"verdict":"dismissed"}(you closed the tab without deciding)
Because the binary exits the instant you click, the Claude Code session is notified on
exit — it's woken by your click, not by polling. Closing the tab, or walking away, resolves
cleanly to dismissed so a session never hangs forever.
The page follows your system light/dark theme, and fenced ```mermaid blocks render as
diagrams.
Beneath Approve / Request-changes, the review page shows a scrollable strip of curated command buttons — one-click shortcuts for the follow-ups you'd otherwise type ("review this with a subagent", "verify it against the codebase", "stress-test it"). Clicking one ends the round and hands its instruction back to the agent, which acts on it:
MDVIEW_VERDICT {"verdict":"command","command":"verify-against-codebase","prompt":"Verify this against the actual codebase …"}
A built-in set ships by default; an agent can tailor the buttons to the document it's showing
you — and highlight the one or two it most recommends (a gold ✦ sparkle pill) — by passing
MDVIEW_COMMANDS (see Manual CLI below). They're suggestions, never
auto-actions: nothing runs until you click.
/plugin marketplace add claude-code-tools/mdview-review
/plugin install mdview-review
The bundled skill downloads and checksum-verifies the matching release binary on first use, then the agent reaches for it whenever it wants you to review a markdown document.
brew install claude-code-tools/tap/mdview
Grab the binary for your platform from the
latest release (or
go install github.com/claude-code-tools/mdview-review@latest), then:
mdview path/to/file.md # review in the browser, wait for the verdict (default)
mdview --view file.md # overview/FYI: render + open, return immediately (no buttons, no wait)
mdview --print file.md # render the self-contained HTML to stdout (no server, no browser)
mdview --versionEnvironment overrides: MDVIEW_BROWSER (or the standard BROWSER) to force a specific
browser, e.g. MDVIEW_BROWSER="open -a Safari"; MDVIEW_NO_CLIENT_SECONDS (default 60) and
MDVIEW_MAX_LIFETIME_SECONDS (default 7200) tune the review-mode timeouts. For agent
integrations: MDVIEW_KEY enables a persistent per-key browser tab across review rounds;
MDVIEW_OWNER_PID makes the server exit when that pid dies; mdview --stop (with the same
MDVIEW_KEY) definitively tears the server down. MDVIEW_STATE_DIR overrides where the
per-key rendezvous files live. On a keyed re-run, mdview reuses the already-open tab (it
reloads itself) instead of opening a new one; MDVIEW_OPEN_GRACE_SECONDS (default 1) is how
long it waits for that tab to reconnect before opening a fresh one.
MDVIEW_COMMANDS (review mode) sets the curated command buttons shown beneath Approve /
Request-changes — a JSON array of {id,label,prompt,recommended?} that replaces the built-in
set ([] disables the strip). Clicking one returns MDVIEW_VERDICT {"verdict":"command",...}
to the caller; the agent acts on the button's prompt.
- Binds
127.0.0.1only — never reachable off your machine. - A random per-run token gates the verdict endpoint, so nothing else on your machine can inject a decision.
- No network access at render time — all assets are embedded in the binary.
git clone https://github.com/claude-code-tools/mdview-review
cd mdview-review
go build -o mdview .
go test ./...The version is pinned in two places (plugin.json and the skill's binary path).
scripts/release.sh bumps both, commits, tags, and pushes in one step:
scripts/release.sh 0.1.3 # bump, tag v0.1.3, push (cuts the release)
scripts/release.sh 0.1.3 --no-push # commit + tag locally onlyPushing the tag triggers .github/workflows/release.yml, which cross-compiles all
platforms, publishes the GitHub Release with SHA256SUMS, then regenerates the
Homebrew formula from .github/mdview.rb.tmpl and pushes it to
claude-code-tools/homebrew-tap. Nothing else is edited by hand.
MIT — see LICENSE.

