Settings
Every setting in sitemd lives in a markdown file with YAML frontmatter. Edit the file, save, and your site rebuilds with the new values.
# settings/meta.md
---
title: My Site
url: https://example.com
description: A site built with sitemd
---
Settings files are in your settings/ directory, tracked in git, and readable by humans and AI agents alike. The only exception is secrets (API keys, tokens, passwords) — those are stored separately in .sitemd/config.json and never committed.
Settings files
| File | What it controls |
|---|---|
meta.md |
Site title, URL, description, favicon |
header.md |
Brand display, navigation items, search, theme toggle, auth button |
footer.md |
Footer links, copyright, tagline, social icons |
theme.md |
Color palette, dark/light mode, border radius, fonts |
groups.md |
Page groups for sidebars, header dropdowns, footer columns |
build.md |
Build pages list, output directory |
seo.md |
Language, OG images, structured data, robots, IndexNow |
deploy.md |
Domain, deploy target, provider settings, media hosting |
email.md |
Email provider, sender address, SMTP settings |
analytics.md |
Analytics provider, tracking ID, GTM, custom head |
auth.md |
Auth provider, login mode, redirects, provider URLs |
data.md |
Data provider, cache TTL, data sources, provider URLs |
forms.md |
Default submit label, thank-you message, honeypot |
The 9 core files (meta, header, footer, theme, groups, build, seo, deploy, data) ship with the scratch template. The remaining files (email, analytics, auth, forms) are created when you enable those features — via sitemd config setup, the MCP setup tools, or by creating the file manually. Run sitemd init or call sitemd_init to scaffold a new project with the core files.
How settings work
Every settings file follows the same pattern: YAML key-value pairs between --- delimiters. Comments starting with # are documentation — the build engine ignores them.
# settings/deploy.md
---
# Deploy target: cloudflare, github, netlify, vercel
target: cloudflare
# Cloudflare Pages project name
cloudflareProject: my-site
# ── Secrets (CLI-managed) ─────────────────────────
# Manage secrets: sitemd config setup deploy
# cloudflareApiToken: ...8759
---
Three kinds of lines:
- Active settings —
key: valuelines that the build engine reads - Comments — lines starting with
#that document what each setting does - Commented-out settings —
# key: valuelines showing available options with defaults
To enable a commented-out setting, remove the # and set your value.
Two-tier architecture
Settings are split into two tiers based on sensitivity:
Settings files (settings/*.md) |
Config store (.sitemd/config.json) |
|
|---|---|---|
| Contains | Everything you'd put in source control | API keys, tokens, passwords |
| Edited by | You, directly in the file | sitemd config set or sitemd config setup |
| Tracked in git | Yes | No (gitignored) |
| Examples | Provider names, project IDs, URLs, domains, UI preferences | Cloudflare API token, email API key, Supabase anon key |
The rule: if it's safe to commit to git, it belongs in a settings file. If it's a secret, it belongs in the config store.
The secrets mirror block
Settings files that have associated secrets show a mirror block at the bottom:
# ── Secrets (CLI-managed) ─────────────────────────
# Manage secrets: sitemd config setup deploy
# cloudflareApiToken: ...8759
This block is read-only — the build engine writes it on every build to show which secrets are configured. The values are redacted (only the last 4 characters shown). To change a secret, run the command shown in the block or use sitemd config set.
Edit anything above the mirror block. The mirror block itself is overwritten on every build.
Build precedence
When the same value exists in multiple places:
- Environment variables — highest precedence (for CI)
- Config store secrets —
.sitemd/config.json - Settings files —
settings/*.mdfrontmatter
In practice, you edit settings files for day-to-day changes, use the config store for secrets, and use environment variables only in CI pipelines.
Settings schema
Every settings file has a defined schema of valid keys. The schema is centralized in settings-schema.js — a single source of truth used by the build validator, MCP tools, and agents.
Each file entry in the schema defines:
- required — keys that must be present (e.g.
titleinmeta.md) - known — all valid keys for that file
- validValues — constrained options for specific keys (e.g.
targetindeploy.mdmust be one ofcloudflare,github,netlify,vercel)
Retrieving the schema
Agents retrieve the full annotated schema by reading settings/_schema (or calling the MCP settings tool with name: "_schema"):
{ "name": "_schema" }
The response includes a _guide explaining the two-tier pattern, then every settings file with per-key metadata:
{
"_guide": "Settings live in two places: settings/*.md for non-secret config...",
"deploy.md": {
"required": [],
"keys": {
"target": { "validValues": ["cloudflare", "github", "netlify", "vercel"] },
"cloudflareProject": { "label": "Cloudflare Pages project name", "secret": false },
"cloudflareApiToken": {
"label": "Cloudflare API token",
"secret": true,
"setVia": "sitemd_config_set",
"configKey": "deploy.cloudflareApiToken"
}
}
}
}
Each key includes:
| Field | Meaning |
|---|---|
label |
Human-readable description |
secret |
true if the value is a secret — must use sitemd_config_set, never write to settings files |
setVia |
Which tool to use (sitemd_config_set for secrets) |
configKey |
The dot-path key to pass to sitemd_config_set (included when it differs from the obvious file.key pattern) |
validValues |
Array of allowed values for constrained keys |
Keys with an empty object {} are simple non-secret settings — edit them directly in the settings file.
Key reference
| File | Required | Known keys |
|---|---|---|
meta.md |
title |
title, brandName, description, url, brandImage, favicon, customFavicon, titleSuffix, tabTitle, tabTitleSuffix |
header.md |
— | brandDisplay, brandName, themeModeToggle, search, headerAuth, items |
footer.md |
— | copyright, brandName, brandDisplay, tagline, items, social |
theme.md |
— | defaultMode, accentColor, fontSans, fontMono, contentWidth, pageWidth, radius, imageCorners, borderRadius, buttonStyle |
build.md |
— | port, pagesDir, themeDir, outputDir, sitemap, robots, imageOptimization, imageMaxWidth, imageQuality |
deploy.md |
— | target, cloudflareProject, cloudflareAccountId, cloudflareBranch, netlifySiteId, vercelProjectId, vercelTeamId, githubRepo, githubBranch, mediaHosting, mediaCdnUrl, r2AccountId, r2Bucket, s3Region, s3Bucket, deployPages, additionalDomains |
seo.md |
— | language, ogImage, ogStyle, ogBackground, ogTextColor, ogLogo, defaultAuthor, twitterHandle, structuredData, llmsTxt, markdownOutput, allowAICrawlers, indexNow, orgName, orgLogo |
email.md |
— | provider, from, host, port, user, region |
analytics.md |
— | provider, id, host, gtm, pixels, customHead |
auth.md |
— | provider, loginMode, loginPage, afterLogin, afterLogout, userDataUrl, userTypeField, accessDeniedPage, apiUrl, supabaseUrl, firebaseAuthDomain, firebaseProjectId, auth0Domain, auth0ClientId |
data.md |
— | provider, cacheTTL, loadingText, emptyText, errorText, supabaseUrl, firebaseProjectId, airtableBaseId, restBaseUrl, sources |
forms.md |
— | submitLabel, thankYou, honeypot, countrySortToTop |
groups.md |
— | groups |
Keys starting with palette. are always valid in any file — they define custom named colors.
Self-repair
The build engine validates your settings files against the schema on every build. Warnings are non-blocking — your site still builds. They surface three types of issues:
Missing required keys
⚠ meta.md: missing required "title"
The key is required but not present in the file. Add it.
Unknown keys
⚠ meta.md: unknown key "typo" — check spelling or remove
The key isn't recognized in any settings file. Usually a typo.
Misplaced keys
⚠ meta.md: "items" belongs in header.md, not here
The key is valid but in the wrong file. The validator cross-references the schema to tell you exactly where it should go. Move it to the indicated file.
Invalid values
⚠ deploy.md: "target" has invalid value "clouflare" (expected: cloudflare, github, netlify, vercel)
The key has a value that doesn't match the allowed options. Fix the typo or pick from the listed values.
Auto-scaffolding
Beyond settings validation, the build engine also auto-scaffolds missing pages referenced in navigation. If your header.md lists a nav item pointing to /about but pages/about.md doesn't exist, the build creates a placeholder page with the right frontmatter and a content template. This means you can define your navigation structure first, then fill in the content — the build won't break on missing pages.
Editing settings via CLI or MCP
You don't have to edit files by hand. The CLI and MCP server both route values to the right place automatically:
# Sets a secret → goes to .sitemd/config.json
sitemd config set deploy.cloudflareApiToken cf_xxx
# Sets a non-secret → goes to settings/deploy.md frontmatter
sitemd config set deploy.cloudflareProject my-site
The sitemd config setup wizard does this routing automatically — it asks for values, then writes non-secrets to settings files and secrets to the config store.
AI agents do the same thing through MCP:
// Agent calls sitemd_config_set
{ "key": "deploy.cloudflareProject", "value": "my-site" }
// → Written to settings/deploy.md frontmatter
{ "key": "deploy.cloudflareApiToken", "value": "cf_xxx" }
// → Written to .sitemd/config.json
CI environment variables
For CI pipelines, set environment variables instead of editing files. Environment variables take the highest precedence and override both settings files and the config store. See CLI — CI environment variables for the full mapping.
Resetting a settings file
If a settings file gets corrupted or you want to start over, delete it and run sitemd init (or call sitemd_init via MCP) to copy the default from the scratch template. The build engine handles missing settings files gracefully — it uses built-in defaults for anything not specified.
Related
- CLI — manage secrets and run interactive setup
- MCP Server — programmatic access to settings, including schema retrieval
- Build Modes — how trial (unactivated) and activated modes affect builds
- Project Structure — where settings fit in the directory layout
- Site Identity — meta.md deep dive
- Themes — theme.md deep dive