# MCP Server

Programmatic access to your entire site — pages, settings, groups, config, auth, and deploy — from any AI coding agent.

The sitemd MCP server wraps the build engine and CLI as structured tools. Agents create pages, configure services, authenticate, and deploy — all without shelling out to a terminal. For reads (pages, settings, groups), agents use their native file tools directly. See [MCP vs CLI](/docs/mcp-vs-cli) for a comparison of both interfaces.

## Setup

The server is registered in `.mcp.json` at your project root:

```json
{
  "mcpServers": {
    "sitemd": {
      "command": "./sitemd/sitemd",
      "args": ["mcp"]
    }
  }
}
```

Claude Code, Codex CLI, Gemini CLI, and Cursor all read `.mcp.json` automatically. No extra configuration needed — the MCP server is built into the sitemd binary.

## Tools

The server exposes 22 tools across seven categories: project overview, build and deploy, authentication, configuration, content creation, [website cloning](/docs/clone), and updates.

For reading pages, settings, and groups, agents use their native file tools directly — no MCP call needed. Pages live at `pages/{slug}.md`, settings at `settings/{name}.md`, and groups at `settings/groups.md`. This reduces token overhead and avoids unnecessary round-trips.

### sitemd_status

Get full project state — site name, page count, auth, deploy/email/analytics config, and a list of contextual next actions.

**Parameters:** none

**Returns:** Object with `project`, `pages`, `requiresActivation`, `auth`, `deploy`, `email`, `analytics`, `nextAction`, and `actions`. The `actions` array adapts to what's configured — it suggests `sitemd_init` for fresh projects, `sitemd_build` for validation, `deploy` when everything is ready, and `auth login` when not authenticated.

The `requiresActivation` field is a top-level boolean — `true` when the site has not been activated, `false` after activation. Agents can branch on this directly instead of parsing the `site.hint` string.

The `nextAction` field is a single string telling the agent what to do right now based on current state — e.g. `"Site is ready to deploy. Run sitemd_deploy."`. Agents can use this to drive autonomous workflows without parsing the full status object.

This is the MCP equivalent of running `sitemd` interactively in the terminal. Agents call this first to understand the project and guide the user.

### sitemd_init

Initialize a project from the scratch template. Copies default settings and starter pages, then optionally sets brand identity.

**Parameters:**

| Name | Required | Description |
| --- | --- | --- |
| `brandName` | no | Site/brand name — updates `meta.md`, `header.md`, and `footer.md` |
| `description` | no | Site description for SEO, under 160 characters — updates `meta.md` |
| `url` | no | Site URL, e.g. `https://example.com` — updates `meta.md` |

**Returns:** Object with `initialized` (files copied from template), `updated` (files patched with brand info), `skipped` (files that already existed), `mode` (trial/activated explanation with next steps), and `hints`.

Safe to call on existing projects — only copies files that are missing. Existing files are never overwritten. Call this first on a fresh project to get all 9 settings files and 4 starter pages (home, 404, access-denied, maintenance) in place before creating content.

### sitemd_build

Build the site locally without deploying. Validates the build, reports page count, and catches errors before deploying.

**Parameters:** none

**Returns:** Object with `built`, `mode` (trial or activated), `trialMode` (boolean, present only in trial mode), `pages` count, `userPages` (array of `{title, slug}` for content pages), `systemPages` (array of slugs for 404, access-denied, maintenance), `outputDir`, `activation` (structured activation guidance in trial mode), and `warnings`.

In trial mode, the `activation` object tells the agent exactly what to do:

```json
{
  "required": true,
  "steps": ["sitemd_auth_login — sign in first", "sitemd_activate — unlock disk output and deployment"],
  "note": "Build succeeded in memory. Activate to write files to disk and enable deploy."
}
```

The build runs lightweight validation and reports two levels of issues. The `errors` array contains actionable problems — missing pages and broken links. The `warnings` array contains advisory issues — missing alt text, undefined modal references, placeholder webhook URLs, and gated sections without an auth provider. Every warning includes a `Fix:` suffix telling the agent exactly what to do.

`sitemd_deploy` already includes a build step, so use `sitemd_build` only when you want to verify without deploying.

### sitemd_deploy

Build the site and deploy to the configured hosting target.

**Parameters:**

| Name | Required | Description |
| --- | --- | --- |
| `skipBuild` | no | Skip building and deploy existing `site/` output instead |

**Returns:** Object with `deployed`, `target`, `domain`, `url`, `verifyUrl`, and `message`.

