CLI Reference

mkdnsite ships with a CLI that covers every configuration option. All flags map directly to fields in mkdnsite.config.ts — the two are equivalent and can be combined.

Usage

mkdnsite [directory] [options]
# Basic usage
mkdnsite ./content

# With config file
mkdnsite --config mysite.config.ts

# Mix config file and CLI overrides
mkdnsite --config mysite.config.ts --color-scheme dark --port 4000

Config file

FlagDescription
--config <path>Path to config file (default: auto-detects mkdnsite.config.ts in cwd)

When a config file is found, CLI flags override its values. This lets you use the config file for stable settings and override specific values for testing.

# Force dark mode on a light-mode site
mkdnsite --config docs.config.ts --color-scheme dark

Content

FlagTypeDefaultDescription
[directory]positional./contentPath to directory containing .md files
--static <dir>pathDirectory for static assets (images, CSS, fonts)
--include <pattern>globOnly serve files matching this pattern (repeatable)
--exclude <pattern>globSkip files matching this pattern (repeatable)
mkdnsite ./docs --static ./public

Static assets are served at the root: ./public/logo.png/logo.png.

Non-filesystem deployments (Cloudflare Workers, Vercel Edge, etc.) cannot use --static / staticDir because the filesystem is unavailable. Use the programmatic staticHandler option in createHandler() instead — see configuration reference.

Filtering content with --include / --exclude

Use these flags to control which .md files are served. They are mutually exclusive — use one or the other.

# Only serve files under docs/ and guides/
mkdnsite --include 'docs/**' --include 'guides/**'

# Exclude draft files and a private directory
mkdnsite --exclude '**/*.draft.md' --exclude 'private/**'

Patterns use picomatch glob syntax and are matched against paths relative to the content directory. These options map to the include and exclude config file keys.

Server

FlagShortDefaultDescription
--port <n>-p3000Port to listen on
mkdnsite -p 8080
mkdnsite --port 4000

Site metadata

FlagDescription
--title <text>Site title (shown in <title> as Page — Site)
--url <url>Base URL for absolute links
--favicon <path>Favicon path or URL (.ico, .png, .svg)
mkdnsite --title "My Docs" --url "https://docs.example.com"

OpenGraph / social meta tags

Controls the og:* and twitter:* meta tags for rich preview cards in Slack, Discord, iMessage, and social platforms.

FlagDescription
--og-image <url>Default OpenGraph image URL
--og-type <type>Default OpenGraph type (website or article)
--twitter-card <type>Twitter card type: summary or summary_large_image
--twitter-site <handle>Twitter @handle for the site
mkdnsite ./content \
  --url "https://docs.example.com" \
  --og-image "https://docs.example.com/og-image.png" \
  --twitter-card summary_large_image \
  --twitter-site "@myproject"

Individual pages can override og:image and og:type via frontmatter (og_image, og_type). See Frontmatter.

Theme

Color scheme

FlagValuesDefaultDescription
--color-scheme <val>system, light, darksystemColor scheme
mkdnsite --color-scheme dark    # always dark
mkdnsite --color-scheme light   # always light
mkdnsite --color-scheme system  # follow OS (default)

Theme mode

FlagValuesDescription
--theme-mode <mode>prose, componentsRendering mode

prose uses the built-in shadcn/Radix-inspired typography. components expects you to provide your own React component overrides.

Colors

FlagDescription
--accent <color>Accent color (links, active nav, focus rings). Any CSS color value.
mkdnsite --accent "#7c3aed"
mkdnsite --accent "oklch(0.5 0.2 270)"

This sets theme.colors.accent. For full color control, use a config file with the colors and colorsDark objects. See Theming.

Fonts

FlagDescription
--font-body <family>Body/prose font stack
--font-mono <family>Monospace font stack
--font-heading <family>Heading font stack
mkdnsite --font-heading '"Playfair Display", serif' \
         --font-body '"Inter", sans-serif'

Quote the value if it contains spaces. For Google Fonts, combine with --custom-css-url:

mkdnsite \
  --custom-css-url "https://fonts.googleapis.com/css2?family=Inter:wght@400;600&display=swap" \
  --font-body '"Inter", sans-serif'
FlagDescription
--logo <url-path>Logo image URL path, e.g. /logo.svg (served from --static dir)
--logo-text <text>Site name displayed next to logo in nav header
mkdnsite --static ./static --logo /logo.png --logo-text "My Docs"

The logo src is a URL path, not a filesystem path. The file should be in your --static directory.

Custom CSS

FlagDescription
--custom-css <css>Inline CSS string appended after built-in styles
--custom-css-url <url>External stylesheet URL loaded via <link rel="stylesheet">
--no-builtin-cssStrip all built-in CSS (start from blank slate)
# Quick tweak via inline CSS
mkdnsite --custom-css ".mkdn-main { max-width: 1000px; }"

# Load a custom theme file
mkdnsite --static ./static --custom-css-url /my-theme.css

