Skip to main content
The MDCMS CLI is designed for headless operation in CI/CD pipelines. All commands accept configuration via environment variables, and interactive prompts are automatically skipped in non-TTY environments.

Environment variables

Set these in your CI provider’s secret management:
VariableDescription
MDCMS_API_KEYAPI key for authentication (replaces mdcms login)
MDCMS_PROJECTTarget project slug
MDCMS_ENVIRONMENTTarget environment name
MDCMS_SERVER_URLMDCMS server URL (overrides mdcms.config.ts)
Create a dedicated API key with minimal scopes for CI use. Schema sync requires schema:read and schema:write. Content push requires content:write and content:read:draft.

GitHub Actions: Schema sync

Automatically sync the schema to the server whenever mdcms.config.ts changes on the main branch.
.github/workflows/mdcms-schema-sync.yml
name: MDCMS Schema Sync

on:
  push:
    branches: [main]
    paths:
      - "mdcms.config.ts"

jobs:
  schema-sync:
    runs-on: ubuntu-latest
    steps:
      - name: Checkout repository
        uses: actions/checkout@v4

      - name: Setup Bun
        uses: oven-sh/setup-bun@v2
        with:
          bun-version: latest

      - name: Install dependencies
        run: bun install --frozen-lockfile

      - name: Sync schema
        run: bunx mdcms schema sync
        env:
          MDCMS_API_KEY: ${{ secrets.MDCMS_API_KEY }}
          MDCMS_PROJECT: ${{ vars.MDCMS_PROJECT }}
          MDCMS_ENVIRONMENT: ${{ vars.MDCMS_ENVIRONMENT }}
          MDCMS_SERVER_URL: ${{ vars.MDCMS_SERVER_URL }}

GitHub Actions: Content push

Push content changes to the server on every merge to main. The --force flag skips interactive prompts.
.github/workflows/mdcms-content-push.yml
name: MDCMS Content Push

on:
  push:
    branches: [main]
    paths:
      - "content/**"

jobs:
  content-push:
    runs-on: ubuntu-latest
    steps:
      - name: Checkout repository
        uses: actions/checkout@v4

      - name: Setup Bun
        uses: oven-sh/setup-bun@v2
        with:
          bun-version: latest

      - name: Install dependencies
        run: bun install --frozen-lockfile

      - name: Sync schema
        run: bunx mdcms schema sync
        env:
          MDCMS_API_KEY: ${{ secrets.MDCMS_API_KEY }}
          MDCMS_PROJECT: ${{ vars.MDCMS_PROJECT }}
          MDCMS_ENVIRONMENT: ${{ vars.MDCMS_ENVIRONMENT }}
          MDCMS_SERVER_URL: ${{ vars.MDCMS_SERVER_URL }}

      - name: Push content
        run: bunx mdcms push --force
        env:
          MDCMS_API_KEY: ${{ secrets.MDCMS_API_KEY }}
          MDCMS_PROJECT: ${{ vars.MDCMS_PROJECT }}
          MDCMS_ENVIRONMENT: ${{ vars.MDCMS_ENVIRONMENT }}
          MDCMS_SERVER_URL: ${{ vars.MDCMS_SERVER_URL }}
Schema sync runs before content push to ensure the schema hash is available. Push requires a valid schema hash from a prior sync.

Status check

Use mdcms status as a CI gate. The command exits with code 1 when drift is detected, making it suitable for blocking deployments.
- name: Check sync status
  run: bunx mdcms status
  env:
    MDCMS_API_KEY: ${{ secrets.MDCMS_API_KEY }}
    MDCMS_PROJECT: ${{ vars.MDCMS_PROJECT }}
    MDCMS_ENVIRONMENT: ${{ vars.MDCMS_ENVIRONMENT }}
    MDCMS_SERVER_URL: ${{ vars.MDCMS_SERVER_URL }}
This step fails the workflow if local content or schema is out of sync with the server.

Schema drift detection

Prevent deployments when the local schema definition has diverged from the server. This is useful as a pull request check to ensure schema changes are synced before merging.
.github/workflows/mdcms-drift-check.yml
name: MDCMS Drift Check

on:
  pull_request:
    branches: [main]

jobs:
  drift-check:
    runs-on: ubuntu-latest
    steps:
      - name: Checkout repository
        uses: actions/checkout@v4

      - name: Setup Bun
        uses: oven-sh/setup-bun@v2
        with:
          bun-version: latest

      - name: Install dependencies
        run: bun install --frozen-lockfile

      - name: Check for drift
        run: bunx mdcms status
        env:
          MDCMS_API_KEY: ${{ secrets.MDCMS_API_KEY }}
          MDCMS_PROJECT: ${{ vars.MDCMS_PROJECT }}
          MDCMS_ENVIRONMENT: ${{ vars.MDCMS_ENVIRONMENT }}
          MDCMS_SERVER_URL: ${{ vars.MDCMS_SERVER_URL }}
If mdcms status reports drift on a pull request, the author should run mdcms schema sync and mdcms push locally before merging, or include the schema sync step in the merge workflow.