Requires authentication (`sitemd_auth_login`), site activation (`sitemd_activate`), and deploy config (`sitemd_config_set` with `deploy.*` keys). Reads the domain from `settings/deploy.md` frontmatter.

If called before activation, the tool returns an immediate error without wasting time on a build cycle. If credentials are missing, the error tells you exactly which keys are needed.

### sitemd_activate

Permanently activate this site by locking its identity fingerprint. Consumes 1 site slot.

**Parameters:** none

**Returns:** Object with `activated`, `siteTitle`, `domain`, and `status` (`"already active"` or `"newly activated"`).

Requires authentication and a domain set in `settings/meta.md` url field. Activations are permanent — there is no deactivation. This is the MCP equivalent of `sitemd activate`.

### sitemd_auth_setup

Enable user authentication for the site.

**Parameters:**

| Name | Required | Description |
| --- | --- | --- |
| `provider` | yes | Auth provider: `custom`, `supabase`, `firebase`, `clerk`, or `auth0` |
| `loginMode` | no | `password` (default) or `magic-link` |

**Returns:** Object with `status`, `provider`, `loginMode`, and `created` (list of files created).

Copies login, sign-up, forgot-password, and account page templates into the project. Creates `settings/auth.md` with `enabled: true` and the chosen provider. Safe to call multiple times — skips if auth is already enabled. See [User Auth & Gating](/docs/user-auth) for the full setup guide.

### sitemd_auth_login

Start the browser OAuth login flow.

**Parameters:** none

**Returns:** Object with `browserUrl` (URL for the user to open), `code` (verification code), and `pollUrl` (for completing the flow).

After calling this tool, tell the user to open the URL in their browser. Then call `sitemd_auth_poll` with the `pollUrl` to wait for completion.

### sitemd_auth_poll

Poll for OAuth login completion.

**Parameters:**

| Name | Required | Description |
| --- | --- | --- |
| `pollUrl` | yes | The `pollUrl` returned by `sitemd_auth_login` |

**Returns:** Object with `status` — either `pending` (call again in a few seconds) or `approved` (login complete, includes `email`).

### sitemd_auth_status

Check current authentication state, account info, and license details.

**Parameters:** none

**Returns:** Object with `loggedIn`, `email`, `tokenValid`, `name`, `emailVerified`, and `licenses` (count, total slots, used slots).

### sitemd_auth_logout

Clear saved authentication credentials.

**Parameters:** none

### sitemd_auth_api_key

Create an API key for CI and automated deploys.

**Parameters:**

| Name | Required | Description |
| --- | --- | --- |
| `name` | no | Label for the key (e.g. "GitHub Actions"). Defaults to "CLI" |

**Returns:** Object with `name`, `key`, and `instructions`. The key is shown once and cannot be retrieved again.

### sitemd_config_set

Set a config value. Routes secrets (API keys, tokens) to `.sitemd/config.json` (gitignored) and non-secrets (project IDs, URLs, provider names) to `settings/*.md` frontmatter.

**Parameters:**

| Name | Required | Description |
| --- | --- | --- |
| `key` | yes | Dot-path config key (e.g. `deploy.cloudflareApiToken`) |
| `value` | yes | Value to set |

See [CLI Config](/docs/cli-config) for the full list of config keys. This is how agents handle the interactive config setup — they ask the user for each value in conversation, then call this tool for each answer.

### sitemd_pages_create

Create a new page file with frontmatter and markdown content.

**Parameters:**

| Name | Required | Description |
| --- | --- | --- |
| `title` | yes | Page title (e.g. "My Page") |
| `description` | yes | Meta description, under 160 characters |
| `slug` | yes | URL path (e.g. "/docs/my-page"). Auto-prepends `/` if missing |
| `content` | yes | Markdown body (no frontmatter) |
| `groupMember` | no | Groups this page belongs to (e.g. `["docs"]`) |
| `sidebarGroupShown` | no | Which group sidebar to display |
| `addToNav` | no | If `true`, adds this page to the header navigation automatically |
| `frontmatter` | no | Additional frontmatter fields as a JSON object |

The tool derives the file path from the slug — `/docs/my-page` becomes `pages/docs/my-page.md`. It creates any missing directories automatically.

When `groupMember` is provided, pages are automatically added to the group's sidebar navigation. The group is created if it doesn't exist. If `sidebarGroupShown` is omitted but `groupMember` is provided, `sidebarGroupShown` is auto-set to the first group.

Slugs are validated automatically — the tool rejects slugs with uppercase letters, spaces, special characters, double slashes, or trailing slashes.

