Getting started with the MD Engine
This file is itself served by the engine. Open the engine folder with:
then visit http://localhost:8031/md/Guides/getting-started.md — what you're reading is the live render. The folder map is on the home page.mddash ~/Documents/md-engine
Local time, from the built-in widget:
1. The mental model
There are two separate things:
| Thing | Where it lives | What it is |
|---|---|---|
| The engine | ~/Documents/md-engine/ |
The server, default style.css, default widgets/ (just clock), node_modules, .venv. Install once, never copy again. |
| A content folder | anywhere on your laptop | Your .md notes, plus optional images/ and videos/. You can have as many as you want. |
The engine renders any content folder. You are never tied to one project.
(engine: server + css + widgets)"] A["~/Documents/AI_Learning"] P["~/Documents/Physics"] M["~/Documents/Music_Theory"] E --> A E --> P E --> M %% -- dashboard status styles -- classDef ok fill:#DCFCE7,stroke:#16A34A,stroke-width:1.5px,color:#052E16; classDef warn fill:#FEF9C3,stroke:#CA8A04,stroke-width:1.5px,color:#422006; classDef err fill:#FCE7EF,stroke:#DB2777,stroke-width:1.5px,color:#500724; classDef crit fill:#FEE2E2,stroke:#DC2626,stroke-width:1.5px,color:#450A0A; classDef off fill:#F1F5F9,stroke:#94A3B8,stroke-width:1.5px,color:#111827; classDef info fill:#EFF6FF,stroke:#3B82F6,stroke-width:1.5px,color:#0C1E3E;
2. The one command: mddash
No setup step. There is nothing to "render" or prepare first.
mddashis the render —cdinto any folder and run it, or pass a path. Done.
mddash # serve the folder you're standing in
mddash ~/Documents/Physics # serve a specific folder
mddash -p 8050 ~/Documents/Physics # use a different port
By default it auto-opens your browser. Pick which one (or turn it off):
mddash -b safari # open in Safari
mddash -b chrome # open in Chrome
mddash -b both # open in BOTH Safari and Chrome
mddash -n # don't open any browser
You can set a permanent default in ~/.zshrc: export MDDASH_BROWSER=both.
Then the page is at http://localhost:8031/ (or your -p port). Stop with Ctrl+C.
- The home page (
/) rendersindex.mdin the served folder. If there's noindex.md, the engine creates a starterai_notes.md. - Any other file is at
/md/<relative-path>.md, e.g. a note atchapters/intro.mdishttp://localhost:8031/md/chapters/intro.md. - Hot reload: save a
.md,style.css, or a widget — the page refreshes itself (~200 ms poll). No manual reload.
Only one server per port. To view two folders at once, give the second a different port:
mddash -p 8032 ~/Documents/Physics.
3. A good folder layout
Nothing is required except your .md files, but this scales well:
~/Documents/Physics/
index.md ← the home page (start here)
mechanics.md
thermodynamics.md
images/ ← put pictures here -> 
videos/ ← put clips here -> served at /videos/clip.mp4
style.css ← OPTIONAL: overrides the engine's look for THIS folder
widgets/ ← OPTIONAL: extra Python widgets for THIS folder
The override rule (important)
For style.css and widgets/, the engine checks the served folder first,
and falls back to its own defaults:
- No
style.cssin the folder → uses the engine's global stylesheet. - A
style.cssin the folder → that folder looks however you want, without touching any other folder. - Same for
widgets/: the global default is onlyclock; drop awidgets/mything.pyinto a folder to add widgets just for that folder.
4. What you can write in a note
Math (KaTeX)
Inline $E = mc^2$ and display:
$$ \int_{0}^{\infty} e^{-x}\,dx = 1 \qquad \nabla \cdot \mathbf{E} = \frac{\rho}{\varepsilon_0} $$
Tables, code, task lists
def greet(name):
return f"hello {name}"
- Math renders
- Diagrams render
- Write tomorrow's notes
Diagrams (Mermaid)
Images and videos
Drop files into the folder's images/ and videos/, then reference them:

The clock widget
Type {{ clock }} or {{ clock: My label }} anywhere — it updates every second.
This is the only widget shipped globally; add your own per folder (Section 6).
Captions & cross-references
<div id="setup" class="caption-box caption-figure" markdown="1">
<div class="caption-content" markdown="1">

</div>
<div class="caption-title"><span class="caption-label">Figure</span>: Lab setup</div>
</div>
Then reference it elsewhere with @fig-setup and it becomes a numbered link.
5. A typical workflow
- Make a folder:
mkdir ~/Documents/Physics && cd ~/Documents/Physics - Create
index.md, start writing. - Run
mddash(from inside the folder) → open the browser. - Keep the browser open; every save hot-reloads.
- Next topic? New folder, repeat. Same engine, zero setup.
Tip: add
images/andvideos/subfolders up front so links just work.
6. Adding your own widget (optional)
A widget is a tiny Python file. Put it in that folder's widgets/ so it
stays local (the global engine deliberately ships only clock).
~/Documents/Physics/widgets/today.py:
from datetime import date
def render(context=None, argument=None):
label = (argument or "Today").strip()
return f'<div class="py-widget"><b>{label}:</b> {date.today():%A, %d %B %Y}</div>'
Use it in a note with {{ today }} or {{ today: Date }}.
- The function signature is
render(context=None, argument=None) -> str(HTML). argumentis whatever follows the colon in{{ name: argument }}.- Emit flush-left HTML (no leading indentation) or Markdown will treat it as a code block.
7. Always-on server (disabled on this Mac)
Currently off. The LaunchAgent below is disabled — nothing runs until you open a file, and each server serves one folder. The always-on copy of the engine that is running lives on the Raspberry Pi; see PI-GUIDE.md.
It would run automatically when you log in and serve a folder on http://localhost:8031/ — no browser pop-up, restarting itself if it crashes. It is a macOS LaunchAgent at:
~/Library/LaunchAgents/com.mddash.server.plist
Manage it:
launchctl list | grep mddash # running? (PID exit-code label)
launchctl unload ~/Library/LaunchAgents/com.mddash.server.plist # stop
launchctl load ~/Library/LaunchAgents/com.mddash.server.plist # start
tail ~/Documents/md-engine/mddash.log # see its output (only written while it runs)
To change the folder it serves at boot, edit the folder path in the <array>
of that plist, then unload + load.
If you re-enable it, the boot server holds port 8031, so run ad-hoc folders on another port:
mddash -p 8032 ~/Documents/Physics.
8. Quick reference
| Task | How |
|---|---|
| Serve current folder | mddash |
| Serve a specific folder | mddash ~/path/to/folder |
| Different port | mddash -p 8050 ~/path |
| Open in Safari / Chrome / both | mddash -b safari · -b chrome · -b both |
| Don't auto-open a browser | mddash -n |
| Home page | http://localhost:8031/ → renders index.md |
| Open any note | http://localhost:8031/md/<relative-path>.md |
| Stop the server | Ctrl+C |
| Restyle one folder | add style.css to that folder |
| Add a widget to one folder | add widgets/<name>.py to that folder |
| Always-on server | LaunchAgent com.mddash.server — disabled, see §7 |
| Where the engine lives | ~/Documents/md-engine/ |
Engine home: ~/Documents/md-engine/ · Launcher: ~/.local/bin/mddash · Boot agent: com.mddash.server (disabled — see §7)