mdhub-cli
v0.1.0
Published
Local web hub for browsing, navigating, and editing every markdown file in your repo — with a GSD-aware view for Claude Code users
Maintainers
Readme
mdhub
A zero-dependency local web hub for every markdown file in your repo. Built for engineers who live inside Claude Code (or any AI coding assistant) and want a fast, opinionated way to read, navigate, and edit the planning artifacts those tools generate — plus all the other markdown lying around the project.
cd ~/codes/my-project
mdhub
# opens http://127.0.0.1:4444 in your browserWhat it does
- Discovers every
.mdfile in the repo —.planning/,docs/,CLAUDE.md,AGENTS.md, READMEs, code-adjacent docs, design system reference, anything. - Four navigation lenses over the same data — GSD planning view, auto-categorized buckets, raw folder tree, flat list.
- In-doc navigation — clickable TOC outline with scroll-spy, in-app relative
.mdlink routing, anchored URLs. - Live updates — file changes on disk propagate to the browser via SSE, no refresh needed.
- In-browser editing — toggle to edit mode, save with
Cmd-S, mtime-conflict-safe (no silent clobbers). - Claude Code helpers — copy
@path/to/fileto clipboard, hover any heading to copy a section block with path prefix, pin frequently-referenced files, view a phase's PLAN ↔ SUMMARY in one click. - TODO aggregator — every
- [ ]in the repo, grouped by file. Check/uncheck writes back through the editor pipe. - Git status decoration — colored dot next to modified / untracked / staged markdown files.
- Search —
/opens a palette with substring search across every markdown file. - Mermaid + syntax highlighting for code blocks, with per-block copy buttons.
Hard constraints
- Markdown files only. Not a general file browser, not a code viewer. Only
*.md(no.mdx, no.markdown). - Local only. Binds to
127.0.0.1. No auth, no telemetry, no remote use. - Zero npm runtime dependencies on the server. Pure Node
http. Client-sidemarked,mermaid, andhighlight.jslazy-load from CDN. - No build step.
node bin/mdhub.jsworks straight from a fresh checkout. - Node ≥ 18.
Install
npm install -g mdhub-cli
mdhub /path/to/repo # or just `mdhub` from inside the repoThe npm package is mdhub-cli; the binary it installs is mdhub (the unprefixed name was already taken on npm by an unrelated micro-frontend library).
One-off without install:
npx mdhub-cli /path/to/repoOr from source:
git clone <repo-url> mdhub
cd mdhub
node bin/mdhub.js /path/to/repoCLI
mdhub [path] Serve the repo at [path] (default: cwd)
mdhub --port 5000 Custom port (default: 4444; auto-walks up to +30 on conflict)
mdhub --no-open Don't auto-open browser
mdhub --help Show help
Env:
MDHUB_PORT=4444 Same as --port
MDHUB_EDITOR=$VISUAL Used by "open in editor"; falls back to $VISUAL, $EDITOR, then `code`Keyboard shortcuts
| Key | Action |
|---|---|
| / | Open search palette |
| e | Toggle edit mode on the current file |
| Esc | Exit edit mode (or close search) |
| Cmd/Ctrl-S | Save (in edit mode) |
| Cmd/Ctrl-B | Wrap selection in **bold** |
| Cmd/Ctrl-I | Wrap selection in *italic* |
| Cmd/Ctrl-K | Wrap selection as a markdown link |
| Tab / Shift-Tab | Indent / dedent (4-space) in textarea |
Architecture
Pure-Node HTTP server in src/:
src/server.js routes, lifecycle, SSE bus
src/scanner.js filesystem walk → four view structures
src/classifier.js filename → doc-type, path → category
src/phase-status.js phase progress inference from filenames
src/todos.js checkbox extraction + toggle
src/git.js best-effort git status decoration
src/watcher.js fs.watch + polling fallback, debounced
src/search.js substring search across markdownVanilla-ES-modules frontend in public/:
public/index.html layout shell
public/styles.css dark + light themes via CSS custom properties
public/app.js router, sidebar, state
public/render.js marked + mermaid + hljs + link rewriting
public/outline.js TOC + IntersectionObserver scroll-spy
public/editor.js textarea editor + save flowAPI
| Method | Path | Purpose |
|---|---|---|
| GET | /api/repo | { name, root, hasPlanning, totalMarkdown } |
| GET | /api/tree | All four view structures |
| GET | /api/file?path= | Markdown content + mtime/size (5MB cap) |
| PUT | /api/file | Save markdown (409 on mtime conflict) |
| GET | /api/raw?path= | Image asset embedded in markdown |
| GET | /api/activity?limit= | Recent files by mtime |
| GET | /api/phase-status | Phase progress inference |
| GET | /api/todos | All - [ ] items grouped by file |
| POST | /api/todo-toggle | Toggle a specific checkbox |
| GET | /api/git-status | Modified/staged/untracked .md |
| GET | /api/search?q=&type= | Substring search |
| POST | /api/open-in-editor | Shell $VISUAL/$EDITOR/code |
| GET | /api/events | SSE change stream |
All path-taking endpoints validate through safeResolve() and return 400 on traversal.
Why "mdhub"
It's a hub for all the markdown in your repo. GSD is one lens, not the product.
License
MIT.