The response includes a `warnings` array when content issues are detected at create time — broken modal references and incomplete form blocks. Won't overwrite existing files — if a page already exists at that slug, the tool returns an error directing you to edit the file directly.

### sitemd_pages_create_batch

Create multiple pages in one call. Each page follows the same schema as `sitemd_pages_create`.

**Parameters:**

| Name | Required | Description |
| --- | --- | --- |
| `pages` | yes | Array of page definitions (each requires `title`, `description`, `slug`, `content`) |

**Returns:** Object with `created` (count), `failed` (count), `results` (per-page details including any warnings), and `message`.

Pages are created sequentially — if one fails (e.g. duplicate slug), the rest continue. Use this instead of calling `sitemd_pages_create` in a loop when creating 3+ pages.

### sitemd_pages_delete

Delete a page and clean up its references in groups and navigation.

**Parameters:**

| Name | Required | Description |
| --- | --- | --- |
| `slug` | yes | URL slug of the page to delete (e.g. "/about") |
| `force` | no | Set to `true` to allow deleting the home page |

**Returns:** Object with `deleted` (slug), `file` (path), `removedFromGroups` (array of group names if any), and `removedFromNav` (`true` if removed from header).

Automatically removes the page from any groups in `settings/groups.md` and from header navigation in `settings/header.md`. Refuses to delete the home page (`/`) unless `force: true` is passed.

### sitemd_groups_add_pages

Add one or more pages to a group in one call. Creates the group automatically if it doesn't exist. Skips duplicates. Use this instead of editing `settings/groups.md` directly — the file uses indent-sensitive formatting (2-10 space levels) that is error-prone to edit manually.

**Parameters:**

| Name | Required | Description |
| --- | --- | --- |
| `groupName` | yes | Name of the group (e.g. "docs") |
| `pages` | yes | Array of `{label, slug}` objects to add |

**Returns:** Object with `groupName`, `groupCreated` (boolean), `added` (array of entries that were added), and `skipped` (array of entries already in the group).

```json
{
  "groupName": "docs",
  "pages": [
    { "label": "Getting Started", "slug": "/docs/getting-started" },
    { "label": "Authentication", "slug": "/docs/authentication" }
  ]
}
```

### sitemd_site_context

Get site identity, existing pages, conventions, and type-specific state before writing content. The full syntax reference is in the agent context file (CLAUDE.md) — this tool returns only dynamic data.

**Parameters:**

| Name | Required | Description |
| --- | --- | --- |
| `contentType` | yes | One of: `page`, `docs`, `blog`, `changelog`, `roadmap` |
| `topic` | no | Optional topic or subject for the content |

**Returns:** Object with `site` (name, description, URL), `existingPages` (filtered to target group), `conventions` (title suffix, date format), `currentState` (type-specific: latest changelog version, roadmap sections), `groups`, and `guidance` (tips on groups, navigation, content types).

Agents call this before creating content to understand what exists and match the site's voice and structure.

### sitemd_content_validate

Validate a page against quality rules for its content type.

**Parameters:**

| Name | Required | Description |
| --- | --- | --- |
| `slug` | yes | Slug of the page to validate (e.g. "/docs/my-page") |

**Returns:** Validation result with errors, warnings, and checks passed. Warning messages include actionable `Fix:` hints.

### sitemd_seo_audit

Run a comprehensive [SEO health check](/docs/seo-audit) on your site.

**Parameters:**

| Name | Required | Description |
| --- | --- | --- |
| `scope` | no | `all` (default), `settings`, or `pages` |
| `slug` | no | Audit a single page instead of all pages |

**Returns:** Scored report with actionable recommendations.

### sitemd_clone

Scrape a website and return a structured report mapping its content to sitemd components. Extracts pages, navigation, images, forms, and embeds. See [Website Cloning](/docs/clone) for full documentation.

**Parameters:**

| Name | Required | Description |
| --- | --- | --- |
| `url` | yes | Website URL to clone |
| `maxPages` | no | Maximum pages to crawl (default 50, max 200) |
| `includeAssets` | no | Download and localize images (default true) |
| `skipPaths` | no | URL path prefixes to skip |

### sitemd_update_check

Check for newer versions of sitemd. Returns current version, latest available version, whether an update is available, and release notes. See [Updates](/docs/updates) for full documentation.

### sitemd_update_apply

Check for and apply sitemd updates in one step. Downloads the latest release and replaces engine and theme files in-place. Preserves all user content (pages, settings, media). This is the MCP equivalent of `sitemd update`.

## Direct file access

Agents read and edit these files directly — no MCP tool needed:

