Quick start Features Configuration Install Licensing GitHub Get started

Getting Started

This guide takes you from an empty terminal to a running documentation site, then connects an AI agent to the same content. You need a folder of Markdown files and a minute or two.


Install

The install script works on Linux and macOS, on amd64 and arm64:

curl -fsSL https://raw.githubusercontent.com/monolithiclab/gomddoc/main/scripts/install.sh | sh

It downloads the release archive for your platform, checks it against the release SHA256SUMS, and installs the binary to /usr/local/bin. It uses sudo when that directory isn't writable, and falls back to ~/.local/bin when sudo isn't available.

If cosign is on your PATH, the script also verifies the signature over SHA256SUMS before trusting it. Install cosign first if you want a provenance check, since the checksum file comes from the same origin as the archive. Three environment variables adjust the install:

Variable Effect
GOMDDOC_VERSION Install a specific release instead of the latest
GOMDDOC_INSTALL_DIR Install somewhere other than /usr/local/bin
GOMDDOC_REQUIRE_COSIGN=1 Abort when cosign is not installed, instead of warning and continuing
curl -fsSL https://raw.githubusercontent.com/monolithiclab/gomddoc/main/scripts/install.sh \
  | GOMDDOC_VERSION=0.1.3 GOMDDOC_INSTALL_DIR="$HOME/bin" sh

Other ways to install

# Homebrew (macOS and Linux)
brew install monolithiclab/tap/gomddoc

# Go toolchain
go install github.com/monolithiclab/gomddoc/cmd/gomddoc@latest

The Docker image needs no install at all. Its entrypoint is the bare binary, so always pass a subcommand:

docker run --rm -p 8080:8080 -v "$PWD:/site" ghcr.io/monolithiclab/gomddoc serve /site

Release archives, signature verification and the container tags are covered in installation options.


Preview your docs

Run preview in any directory that contains Markdown:

gomddoc preview --open ./docs

gomddoc picks the first free port from 8080, prints the URL, and opens it in your browser. Leave the directory out to serve the current one.

If you don't have docs handy, make a two-page site first:

mkdir my-docs
printf '# My Project\n\nWelcome to the docs.\n' > my-docs/README.md
printf '# Install\n\nRun the installer.\n' > my-docs/install.md
gomddoc preview --open my-docs

What you get

The page in your browser has a sidebar built from your folders, breadcrumbs, a table of contents for the current page, syntax-highlighted code, and a light/dark toggle. Press Ctrl+K (Cmd+K on macOS) to search every page. None of it needs a config file.

Edit and refresh

Edits to the body of an existing page show up when you refresh the browser. The navigation tree, search index, tag index and URL map are built once at startup, so restart preview when you add, rename or delete a file, change a page's title or tags, or edit .gomddoc/config.yml.

Review with notes

Select any passage on a page and click the pen in the margin to attach a note. The Annotations button in the header copies every note of the page as Markdown that names the source file, so you can paste your review into an AI coding agent and let it revise the file. Notes are kept in your browser only.


How files map to URLs

Your folder structure is the site structure. Each README.md is its directory's index page, and the .md extension is dropped from URLs:

File URL
README.md /
install.md /install
api/README.md /api/
api/endpoints.md /api/endpoints
images/logo.png /images/logo.png

A request for /install.md gets a 301 redirect to /install, so links written with the extension keep working. Page titles come from the frontmatter title, then the first # heading, then the file name. Dotfiles and directories such as .git/ are never served.


Connect an AI agent

The same folder is available to AI agents over the Model Context Protocol. Add gomddoc to your MCP client's configuration, for example .mcp.json for Claude Code or claude_desktop_config.json for Claude Desktop:

{
  "mcpServers": {
    "docs": {
      "command": "gomddoc",
      "args": ["mcp", "/absolute/path/to/docs"]
    }
  }
}

The client starts gomddoc mcp as a subprocess and talks to it over stdio. The agent can then search your docs, read a page or a single section, list pages by tag, and walk the navigation tree. Every tool is read-only.

A running serve or preview instance also answers MCP over HTTP at /_mcp/, for clients that connect to a URL instead of launching a process. Any HTTP client can also fetch a page's Markdown source directly:

curl -H "Accept: text/markdown" http://localhost:8080/install

Features lists every tool, resource and prompt.


Serve a Git repository

serve, preview, build, mcp and doctor all accept a Git URL in place of a directory. gomddoc makes a shallow clone of one branch at startup and serves that commit:

gomddoc serve "git+https://github.com/your-org/your-docs.git"

Add #branch:subdir to pick a branch, a subdirectory, or both:

# The docs/ folder of the main branch
gomddoc serve "git+https://github.com/your-org/monorepo.git#main:docs"

# The docs/ folder of the default branch
gomddoc serve "git+https://github.com/your-org/monorepo.git#:docs"

The branch defaults to the repository's default branch. Tags and commit hashes aren't supported as refs. Restart gomddoc to pick up new commits.

Private repositories

Private repositories need SSH and an explicit key file:

ssh-keyscan github.com >> ~/.ssh/known_hosts
gomddoc serve "git+ssh://git@github.com/your-org/private-docs.git" --git-key-file ~/.ssh/id_ed25519

gomddoc doesn't use your SSH agent or look for default keys, so --git-key-file (or GOMDDOC_SERVER_GIT_SSH_KEY) is required. The host must already be listed in $SSH_KNOWN_HOSTS or ~/.ssh/known_hosts; an unknown host fails the connection. HTTPS token authentication isn't supported.

A .gomddoc/config.yml committed to the repository is ignored for Git sources. Set site options with environment variables instead, such as GOMDDOC_SITE_META_TITLE and GOMDDOC_SITE_THEME_NAME. Theme files under the repository's .gomddoc/assets/ are still used.


Build a static site

When you want plain files for a static host, build renders every page through the same templates as serve:

gomddoc build ./docs -o ./public

Each page is written as a directory index (install.md becomes install/index.html), so clean URLs work on GitHub Pages, Netlify, Cloudflare Pages or S3 without rewrite rules. The output also contains 404.html, robots.txt, the tag pages, and sitemap.xml and feed.xml when a domain is set with -d docs.example.com. The default output directory is build/site.

A static host has no server behind it, so a build has no search backend, no content negotiation, no MCP endpoint and no metrics. Turn off the search button for static deployments:

# .gomddoc/config.yml
theme:
  features:
    search: false

Add a config file

gomddoc runs without configuration. When you want to set a site title, a domain or a theme, scaffold a config file:

gomddoc init ./my-docs

This writes .gomddoc/config.yml with the defaults spelled out and a title taken from the directory name. init won't overwrite an existing file. --theme midnight writes a different theme name, but only default ships in the binary: install others from gomddoc-themes into .gomddoc/assets/themes/<name>/. The configuration reference covers every key.


Check your site

doctor loads the site the way serve does and reports every problem it finds, each with a file, a line and a fix:

gomddoc doctor ./my-docs

It catches unknown config keys, GOMDDOC_* variables that don't parse, feature toggles the theme never reads, frontmatter of the wrong type, clean-URL collisions, conflicting redirects and exclude patterns that match nothing. Add --strict in CI to fail on warnings as well as errors, --json for a machine-readable report, and -v to include informational findings such as pages without a description.

Two more commands help when you're setting things up:

gomddoc info                  # every setting with its config key, env var, flag and default
gomddoc help configuration    # the full user guide, built into the binary

Next steps