Check a website's llms.txt from the command line, Node or CI. Get a clear result for each check, with readable output or JSON.
Eight structure checks and two informational discovery checks. The result describes the file's structure and the home page's discovery links. It does not measure overall agent readiness or predict AI-search citations.
npm package · Try it in your browser · llms.txt guide · All turva.dev tools
Requires Node.js 18.17 or newer. Run it without a global install:
npx --yes turva-llms-txt-validator example.comReplace example.com with the domain you want to check. A domain, HTTP URL or HTTPS URL is accepted. Validation uses the host's /llms.txt and home page over HTTPS, regardless of the supplied path.
For repeated use, install the CLI globally:
npm install -g turva-llms-txt-validator
llms-txt-validate example.comThe summary comes last. Each preceding line reports one check. This shortened example uses the hosted validator's turva.dev result observed on 2026-09-09, formatted as the CLI prints it. The remaining passing checks are omitted here:
https://turva.dev/llms.txt
ok File exists at /llms.txt (HTTP 200)
ok Response is plain text (text/plain)
ok Starts with an H1 title ("# turva.dev")
result: valid
A warn identifies something to review, such as a missing blockquote summary. It does not fail the command unless you add --strict. A FAIL means a structural requirement failed. Each line includes the observed detail.
The eight structure checks determine the summary:
| Summary | Meaning | Default exit code | With --strict |
|---|---|---|---|
valid |
No structure warnings or failures | 0 |
0 |
valid with warnings |
At least one warning, no failures | 0 |
1 |
not valid |
At least one failure | 1 |
1 |
| Input or fetch error | Validation could not complete | 2 |
2 |
The two discovery checks return pass or info. They never change the summary or exit code, including in strict mode. If the home page cannot be read, those checks report info. The file's structure result still stands.
Use JSON for automation and strict mode when warnings should fail a CI step:
npx --yes turva-llms-txt-validator example.com --json --strictCompleted validation returns { target, summary, checks }. Each check contains { id, status, label, detail }. With --json, input and fetch errors return { "error": "..." } and exit with code 2.
| # | Check | Failure | Warning |
|---|---|---|---|
| 1 | /llms.txt returns HTTP 200 |
Non-200 response, rejected or excessive redirects | none |
| 2 | Response is plain text | Body looks like an HTML page | Content type is neither text/plain nor text/markdown |
| 3 | First non-empty line is a Markdown H1 | Missing H1, including a title indented as a code block | none |
| 4 | Blockquote summary follows the title | none | Missing summary |
| 5 | H2 sections group the content | none | No H2 sections, or no section contains a Markdown link list |
| 6 | Markdown links have names and absolute HTTP or HTTPS targets | none | Missing links, empty names, relative targets or unsupported targets |
| 7 | File is small enough to read cheaply | none | Over 50 KB, or truncated at the 256 KB read limit |
| 8 | File contains no HTML markup | none | HTML tags found |
Some failures stop the file checks early. For example, an HTML response is reported as a failed plain-text check rather than parsed as Markdown.
These checks are labelled v2 in the output. They look for link relations in the home page's HTML head or HTTP Link header.
| # | Check | Pass condition | Otherwise |
|---|---|---|---|
| 9 | Home page points to its llms.txt | rel="describedby" has a non-empty target |
info |
| 10 | Home page points to a Markdown version | rel="alternate" has media type text/markdown and a non-empty target |
info |
The validator detects these declarations without fetching their targets. It also does not follow the links inside llms.txt, crawl the site or test whether an AI agent can complete a task there.
Install the package in your project:
npm install turva-llms-txt-validatorUse an ES module, for example validate.mjs:
import { validateHost } from "turva-llms-txt-validator";
const result = await validateHost("example.com");
console.log(result.summary);
for (const check of result.checks) {
console.log(check.status, check.label, check.detail);
}validateHost rejects on invalid input or a failed /llms.txt fetch. Structural failures are returned in checks with the summary not valid.
Add this step to a GitHub Actions job that already has Node.js 18.17 or newer available. Replace your-domain.com with your domain:
- name: Validate llms.txt
run: npx --yes turva-llms-txt-validator your-domain.com --strictThe same command works in Woodpecker and other runners with Node installed. Omit --strict if warnings should remain advisory.
The default validation requests two documents: https://<host>/llms.txt and https://<host>/. Redirects may add requests, but linked pages and discovery targets are never fetched. The validator stores no results.
- Timeout: eight seconds per document, shared across its redirect chain.
- Read limit: 256 KB per response.
- Redirects: up to four hops, over HTTPS, to the same host or its
www/apex equivalent. Off-site redirects, embedded credentials and unsupported ports are rejected. - Host checks: IP literals, bracketed IPv6 addresses, localhost and the internal-use TLDs
local,internal,home,lan,corp,testandinvalidare rejected before a request is sent. Redirect targets are checked too.
DNS resolution is not checked for private addresses. A syntactically public domain can resolve to a private IP, so if you expose this package through a service that accepts untrusted domains, enforce private-address restrictions at the network layer. Local and CI runs use their own network policy. The hosted validator runs on the Cloudflare edge.
For vulnerability reporting and supported versions, see SECURITY.md.
The hosted validator accepts any public domain in the browser. It requests the same two documents, /llms.txt and the home page, and runs the same checks. Its source is in the turva.dev Cloudflare Worker. The hosted validator is the canonical implementation: if results diverge, this package is updated to match it.
The hosted version also returns JSON with the same result shape:
curl -H "Accept: application/json" "https://turva.dev/llms-txt-validator?url=example.com"In Windows PowerShell, use curl.exe if curl resolves to Invoke-WebRequest.
The package has no runtime dependencies. The repository's release workflow uses npm trusted publishing with provenance. See SECURITY.md for details and CHANGELOG.md for releases.
markdown-parity-check is a separate tool for a different question. This validator reads the structure of llms.txt and the home page's discovery links. The parity check compares the main content of one page's HTML and Markdown versions and reports changed text, numbers, links or blocks. It requires Node.js 22 or newer:
npx --yes markdown-parity-check --url https://example.com/page --format jsonReplace the URL with your page. If Markdown is served at another address, add --markdown-url https://example.com/page.md. Its browser version on turva.dev checks turva.dev's own pages only. See the comparison README for local-file mode, exit codes and limits.
MIT. Built by Erik Rekola at turva.dev.