mdmini

A minimalist yet powerful markdown editor your agent can drive.

macOS free open source
$ brew tap malinborn/mdmini && brew trust malinborn/mdmini && brew install --cask mdmini
Or look at the source on GitHub →

Features

Everything a markdown file needs, nothing else.

Live Preview

Markdown renders inline as you type. No split pane, no preview toggle.

**fast** fast

GFM Tables

Create, edit, reorder, and delete table rows and columns. Drag to reorder.

item
qty
tag
flour
2
⋮⋮
eggs
6

Collapsible Headings

Click any heading to fold the section below it. Keeps long docs navigable.

Setup
Usage

Syntax-Highlighted Code

Fenced code blocks render with language-aware syntax highlighting.

let editor = "minimal";
fn render(md) { … }

Mermaid Diagrams

Flowcharts, sequence, class, Gantt, ER, pie, mindmap — all render inline as SVG. Pinch to zoom, swipe to pan around the big ones.

write md? ship

Secret Masking

Secret values in .env and shell configs (.zshrc, .bashrc) are masked by default. Cursor or Cmd+E to reveal.

API_KEY=•••••••• ⌘E

File Watching

External changes to open files are detected and reloaded automatically.

notes.md reloaded just now

CLI Launcher

Open files instantly from the terminal with mdmini file.md.

$ mdmini file.md

Dock Drop

Drag any file onto the Dock icon to open it. Works with multiple files at once.

a.md b.md

Session Restore

Reopen the windows you had last time with ⇧⌘T — files, positions, scroll, and unsaved drafts.

⇧⌘T 3 windows restored

Dark & Light Themes

Four themes: Rosé Pine dark and Rosé Pine Dawn, plus an Aurora light/dark pair that matches the app icon. Switch with a single keypress.

Rosé Pine Dawn Aurora Dark Aurora Light

Auto-Save & Recovery

Changes are saved continuously. Crash recovery restores your last session.

Saved · just now

Quick start

Install with Homebrew, open from anywhere, and register the MCP server once — your agent gets a local socket into the running app. No daemon, no cloud.

