CLI Reference

Accent CMS uses subcommands for all operations. Run accent --help to see available commands, or accent <command> --help for details on a specific command.

Global Options

These flags are available on the top-level accent binary, before any subcommand.

FlagShortDescription
--version-VPrint version and git commit hash
--help-hPrint help

accent init [PATH]

Create a new Accent CMS project with starter files.

ArgumentDefaultDescription
PATH. (current directory)Directory to initialize

Creates config.yaml, a starter content page at content/01.home/default.md, and the simple theme at themes/simple/ with base templates.

# Initialize in the current directory
accent init

# Initialize in a new directory
accent init my-site

accent serve

Start the development web server.

FlagShortDefaultDescription
--config <PATH>-cconfig.yamlPath to configuration file
--site-dir <PATH>Project root directory (sets content and theme directories relative to it)
--content-dir <PATH>Override content directory
--theme-dir <PATH>Override themes directory
--theme <NAME>Override active theme name
--address <ADDR>Override server bind address
--port <PORT>-pOverride server port
--productionDisable dev features (hot reload, browser reload, debug). Requires Standard or Pro license.
--tlsEnable HTTPS. Already the default in development mode, so this matters with --production or with --cert/--key.
--no-tlsServe plain HTTP in development mode. Cannot be combined with --tls, --cert, or --key.
--cert <PATH>Path to a PEM certificate file. Requires --tls and a Standard or Pro license.
--key <PATH>Path to a PEM private key file. Requires --tls and a Standard or Pro license.

By default, accent serve runs in development mode with hot reload, browser auto-refresh, and the debug panel enabled. Use --production to disable all dev features for production deployments.

HTTPS in development mode

Development mode serves over HTTPS with a self-signed certificate. Production mode is unchanged and stays on plain HTTP unless you pass --tls.

CommandProtocol
accent serveHTTPS (HTTP/2)
accent serve --no-tlsHTTP/1.1
accent serve --productionHTTP/1.1
accent serve --production --tlsHTTPS

HTTPS negotiates HTTP/2, which multiplexes every request over a single connection. That matters in development because the browser reload stream is a long-lived connection: over HTTP/1.1 it permanently occupies one of the six connections a browser will open per origin, and a page loading many assets while that stream reconnects can stall waiting for a free slot.

The certificate covers localhost and 127.0.0.1 and is cached, so your browser only prompts once:

PlatformLocation
macOS~/Library/Caches/dev.accentcms/dev-cert/
Linux$XDG_CACHE_HOME/accentcms/dev-cert/ (usually ~/.cache/...)
Windows%LOCALAPPDATA%\accentcms\dev-cert\

On the first start the server prints the certificate path along with the command that installs it into your platform’s trust store, which removes the warning entirely. The certificate is valid for a year and is regenerated automatically when it expires, when its files no longer match their recorded digests, or when it stops covering the host names in use.

Environment variableEffect
ACCENTCMS_DEV_CERT_DIRStore the certificate somewhere else. Point each CI run at its own scratch directory.
ACCENTCMS_DEV_CERT_SANSCertify extra host names, comma-separated.

Reaching the dev server from another machine

Setting server.address to 0.0.0.0 makes the server reachable across your network, but a wildcard bind is not a name a browser can ask for, so Accent cannot know which address the visitor will use. Name it explicitly:

ACCENTCMS_DEV_CERT_SANS=192.168.1.20 accent serve

Without it the server warns at startup and a phone or second machine reports a certificate name mismatch – an error mobile browsers make hard, sometimes impossible, to click past. --no-tls is the other way out.

accent serve --production --tls uses a self-signed certificate too, but never writes it down: a production serving key does not belong in a cache directory that eviction tooling and profile backups treat as disposable. Each start mints a fresh one. Use --cert/--key for a real production certificate.

Use --no-tls for a test harness or HTTP client that cannot be told to accept a self-signed certificate. It is accepted alongside --production too, where it restates the default explicitly rather than changing it.

CLI arguments take precedence over values in config.yaml.

# Start with defaults (dev mode)
accent serve

# Custom port
accent serve --port 3000

# Test with different content and theme
accent serve --content-dir ./site/content/test --theme dark

# Use a separate config file
accent serve --config staging.yaml

# Production mode
accent serve --production

# Plain HTTP in dev mode (HTTPS is the default)
accent serve --no-tls

# HTTPS in production mode with a self-signed certificate (all editions)
accent serve --production --tls

