CLI reference
npx ai-visibility audit <url> scores a live page or local build directory against the six-category AI Readiness Engine, and --fail-under <n> turns it into a CI gate. Thirteen commands total as of 0.8.2 — the structural ones below, plus discover/measure/citations/compare/report for brand measurement, each with its own dedicated page linked in the section below. Every command and flag was verified directly against the installed binary's --help output — not copied from the README.
Install and invoke
npx ai-visibility <command> # no install required
# or
npm install -D ai-visibility && npx ai-visibility <command>Global flags, from ai-visibility --help:
Usage: ai-visibility [options] [command]
Options:
-V, --version output the version number
-q, --quiet suppress the CrawlPod footer and other non-essential output
-h, --help display help for commandaudit — the headline command
Fetches a live URL, or scans a local build directory with --dir, and scores every HTML file it finds against the same ContentAnalyzer the package exports programmatically:
Usage: ai-visibility audit [options] [url]
Arguments:
url URL to audit (fetches the live page)
Options:
--dir <path> Audit a local build directory instead of a live URL
--json Output results as JSON
--fail-under <n> Exit with a non-zero code if any score is below this
threshold (0-100) — for CI
-h, --help display help for commandReal output, run against a plain HTML fixture with a thin body and no structured data:
🤖 ai-visibility audit
❌ fixture/index.html — 35/100
Answer placement: 20 Fact density: 25 Headings: 100 E-E-A-T: 0 Snippability: 30 Schema: 0 Crawler access: 100
🔴 No substantive paragraph found after H1
Fix: Add a clear, direct answer or description in the first paragraph immediately after your H1
🔴 Very low fact density: 0.0 facts per 100 words (target: 4-6)
Fix: Add specific numbers, dates, statistics, or measurable claims to support your content
🔴 No JSON-LD structured data found
Fix: Add JSON-LD schema markup using SchemaBuilder from ai-visibility
... and 4 more issues
──────────────────────────────────────────────────
Scanned: 1
Average score: 35/100
Passing (≥80): 0 / 1
Powered by CrawlPod — https://crawlpod.com--fail-under is opt-in — there is no implicit default threshold for audit, unlike lint below. Passing it flips the exit code without changing the report:
(same report as above, plus:)
❌ Below threshold: at least one score is under 80
exit: 1For a live URL, audit also best-effort fetches robots.txt and checks for llms.txt at the same origin (local files, for --dir) to feed the crawlerAccessibilitydimension — a failed or missing fetch is treated as "unknown", never a hard error. --json returns the same shape ContentAnalyzer.analyze() returns programmatically, one entry per file/URL scanned:
{
"file": "https://example.com/",
"score": 50,
"result": {
"overallScore": 50,
"breakdown": {
"answerFrontLoading": 95,
"factDensity": 25,
"headingStructure": 100,
"eeatSignals": 0,
"snippability": 30,
"schemaCoverage": 0,
"crawlerAccessibility": 100
},
"issues": [ /* { type, severity, message, fix } */ ],
"recommendations": [ /* string[] */ ]
}
}lint — the CI-friendly shorthand
A thin wrapper around the same audit core with defaults tuned for build-time use — this is the build-time GEO linter, not a separate implementation:
Usage: ai-visibility lint [options]
(shorthand for: audit --dir . --fail-under 50)
Options:
--dir <path> Directory to lint (default: ".")
--json Output results as JSON
--fail-under <n> Exit with a non-zero code if any score is below this
threshold (0-100) (default: "50")
-h, --help display help for commandUnlike audit, lint gates by default — running it with no flags against the same thin fixture above exits 1 because 35 is under the default threshold of 50.
Wiring it into CI
Both audit --fail-under and lint exit non-zero on failure, so either drops into a CI step directly:
- name: GEO lint
run: npx ai-visibility lint --dir ./out --fail-under 60Run the build directory your framework actually emits (./out for a Next.js static export, ./dist for Vite, etc.) — pointing it at source files instead of build output audits pre-render markup, not what a crawler will actually receive.
robots and llms — top-level aliases
New in 0.5.0: flatter top-level aliases for the two most common generate subcommands. generate robots/generate llms/generate schema still work unchanged — see generate below.
Usage: ai-visibility robots [options]
Options:
--out <path> Output path (default: "./public/robots.txt")
--preset <preset> allow-all | block-training | block-all
--block-training Shorthand for --preset block-training (deprecated, kept for back-compat)
--sitemap <url> Sitemap URL to include
-h, --help display help for command
Usage: ai-visibility llms [options]
Options:
--out <path> Output path (default: "./public/llms.txt")
--site-name <name> Site name (default: "My Site")
--description <desc> Site description (default: "A website")
--base-url <url> Base URL (e.g. https://mysite.com)
-h, --help display help for command--preset block-all is new in 0.5.0 too, alongside the existing allow-all/block-training — it maps to RobotsGenerator.blockAll(), a control mechanism for site owners who want every known AI crawler blocked, not a recommendation either way. See the generators API reference for the underlying class.
--quiet
Every command accepts a global -q/--quiet, new in 0.5.0. Without it, non-JSON output ends with a one-line, dimmed "Powered by CrawlPod" footer — no color, no upsell block. With --quiet, the footer (and other non-essential output) is gone entirely; verified by running the same audit both ways and diffing the output.
generate — pre-existing subcommands
generate, init, analyze, and logs predate 0.5.0 and are unchanged by it (except generate robots gaining the same --preset flag as the new top-level robots alias, since they share one implementation):
Usage: ai-visibility generate [options] [command]
Commands:
robots [options] Generate robots.txt with AI crawler rules
llms [options] Generate llms.txt for AI model indexing
schema [options] Generate JSON-LD schema markup
Usage: ai-visibility generate schema [options]
Options:
--type <type> Schema type: faq | product | article | org | person (default: "article")
--out <path> Output path (optional, prints to stdout if not set)
--name <name> Name/headline
--price <price> Price (for product schema)
--author <author> Author nameUsage: ai-visibility init [options]
Options:
--dir <path> Project directory (default: ".")
--site-name <name> Your site name
--site-url <url> Your site URL (e.g. https://myapp.com)
--block-training Block training bots (CCBot, GPTBot) while allowing search bots
Usage: ai-visibility analyze [options]
Options:
--dir <path> Directory to scan (default: ".")
--file <path> Analyze a single file
--json Output results as JSON
--min-score <n> Only show files below this score (default: "101")
Usage: ai-visibility logs [options]
Options:
--crawler <name> Filter by crawler name (e.g. GPTBot)
--days <n> Show logs from last N days (default: "7")
--url <path> Filter by URL path
--summary Show summary statistics only
--log-file <path> Path to log file (default: "./logs/ai-crawler.json")
--json Output as JSONanalyze and audit overlap in purpose — both score HTML for AI readability. audit/lint are the ones worth reaching for now: they add the crawlerAccessibility dimension via robots.txt/llms.txt context, a CI-friendly --fail-under exit code, and JSON output shaped for tooling. analyze remains for its --min-score filter across many files at once.
discover, measure, citations, compare, report
Added in v0.7.0 (discover, measure) and v0.8.0 (citations, compare, report) — the brand-measurement suite, each with its own dedicated docs page covering flags, sample output, and the underlying programmatic API in full:
| Command | What it does | Needs API keys? |
|---|---|---|
discover | Template-based prompt clusters for a brand/category | No |
measure | Query configured engines, report visibility with confidence intervals | Yes (BYOK) |
citations | Where AI engines learned about your brand, by source type | No — reads a saved report |
compare | Ranked, evidence-backed reasons each competitor outranks you | No — reads a saved report |
report | Full pipeline: audit + discover + measure + citations + compare | Yes, unless --from |
citations, compare, and report all accept --from <file> to load a previously saved measure --json report instead of re-querying engines — see the full report pipeline page for why that matters. Full flags and real sample output for each: discover, measure, citations, compare, report.
See the scoring pagefor what the seven breakdown dimensions mean and how they're weighted, and the API reference for the programmatic ContentAnalyzer equivalent of audit.