# Full replacement
mkdnsite --no-builtin-css --custom-css-url /my-complete-theme.css

mkdnsite mcp — stdio MCP server

Run mkdnsite as a standalone MCP server over stdio, without starting a web server. Use this to connect AI clients like Claude Desktop directly to your documentation.

# Local content directory
mkdnsite mcp ./content

# GitHub repository
mkdnsite mcp --github owner/repo

# GitHub repo with specific branch and subdirectory
mkdnsite mcp --github owner/repo --github-ref v2.0 --github-path docs

# Use a config file
mkdnsite mcp --config my-docs.config.ts

All the same content source flags work (--github, --github-ref, --github-path, --github-token, positional directory argument).

Claude Desktop configuration

Add to claude_desktop_config.json:

{
  "mcpServers": {
    "my-docs": {
      "command": "mkdnsite",
      "args": ["mcp", "./path/to/content"]
    }
  }
}

For a GitHub-hosted repo:

{
  "mcpServers": {
    "mkdnsite-docs": {
      "command": "mkdnsite",
      "args": ["mcp", "--github", "mkdnsite/mkdnsite"]
    }
  }
}

MCP server

Controls the built-in MCP (Model Context Protocol) server (HTTP endpoint).

FlagDescription
--no-mcpDisable the built-in MCP server
--mcp-endpoint <path>Custom MCP endpoint path (default: /mcp)
# Disable MCP (e.g. public-facing site)
mkdnsite --no-mcp

# Custom endpoint path
mkdnsite --mcp-endpoint /api/mcp

GitHub source

Serve content from a public GitHub repository instead of a local directory.

FlagDescription
--github <owner/repo>Serve a GitHub repo, e.g. --github mkdnsite/mkdnsite
--github-ref <ref>Branch, tag, or commit SHA (default: main)
--github-path <path>Subdirectory within the repo to use as content root
--github-token <token>GitHub token for private repos or higher rate limits. Also reads GITHUB_TOKEN or MKDNSITE_GITHUB_TOKEN env var.
# Serve a public repo from main branch
mkdnsite --github owner/repo

# Serve a specific branch and subdirectory
mkdnsite --github owner/repo --github-ref develop --github-path docs

# Use a token for private repos or to avoid rate limits
mkdnsite --github myorg/private-docs --github-token ghp_xxx

# Or set the env var (no need for --github-token)
GITHUB_TOKEN=ghp_xxx mkdnsite --github myorg/private-docs

Content is cached for 5 minutes. File listing uses the GitHub Git Trees API (one call per cache window); file contents come from raw.githubusercontent.com. Unauthenticated requests are limited to 60 API calls/hour; a token raises this to 5,000.

Presets

Apply a preset to configure sensible defaults for a common use case. User values always override the preset.

FlagDescription
--preset <name>Apply preset: docs or blog
mkdnsite --preset docs ./content   # nav + TOC + prev/next links
mkdnsite --preset blog ./posts     # page title, date, reading time, prev/next

See Configuration — preset for full details.

Page metadata

Controls how frontmatter values are displayed in the rendered page.

FlagDescription
--page-titleRender frontmatter title as <h1> above article content
--no-page-titleDisable page title rendering
--page-dateRender date/updated from frontmatter below the page title
--no-page-dateDisable page date rendering
--reading-timeShow estimated reading time (calculated at 238 wpm)
--no-reading-timeDisable reading time display
--prev-nextShow prev/next page navigation links at the bottom of the article
--no-prev-nextDisable prev/next navigation
--no-tocDisable the table of contents sidebar
# Manual blog setup without a preset
mkdnsite ./posts \
  --page-title \
  --page-date \
  --reading-time \
  --prev-next \
  --no-nav \
  --no-toc

Navigation

FlagDescription
--no-navDisable the navigation sidebar
--no-tocDisable the table of contents sidebar
--no-footerHide "Powered by mkdnsite" footer
mkdnsite --no-nav   # single-page or minimal sites
mkdnsite --no-toc   # disable TOC without disabling nav

Content negotiation

FlagDescription
--no-negotiateDisable Markdown serving via Accept: text/markdown
--no-llms-txtDisable /llms.txt generation
# Public site where you don't want to expose raw Markdown
mkdnsite --no-negotiate --no-llms-txt

Client-side features

FlagDescription
--no-client-jsDisable all client-side JavaScript (pure static HTML/CSS)
--no-theme-toggleDisable the light/dark toggle button
--no-mathDisable KaTeX math rendering
--no-searchDisable the ⌘K search modal and /api/search endpoint
--no-chartsDisable Chart.js chart rendering
--syntax-highlight <mode>Syntax highlighting: client (default), server (Shiki SSR), or false
--no-syntax-highlightDisable syntax highlighting entirely
# Maximum performance / accessibility
mkdnsite --no-client-js

# Keep mermaid and copy but remove theme toggle
mkdnsite --no-theme-toggle

# Disable search (e.g. public-facing site without search UI)
mkdnsite --no-search