zsh — 80×16
$ brew tap malinborn/mdmini && brew trust malinborn/mdmini && brew install --cask mdmini
$ mdmini README.md # opens in a native macOS window
$ mdmini *.md notes/*.md # each file gets its own window
$ claude mcp add --scope user mdmini -- mdmini mcp # connect your AI agent — or use plain CLI verbs: mdmini show / edit / ask
$ brew update && brew upgrade --cask mdmini

After an upgrade, macOS asks for folder access again. mdmini is ad-hoc signed — no Apple Team ID — so macOS identifies it by a code hash that changes with every release, and the permission you granted belongs to what it now considers a different app. Signing and notarizing properly costs $99/year, which a free open-source tool is not going to carry. Grant it again and carry on.

Changelog

v1.2.0 2026-09-12 feature Type in Live Render without breaking it, and edit tables like a grid
  • Live Render survives being typed in — the mode hides the markers, which meant every edit that touched one silently damaged the file. Backspace past a bold word turned **bold word** into **bold word.; Enter inside it left two unpaired ** on separate lines; a space after it produced **bold **, which CommonMark refuses to close, so the asterisks stopped being markup and became four literal characters on screen. A repair layer now sits in front of the document and tells “the user is deleting this whole span” from “the pair just got torn” by the shape of the change, and writes the marker back before it ever reaches disk
  • Typing continues the format — the character after a bold word is bold, the way it is in every editor where you can see what you are doing. Esc or the format shortcut ends it. Option+arrows and Option+Backspace step over the hidden markers instead of stopping on them, so a “word” is a word you can see
  • The caret tells you the format — thicker for bold, slanted for italic, a narrow stem with a crossbar for strikethrough, serifs top and bottom for inline code, and they combine. With the asterisks hidden, the screen had nowhere left to say which format the next character carries, so the signal went to the one place the eye is already looking. It is right before the first character exists, too
  • Tables are editable, not just renderable — a click parks the caret in the cell it landed in. It used to jump to the table's first character, so the next keystroke landed in the wrong cell and wrecked the row. Cell text now selects, copies, takes bold/italic/code from the toolbar, and takes comments; the cell expands while you type instead of sliding under its neighbour
  • And navigable from the keyboardTab / ⇧Tab across columns, wrapping within the row; to the next row, and on the last row it leaves the table rather than dead-ending; ⇧↵ breaks a line inside the cell; ⌘↵ commits; ⌘⇧↵ adds a row. The beside the wrap toggle has the whole map, because a keyboard grid nobody is told about is a keyboard grid nobody uses
  • A comment you never have to send — the reply area is always editable and saves itself as you type, so a half-written thought survives a crash, a reload and the agent answering in the middle of it: the incoming answer freezes the previous turn without swallowing the sentence you are still writing. And the agent is no longer woken mid-phrase — 20 seconds of quiet first, with the countdown running inside the send button so you can cut it short
  • A comment lands where it was written — anchoring was indexOf(quote), the first occurrence from the top of the file, so a one-word quote or a heading that also appears in a table of contents put the card on a duplicate, usually far above, and reported a confident match while doing it. Threads are now anchored by the text around them. Measured over 20,962 cases generated from this repo's own markdown and then edited the way an agent edits a file: first occurrence 61.5%, context anchoring 100%
  • Saving stopped damaging the file — an atomic write is a temp file plus a rename, and rename keeps the directory entry while dropping everything that lives on the inode. Mode, owner, group, ACLs and extended attributes — quarantine included — are now copied onto the temp before it moves into place; editing through a symlink writes to what the link points at instead of replacing the link; and a save the filesystem refuses raises a toast rather than failing in silence. The atomicity itself is still there and now proven rather than asserted: a test really does SIGKILL the process mid-write and checks the file came back whole. Comment sidecars go through the same path, since they sit in the same protected, cloud-synced folders
  • JSON formatting stopped corrupting numbersJSON.stringify(JSON.parse(s)) is not a formatter, it is a re-serializer: every literal was destroyed and rebuilt from a JavaScript double. 12345678901234567890 came back as 12345678901234567000, 1e5 as 100000, 3.0 as 3. It now re-indents the text it was given, so number literals, string escapes, key order and duplicate keys survive byte for byte — and the result lands in a ```json fence when the file is markdown
  • Easier to read, in small places — six heading levels you can tell apart, each theme fading its own gradient down the scale. One indent step per list level whatever the marker: the parser was the culprit, not the CSS — Tab always inserted two spaces, and CommonMark nests a sub-item only once its marker reaches the parent's content column, which is 3 for 1. and 4 for 10., so an ordered sub-list never nested at all. Tab now indents every selected item, not just the first; folded sections stop hiding text in Raw mode; an AI edit highlights the regions that changed rather than everything between them; toolbar buttons name their shortcut; and [1] in prose keeps its brackets instead of being read as a link reference
v1.1.0 2026-08-24 feature Now you can ask it back — comments your agent answers
  • Comment on any text — select a fragment and press ⇧⌘M, or use the 💬 in Live Render's selection toolbar. The quoted words stay highlighted in the document, the card header carries an excerpt of them, and putting the caret in a commented fragment makes its cards shimmer — and the other way around. With several comments stacked under one paragraph, that is the difference between finding the right card and hunting for it
  • Your agent gets woken, not polledAI → Connect Agent to Doc Questions copies a prompt that arms a watcher over your project. With Claude Code's Monitor tool, a new comment interrupts the session that already has your context, the moment you send it. That is the whole design: nothing here spawns an agent or hands your question to one that knows nothing about the work
  • The answer comes back into the threadmdmini answer plan.md --id c-4f2a1b. If the comment asked for a change rather than an answer, insert into text folds it into the document — highlighted like any other AI edit, Escape to dismiss, ⌘Z to take it back. If it was just a question, resolve closes the thread
  • The comments live next to your file — in .mdmini_comments_<file>.md, plain markdown you can read, edit by hand and diff in git. md-mini never rewrites that file wholesale, only appends to it. So the feature works with the app closed, works for agents with no MCP, and needs no store of its own — md-mini is deliberately not the source of truth here
  • Git worktrees stop being a problem — comments sit beside the copy they were written on, so the agent watching that tree is the one that answers. No routing, no claims, no queue to divide between sessions
v1.0.1 2026-08-23 fix Now it installs on your Intel Mac, and tells you it speaks AI
  • Intel Macs are supported — the build is universal now, one download for both architectures. Previously brew install --cask mdmini simply refused on an Intel machine, and never said why. The culprit was a single arch-dependent type: Objective-C's BOOL is a bool on Apple Silicon and an i8 everywhere else, so one true literal compiled on one machine and broke the other
  • The AI interface is findable — 1.0 shipped it and then hid it. A toast on launch now says the editor can be driven by your agent, and a new Getting Started entry sits at the top of the AI menu. It leads with a map of that menu rather than a wall of setup, because the thing worth remembering is where this lives, not which command to type
  • It knows when to stop — the toast appears at most three times, once a day, never on the launch that already opened the welcome window, and never again once an agent has actually connected. The first time one does, md-mini says so — useful if someone handed you a config and you were wondering what just moved on screen
v1.0.0 2026-08-23 feature One point oh — now your agent can type too
  • An interface for AI agentsmdmini show file.md --line 42 scrolls a window to a spot and pulses it; cat new.md | mdmini edit file.md pushes content straight into the live buffer and highlights exactly what changed. No writing to disk and praying the watcher notices
  • Your agent can ask you thingsmdmini ask plants a real question with option buttons inside the document and blocks until you click. Checkboxes for multi-select, a free-text field when none of the options fit
  • Speaks MCP toomdmini mcp runs a stdio MCP server exposing the same three verbs as tools, so agents that prefer MCP need no shell glue. mdmini agent prints a ready-to-paste block for your CLAUDE.md
  • Live Render, in beta — an opt-in mode where markdown markers stay hidden even when the caret sits on them, Notion-style. It installs only while selected, so the live-preview mode you already trust is untouched by construction. View → Editor Engine → (beta) Live Render
  • Aurora themes — two new palettes, light and dark, alongside Rosé Pine. Five entries in the theme menu now, System included, and the caret picked up a gradient
  • A new app icon — and, at the last minute, a properly antialiased one: the first cut carried a baked drop shadow that ate a fifth of the canvas at 32px
  • A welcome window, once — on first launch after the upgrade md-mini opens a short document showing how to connect your agent, by CLI or by MCP. Close it and it stays closed
  • Fixed: external edits no longer jump you around — when a watched file is reloaded from disk, your scroll position and caret stay where you left them
  • Fixed: selecting across a diagram — dragging a selection over a mermaid block or a table no longer paints over the widget
  • New home — the site lives at md-mini.com; the old GitHub Pages address redirects
v0.5.1 2026-07-28 fix Close that update notice once
  • One notice, not one per window — dismissing the “new version available” toast now dismisses it everywhere instead of making you close it in every open window
  • It stays dismissed — neither the next hourly check nor a window you open afterwards brings it back. A genuinely newer version still shows up
  • One check per app, not per window — five windows used to mean five requests an hour for the same answer
v0.5.0 2026-07-28 feature Your windows come back
  • Reopen your last session — quitting no longer loses the windows you had open. A toast tells you how many are waiting; ⇧⌘T brings them back, or use File → Reopen Windows from Last Session
  • Everything comes back with them — file, window position and size, where the caret was, and how far you had scrolled
  • Unsaved drafts too — an Untitled window you never saved returns with its text intact, still marked dirty
  • Survives an upgrade — this is the point: brew upgrade --cask mdmini closes every window, and now you can get them back
  • Notifications stack — the update notice and the session offer sit above one another instead of overlapping, and each waits until you dismiss it
  • Fixed: scrolling a diagram-heavy file — reaching the end of a document full of mermaid diagrams and scrolling back up threw you straight down again. Diagrams no longer briefly lay out at full natural size, which was corrupting every scroll position on the page
v0.4.0 2026-07-25 feature Big diagrams, finally navigable
  • Pinch to zoom — two fingers on the trackpad zoom around the cursor; Cmd+scroll does the same for a mouse
  • Swipe to pan — a two-finger swipe moves around a zoomed diagram; at full view it scrolls the document exactly as before
  • Gestures that don’t yank the page — running into an edge mid-swipe springs back instead of throwing you down the document; lift your fingers and swipe again to scroll on
  • Back to full view — the button or a double-click refits; drag the bottom edge to resize the frame
  • Zoom sticks around — scrolling a diagram off screen, or editing text above it, no longer resets what you were looking at
v0.3.5 2026-06-16 fix Links that work inside tables
  • Markdown links in table cells[text](url) inside a cell now renders as a clickable link instead of raw brackets and parens
  • Anchor links scroll, not escape — in-cell [Back to top](#heading) jumps within the document; re-clicking the same anchor no longer leaks out to the system browser
  • Mixed inline formatting — links coexist with bold, italic, code and strikethrough in the same cell
v0.3.4 2026-06-05 feature Shell configs come alive
  • Syntax highlighting for shell configs.zshrc, .bashrc, .bash_profile, .profile and friends now render as Shell code instead of plain text
  • Inline secret masking — values in export API_KEY=…, TOKEN=… are masked to a sk-…jkl pill with a Copy button, while the key and the rest of the line stay highlighted
  • Reveal on demand — put the cursor on the line, or press Cmd+E, to see the raw value; shell expansions ($VAR, $(…)) are left untouched
v0.3.3 2026-06-04 fix TOC links that actually jump
  • In-document anchor links — clicking [Section](#section) now scrolls to the matching heading instead of doing nothing
  • Cyrillic & duplicates — percent-encoded and non-ASCII fragments resolve; duplicate headings disambiguate (#section-2)
  • Folded sections auto-expand — a collapsed parent heading opens before scrolling to the target
v0.3.2 2026-05-23 fix Ordered lists that count themselves
  • Tab restarts numbering — indenting a numbered item now opens a fresh sub-list starting at 1.
  • Shift-Tab renumbers the parent — outdenting back to the previous level keeps the surrounding numbers sequential
  • Works at any nesting depth — list continuation on Enter no longer breaks at the third level and beyond
v0.3.1 2026-05-23 feature Tables that fit your viewport
  • Auto-wrap by default — cells wrap their text to keep tables inside the editor width, no more sideways spillover
  • Per-table toggle (⇔) — release any single table to its natural width when you want the overflow back
  • Multi-line cells — double-click opens a growing textarea; Cmd+Enter to commit, Enter for a new line
  • Pipe & newline roundtrip| and line breaks inside cells survive a save/reload via \| and <br>
  • Stable column alignment — switched to native CSS table layout so columns no longer drift on edit
  • Cursor never gets stuck — arrow keys past a table snap to the next or previous visible line
v0.3.0 2026-05-23 fix Inline markdown inside headings
  • Code, bold, italic, strike, links inside headings — formatting now decorates correctly when used inside # H1###### H6
v0.2.2 2026-04-05 feature Line Glow & heading fold redesign
  • Line Glow — subtle gradient glow on active line, toggle via View menu
  • Fold toggle — ▾/▸ inline after headings with glow when folded
v0.2.1 2026-04-05 feature Heading fold toggle redesign
  • Inline fold toggle — ▾/▸ appears right after heading text, no layout shift
  • Glow indicator — folded sections show ▸ with subtle glow
v0.2.0 2026-04-05 feature Mermaid Diagrams
  • Live diagram preview```mermaid blocks render as inline SVG diagrams
  • All diagram types — flowcharts, sequence, class, state, ER, Gantt, pie, gitgraph, mindmap
  • Lazy-loaded — zero overhead for documents without diagrams
  • Hybrid errors — shows last valid diagram + error overlay while editing
  • Theme-aware — diagrams adapt to light/dark theme
v0.1.6 2026-04-03 fix Foreground windows
  • Windows open in foreground — new windows from CLI now appear on top via NSApp activate
v0.1.5 2026-04-02 feature File associations & smart windows
  • Dock file drop — drag files onto the Dock icon to open
  • File associations — macOS registers mdmini for .md, .txt, .json, .py, .rs, .yml, .toml, .sh
  • Smart window reuse — drag-drop and Dock drop open in empty windows
  • No white flash — dark background set before CSS loads
  • Cmd+Z safety — undo no longer clears content after file open
v0.1.4 2026-04-02 fix Text wrapping & table alignment
  • Text wrapping — long text wraps correctly even with wide tables
  • Gutter cleanup — removed gray bar, auto-hides on horizontal scroll
  • Table alignment — consistent column alignment across all rows
v0.1.3 2026-03-30 fix Update checks & theme fixes
  • Update banner — correct brew command with brew update prefix
  • Theme menu — single checkmark radio behavior
  • Hourly update checks while app is open
v0.1.0 2026-03-30 initial Initial release
  • Live preview — inline markdown rendering via CodeMirror 6 decorations
  • GFM tables — create, edit, reorder rows/columns, drag-drop
  • Collapsible headings — click to fold sections
  • Syntax highlighting — fenced code blocks with language detection
  • Secret masking.env values blurred by default
  • File watching — external edits reload automatically
  • CLI launchermdmini file.md via Homebrew tap
  • Themes — Rosé Pine dark & dawn
  • Auto-save & crash recovery

Full release history on GitHub →