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
- Features: everything gomddoc does, from search to Prometheus metrics
- Configuration: config keys, environment variables, flags and frontmatter
- Installation options: Docker, Homebrew, release archives and signatures
- Licensing: free for noncommercial use, with a commercial licence per deployment