Note: --no-client-js disables everything including Mermaid diagrams, copy buttons, and the theme toggle. For granular control, use individual flags.

Analytics

FlagDescription
--ga-measurement-id <id>Google Analytics 4 measurement ID (e.g. G-XXXXXXXXXX)
--traffic-analyticsEnable server-side traffic analytics
--traffic-consoleLog traffic events as JSON lines to stdout
# Add Google Analytics
mkdnsite --ga-measurement-id G-XXXXXXXXXX

# Debug traffic classification locally
mkdnsite --traffic-analytics --traffic-console

Caching

FlagDescription
--cacheEnable in-memory response caching (default: off)
--no-cacheDisable response caching
--cache-max-age <seconds>Cache-Control max-age for HTML (default: 300)
--cache-max-age-markdown <seconds>Cache-Control max-age for markdown (default: 300)
--cache-swr <seconds>stale-while-revalidate seconds (default: 0, meaning omitted)
--cache-version <tag>Version tag for ETag header (e.g. v1.0.0 or git SHA)
# Enable caching with custom TTL
mkdnsite --cache --cache-max-age 600

# Cache with stale-while-revalidate for CDN
mkdnsite --cache --cache-max-age 300 --cache-swr 60 --cache-version v1.4.1

Security

FlagDescription
--no-cspDisable the Content-Security-Policy header

The CSP header is enabled by default on all HTML responses. Use --no-csp to disable it, or configure additional allowed sources via the config file (see Configuration — csp).

Renderer

FlagValuesDescription
--renderer <engine>portable, bun-nativeMarkdown rendering engine
mkdnsite --renderer bun-native   # Bun only, faster but no full GFM support
mkdnsite --renderer portable     # works everywhere, full GFM support (default)

Help and version

mkdnsite --help     # show all flags
mkdnsite -h

mkdnsite --version  # show version
mkdnsite -v

Common patterns

Blog with reading time and date

mkdnsite ./posts --preset blog --title "My Blog"

Local docs site with full branding

mkdnsite ./content \
  --static ./static \
  --logo /logo.svg \
  --logo-text "My Project" \
  --accent "#0ea5e9" \
  --title "My Project Docs"

Private/internal site (no AI exposure)

mkdnsite ./content \
  --no-negotiate \
  --no-llms-txt \
  --title "Internal Docs"

Performance-optimized static output

mkdnsite ./content \
  --no-client-js \
  --color-scheme light

Development with a named config file

# Use a project-specific config
mkdnsite --config docs.config.ts

# Override color scheme for testing
mkdnsite --config docs.config.ts --color-scheme dark

Config parity

Every CLI flag maps to a field in mkdnsite.config.ts. CLI flags take precedence over the config file. This table shows the mapping:

CLI flagConfig field
[directory]contentDir
--config(CLI only)
--portserver.port
--titlesite.title
--urlsite.url
--og-imagesite.og.image
--og-typesite.og.type
--twitter-cardsite.og.twitterCard
--twitter-sitesite.og.twitterSite
--staticstaticDir
--color-schemetheme.colorScheme
--theme-modetheme.mode
--accenttheme.colors.accent
--logotheme.logo.src
--logo-texttheme.logoText
--custom-csstheme.customCss
--custom-css-urltheme.customCssUrl
--no-builtin-csstheme.builtinCss: false
--font-bodytheme.fonts.body
--font-monotheme.fonts.mono
--font-headingtheme.fonts.heading
--no-mcpmcp.enabled
--mcp-endpointmcp.endpoint
--githubgithub.owner + github.repo
--github-refgithub.ref
--github-pathgithub.path
--github-tokengithub.token
--presetpreset
--page-titletheme.pageTitle: true
--no-page-titletheme.pageTitle: false
--page-datetheme.pageDate: true
--no-page-datetheme.pageDate: false
--prev-nexttheme.prevNext: true
--no-prev-nexttheme.prevNext: false
--reading-timetheme.readingTime: true
--no-reading-timetheme.readingTime: false
--no-toctheme.showToc: false
--no-navtheme.showNav: false
--no-negotiatenegotiation.enabled: false
--no-llms-txtllmsTxt.enabled: false
--rendererrenderer
--no-client-jsclient.enabled: false
--no-theme-toggleclient.themeToggle: false
--no-mathclient.math: false
--no-searchclient.search: false
--no-chartsclient.charts: false
--syntax-highlightclient.syntaxHighlight
--no-syntax-highlightclient.syntaxHighlight: false
--faviconsite.favicon.src
--no-footertheme.showFooter: false
--ga-measurement-idanalytics.googleAnalytics.measurementId
--traffic-analyticsanalytics.traffic.enabled: true
--traffic-consoleanalytics.traffic.console: true
--cachecache.enabled: true
--no-cachecache.enabled: false
--cache-max-agecache.maxAge
--cache-max-age-markdowncache.maxAgeMarkdown
--cache-swrcache.staleWhileRevalidate
--cache-versioncache.versionTag
--no-cspcsp.enabled: false