# HTTPS with custom certificates (Standard or Pro license required)
accent serve --tls --cert /path/to/cert.pem --key /path/to/key.pem

# Combine multiple options
accent serve --content-dir ./demo --theme minimal --port 8080

Serving Arbitrary Content Directories

Accent CMS can serve any directory of markdown files, not just those following CMS conventions. Use --content-dir to point at any markdown collection:

# Serve a project's docs folder
accent serve --content-dir ./docs

# Serve any markdown collection
accent serve --content-dir ~/notes

See the Getting Started guide for details on index file recognition, automatic title derivation, and template fallback.

accent build

Generate a static site as HTML, CSS, and assets.

FlagShortDefaultDescription
--config <PATH>-cconfig.yamlPath to configuration file
--output <PATH>-ooutputOutput directory for the built site
--cleanRemove existing output directory before building
--base-url <URL>Base URL for absolute links in sitemap and feed (fallback: site.url from config). If its path component is non-root (e.g. https://username.github.io/repo), that path also sets the site’s base path automatically – see --base-path.
--base-path <PREFIX> Explicit sub-path prefix for every internal URL Accent emits (page links, theme assets, media, search, pagination). Overrides both config and any prefix derived from --base-url/site.url. Normalized to a leading slash with no trailing slash.
--site-dir <PATH>Project root directory override
--content-dir <PATH>Override content directory
--theme-dir <PATH>Override themes directory
--theme <NAME>Override active theme name

--base-path can be set to a prefix other than the one derived from --base-url/site.url (as in the last example below). This is allowed, but absolute URLs (sitemap, feeds, canonical links, JSON-LD) always compose --base-url/site.url with the resolved base_path appended, so --base-url https://username.github.io/repo --base-path /other produces https://username.github.io/repo/other/..., not https://username.github.io/other/.... Accent logs a startup warning when --base-path diverges from the URL’s own path this way.

The static build requires no license key.

# Build with defaults
accent build

# Build to a custom directory, cleaning first
accent build --output ./dist --clean

# Build with a base URL for sitemap and feed
accent build --base-url https://example.com

# Build a GitHub Pages project site (base path derived from the URL's path)
accent build --base-url https://username.github.io/repo

# Or set the prefix explicitly
accent build --base-url https://username.github.io/repo --base-path /repo

accent validate

Validate content integrity across all pages. Checks for missing templates, broken internal links, invalid dates, orphaned pages, and missing required fields.

FlagShortDefaultDescription
--config <PATH>-cconfig.yamlPath to configuration file
--site-dir <PATH>Project root directory override
--content-dir <PATH>Override content directory
--theme-dir <PATH>Override themes directory
--theme <NAME>Override active theme name
--templatesValidate only template syntax (skip content validation). Parses all .jinja/.j2 files and reports syntax errors.
# Validate all content
accent validate

# Validate with a specific config
accent validate --config prod.yaml

# Validate template syntax only (fast feedback loop)
accent validate --templates

# Use in CI pipelines (exits with code 1 if problems found)
accent validate || echo "Content issues found"

accent serve-static

Serve a pre-built static site from a local directory. Useful for previewing the output of accent build before deploying, or for running parity checks between the dynamic server and the static build.

FlagShortDefaultDescription
--dir <PATH>-doutputDirectory to serve
--address <ADDR>127.0.0.1Server bind address
--port <PORT>-p4403Server port
--base-path <PREFIX>(resolved site.base_path) Mount the served output under this prefix. Defaults to the resolved site.base_path, so previewing a build that was made with a base path needs no extra flags.
--tlsEnable HTTPS. Already the default, so this matters only alongside --cert/--key.
--no-tlsServe plain HTTP. Cannot be combined with --tls, --cert, or --key.
--cert <PATH>Path to a PEM certificate file. Requires --tls and a Standard or Pro license.
--key <PATH>Path to a PEM private key file. Requires --tls and a Standard or Pro license.
--config <PATH>-cconfig.yamlPath to config file (used for license key lookup only)
--openOpen the URL in the default browser after starting

serve-static defaults to HTTPS as well, using the same cached development certificate as accent serve, so a build checked with one is reached over the same scheme as with the other. Pass --no-tls for plain HTTP.

# Build then preview
accent build --clean
accent serve-static

# Serve from a custom directory on a custom port
accent serve-static --dir ./dist --port 8080

# Preview a GitHub Pages project-site build -- the prefix is picked up automatically
accent build --output ./public --base-url https://username.github.io/repo
accent serve-static --dir ./public
# Visit https://127.0.0.1:4403/repo

# Preview over plain HTTP (HTTPS is the default)
accent serve-static --no-tls

# HTTPS with custom certificates (Standard or Pro license required)
accent serve-static --tls --cert cert.pem --key key.pem

# Open the browser automatically
accent serve-static --open

accent plugin Free

Manage WASM plugins. The accent plugin commands require no license key.

FlagShortDefaultDescription
--config <PATH>-cconfig.yamlConfiguration file (for plugin directory)

Subcommands

SubcommandDescription
plugin listList all installed plugins with name, version, hooks, filters, and routes
plugin info <NAME>Show detailed plugin metadata from plugin.toml
plugin install <NAME[@VERSION]>Install a plugin from the registry (supports version pinning)
plugin remove <NAME>Remove an installed plugin
# List installed plugins
accent plugin list

# Show details for a plugin
accent plugin info syntax-highlight

# Install a plugin (latest version)
accent plugin install my-plugin

# Install a specific version
accent plugin install my-plugin@1.0.0

# Remove a plugin
accent plugin remove old-plugin

accent query Free

Query content, tags, and hierarchy from the command line. Requires no license key.

Shared Flags

FlagShortDefaultDescription
--config <PATH>-cconfig.yamlPath to configuration file
--site-dir <PATH>Project root directory override
--content-dir <PATH>Override content directory
--theme-dir <PATH>Override themes directory
--theme <NAME>Override active theme name

Subcommands

SubcommandDescription
query page <URL>Get a single page by URL path
query listList pages matching filter criteria
query tags [TAG]List tags with page counts (optionally filter to one tag)
query treeShow the content hierarchy tree
query schemaShow the content model schema
query search <TERM>Search content by text
query validate [URL]Validate content integrity (optionally for a single page)

query page

Argument / FlagDefaultDescription
URL (required)Page URL path (e.g., /blog/my-post)
--include-contentInclude raw markdown content in output
--format <FORMAT>jsonOutput format: json, yaml, plain
--fields <FIELDS>Comma-separated list of fields to include

query list

FlagDefaultDescription
--tag <TAG>Filter by tag name
--author <AUTHOR>Filter by author
--status <STATUS>Filter by status (published, draft, review, archived)
--path <PATH>Filter by URL path glob (e.g., /blog/*)
--template <TEMPLATE>Filter by template name
--language <LANGUAGE>Filter by language code
--sort <FIELD>dateSort field: date, title, url, modified
--order <ORDER>descSort order: asc, desc
--limit <NUM>50Maximum pages to return
--offset <NUM>0Offset for pagination
--format <FORMAT>jsonOutput format: json, yaml, plain
--fields <FIELDS>Comma-separated list of fields to include
--navShow only navigation-visible pages (menu-visible, published, top-level). Sorted by menu.order then URL.

query tags

Argument / FlagDefaultDescription
TAG (optional)Filter to a specific tag name
--include-pagesInclude page URLs for each tag
--format <FORMAT>jsonOutput format: json, yaml, plain

query tree

FlagDefaultDescription
--root <URL>/Root URL for subtree
--flatOutput flat list with parent references instead of nested tree
--format <FORMAT>jsonOutput format: json, yaml, plain

query schema

FlagDefaultDescription
--format <FORMAT>jsonOutput format: json, yaml, plain
Argument / FlagDefaultDescription
TERM (required)Search term
--in <FIELDS>title,content,tagsFields to search in (comma-separated). Allowed: title, content, tags, lead, frontmatter
--limit <NUM>20Maximum results
--format <FORMAT>jsonOutput format: json, yaml, plain
--fields <FIELDS>Comma-separated list of fields to include in results

query validate

Argument / FlagDefaultDescription
URL (optional)Validate a specific page only
--format <FORMAT>jsonOutput format: json, yaml, plain

This wraps the same validation infrastructure as the top-level accent validate command but with structured output and optional per-page targeting. For CI pipelines, prefer accent validate which returns exit code 1 on errors and produces human-readable output.

Shared Output Options

All query subcommands support --format to control output:

  • json (default) – machine-readable JSON
  • yaml – human-friendly YAML
  • plain – minimal plain-text output

Subcommands that return page data also support --fields to select specific fields (e.g., --fields title,url,date).

# Get details for a specific page
accent query page /blog/my-post

# Include raw markdown content
accent query page /blog/my-post --include-content

# List recent blog posts
accent query list --path "/blog/*" --limit 10

# Filter by tag and author
accent query list --tag rust --author "Jane Doe"

# List navigation-visible pages (matches the `pages` template variable)
accent query list --nav

# List all tags with page counts
accent query tags

# Show pages for a specific tag
accent query tags rust --include-pages

# Show content hierarchy
accent query tree

# Show subtree starting from /docs
accent query tree --root /docs

# Show content schema
accent query schema --format yaml

# Search across content
accent query search "getting started"

# Search only in titles and tags
accent query search "rust" --in title,tags

# Validate all content (JSON report)
accent query validate

# Validate a single page
accent query validate /blog/my-post

accent docs

Generate agent-friendly documentation, template reference material, and serve the built-in documentation site.

Subcommands

SubcommandDescription
docs agent-readmeWrite agent-tools-README.md command reference to the current directory
docs claude-mdAppend CMS Content Operations section to ./CLAUDE.md
docs template-filtersPrint all available template filters, tests, and functions to stdout
docs template-contextPrint template context variable schema with types to stdout
docs serveServe the built-in documentation site from the binary
# Print filter/function reference (pipe to a file or read directly)
accent docs template-filters

# Print template context variable schema
accent docs template-context

# Generate agent tool documentation
accent docs agent-readme

# Serve the built-in documentation site
accent docs serve

# Serve on a custom port
accent docs serve --port 8080

accent license

Manage license keys from the command line. Offline commands (status, activate, deactivate) work with no license key. Browser-based commands (buy, renew, refund) require a Standard or Pro license.

FlagShortDefaultDescription
--config <PATH>-cconfig.yamlPath to configuration file

Subcommands

SubcommandDescriptionNetwork?
license statusShow current license details (edition, org, email, expiry, status)No
license activate <KEY>Validate a JWT key and save it to config.yaml. Pass - to read from stdin.No
license deactivateRemove the license key from config.yamlNo
license buyOpen a checkout in the browser and receive the key via localhost callbackYes (browser)
license renewOpen a checkout for the edition and cadence of the current licenseYes (browser)
license refundOpen the Polar.sh customer portal for refund requestsYes (browser)

license buy

FlagDefaultDescription
--edition <EDITION>promptEdition to purchase: core_plus, standard, or pro. Skips the interactive selection prompt.
--cadence <CADENCE>yearlyBilling cadence: yearly (owned – covered releases keep running after expiry) or monthly (rental – reverts to free Core after expiry).
# Show current license status (offline, works in all editions)
accent license status

# Activate a license key from email or team admin
accent license activate eyJhbGciOiJFZERTQSIs...

# Activate from stdin (CI/CD pipelines)
echo "$LICENSE_KEY" | accent license activate -

# Remove the license key (server reverts to dev mode)
accent license deactivate

# Purchase a license (opens browser, receives key via callback)
accent license buy

# Purchase a specific edition directly
accent license buy --edition standard

# Purchase on the monthly (rental) cadence instead of yearly
accent license buy --edition standard --cadence monthly

# Renew an existing license
accent license renew

# Request a refund via the Polar.sh portal
accent license refund

The buy and renew commands start a temporary localhost server to receive the license key after the browser flow completes. If the browser flow does not complete within 5 minutes, you can paste the key manually at the terminal prompt.

renew reads the edition and cadence off your current key and opens a fresh checkout for the same combination. If your subscription renewed on its own, you do not need it – the new key is emailed to you, and accent license activate <key> installs it.

Neither command talks to the payment provider directly. The browser is sent to the Accent issuance service, which creates the checkout, signs your key after payment clears, and redirects back to the one-off localhost address the command registered. The signing key never leaves that service, and the callback address is validated before any key is handed out. If the redirect does not arrive, the key is emailed to you regardless.

When the ACCENTCMS_LICENSE environment variable is set, it takes priority over the key in config.yaml. The CLI warns about this during activate and buy operations.

Environment Variables

VariableDescriptionOverrides
ACCENTCMS_LICENSELicense key for Standard/Pro editionslicense.key in config
RUST_LOGDetailed log filtering using the tracing directives formatStandard Rust logging

The default log filter is accent=info,tower_http=debug. Set RUST_LOG for fine-grained control:

# Enable debug logging for all Accent CMS modules
RUST_LOG=accent=debug accent serve

# Trace-level logging for content loading
RUST_LOG=accent::content=trace accent serve

Exit Codes

CodeMeaning
0Success
1Content validation found problems (accent validate), or a config-load failure
2Query error (accent query error path)