Configuration
Save repeatable scan settings in a JSON file. Command-line options usually override the file. Some settings work only as command-line flags; the tables below call out those limits.
Use this reference to choose scan categories, report formats, and time limits. It separates settings for the command-line tool from options for your own application.
See the command-line options for individual commands and understand your score for the results.
The config file
A config file lets a repository keep its scan settings under version control instead of in a long command line. The CLI looks for these names in the working directory, in this order, and uses the first that exists:
agent-lighthouse.config.json.agent-lighthouserc.json.agent-lighthouserc
All three are parsed as JSON. An auto-discovered file that fails to parse is reported as a warning and ignored, and the scan continues with defaults.
--config <path> overrides the search with an explicit file. In that case the file must exist and must parse: a missing path or invalid JSON is a fatal error rather than a fall back to auto-discovery.
{
"url": "https://staging.yourstore.com",
"preset": "ecommerce",
"minScore": 80,
"assertCategories": {
"structured-data": 90,
"access-crawl-control": 75
},
"output": ["terminal", "html", "json", "md"],
"outputDir": "./reports"
}
With that file in place, agent-lighthouse audit — the sub-command with no URL after it — scans the declared URL and enforces the declared budgets. Any invocation whose first argument is a flag reads the file too, so agent-lighthouse --silent and agent-lighthouse --config ./ci/staging.json also pick the URL up from it.
A bare agent-lighthouse with no arguments at all does not: it prints the usage block and exits 1 before the config file is opened. See cli.md.
Keys
| Key | Type | Default | Effect |
|---|---|---|---|
url |
string |
none | Target URL, used when the invocation gives none — see cli.md for which forms read it. |
preset |
"ecommerce" | "saas" | "content" | "quick" | "full" |
"full" |
Preset name shown in the run header. |
minScore |
number (0–100) |
0 |
Overall-score budget; the run exits 1 below it. |
assertCategories |
Record<string, number> |
{} |
Per-category budgets, keyed by category id. |
output |
Array<"terminal" | "html" | "json" | "md"> |
["terminal", "html", "json"] |
Report formats to produce. |
outputDir |
string |
"./reports" |
Where report files are written. |
timeout |
number (seconds) |
180 |
Wall-clock budget for the scan; 0 disables it. --timeout overrides it. |
categories |
string[] |
— | Not read by the CLI. Use the --categories flag instead. |
maxPages |
number |
— | Not read by anything. The page budget is fixed; see Fixed limits. |
The config file accepts the last two keys, but they do not change the scan. Use the --categories command-line option to limit categories. You cannot change the page limit with maxPages.
Precedence
For every setting that both surfaces expose, the order is:
command-line flag → config file → built-in default.
assertCategories is the one exception, and it merges rather than overrides: thresholds from the config file and thresholds from repeated --assert-category flags are combined, with a flag winning for a category named in both.
defineConfig
@forkpoint/agent-lighthouse-core exports a defineConfig identity helper for authoring a config object in TypeScript with full type checking:
import { defineConfig } from "@forkpoint/agent-lighthouse-core";
export default defineConfig({
url: "https://staging.yourstore.com",
minScore: 80,
});
Note that the CLI’s loader reads JSON only — it does not import a .ts or .js config. Use defineConfig when you build the object in your own script (and, if you want the CLI to read it, write the result out as JSON).
The eight categories
Every audit belongs to exactly one category. These ids are what --categories and assertCategories accept, and what the JSON report keys its category results by.
| Id | Name | What it covers |
|---|---|---|
access-crawl-control |
Access & Crawl Control | Whether named AI crawlers and agents are allowed in at all: robots.txt groups for GPTBot, ClaudeBot, PerplexityBot and their peers, blanket blocks, bot walls, edge parity, HTTPS, and declared usage terms. |
content-extraction |
Content Extraction | Whether a fetched page yields clean text: server-rendered HTML, a findable main content region, semantic structure, and the cost of getting to it. |
machine-discovery |
Machine Discovery | The machine-readable index of the site: llms.txt and llms-full.txt, sitemaps and their freshness, feeds, and .well-known surfaces. |
structured-data |
Structured Data | Schema.org correctness: valid JSON-LD, Product, Offer, Organization, identifiers such as SKU and GTIN, and review and service markup. |
answer-readiness |
Answer Readiness | Whether the content can be quoted as an answer: direct definitions, question headings, first-paragraph answers, comparison tables, dated and specific claims, trust signals. |
agent-interfaces |
Agent Interfaces | The programmatic surface an agent can call: WebMCP tools, MCP server declarations, OpenAPI specs and their discovery, agents.json, and search actions. |
agentic-commerce |
Agentic Commerce | Whether a transaction can be completed by an agent: offer truth, availability, product identifiers, checkout eligibility and payment surfaces. |
operability-safety |
Agent Operability & Safety | Whether an agent can operate the site without breaking it: reachable endpoints, stability, accessible controls, security.txt, tdmrep, and safety signals. |
Narrow a scan with the flag:
agent-lighthouse https://yourstore.com --categories structured-data,agentic-commerce
Unlisted categories are not scanned at all, so their audits appear nowhere in the report and contribute nothing to the score. An unknown id is rejected before the scan starts, with the valid list printed and exit code 1.
Experimental audits
--categories and --experimental are two independent filters over the same registry, applied together.
--categoriesdecides which categories run.--experimentaldecides whether experimental-tier audits are part of the run. They are excluded by default.
An experimental audit carries weight 0 whether or not it runs, so this flag can never move a score — it only adds results to the report. See scoring.md for the tiers and the evidence policy for what puts an audit in each one.
Programmatic options
runScan(url, options) from @forkpoint/agent-lighthouse-core takes the same decisions as ScanOptions:
| Option | Type | Default | Effect |
|---|---|---|---|
categories |
string[] |
all eight | Restrict the scan to these category ids. Unknown ids match nothing — validate them at your entry point so a typo is heard. |
includeExperimental |
boolean |
false |
Include experimental-tier audits, reported but never scored. |
onEvent |
(event: ScanEvent) => void |
none | Progress callback; the CLI’s progress display and its NDJSON stream are both built on it. |
pages |
PageOverride[] | null |
none | Scan these exact URLs with a declared page type instead of relying on discovery. |
signal |
AbortSignal |
none | Cancel an in-flight scan. |
timeoutMs |
number |
180000 |
Wall-clock budget. When it runs out the scan finishes with what it has and records it under conditions.budget; 0 disables it. |
import { runScan } from "@forkpoint/agent-lighthouse-core";
const report = await runScan("https://yourstore.com", {
categories: ["structured-data", "agentic-commerce"],
includeExperimental: false,
pages: [
{ url: "https://yourstore.com/products/blue-widget", pageType: "product" },
{ url: "https://yourstore.com/collections/widgets", pageType: "category" },
],
onEvent: (event) => console.error(JSON.stringify(event)),
});
console.log(report.overallScore, report.scoreTier);
A PageOverride declares { url, pageType }, where pageType is homepage, category, product or content. The declared type is forced onto that page, so type-gated audits run against the page you meant rather than against whatever discovery guessed. Overrides are resolved, de-duplicated (ignoring a trailing slash) and any that collide with the homepage are dropped; the remaining page budget is filled by discovery.
Field-level product verification (report.productFields) is only produced when a page override with pageType: 'product' is supplied. Without one, the report marks it skipped rather than guessing from an auto-discovered page.
Environment variables
| Variable | Default | Effect |
|---|---|---|
LOG_LEVEL |
info |
Engine log verbosity: silent, error, warn, info or debug. --progress-json forces silent. |
SCANNER_A11Y_MAX_PAGES |
3 |
How many pages get the jsdom-based accessibility pass. Accessibility problems are template-wide, so the first few pages are representative; 0 disables the pass entirely and its audits degrade to not-applicable. |
A11Y_CONCURRENCY |
3 |
How many of those accessibility passes run at once. |
Fixed limits
These are compile-time constants in packages/core/src/constants.ts and packages/core/src/fetcher.ts. There is no flag, config key or environment variable for them. The scan budget is the one exception: its default is a constant, and --timeout, the timeout key and timeoutMs change it.
| Limit | Value |
|---|---|
| Pages per scan | 6 — the homepage plus five more, whether discovered or overridden |
| Request timeout | 10 seconds per request |
| Scan budget | 180 seconds per scan by default; see --timeout in cli.md |
| Response body read | 5 MB, after which the body is truncated |
| Scanner user agent | AgentLighthouse/1.0 (+https://github.com/ForkPoint/agent-lighthouse) |
The user agent is deliberately identifiable so that site owners can recognise, rate-limit or allow a scan in their logs. Individual audits that probe crawler parity send other user agents on purpose, to compare how the site answers a named AI crawler versus an ordinary browser.