← All guides Automate

Add cursor-doctor to your CI pipeline in 2 minutes

March 4, 2026 · Catch broken rules, conflicts, and syntax errors before they merge.

tl;dr

Add this to .github/workflows/cursor-rules.yml:

- uses: nedcodes-ok/cursor-doctor@v1

Every PR now checks your Cursor rules for errors before merge.

why lint Cursor rules in CI

i built cursor-doctor after watching teams waste hours debugging rules that "stopped working." The problem is always the same: someone added a rule with broken YAML frontmatter, or two rules contradicted each other, or a glob pattern had a typo. Cursor doesn't warn you. The rule silently fails and your team wonders why the AI is ignoring instructions.

Linting in CI catches these before they reach your team:

GitHub Actions setup

Create .github/workflows/cursor-rules.yml in your repo:

name: Cursor Rules Health Check

on:
  push:
    branches: [main]
  pull_request:
    branches: [main]

jobs:
  lint-cursor-rules:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - uses: nedcodes-ok/cursor-doctor@v1

This runs on every push to main and on every pull request. If cursor-doctor finds issues, the workflow fails and the PR can't merge.

Tip: The action handles Node.js setup automatically. No setup-node step needed.

action inputs

Two optional inputs:

- uses: nedcodes-ok/cursor-doctor@v1
  with:
    path: './my-project'       # Path to scan (default: '.')
    fail-on-warning: 'true'    # Fail on warnings too (default: 'false')

only run when rules change

Save CI minutes with a paths filter:

on:
  push:
    branches: [main]
    paths:
      - '.cursor/rules/**'
      - '.cursorrules'
      - 'CLAUDE.md'
      - 'AGENTS.md'
  pull_request:
    branches: [main]
    paths:
      - '.cursor/rules/**'
      - '.cursorrules'
      - 'CLAUDE.md'
      - 'AGENTS.md'

what the output looks like

Here's actual output from cursor-doctor lint on a project with a few issues:

cursor-doctor v1.10.24 -- lint

.cursor/rules/testing.mdc  (3 warnings)
  ⚠ Vague rule detected: "follow best practices" (line 5)
    → Replace with a specific instruction. Say exactly what
      to do: what tool, what pattern, what format.
  ⚠ Description is very short (<10 chars)
    → A descriptive description helps Cursor decide when to
      apply this rule.
  ⚠ Description is identical to filename
    → Describe what the rule does, not just repeat the filename.

.cursor/rules/types.mdc  (1 warning, 1 info)
  ⚠ Rule uses weak language: "try to/maybe/consider"
    → AI models follow commands better than suggestions. Use
      imperative mood: "Do X" instead of "try to do X".
  ℹ Multiple globs could be simplified: *.ts, *.tsx
    → Consider using ["*.{ts,tsx}"] for cleaner syntax.

──────────────────────────────────────────────────
4 warnings, 1 info, 1 passed

  ⚡ 4 issues can be auto-fixed.  Run: npx cursor-doctor fix

The check command (used by default in CI) gives a pass/fail health grade:

▒▒ Cursor Health: A ▒▒

  ██████████████████████████████  96%

  ✓ Rule syntax
  ✓ No legacy .cursorrules
  ✓ Token budget within limits
  ✓ No semantic conflicts

  4 passed  0 issues

Grades D and F fail the build. A, B, and C pass.

pre-commit hook

CI is your safety net. Catch issues before you even push with a pre-commit hook.

Copy the included hook script:

cp node_modules/cursor-doctor/scripts/pre-commit-hook.sh .git/hooks/pre-commit
chmod +x .git/hooks/pre-commit

Or create .git/hooks/pre-commit manually:

#!/usr/bin/env bash
# cursor-doctor pre-commit hook

STAGED=$(git diff --cached --name-only --diff-filter=ACM \
  | grep -E '\.mdc$|\.cursorrules$|CLAUDE\.md$|AGENTS\.md$')

if [ -z "$STAGED" ]; then
  exit 0
fi

echo "cursor-doctor: checking staged rule files..."
npx cursor-doctor check
exit $?

The hook only runs when you stage rule files. If cursor-doctor finds issues, the commit is blocked.

Note: Pre-commit hooks are local only. They don't transfer when someone clones your repo. Use CI as the enforced gate.

what cursor-doctor catches in CI

frontmatter errors

glob pattern mistakes

semantic conflicts

cursor-doctor checks 48 semantic conflict patterns across formatting, imports, error handling, state management, and more.

vague instructions

These don't change model behavior. They just waste tokens. Replace them with specific instructions like "extract functions longer than 20 lines" or "add JSDoc comments to exported functions."

other CI platforms

The GitHub Action runs npx cursor-doctor check under the hood. Use the same command anywhere with Node.js:

GitLab CI

lint-cursor-rules:
  image: node:20
  script:
    - npx cursor-doctor check
  only:
    - merge_requests
    - main

CircleCI

version: 2.1
jobs:
  lint-cursor-rules:
    docker:
      - image: cimg/node:20.0
    steps:
      - checkout
      - run: npx cursor-doctor check
workflows:
  check-rules:
    jobs:
      - lint-cursor-rules

Jenkins

pipeline {
  agent any
  stages {
    stage('Lint Cursor Rules') {
      steps {
        sh 'npx cursor-doctor check'
      }
    }
  }
}

Exit code 0 means healthy. Exit code 1 means issues found. Same on every platform.

testing locally

Run the same check CI will run:

npx cursor-doctor check

For the detailed breakdown:

npx cursor-doctor lint

Fix the issues, push, and the CI check passes on the first try.

Pro tip: npx cursor-doctor fix --preview shows what auto-fixes are available. Many issues (frontmatter syntax, boolean strings, glob corrections) can be fixed automatically. First fix is free, all fixes with Pro ($9).

related guides

Start linting Cursor rules in CI

One line of YAML. Zero config. Broken rules never merge again.

- uses: nedcodes-ok/cursor-doctor@v1