| What | Path | Notes |
|---|---|---|
| Read a page | `pages/{slug}.md` | `/about` → `pages/about.md`, `/` → `pages/home.md` |
| Edit a page | `pages/{slug}.md` | Use the Edit tool to preserve formatting and comments |
| List all pages | `pages/**/*.md` | Glob the directory |
| Read settings | `settings/{name}.md` | e.g. `settings/meta.md`, `settings/theme.md` |
| Edit settings | `settings/{name}.md` | Preserve inline `#` comments — they document the settings |
| Read groups | `settings/groups.md` | For writes, use `sitemd_groups_add_pages` (indent-sensitive format) |
| Read config | `.sitemd/config.json` | Gitignored secrets. For writes, use `sitemd_config_set` |

This design keeps the MCP tool count low (22 tools instead of 37), reducing the per-message token overhead by ~40%. Agents already have Read, Edit, Write, and Glob tools — duplicating them as MCP tools wastes context window on redundant tool schemas.

## Typical agent workflow

A new agent building a site from scratch follows this sequence:

1. `sitemd_status` — understand project state, see suggested actions
2. `sitemd_init` — set brand name, description, URL; scaffold all settings and starter pages
3. `sitemd_pages_create_batch` — create all pages in one call (or `sitemd_pages_create` one at a time)
4. `sitemd_groups_add_pages` — organize pages into groups for sidebar navigation
5. `sitemd_build` — validate the build, review warnings and Fix hints, catch errors
6. `sitemd_deploy` — ship to production

To edit existing content, agents read the page file directly, use the Edit tool to make changes, then call `sitemd_content_validate` to verify quality.

## Import command

The `/import` command converts any raw markdown file into a sitemd page:

```text
/import path/to/article.md
```

Claude reads the source file, surveys the existing site structure, then generates frontmatter, determines group membership, converts content to sitemd syntax, and creates the page file. The dev server auto-rebuilds when the new file is written.

## Auth flow via MCP

Authentication uses a two-step flow since agents can't interact with a browser directly:

1. Agent calls `sitemd_auth_login` → gets a browser URL and verification code
2. Agent tells the user to open the URL and log in
3. Agent calls `sitemd_auth_poll` with the `pollUrl` every few seconds
4. When the user completes login, `sitemd_auth_poll` returns `approved` with the user's email

The agent handles the polling automatically. From the user's perspective, they click a link, log in, and the agent confirms it worked.

## Config setup via MCP

Instead of the terminal's interactive setup wizard, agents handle config setup conversationally:

1. Agent calls `sitemd_status` to see what's already configured
2. Agent asks the user for each value in the chat (e.g. "What's your Cloudflare project name?")
3. Agent calls `sitemd_config_set` for each answer
4. Agent calls `sitemd_status` again to confirm

## Architecture

The MCP server lives at `sitemd/engine/mcp/` and imports the build engine and CLI modules directly:

```text
sitemd/engine/
  build/          ← core build system
    config.js       loadSettings(), validateSettings()
    discover.js     findMarkdownFiles()
    parse.js        parseFrontmatter(), parseGroups()
    groups.js       writeGroupsFile()
    render.js       build()
    css.js          syncThemeToCSS()
  cli/            ← CLI commands
    auth-store.js   getAuth(), saveAuth(), clearAuth()
    auth-browser.js browserLogin(), API_URL
    config-store.js loadBackendConfig(), saveProjectConfig()
  deploy/         ← deploy targets
    index.js        deploy()
  mcp/            ← MCP server
    index.js        stdio server entry point
    tools.js        22 tool handlers
    vendor/         pre-bundled MCP SDK
```

The build engine has minimal dependencies — just `lucide-static` for icons, installed via `npm install`. The MCP SDK is pre-bundled into a single file at `sitemd/engine/mcp/vendor/mcp-sdk.js` — no additional setup required.

## Cross-agent compatibility

Any MCP-capable agent can use these tools — not just Claude Code. The `.mcp.json` file at the project root is read by Claude Code, Codex CLI, Gemini CLI, and Cursor. Each agent calls the same tools with the same parameters and gets the same structured responses.

The MCP server is one layer of a broader onboarding system that teaches agents your site's structure, syntax, and conventions automatically. See [Agent Onboarding](/docs/agent-onboarding) for the full picture.

## Related

- [CLI](/docs/cli-config) — the same capabilities for terminal users
- [MCP vs CLI](/docs/mcp-vs-cli) — when to use each interface
- [Agent Onboarding](/docs/agent-onboarding) — how agents learn your site