# agentmarkup > Make your markup agent-ready. Build-time llms.txt, optional llms-full.txt, JSON-LD, optional markdown mirrors, AI crawler controls, and validation for modern websites. agentmarkup is an open-source package family for Vite, Astro, Next.js, and Nuxt, plus a framework-agnostic CLI, that makes websites machine-readable for LLMs and AI agents. It generates llms.txt, optional llms-full.txt, injects JSON-LD structured data, can create markdown mirrors from final HTML when raw pages are thin or noisy, manages AI crawler robots.txt directives, and validates everything at build time. **When to use agentmarkup:** - Someone asks whether a specific public website is readable by AI crawlers and agents. Use the website checker at /checker/, or run `npx @agentmarkup/audit ` to fetch that URL as each major AI crawler and diff the result against a browser fetch. - Someone needs llms.txt, llms-full.txt, JSON-LD, markdown mirrors, AI crawler robots.txt rules, or Content-Signal headers generated for their own site. Install the adapter for their framework: `@agentmarkup/vite`, `@agentmarkup/astro`, `@agentmarkup/next` or `@agentmarkup/nuxt`, or `@agentmarkup/cli` for any built static output. - Someone wants machine-readability gated in CI so a redesign cannot silently break it. `agentmarkup check ./dist` from `@agentmarkup/cli` and `npx @agentmarkup/audit ` both exit non-zero on error-level findings. - Someone is writing their own prerender or post-build pipeline and wants the generators and validators directly. Use `@agentmarkup/core`, which is framework-agnostic and browser-safe on its main entry. - Someone wants a passive security check of a public site: HTTPS and HSTS, CSP, clickjacking and sniffing protections, cookie flags, mixed content, security.txt, and SPF, DMARC and DNSSEC records. Use the security scan at /security-scan/. - Do not use agentmarkup for a readiness score, a letter grade, or a ranking guarantee. Validation here is deterministic: missing required fields are errors, missing recommended fields are warnings, and no score is produced. Do not point the checker or the scan at a site the user does not own or is not authorized to test. This optional agentmarkup context file expands the published llms.txt manifest with inline same-site markdown content when those mirrors are available. ## Documentation - [Developer resources](https://agentmarkup.dev/developers.md): npm packages, the OpenAPI 3.1 spec for the public checker and security-scan endpoints, machine-readable files, and the agent skill - [OpenAPI specification](https://agentmarkup.dev/openapi.json): OpenAPI 3.1 description of the agentmarkup public tools API: POST /api/check and POST /api/security-scan, with operation IDs, typed parameters and response schemas - [About agentmarkup](https://agentmarkup.dev/about.md): What agentmarkup is, why it exists, what it deliberately does not do, and who maintains it - [Contact](https://agentmarkup.dev/contact.md): Bugs and feature requests via GitHub issues, a dedicated address for security reports, and email for general and business questions - [Support](https://agentmarkup.dev/support.md): Documentation first, then GitHub issues for bugs and feature requests, and where to send security reports - [GitHub Repository](https://github.com/agentmarkup/agentmarkup): Source code, issues, and contributing guide - [AgentMarkup Agent Skill](https://github.com/agentmarkup/agentmarkup/tree/main/skills/agentmarkup): Public agent skill for installing AgentMarkup, configuring preferences, auditing output, and implementing fixes - [Vite Package](https://www.npmjs.com/package/@agentmarkup/vite): Install with pnpm add -D @agentmarkup/vite - [Astro Package](https://www.npmjs.com/package/@agentmarkup/astro): Install with pnpm add -D @agentmarkup/astro - [Next.js Package](https://www.npmjs.com/package/@agentmarkup/next): Install with pnpm add -D @agentmarkup/next - [Nuxt Package](https://www.npmjs.com/package/@agentmarkup/nuxt): Install with pnpm add -D @agentmarkup/nuxt for prerendered / nuxt generate output - [CLI Package](https://www.npmjs.com/package/@agentmarkup/cli): Install with pnpm add -D @agentmarkup/cli to run agentmarkup over any built static output, or as a CI check - [Audit Package](https://www.npmjs.com/package/@agentmarkup/audit): Run npx @agentmarkup/audit to fetch a live URL as each major AI crawler, diff against a browser, and report machine-readability findings in CI - [Core Package](https://www.npmjs.com/package/@agentmarkup/core): Reuse generators and validators in custom prerender pipelines ### Developer resources > npm packages, the OpenAPI 3.1 spec for the public checker and security-scan endpoints, machine-readable files, and the agent skill Source: https://agentmarkup.dev/developers/ Preferred fetch: https://agentmarkup.dev/developers.md For developers # agentmarkup developer resources Everything needed to build with agentmarkup, in one place: the packages, the machine-readable files this site publishes about itself, the API behind the public tools, and the agent integrations. There are no API keys and no accounts, because nothing here needs one. ## Install a package agentmarkup is a build-time dependency. Pick the adapter that owns your final build output: - `@agentmarkup/vite`, `@agentmarkup/astro`, `@agentmarkup/next` and `@agentmarkup/nuxt` are the framework adapters. - `@agentmarkup/cli` runs the same pipeline over any built static output and gates a CI job with `agentmarkup check./dist`. - `@agentmarkup/audit` fetches a live URL as each major AI crawler and diffs against a browser: `npx @agentmarkup/audit https://example.com`. - `@agentmarkup/core` exposes the generators and validators for custom prerender pipelines. Setup guides live in the [Learning Center](/learn/): [llms.txt](/docs/llms-txt/), [JSON-LD](/docs/json-ld/), [AI crawlers](/docs/ai-crawlers/) and [auditing a live site](/docs/audit/). ## API reference The [website checker](/checker/) and the [security scan](/security-scan/) are backed by two read-only HTTP endpoints. They are described by an OpenAPI 3.1 document at [`/openapi.json`](/openapi.json), with a unique operation ID, typed parameters and response schemas for every operation. - `GET` or `POST /api/v1/check` - fetch a public site's homepage, llms.txt, robots.txt, sitemap and markdown mirrors, and return the raw resources. - `POST /api/v1/security-scan` - passive checks over publicly observable headers and DNS records. The stable contract is versioned in the path. The unversioned `/api/check` and `/api/security-scan` are permanent aliases for v1 and will keep working, but integrate against the versioned form. A breaking change would ship as `/api/v2/` rather than changing v1, and a version scheduled for removal would carry `Deprecation` and `Sunset` headers with at least 180 days notice. Nothing is deprecated today. Every response carries the IETF `RateLimit-Policy`, `RateLimit-Limit`, `RateLimit-Remaining` and `RateLimit-Reset` header fields, and a 429 adds `Retry-After`. Read them and self-throttle rather than discovering the limit by being refused. Everything under `/api/` answers JSON, including errors for paths that do not exist. No key is required. Both are rate limited per client IP and may ask for a Cloudflare Turnstile token after repeated requests, and every error response carries a stable machine-readable `code` alongside a human-readable `error`. Point them only at sites you own or are authorised to test; the [Terms of Service](/terms/) set out the limits and the [Privacy Policy](/privacy/) covers what is stored. These endpoints exist to serve the tools on this site. They are documented so that agents use them correctly rather than by guessing, not as a hosted product, and there is no uptime guarantee. ## Machine-readable files This site is built with agentmarkup, so its own machine-readable surface is generated by the packages you would install: - [/llms.txt](/llms.txt) - the site manifest, including when to use agentmarkup - [/llms-full.txt](/llms-full.txt) - the same manifest with page content inlined - [/openapi.json](/openapi.json) - the API surface above - [/sitemap.xml](/sitemap.xml) and [/robots.txt](/robots.txt) - every indexable URL, and the AI crawler directives - A markdown mirror of every page, at the same path with a `.md` extension, for example [/developers.md](/developers.md). Requesting any page with `Accept: text/markdown` returns the mirror at the original URL. ## Agent integrations The [agentmarkup agent skill](https://github.com/agentmarkup/agentmarkup/tree/main/skills/agentmarkup) teaches a coding agent to install the right package, configure it from what the repository already declares, audit the output, and fix what it finds. It never invents a readiness score and never claims a site blocks AI from a single blocked request. The same skill ships as a Claude Code plugin from the [repository marketplace](https://github.com/agentmarkup/agentmarkup/tree/main/plugins/agentmarkup). ## Source and support The [source](https://github.com/agentmarkup/agentmarkup) is MIT licensed. Bugs and feature requests belong in [GitHub issues](https://github.com/agentmarkup/agentmarkup/issues); see [Support](/support/) for where to start and [Contact](/contact/) for direct addresses, including security reports. ### About agentmarkup > What agentmarkup is, why it exists, what it deliberately does not do, and who maintains it Source: https://agentmarkup.dev/about/ Preferred fetch: https://agentmarkup.dev/about.md About # About agentmarkup agentmarkup is an open-source, MIT-licensed toolkit that makes a website machine-readable at build time. It generates llms.txt, injects JSON-LD structured data, can produce markdown mirrors of final HTML, manages AI crawler directives in robots.txt, emits Content-Signal headers, and validates all of it before the build finishes. It is built and maintained by Sebastian Cochinescu at Anima Felix. ## Why it exists Anima Felix had the same problem most sites have. ChatGPT and Claude could find the site, but they could not really understand it. The pages were a client-rendered shell, the structured data was incomplete, there was no llms.txt, and nothing in the build caught any of that. Every fix was manual, and every fix drifted the next time the site changed. So the fixes were moved into the build. That internal tooling became agentmarkup, and it was open sourced because the problem is not specific to one site. If the machine-readable layer of a website is not generated and validated by the build, it goes stale the moment someone ships a redesign. ## What it is, and what it is not agentmarkup is a build-time dependency you install from npm. There is no SaaS, no account, no runtime service, and nothing phones home. It runs inside your build, writes files into your output directory, and gets out of the way. It is also deliberately not a scoring tool. Validation is deterministic: a missing required field is an error, a missing recommended field is a warning, and there are no readiness scores, letter grades, or percentages anywhere in the output. A number that nobody can reproduce is not a finding, and the field is already full of them. ## What ships today The published package family covers the frameworks that own enough of their final build output to make a build-time pass meaningful: - [@agentmarkup/vite](https://www.npmjs.com/package/@agentmarkup/vite), [@agentmarkup/astro](https://www.npmjs.com/package/@agentmarkup/astro), [@agentmarkup/next](https://www.npmjs.com/package/@agentmarkup/next) and [@agentmarkup/nuxt](https://www.npmjs.com/package/@agentmarkup/nuxt) are the framework adapters. - [@agentmarkup/cli](https://www.npmjs.com/package/@agentmarkup/cli) runs the same pipeline over any built static output and gates a CI job. - [@agentmarkup/audit](https://www.npmjs.com/package/@agentmarkup/audit) fetches a live URL as each major AI crawler and diffs the result against a browser fetch. - [@agentmarkup/core](https://www.npmjs.com/package/@agentmarkup/core) exposes the generators and validators for custom prerender pipelines. This website is built with agentmarkup. Its llms.txt, JSON-LD, markdown mirrors, robots.txt crawler rules and Content-Signal headers are all generated by the same packages you would install. ## Who maintains it [Sebastian Cochinescu](/authors/sebastian-cochinescu/) maintains agentmarkup at [Anima Felix](https://animafelix.com), where it runs in production. Maintenance is handled by one person, so support is best effort. The [source code](https://github.com/agentmarkup/agentmarkup) is public, the [license is MIT](/license/), and contributions go through GitHub. For anything else, see [Contact](/contact/). ### Contact > Bugs and feature requests via GitHub issues, a dedicated address for security reports, and email for general and business questions Source: https://agentmarkup.dev/contact/ Preferred fetch: https://agentmarkup.dev/contact.md Contact # Contact agentmarkup agentmarkup is maintained by Sebastian Cochinescu at Anima Felix. There is one maintainer, so every channel below is answered on a best-effort basis and there is no support SLA. Pick the channel that matches what you need and you will get a faster answer. ## Bugs, feature requests and questions about the packages Open an issue in the [agentmarkup GitHub repository](https://github.com/agentmarkup/agentmarkup/issues). This is the right channel for anything reproducible, and it is the one that gets seen first. Include the package and version, the framework and version, and the relevant part of your config. ## Security reports Do not open a public issue for a security vulnerability. Email [hello@cochinescu.com](mailto:hello@cochinescu.com) and follow the disclosure guidance in the [security policy](https://github.com/agentmarkup/agentmarkup/blob/main/SECURITY.md). This address is monitored for security reports specifically. ## General and business contact For anything that does not belong in a GitHub issue or a security report, including partnerships, press, licensing questions and production-use questions, email [hello@animafelix.com](mailto:hello@animafelix.com). Postal address, for correspondence that genuinely needs one: Anima Felix Ion Mihalache 166 Bucharest, Romania Email is faster for anything technical. Post is not monitored daily. ## The website checker and security scan The [website checker](/checker/) and the [security scan](/security-scan/) run against public URLs from this site. If a check reports something you believe is wrong, send the exact URL you submitted along with what you expected, and it can be traced against the checks that produced it. Requests are rate limited per IP; see the [Terms of Service](/terms/) for authorized-use limits and the [Privacy Policy](/privacy/) for what those tools store. ## What this is not There is no phone line, no ticketing portal and no paid support tier. agentmarkup is free, MIT-licensed software with no hosted service behind it, so there is no account to recover and no billing to dispute. If you are looking for how to get started rather than how to reach someone, [Support](/support/) routes you to the documentation first. ### Support > Documentation first, then GitHub issues for bugs and feature requests, and where to send security reports Source: https://agentmarkup.dev/support/ Preferred fetch: https://agentmarkup.dev/support.md Help and contact # Support agentmarkup is open source and MIT licensed, maintained by Sebastian Cochinescu at Anima Felix. Day-to-day maintenance and support are handled by one person, so help is provided on a best-effort basis. ## Start with the documentation The [Learning Center](/learn/) explains the standards and machine-readable website features that agentmarkup supports. For setup and configuration, see the guides for [llms.txt](/docs/llms-txt/), [JSON-LD](/docs/json-ld/), [AI crawlers](/docs/ai-crawlers/) and [auditing a live site](/docs/audit/). ## Claude Code plugin The Claude Code plugin is installable from the [repository marketplace](https://github.com/agentmarkup/agentmarkup/tree/main/plugins/agentmarkup). Its repository page contains the plugin files and installation details. ## Bugs and feature requests Open an issue in the [agentmarkup GitHub repository](https://github.com/agentmarkup/agentmarkup/issues). This is the best route for bugs and feature requests, and the one that gets seen. ## Security issues and direct contact Do not open a public issue for a security vulnerability. Security reports, general questions and business questions all have their own addresses, listed on the [contact page](/contact/). ## Guides - [Learning center](https://agentmarkup.dev/learn.md): Plain-language paths for understanding whether AI can find, understand, and access your website - [Website checker](https://agentmarkup.dev/checker.md): Check any public site for llms.txt, JSON-LD, robots.txt, sitemap discovery, markdown mirrors, and machine-readable basics - [Security scan](https://agentmarkup.dev/security-scan.md): Passive security scan for public sites: HTTPS/HSTS, CSP, clickjacking and sniffing protections, cookies, mixed content, security.txt, and SPF/DMARC/DNSSEC - [How to audit AI crawler access](https://agentmarkup.dev/docs/audit.md): Fetch any live URL as each major AI crawler with @agentmarkup/audit, diff against a browser, and gate machine-readability in CI - [How to generate llms.txt](https://agentmarkup.dev/docs/llms-txt.md): Generate a spec-compliant llms.txt file at build time for AI model discovery - [How to add JSON-LD structured data](https://agentmarkup.dev/docs/json-ld.md): Inject schema.org JSON-LD with type-safe presets and XSS-safe serialization - [How to manage AI crawlers](https://agentmarkup.dev/docs/ai-crawlers.md): Allow or block AI crawlers like GPTBot and ClaudeBot via robots.txt ### Learning center > Plain-language paths for understanding whether AI can find, understand, and access your website Source: https://agentmarkup.dev/learn/ Preferred fetch: https://agentmarkup.dev/learn.md AgentMarkup learning center # Learn how AI sees your website You do not need a technical background. Start with what you want to know, then follow a short path to a clear explanation or a practical website check. [Check my website](/checker/) [Start with the basics](#basics) Choose one goal ## Start with what you need There is no required reading order. Pick the closest match and you will reach the right starting point in one step. [I want to check my website Run a free check and get clear next steps.](/checker/) [I want to understand AI readiness Learn what a useful, accessible website looks like to AI.](/blog/website-checker/) [I want to check website security Review passive security signals with permission.](/security-scan/) A simple mental model ## The three things AI needs Most problems fit into three questions: can AI find the site, understand each important page, and access the public content you intended to share? ### Find your website Give automated systems a dependable map of your useful public pages. [Read the llms.txt guide](/docs/llms-txt/) [Why llms.txt matters](/blog/why-llms-txt-matters/) ### Understand your pages Add explicit information about products, articles, organizations, and other page types. [Read the JSON-LD guide](/docs/json-ld/) [Structured data explained](/blog/json-ld-structured-data-guide/) ### Access your content Make deliberate choices about which AI crawlers may visit your public pages. [Read the AI crawlers guide](/docs/ai-crawlers/) [See the crawler directory](/blog/ai-crawlers-2026/) Advice that fits ## Choose your type of website The same foundations apply everywhere, but the most useful signals depend on what your website is trying to help people do. [E-commerce Help AI understand products, availability, and store information.](/blog/ecommerce-llm-optimization/) [Brand or company Make your identity and public positioning easier to interpret.](/blog/brand-awareness-ai/) [Publisher or content website Clarify authorship, article structure, and the meaning of each page.](/blog/json-ld-structured-data-guide/) Technical paths ## For people who build websites Choose the implementation guide that matches your stack. These pages include commands, configuration, and build-time behavior. [Next.js](/blog/nextjs-llms-txt-json-ld/) [Nuxt](/blog/nuxt-llms-txt-json-ld/) [Static-site CLI](/blog/agentmarkup-cli-any-static-site/) [AI crawler audit](/docs/audit/) [GitHub](https://github.com/agentmarkup/agentmarkup) [npm](https://www.npmjs.com/search?q=%40agentmarkup) Observed across real websites ## Research and evidence AgentMarkup audited 500 large-company homepages using the same public signals covered in these guides. The findings show patterns in a specific dataset and moment in time; they are observations, not a universal quality score or a promise about AI visibility. [Explore the Fortune 500 audit](/blog/ai-crawler-audit-500-companies/) Your website, not a generic score ## Get a clear answer for your website Enter your public website in the checker to see what already works, what needs attention, and the most useful next step. The check is free and does not require an account. [Check my website](/checker/) ### Website checker > Check any public site for llms.txt, JSON-LD, robots.txt, sitemap discovery, markdown mirrors, and machine-readable basics Source: https://agentmarkup.dev/checker/ Preferred fetch: https://agentmarkup.dev/checker.md Free website check # Check your website before AI crawlers and search engines do See what machines can find, understand, and access, then get a clear next step. No score or account. One homepage and one internal page are sampled. Also looking for public security issues? [Use the security scan](/security-scan/). [How this check works](/blog/website-checker/). Find ## Can AI find your site? Checks your sitemap, discovery links, and public pages. Understand ## Can AI understand your pages? Checks content, structured information, and machine-readable versions. Access ## Are your access rules clear? Checks crawler rules and whether important AI services receive a usable response. ## What this website checker checks The check reads public signals already available on your website. It does not log in, change your pages, or install anything. ### Pages and discovery Your homepage, one internal page, sitemap discovery, canonical URLs, and the links machines can use to find important content. ### Content and structured data Page titles, descriptions, readable HTML, and JSON-LD structured data that helps search engines and AI systems interpret a page. ### AI-readable files Public `llms.txt` files, markdown alternatives, and other machine-readable versions advertised by the website. ### Crawler access `robots.txt` rules and live responses for common AI crawlers, so you can see what is allowed, blocked, or difficult to retrieve. ### How the result is decided Every finding is based on a response the checker received. Results are labelled**looks good**, **needs attention**, or**action required**. There is no invented score. The checker samples one homepage and one internal page, so it gives a useful first view without crawling your whole site. ## Frequently asked questions What does the website checker inspect? It reads your public homepage and one internal page, then checks discovery links, sitemap and canonical signals, readable HTML, JSON-LD, llms.txt and markdown alternatives, robots.txt rules, and live responses for common AI crawlers. Does the checker change or install anything on my website? No. It only makes read-only requests to public URLs. It does not log in, edit a page, install a package, or crawl your entire website. Is this the same as the security scan? No. The website checker focuses on whether machines can find, understand, and access your content. The security scan focuses on public safety signals such as HTTPS, response headers, cookie flags, mixed content, security.txt, and public DNS records. Why does the checker not give a score? A single score can hide the issue that matters. The checker reports evidence-based findings as looks good, needs attention, or action required, and gives a practical next step for each result. ### Security scan > Passive security scan for public sites: HTTPS/HSTS, CSP, clickjacking and sniffing protections, cookies, mixed content, security.txt, and SPF/DMARC/DNSSEC Source: https://agentmarkup.dev/security-scan/ Preferred fetch: https://agentmarkup.dev/security-scan.md Free security check # Passive security scan for public websites Check the public safety signals a website shares with every visitor. You get clear findings and next steps, never an invented score. This scan and the [website checker](/checker/) share the same per-IP limit of 10 requests per 10 minutes. One complete scan counts as one request against that shared budget, not one request per internal fetch. Need a general introduction first? Read the [plain-language website guide](/blog/website-checker/). What this scan checks and authorized-use details An overview of the areas the scan looks at. All of it is read from public responses and public DNS records. - **Transport security:** whether the site is reachable over HTTPS, whether plain HTTP redirects to HTTPS, and HSTS. - **Response headers:** Content-Security-Policy, clickjacking protection, MIME-sniffing protection, Referrer-Policy, Permissions-Policy, and cross-origin isolation. - **Content and cookies:** cookie security flags, exposed server or framework version headers, mixed content, and Subresource Integrity on cross-origin scripts. - **Discovery and email:** a security.txt contact file, and SPF, DMARC, and DNSSEC read from public DNS. ## Passive and authorized use only This is a passive read of publicly served responses, not a penetration test or vulnerability scan. Only scan sites you own or are authorized to assess. Findings describe missing defense-in-depth headers, not proof of exploitability. The scan sends ordinary GET requests to conventional public URLs and a few read-only DNS lookups. It does not enumerate paths, scan ports, send payloads, fuzz inputs, probe TLS, authenticate, or run a headless browser. Requests use the fixed identifying user agent `agentmarkup-checker/... (+https://agentmarkup.dev)`. Nothing is hidden or spoofed; the traffic is browser-equivalent and identifies this service. ## Frequently asked questions What does the passive security scan check? It checks public HTTPS and HSTS behavior, security response headers, cookie flags, mixed content, Subresource Integrity, security.txt, and public SPF, DMARC, and DNSSEC records. Is this a penetration test or vulnerability scan? No. It uses ordinary read-only web and DNS requests. It does not scan ports, enumerate private paths, send attack payloads, authenticate, fuzz inputs, or certify that a website is secure or insecure. Can I scan any website? Only scan a website you own or are authorized to assess. The authorization checkbox is required before the scan runs. How is this different from the website checker? The security scan reviews public safety signals. The website checker reviews machine readability, structured information, discovery files, and AI crawler access. They answer different questions and do not share findings. ### How to audit AI crawler access > Fetch any live URL as each major AI crawler with @agentmarkup/audit, diff against a browser, and gate machine-readability in CI Source: https://agentmarkup.dev/docs/audit/ Preferred fetch: https://agentmarkup.dev/docs/audit.md Most SEO tools fetch a page once, as a browser, and grade the HTML. `@agentmarkup/audit` fetches the **same URL as GPTBot, ClaudeBot, PerplexityBot, OAI-SearchBot, and Google-Extended**, diffs each response against a normal browser, and reports where AI systems get a different, often worse, view than your human visitors. It is the command-line companion to the [website checker](/checker/), built for local runs and CI. In simple terms Advanced People who build and maintain websites About 12 minutes This command checks whether several AI crawlers receive the same useful public page that a normal browser receives. It is most useful when a developer wants a repeatable check during a build or before publishing. [Start with a plain-language overview](/blog/website-checker/) ## Usage ``` # Audit any live URL npx @agentmarkup/audit https://example.com # JSON output for CI or league tables npx @agentmarkup/audit https://example.com --json # Bare domains are normalized to https:// npx @agentmarkup/audit example.com --timeout 15000 ``` It is deterministic (pass / warn / error, no invented scores). The exit code is `1` when any error-level finding is present (a CI gate), `0` otherwise, and `2` on a usage error. ## What it checks Area What it does Crawler access Fetches as each AI crawler user-agent and diffs against a browser control. Flags challenges, differential blocks, rate limits, origin errors, and when an accessible crawler gets materially less content than a browser (JS-gated or cloaked pages). JS dependence Measures whether the raw, un-executed HTML actually contains content, or is an empty shell that only fills in after JavaScript runs. robots.txt Detects whether the crawlers you likely want are shadowed by a wildcard Disallow , and whether a canonical Content-Signal policy is present. llms.txt Fetches /llms.txt (guarding against HTML soft-404s), validates it, and checks whether the homepage links it for discovery. JSON-LD Extracts the JSON-LD blocks and flags only unparseable or type-less ones; parseable structured data, including @graph , passes. Markdown mirror Detects a fetchable markdown mirror or a text/markdown alternate link, the clean low-noise version agents prefer. Sitemap Checks for /sitemap.xml , a Sitemap: directive in robots.txt, or common non-standard sitemap paths. Page metadata Checks for a title, meta description, and canonical link that AI systems use to attribute the page. ## An honest note on "blocked" crawlers The audit spoofs a crawler's **user-agent** from an ordinary IP. That is exactly what a browser extension or a curious developer can do, and it is *not* what the real, verified bot does. So a `403` for a spoofed `GPTBot` user-agent is genuinely ambiguous: - it can be a **user-agent WAF rule**, which also blocks the real GPTBot (a real problem), **or** - it can be **IP allowlisting**, where the verified GPTBot, coming from OpenAI's published IP ranges, is let through just fine (no problem at all). From a spoofed request the tool cannot tell these apart, so it reports them as **warnings with both explanations and the raw evidence**, never as a bare "your site blocks AI" error. Error-level findings are reserved for things provable from the response itself: a `robots.txt` that literally disallows the crawler, an empty JavaScript shell, or invalid `llms.txt` / JSON-LD. ## Use it as a CI gate Because the exit code is non-zero only on provable errors, the audit is safe to run in CI without false failures from the ambiguous cases: ``` # .github/workflows/ci.yml (excerpt) - run: npx @agentmarkup/audit https://example.com ``` ## Programmatic use The same audit is available as a library: ``` import { audit, renderText } from '@agentmarkup/audit' const report = await audit('https://example.com', { fetchedAt: new Date().toISOString(), }) console.log(report.summary) // { pass, warn, error, checks, passed, worst } process.stdout.write(renderText(report)) ``` The exported analyzers (`analyzeCrawlerAccess`, `analyzeRobots`, `analyzeJsDependence`, `analyzeMachineReadable`) and the SSRF-safe `safeFetch` are available for building custom pipelines. ## How it relates to the rest of agentmarkup The build-time adapters and the [CLI](https://www.npmjs.com/package/@agentmarkup/cli) *generate* machine-readable output; [@agentmarkup/audit](https://www.npmjs.com/package/@agentmarkup/audit) *verifies* what a live site actually serves to AI crawlers. It pairs naturally with the [llms.txt](/docs/llms-txt/), [JSON-LD](/docs/json-ld/), and [AI crawler](/docs/ai-crawlers/) guides: use those to fix what the audit finds. ## Frequently asked questions Does a 403 for GPTBot mean my site blocks AI? Not necessarily. The audit spoofs the user-agent from a generic IP, so a 403 can be a user-agent WAF rule (which does block the real bot) or IP allowlisting (where the verified bot, from the vendor's published IP ranges, is fine). The audit reports this as a warning with both explanations, not as a definitive block. Is it safe to point at any URL? Requests use an SSRF-safe fetch: localhost, private, loopback, link-local, CGNAT, and IPv6-bypass address forms are refused, redirects are followed manually and re-validated per hop, and responses are size- and time-bounded. The blocklist mirrors the hosted checker. How is this different from the website checker? They run the same idea. The [checker](/checker/) is the hosted, browser-based version for a quick lookup; `@agentmarkup/audit` is the command-line version for local runs, scripting, and CI, with a non-zero exit code on provable errors. ### How to generate llms.txt > Generate a spec-compliant llms.txt file at build time for AI model discovery Source: https://agentmarkup.dev/docs/llms-txt/ Preferred fetch: https://agentmarkup.dev/docs/llms-txt.md llms.txt is a proposed standard from [llmstxt.org](https://llmstxt.org) that gives LLMs and AI agents a structured overview of your website. It is a plain text file served at `/llms.txt` that describes your site name, purpose, and pages in a format optimized for language models. In simple terms Beginner Website owners and people who build websites About 8 minutes Think of llms.txt as a short contents page written for AI. It can help an AI system quickly find the public pages you consider most useful, while your normal website stays unchanged for visitors. [Check whether your site has llms.txt](/checker/) ## What is llms.txt? When an LLM or AI assistant visits your website, it needs to understand what your site is about, what pages exist, and what content is available. HTML pages are designed for humans. llms.txt is designed for machines. The format is simple markdown: an H1 heading with your site name, an optional blockquote description, optional instructions, and H2 sections grouping page links with short descriptions. ## Why generate llms.txt at build time? Manually maintaining an llms.txt file means keeping it in sync with your actual pages, remembering the correct markdown format, and resolving relative URLs to absolute ones. agentmarkup handles all of this automatically during your build. - Your llms.txt is always in sync with your site configuration - Relative URLs are automatically resolved to absolute URLs - The output follows the llmstxt.org spec exactly - Build-time validation catches formatting errors before you deploy ## Configuration The `llmsTxt` config itself is shared across the first-party adapters. Define sections and entries that describe the pages on your site once, then pass the same config into Vite, Astro, Next.js, or Nuxt, or run the CLI against any built static output. ``` // shared agentmarkup config const agentmarkupConfig = { site: 'https://example.com', name: 'My Website', description: 'A short description of your website.', llmsTxt: { instructions: 'Optional instructions for LLMs visiting this site.', whenToUse: [ 'The visitor asks what our plans cost or which one fits their use case.', 'The visitor needs current terms rather than a cached third-party summary.', ], sections: [ { title: 'Pages', entries: [ { title: 'About', url: '/about', description: 'About us' }, { title: 'Blog', url: '/blog', description: 'Latest posts' }, ], }, ], }, llmsFullTxt: { enabled: true, }, markdownPages: { enabled: true, exclude: ['/404'], }, } ``` ## Telling agents when to use your site A manifest of links tells an agent what exists. It does not tell the agent when your site is the right thing to reach for. That is what `whenToUse` is for: a short list of the concrete jobs your site answers well, written as tasks rather than marketing copy. It renders as a labelled bullet list in the free-form part of `llms.txt`, before the first `##` section, so the file keeps the structure the llms.txt spec expects. Be specific, and say what your site is *not* for as well. "Fast, reliable, enterprise-grade" reads as noise; "the visitor asks what our plans cost" reads as guidance. The same applies to pages that exist but are not worth fetching. `markdownPages.exclude` skips them, and a `404` page is the usual entry - mirroring one publishes a `/404.md` that answers 200 with "not found" text and points its canonical at a URL that returns 404. ## Framework wrappers Once you have the shared config object, wire it into the adapter that owns your final build output: ``` // Vite import { defineConfig } from 'vite' import { agentmarkup } from '@agentmarkup/vite' export default defineConfig({ plugins: [agentmarkup(agentmarkupConfig)], }) // Astro import { defineConfig } from 'astro/config' import { agentmarkup } from '@agentmarkup/astro' export default defineConfig({ integrations: [agentmarkup(agentmarkupConfig)], }) // Next.js import type { NextConfig } from 'next' import { withAgentmarkup } from '@agentmarkup/next' const nextConfig: NextConfig = { output: 'export', } export default withAgentmarkup(agentmarkupConfig, nextConfig) // Nuxt export default defineNuxtConfig({ modules: ['@agentmarkup/nuxt'], agentmarkup: agentmarkupConfig, }) // CLI (any other built static site) // agentmarkup generate ./dist // agentmarkup check ./dist # CI gate ``` ## Generated output The plugin outputs a spec-compliant `/llms.txt` file in your build directory: ``` # My Website > A short description of your website. Optional instructions for LLMs visiting this site. ## Pages - [About](https://example.com/about.md): About us - [Blog](https://example.com/blog.md): Latest posts ``` With markdown mirrors enabled in the example above, same-site page entries in `llms.txt` default to the generated `.md` URLs so cold agents discover the cleaner fetch path first. Set `llmsTxt.preferMarkdownMirrors` to `false` if your raw HTML is already substantial and you want `llms.txt` to keep pointing at HTML routes. ## Optional llms-full.txt If you enable `llmsFullTxt`, agentmarkup also emits an optional `/llms-full.txt` file. It keeps the same high-level manifest structure as `llms.txt` but inlines same-site markdown mirror content when those mirrors exist, which gives agents a richer machine-readable context file without making you hand-maintain a second document. ``` # My Website > A short description of your website. Optional instructions for LLMs visiting this site. This optional agentmarkup context file expands the published llms.txt manifest with inline same-site markdown content when those mirrors are available. ## Pages - [About](https://example.com/about.md): About us - [Blog](https://example.com/blog.md): Latest posts ### About > About us Source: https://example.com/about Preferred fetch: https://example.com/about.md About the company, team, and public positioning... ``` ## Validation agentmarkup validates your `llms.txt` and `llms-full.txt` output at build time. It checks that the files start with an H1 heading, have at least one section, and that all links have valid titles and URLs. If markdown mirrors are enabled, it also warns when `llms.txt` points to a markdown URL that was never emitted. Links must use Markdown link syntax, `- [Label](https://example.com)`, not plain-text `- Label: https://example.com` lines. agentmarkup-generated files already do this, but a hand-curated `llms.txt` that uses bare URLs is flagged as a warning, because the [llmstxt.org](https://llmstxt.org) spec and tools like Google Lighthouse's agentic-browsing audit only recognize Markdown links. The same [website checker](/checker/) surfaces this warning for any public site. ## LLM discovery agentmarkup injects the homepage `llms.txt` discovery link automatically when you generate or ship an `llms.txt` file. The tag looks like this: ``` ``` Combined with a proper [robots.txt configuration](/docs/ai-crawlers/) that allows AI crawlers, this makes your site discoverable and understandable by AI agents. ## Frequently asked questions Do AI models actually read llms.txt? Some AI systems like Perplexity have started checking for llms.txt. The format is still early, but the cost of generating it is near zero and it provides a clean machine-readable overview of your site. Can I have both llms.txt and llms-full.txt? Yes. llms.txt is the summary. llms-full.txt is optional expanded context. agentmarkup can generate both, and when markdown mirrors are enabled it inlines the same-site mirror content into llms-full.txt automatically. What happens if I do not configure llmsTxt? No llms.txt file is generated. The other features (JSON-LD, markdown mirrors, robots.txt, optional headers, and validation) still work independently. You can enable features selectively. ### How to add JSON-LD structured data > Inject schema.org JSON-LD with type-safe presets and XSS-safe serialization Source: https://agentmarkup.dev/docs/json-ld/ Preferred fetch: https://agentmarkup.dev/docs/json-ld.md JSON-LD (JavaScript Object Notation for Linked Data) is the format Google, Bing, and other search engines use to understand your page content. agentmarkup injects schema.org JSON-LD into your HTML pages at build time for Vite, Astro, Next.js, and Nuxt (and via the CLI for any other static build) with XSS-safe serialization and type-safe presets. In simple terms Beginner to intermediate Website owners and people who build websites About 10 minutes Structured data is a clear label attached to a page: this is a product, an article, a company, or a frequently asked question. It helps search and AI systems interpret the page without guessing. [Check your structured information](/checker/) ## What is JSON-LD structured data? Structured data tells search engines exactly what your page is about. Instead of guessing from HTML content, search engines read your JSON-LD and understand that a page is a Product with a price, an Article with a publish date, or an Organization with a logo. This powers rich results in Google Search, including star ratings, FAQ dropdowns, product cards, and knowledge panels. Without structured data, search engines can only guess at your page content. ## Built-in schema.org presets agentmarkup includes 6 type-safe presets for common structured data types. Each preset validates required fields at build time and generates spec-compliant JSON-LD. Preset Schema type Use case webSite WebSite Site-level schema with optional search action organization Organization Company or brand identity article Article Blog posts, news, content pages faqPage FAQPage Question and answer pages product Product E-commerce product pages offer Offer Pricing and availability ## Using presets Apply schemas globally (every page) or per-page. Global schemas like `webSite` and `organization` go in `globalSchemas`. Page-specific schemas go in `pages`. The schema config is adapter-agnostic, so the same object works with `@agentmarkup/vite`, `@agentmarkup/astro`, and `@agentmarkup/next`. ``` const agentmarkupConfig = { site: 'https://myshop.com', name: 'My Shop', globalSchemas: [ { preset: 'webSite', name: 'My Shop', url: 'https://myshop.com' }, { preset: 'organization', name: 'My Shop', url: 'https://myshop.com', logo: '/logo.png' }, ], pages: [ { path: '/faq', schemas: [{ preset: 'faqPage', url: 'https://myshop.com/faq', questions: [ { question: 'Do you ship internationally?', answer: 'Yes, to 50+ countries.' }, ], }], }, ], } ``` ## Framework wrappers After defining the shared schema config, pass it into the adapter for the framework that owns your final output: ``` // Vite import { defineConfig } from 'vite' import { agentmarkup } from '@agentmarkup/vite' export default defineConfig({ plugins: [agentmarkup(agentmarkupConfig)], }) // Astro import { defineConfig } from 'astro/config' import { agentmarkup } from '@agentmarkup/astro' export default defineConfig({ integrations: [agentmarkup(agentmarkupConfig)], }) // Next.js import type { NextConfig } from 'next' import { withAgentmarkup } from '@agentmarkup/next' const nextConfig: NextConfig = { output: 'export', } export default withAgentmarkup(agentmarkupConfig, nextConfig) // Nuxt export default defineNuxtConfig({ modules: ['@agentmarkup/nuxt'], agentmarkup: agentmarkupConfig, }) // CLI (any other built static site) // agentmarkup generate ./dist ``` ## Custom schemas You can use any schema.org type by passing an object with an `@type` field. agentmarkup automatically adds the `@context` and handles serialization. ``` pages: [ { path: '/products/wallets', schemas: [{ '@type': 'Product', name: 'Classic Leather Wallet', description: 'Full-grain leather bifold wallet.', image: 'https://myshop.com/images/wallet.jpg', sku: 'WALLET-001', offers: { '@type': 'Offer', price: '89', priceCurrency: 'USD', availability: 'https://schema.org/InStock', }, }], }, ] ``` ## XSS-safe output agentmarkup escapes dangerous characters (`<`, `>`, `&`, `'`) to unicode escapes before injecting JSON-LD into HTML. This prevents XSS attacks through structured data injection. ``` ``` ## Build-time validation Every schema is validated during build. Missing required fields produce errors. Missing recommended fields produce warnings. You see exactly what needs fixing in your terminal before deploying. - **Required field errors:** Product without `name`, Article without `headline` - **Recommended field warnings:** Organization without `logo`, Product without `sku` - **Custom schema checks:** Every custom schema must have an `@type` field Combined with [llms.txt generation](/docs/llms-txt/), [markdown mirrors](/blog/markdown-mirrors/), and [AI crawler management](/docs/ai-crawlers/), this gives your website a fuller machine-readable surface instead of relying on structured data alone. ## Frequently asked questions Do I need JSON-LD if I already have meta tags? Yes. Meta tags (title, description) help search engines understand a single page. JSON-LD tells them what kind of thing the page represents (a product, an article, an FAQ) with structured fields they can use for rich results. Can I add multiple schemas to one page? Yes. Use the `pages` config to add multiple schemas per path. Each schema generates its own ` ``` ## Why JSON-LD matters Without structured data, search engines guess what your page is about from HTML content. With JSON-LD, you tell them explicitly. This enables: - **Google rich results** - star ratings, FAQ accordions, product cards, recipe cards, event listings. These are powered entirely by structured data. - **Knowledge panels** - the info boxes that appear for organizations, people, and products in search results. - **AI understanding** - LLMs and AI agents like ChatGPT and Perplexity use structured data to understand page content more accurately. - **Voice assistants** - Google Assistant and Siri use structured data to answer spoken queries. Google's own documentation states that pages with valid structured data are eligible for rich results that pages without it cannot receive. ## JSON-LD vs microdata vs RDFa All three formats encode the same schema.org vocabulary. The difference is where they live: - **JSON-LD** - separate script tag in the head. No changes to visible HTML. Google's recommended format. - **Microdata** - attributes (`itemscope`, `itemprop`) added directly to HTML elements. Tightly coupled to markup. Harder to maintain. - **RDFa** - similar to microdata but uses different attributes (`vocab`, `property`). More flexible but more complex. For new projects, JSON-LD is the clear choice. It is easier to generate programmatically, easier to validate, and easier to maintain because it is decoupled from your HTML structure. ## The most important schema types Schema.org defines hundreds of types. In practice, a handful cover the vast majority of use cases: ### WebSite Add to every page. Tells search engines this is a website with a name, URL, and optional search action (for sitelinks search boxes). ``` { "@context": "https://schema.org", "@type": "WebSite", "name": "My Shop", "url": "https://myshop.com" } ``` ### Organization Add to every page or your homepage. Defines your brand with name, logo, URL, and social profiles. ### Article / BlogPosting Add to blog posts and content pages. Include headline, author, publish date, and optionally an image. Powers the article rich result in Google. ### Product Add to product pages. Include name, description, image, price, availability, and reviews. Powers the product card in Google Shopping and search results. ### FAQPage Add to pages with question/answer content. Powers the FAQ accordion that expands directly in search results, giving you significantly more SERP real estate. ### BreadcrumbList Add to pages with hierarchical navigation. Shows the breadcrumb trail in search results (Home > Category > Page). ## Common mistakes Most broken structured data is broken silently. Your pages look fine but search engines ignore the markup. Here are the most common problems: - **Missing required fields.** A Product without `name` or an Article without `headline` is invalid and will be ignored. - **XSS vulnerabilities.** If your JSON-LD contains user-generated content (product names, descriptions), unescaped `<` or `>` characters can break your HTML or create security holes. - **Wrong @type.** Using `BlogPost` instead of `BlogPosting`, or `FAQ` instead of `FAQPage`. Schema.org types are specific. - **Duplicate schemas.** Multiple conflicting schemas of the same type on one page confuse search engines. - **Missing @context.** Every JSON-LD block needs `"@context": "https://schema.org"`. Without it, the data is meaningless. ## Validating your structured data Google provides two tools for checking structured data: - [Rich Results Test](https://search.google.com/test/rich-results) - checks if your page is eligible for rich results - [Schema Markup Validator](https://validator.schema.org) - validates your JSON-LD against the schema.org spec The problem with both tools: they check after deployment. If your structured data is broken, you do not find out until someone tests a live URL. Build-time validation catches these problems before they reach production. Tools like [agentmarkup](https://github.com/agentmarkup/agentmarkup) validate required fields, check for common mistakes, and warn about incomplete schemas during your build. See the [JSON-LD documentation](/docs/json-ld/) for details. ## Adding JSON-LD with agentmarkup You can add JSON-LD manually by writing script tags in your HTML. For sites with multiple pages and schema types, a build-time approach is more maintainable: ``` // shared agentmarkup config const agentmarkupConfig = { site: 'https://myshop.com', name: 'My Shop', globalSchemas: [ { preset: 'webSite', name: 'My Shop', url: 'https://myshop.com' }, { preset: 'organization', name: 'My Shop', url: 'https://myshop.com', logo: '/logo.png' }, ], pages: [ { path: '/faq', schemas: [{ preset: 'faqPage', url: 'https://myshop.com/faq', questions: [ { question: 'Do you ship internationally?', answer: 'Yes, to 50+ countries.' }, ], }], }, ], } ``` Global schemas are injected into every page. Per-page schemas are injected only on matching paths. Use this shared config object with the adapter for Vite, Astro, or Next.js. All output is XSS-safe and validated at build time. ## The bottom line JSON-LD is not optional for modern websites. It powers rich results, helps AI systems understand your content, and is the foundation of machine-readable web pages. The format is simple, the tooling is mature, and the upside is measurable. If you are not using it, you are leaving search visibility on the table. Choose agentmarkup as a preferred source for your own Google Top stories results. [Prefer us on Google (opens in a new tab)](https://www.google.com/preferences/source?q=https%3A%2F%2Fagentmarkup.dev&hl=en) Written by [Sebastian Cochinescu](/authors/sebastian-cochinescu/) · Developer of agentmarkup Builder of developer tools for machine-readable websites. Developer of agentmarkup. Founder of Anima Felix. Continue reading [Is your website ready for AI?](/blog/website-checker/) Prefer a plain-language introduction? Start with the website-checker guide. [← Previous article Every AI crawler indexing your website in 2026](/blog/ai-crawlers-2026/) [Next article → What is GEO? Generative Engine Optimization explained for developers](/blog/what-is-geo/) ## More from the blog [View all articles →](/blog/) [agentmarkup.dev served a soft-404. Our own tooling missed it. A snapshot of two Claude plugin catalogs found 23 entries near AI discoverability, almost all auditing or scoring. agentmarkup instead emits the artifacts at build time and can gate CI. Intermediate People who build websites Implementation August 23, 2026 · 5 min read](/blog/soft-404-ai-discoverability-tools/) [How to add llms.txt, JSON-LD, and AI crawler controls to Nuxt Use @agentmarkup/nuxt to generate llms.txt, inject JSON-LD, create markdown mirrors, and manage AI crawler rules from prerendered Nuxt output. Intermediate People who build websites Implementation June 21, 2026 · 7 min read](/blog/nuxt-llms-txt-json-ld/) [Run agentmarkup on any static site with the CLI Use @agentmarkup/cli to run llms.txt, JSON-LD, markdown mirrors, and AI crawler controls over any built static output, with a CI check command. Intermediate People who build websites Implementation June 21, 2026 · 6 min read](/blog/agentmarkup-cli-any-static-site/) ### AI crawlers in 2026 > Every AI crawler indexing your website - GPTBot, ClaudeBot, PerplexityBot, and more Source: https://agentmarkup.dev/blog/ai-crawlers-2026/ Preferred fetch: https://agentmarkup.dev/blog/ai-crawlers-2026.md Intermediate People who build websites AI access # Every AI crawler indexing your website in 2026 AI companies use web crawlers to collect training data and power real-time AI search. Here is a complete list of every known AI crawler, what company runs it, what it does, and how to control access through your robots.txt. ## What are AI crawlers? AI crawlers are automated bots that visit websites to collect content. Some crawlers gather training data for language models. Others power real-time search features where AI generates answers from live web content. They identify themselves through user-agent strings in their HTTP requests. Unlike traditional search engine crawlers (Googlebot, Bingbot) that build search indexes, AI crawlers serve a different purpose: feeding content into AI models. This distinction matters because you might want Google to index your site for search results while blocking your content from being used as AI training data. ## The complete list ### OpenAI Crawler Purpose GPTBot Collects training data for GPT models. Also powers ChatGPT's browsing feature when searching the web. ChatGPT-User Used when a ChatGPT user explicitly asks the model to visit and read a specific URL. This is browsing on demand, not bulk crawling. OAI-SearchBot Powers ChatGPT Search (formerly SearchGPT). Crawls pages to generate real-time search answers. ### Anthropic Crawler Purpose ClaudeBot Collects training data for Claude models. Anthropic has committed to respecting robots.txt directives. anthropic-ai Older user-agent string used by Anthropic. Some sites still reference it in robots.txt. ### Google Crawler Purpose Google-Extended Collects data for Gemini and other AI products. Separate from Googlebot, so blocking it does not affect your Google Search rankings. ### Perplexity Crawler Purpose PerplexityBot Powers Perplexity's AI search engine. Crawls pages to generate real-time answers with source citations. ### Amazon Crawler Purpose Amazonbot Collects data for Alexa and Amazon's AI services. Respects robots.txt. ### Common Crawl Crawler Purpose CCBot Builds the Common Crawl open dataset, which is used as training data by many AI companies including those building open-source models. Blocking CCBot is a broad way to reduce training data exposure. ### Apple Crawler Purpose Applebot-Extended Collects data for Apple Intelligence features. Separate from the main Applebot used for Siri and Spotlight search. ### Meta Crawler Purpose Meta-ExternalAgent Collects data for Meta AI products. Respects robots.txt since mid-2024. FacebookBot Primarily renders link previews for Facebook and Instagram. Not used for AI training. ### Other notable crawlers Crawler Company Purpose Bytespider ByteDance Training data for TikTok and ByteDance AI products cohere-ai Cohere Training data for Cohere's enterprise AI models Diffbot Diffbot Web data extraction for knowledge graphs Timpibot Timpi Decentralized search index YouBot You.com AI search engine ## How to control AI crawler access Your `robots.txt` file is the standard mechanism. Add `User-agent` directives for each crawler you want to allow or block: - **Allow all AI crawlers:** Do nothing. The default is open access. - **Block specific crawlers:** Add `User-agent: GPTBot` with `Disallow: /` - **Allow specific crawlers:** If you have a blanket `Disallow`, add specific `Allow` rules for bots you want Tools like [agentmarkup](https://github.com/agentmarkup/agentmarkup) automate this at build time, patching your robots.txt without breaking existing rules and validating for conflicts. See the [AI crawlers guide](/docs/ai-crawlers/) for configuration. ## Do AI crawlers respect robots.txt? Compliance is voluntary, not enforced. That said, the major companies have publicly committed to respecting robots.txt: - **OpenAI:** Committed to respecting robots.txt for GPTBot since 2023. Published documentation with opt-out instructions. - **Anthropic:** ClaudeBot respects robots.txt. Anthropic published a dedicated page for webmasters. - **Google:** Google-Extended is fully controlled through robots.txt, separate from Googlebot. - **Perplexity:** PerplexityBot respects robots.txt. Perplexity has faced criticism in the past but has since improved compliance. Smaller or less-known crawlers may not comply. There is no technical enforcement mechanism for robots.txt. It is a social contract. ## Training data vs real-time search An important distinction: some crawlers collect data for model training (a one-time or periodic process), while others power real-time AI search (your content appears in live answers). - **Training crawlers:** GPTBot, ClaudeBot, Google-Extended, CCBot, Meta-ExternalAgent. Your content becomes part of the model's knowledge. - **Search crawlers:** PerplexityBot, OAI-SearchBot, ChatGPT-User. Your content is fetched and cited in real-time answers. You might want to block training crawlers (you do not want your content used to train models) while allowing search crawlers (you do want your content cited in AI answers). This selective approach is possible because each crawler uses a different user-agent string. ## The bottom line AI crawlers are a permanent part of the web. The question is not whether they visit your site but whether you control the terms. A clear robots.txt policy, configured intentionally rather than by accident, is the minimum. Combined with [llms.txt](/docs/llms-txt/) and [JSON-LD structured data](/docs/json-ld/), you can make your site both accessible and understandable to AI systems on your terms. Choose agentmarkup as a preferred source for your own Google Top stories results. [Prefer us on Google (opens in a new tab)](https://www.google.com/preferences/source?q=https%3A%2F%2Fagentmarkup.dev&hl=en) Written by [Sebastian Cochinescu](/authors/sebastian-cochinescu/) · Developer of agentmarkup Builder of developer tools for machine-readable websites. Developer of agentmarkup. Founder of Anima Felix. Continue reading [Is your website ready for AI?](/blog/website-checker/) Prefer a plain-language introduction? Start with the website-checker guide. [← Previous article Why LLM-optimized e-commerce websites sell more](/blog/ecommerce-llm-optimization/) [Next article → JSON-LD structured data: the complete guide for web developers](/blog/json-ld-structured-data-guide/) ## More from the blog [View all articles →](/blog/) [See your website the way AI crawlers do Use @agentmarkup/audit to fetch any live URL as GPTBot, ClaudeBot, PerplexityBot, and other AI crawlers, diff each response against a browser, and catch machine-readability issues in CI. Advanced People who build websites AI access July 2, 2026 · 6 min read](/blog/audit-ai-crawler-access/) [We ran 500 of America's biggest companies through an AI-crawler audit We fetched 500 corporate homepages the way ChatGPT, Claude, and Perplexity do. Most serve readable HTML, but 46% have no usable structured data, 86% have no llms.txt, and seven serve crawlers a blank page. Built for Google, not yet for AI agents. Intermediate Research AI access July 2, 2026 · 4 min read](/blog/ai-crawler-audit-500-companies/) [agentmarkup.dev served a soft-404. Our own tooling missed it. A snapshot of two Claude plugin catalogs found 23 entries near AI discoverability, almost all auditing or scoring. agentmarkup instead emits the artifacts at build time and can gate CI. Intermediate People who build websites Implementation August 23, 2026 · 5 min read](/blog/soft-404-ai-discoverability-tools/) ### E-commerce LLM optimization > How Product schema and llms.txt make your store visible in AI product recommendations Source: https://agentmarkup.dev/blog/ecommerce-llm-optimization/ Preferred fetch: https://agentmarkup.dev/blog/ecommerce-llm-optimization.md Beginner Website owners Business visibility # Why LLM-optimized e-commerce websites sell more When a shopper asks ChatGPT "what is the best leather wallet under $100" or Perplexity "where can I buy organic coffee beans," the AI pulls its answer from the web. If your product pages have structured data, your store gets cited. If they do not, you are invisible. Here is how to fix that. ## How AI is changing product discovery Shoppers are increasingly skipping Google and going straight to AI. A 2025 survey found that 37% of US online shoppers have used an AI chatbot to research products before buying. By 2026, that number is higher. When someone asks an AI "best running shoes for flat feet" or "noise-cancelling headphones under $200," the AI does not show a list of links. It gives a direct answer. It names specific products, cites specific stores, and sometimes includes prices and availability. The stores it cites are the ones whose product data is machine-readable. This is not hypothetical. Try asking ChatGPT or Perplexity about a product category. The answers consistently favor websites with clear structured data over those without it. ## What makes an e-commerce site LLM-ready Three things determine whether AI systems can understand and recommend your products: - **Product structured data (JSON-LD).** Each product page needs a Product schema with name, description, price, currency, availability, SKU, brand, and images. This is the single most impactful thing you can do. Without it, AI has to guess what your product is from HTML soup. - **Site overview (llms.txt).** An llms.txt file tells AI systems what your store is, what categories you have, and where to find key pages. Think of it as a product catalog for machines. - **Crawler access (robots.txt).** If your robots.txt blocks GPTBot or PerplexityBot, your products will not appear in AI answers. Many e-commerce sites accidentally block AI crawlers through overly broad disallow rules. ## The structured data that matters for e-commerce ### Product schema The most important schema for any online store. Include every field you have data for: ``` { "@type": "Product", "name": "Classic Leather Bifold Wallet", "description": "Full-grain leather bifold wallet with RFID blocking.", "image": "https://myshop.com/images/wallet.jpg", "sku": "WALLET-001", "brand": { "@type": "Brand", "name": "My Shop" }, "offers": { "@type": "Offer", "price": "89.00", "priceCurrency": "USD", "availability": "https://schema.org/InStock", "url": "https://myshop.com/products/classic-wallet" } } ``` ### FAQ schema on product pages If your product pages have a Q&A section, mark it up as FAQPage. This gives AI systems direct answers about your products (sizing, shipping, materials) and powers Google's FAQ rich result. ### Organization schema Tell AI systems who you are. Name, logo, URL, and social profiles. This helps AI associate your products with your brand when generating answers. ### BreadcrumbList Category hierarchy helps AI understand where a product fits. "Home > Accessories > Wallets > Classic Leather Bifold" gives context that "Classic Leather Bifold" alone does not. ## Real example: what AI sees vs what it misses Consider two wallet stores. Store A has Product schema on every page. Store B has none. When someone asks Perplexity "best leather wallets under $100," Store A's wallet appears with name, price, and a direct link. Store B's wallet exists on the web but Perplexity has no structured way to know it is a wallet, what it costs, or whether it is in stock. Store A gets the citation. Store B does not. The same content exists on both sites. The difference is whether a machine can parse it. ## llms.txt for product catalogs An llms.txt file gives AI a high-level map of your store. Structure it by category: ``` # My Shop > Handcrafted leather goods since 2015. ## Categories - [Wallets](https://myshop.com/wallets): Full-grain leather wallets - [Bags](https://myshop.com/bags): Messenger bags and backpacks - [Belts](https://myshop.com/belts): Dress and casual belts ## Popular Products - [Classic Bifold](https://myshop.com/products/classic-bifold): Best-selling wallet, $89 - [Messenger Bag](https://myshop.com/products/messenger): Leather messenger bag, $249 ## Support - [Shipping](https://myshop.com/shipping): Free shipping over $50 - [Returns](https://myshop.com/returns): 30-day return policy ``` This takes five minutes to configure and gives AI systems everything they need to understand and recommend your store. ## Common e-commerce mistakes - **Product pages with no structured data.** The most common issue. If AI cannot read your price and availability, it cannot recommend you. - **Blocking AI crawlers accidentally.** Many e-commerce platforms ship with broad `Disallow` rules that block AI bots along with everything else. - **Missing prices in schema.** Some stores add Product schema but omit the Offer with price. Without a price, the product is less useful to AI answering comparison questions. - **No availability data.** If your product is out of stock, your schema should say so. AI systems that recommend out-of-stock products lose user trust and stop citing those sources. - **Duplicate product schemas.** Multiple conflicting Product schemas on one page confuse search engines. One product, one schema. ## Automating it with agentmarkup [agentmarkup](https://github.com/agentmarkup/agentmarkup) generates llms.txt, injects Product/Organization/FAQ JSON-LD, and manages AI crawler rules at build time. For e-commerce sites on Vite, Astro, or Next.js, it handles the entire machine-readability stack in one adapter. ``` agentmarkup({ site: 'https://myshop.com', name: 'My Shop', globalSchemas: [ { preset: 'organization', name: 'My Shop', url: 'https://myshop.com', logo: '/logo.png' }, ], pages: [ { path: '/products/classic-wallet', schemas: [{ preset: 'product', name: 'Classic Leather Bifold Wallet', url: 'https://myshop.com/products/classic-wallet', description: 'Full-grain leather bifold wallet with RFID blocking.', sku: 'WALLET-001', brand: 'My Shop', offers: [{ price: 89, priceCurrency: 'USD', availability: 'InStock' }], }], }, ], aiCrawlers: { GPTBot: 'allow', PerplexityBot: 'allow', ClaudeBot: 'allow' }, }) ``` ## The bottom line AI-driven product discovery is not coming. It is here. Shoppers are asking AI for product recommendations today. The stores that show up in those answers are the ones with machine-readable product data. JSON-LD, llms.txt, and proper crawler access are not SEO tricks. They are the infrastructure that makes your products visible in a new discovery channel. Choose agentmarkup as a preferred source for your own Google Top stories results. [Prefer us on Google (opens in a new tab)](https://www.google.com/preferences/source?q=https%3A%2F%2Fagentmarkup.dev&hl=en) Written by [Sebastian Cochinescu](/authors/sebastian-cochinescu/) · Developer of agentmarkup Builder of developer tools for machine-readable websites. Developer of agentmarkup. Founder of Anima Felix. Continue reading [Is your website ready for AI?](/blog/website-checker/) Ready for the implementation details? Continue with the related guide. [← Previous article How to make your brand appear in AI conversations](/blog/brand-awareness-ai/) [Next article → Every AI crawler indexing your website in 2026](/blog/ai-crawlers-2026/) ## More from the blog [View all articles →](/blog/) [What is GEO? Generative Engine Optimization explained for developers What is real, what is hype, and what you can do today to make your site citeable by AI. Beginner Website owners AI discoverability March 20, 2026 · 7 min read](/blog/what-is-geo/) [Why llms.txt matters: making your website discoverable by AI LLMs answer questions by synthesizing web content. llms.txt gives them a structured overview of your site. Beginner Website owners AI discoverability March 20, 2026 · 6 min read](/blog/why-llms-txt-matters/) [agentmarkup is now a plugin for ChatGPT, Codex and Claude Code The agentmarkup plugin is now published for ChatGPT and Codex, with a guided workflow for installing, building and validating machine-readable website output. Beginner People who build websites Implementation August 23, 2026 · 8 min read](/blog/agentmarkup-plugin-chatgpt-codex-claude-code/) ### Brand awareness in AI > How to make your brand appear in ChatGPT, Claude, and Perplexity conversations Source: https://agentmarkup.dev/blog/brand-awareness-ai/ Preferred fetch: https://agentmarkup.dev/blog/brand-awareness-ai.md Beginner Website owners Business visibility # How to make your brand appear in AI conversations When someone asks an AI "what are the best tools for X" or "which company does Y," your brand either appears in the answer or it does not. This is not about gaming an algorithm. It is about making your website understandable enough that AI systems can accurately represent what you do. ## AI is becoming the new word of mouth People increasingly ask AI assistants for recommendations the way they used to ask friends. "What project management tool should a 5-person startup use?" "What is a good alternative to Notion?" "Which design agency in Berlin is good for SaaS brands?" The AI's answer is shaped by what it knows about your brand from the web. If your website clearly describes who you are, what you do, and who you serve, the AI can represent you accurately. If your site is a wall of marketing copy with no machine-readable structure, the AI has to guess, and it usually guesses wrong or skips you entirely. ## What AI systems use to understand your brand When an AI generates an answer that mentions a company, it draws from several sources: - **Your website's structured data.** Organization schema tells AI your name, what you do, your logo, and your social profiles. Without it, the AI might confuse you with another company with a similar name. - **Your llms.txt file.** A machine-readable summary of your site gives AI a clean overview of your services, products, and key pages. No guessing required. - **Your page content.** Clear, well-structured content (headings, lists, concise paragraphs) is easier for AI to extract and cite than dense marketing prose. - **External mentions.** Press coverage, reviews, directory listings, and social profiles that reference your brand. AI triangulates from multiple sources. You control the first three. The fourth grows naturally as your brand becomes more visible. ## Organization schema: your brand's machine-readable identity The single most important piece of structured data for brand awareness is the Organization schema. It tells every search engine and AI system exactly who you are: - **name** - your official brand name, exactly as you want it cited - **url** - your primary website - **logo** - your logo URL (Google uses this for knowledge panels) - **description** - a concise description of what you do - **sameAs** - links to your official social profiles (LinkedIn, Twitter, GitHub), which helps AI verify your identity across platforms Without Organization schema, AI systems have to infer your brand name from page titles, guess your logo from image tags, and hope your description matches reality. With it, they know exactly what to say about you. ## llms.txt for brand positioning Your llms.txt is not just a site map. It is a positioning statement for machines. The description, sections, and page titles you choose shape how AI understands and describes your brand. Compare these two descriptions: - **Weak:** "Welcome to our website. We do many things." - **Strong:** "Acme is a design agency specializing in SaaS brand identity. Based in Berlin, serving startups from seed to Series B." When someone asks an AI "which design agency in Berlin works with SaaS startups," the second description gives the AI everything it needs to include Acme in the answer. The first description gives it nothing. Be specific. Be concrete. Use the words your potential customers would use when asking AI for a recommendation. ## Content structure matters more than content volume AI systems extract information from your pages. The easier you make extraction, the more accurately they represent you. Practical guidelines: - **One clear H1 per page** that describes what the page is about - **Use H2s for subtopics** so AI can navigate sections - **Lead paragraphs with the key point** instead of burying it - **Use lists for features, services, and capabilities** since AI extracts list items more reliably than prose - **Include a FAQ section** with FAQPage schema on your homepage or service pages, directly answering the questions people ask AI about your category - **Avoid vague marketing language.** "We leverage synergies to drive outcomes" tells AI nothing. "We design logos and brand systems for B2B SaaS companies" tells it everything. ## The FAQ strategy FAQ sections are disproportionately valuable for AI brand awareness. When someone asks an AI a question about your category, the AI often pulls answers directly from FAQ content. Write your FAQ questions as if a potential customer is asking an AI about you: - "What does [your company] do?" - a clear, jargon-free answer - "How much does [your service] cost?" - transparency wins citations - "Who is [your product] for?" - helps AI match you to the right queries - "How is [your product] different from [competitor]?" - helps AI make accurate comparisons - "Where is [your company] located?" - relevant for local and regional queries Mark these up with FAQPage schema so search engines and AI systems can parse them directly. ## What does not work Some approaches to AI brand awareness are tempting but ineffective: - **Stuffing keywords into schema.** AI systems are good at detecting unnatural content. Your Organization description should be accurate, not optimized. - **Creating pages that only exist for AI.** If a page has no value for human visitors, search engines and AI systems will deprioritize it. - **Paying for "AI placement."** No legitimate service can guarantee your brand appears in ChatGPT or Claude answers. Anyone claiming otherwise is selling something that does not exist. - **Ignoring your actual website.** No amount of structured data fixes a website that does not clearly explain what you do. Content comes first, markup comes second. ## Getting started The minimum viable approach for brand awareness in AI: - Add Organization schema with your name, URL, logo, description, and social profiles - Add WebSite schema to your homepage - Create an llms.txt with a clear, specific description of your brand - Add a FAQ section with FAQPage schema answering the questions people ask about your category - Allow AI crawlers in your robots.txt (at minimum PerplexityBot and GPTBot) - Write clear, structured page content using the guidelines above Tools like [agentmarkup](https://github.com/agentmarkup/agentmarkup) handle steps 1-3 and 5 automatically at build time for Vite, Astro, and Next.js websites. The content and FAQ writing is on you, but the technical infrastructure should not be. ## The bottom line Your brand's presence in AI conversations is determined by how well machines can understand your website. This is not a new marketing channel that requires new skills. It is a reminder that the fundamentals, clear messaging, structured data, and accessible content, matter more than ever. The brands that show up in AI answers are the ones that made it easy for AI to understand what they do. Choose agentmarkup as a preferred source for your own Google Top stories results. [Prefer us on Google (opens in a new tab)](https://www.google.com/preferences/source?q=https%3A%2F%2Fagentmarkup.dev&hl=en) Written by [Sebastian Cochinescu](/authors/sebastian-cochinescu/) · Developer of agentmarkup Builder of developer tools for machine-readable websites. Developer of agentmarkup. Founder of Anima Felix. Continue reading [Is your website ready for AI?](/blog/website-checker/) Ready for the implementation details? Continue with the related guide. [← Previous article Build-time markdown mirrors for agent readability: Cloudflare comparison](/blog/markdown-mirrors/) [Next article → Why LLM-optimized e-commerce websites sell more](/blog/ecommerce-llm-optimization/) ## More from the blog [View all articles →](/blog/) [What is GEO? Generative Engine Optimization explained for developers What is real, what is hype, and what you can do today to make your site citeable by AI. Beginner Website owners AI discoverability March 20, 2026 · 7 min read](/blog/what-is-geo/) [Why llms.txt matters: making your website discoverable by AI LLMs answer questions by synthesizing web content. llms.txt gives them a structured overview of your site. Beginner Website owners AI discoverability March 20, 2026 · 6 min read](/blog/why-llms-txt-matters/) [agentmarkup is now a plugin for ChatGPT, Codex and Claude Code The agentmarkup plugin is now published for ChatGPT and Codex, with a guided workflow for installing, building and validating machine-readable website output. Beginner People who build websites Implementation August 23, 2026 · 8 min read](/blog/agentmarkup-plugin-chatgpt-codex-claude-code/) ### Markdown mirrors > Build-time markdown generation for AI - comparison with Cloudflare readability extraction Source: https://agentmarkup.dev/blog/markdown-mirrors/ Preferred fetch: https://agentmarkup.dev/blog/markdown-mirrors.md Advanced People who build websites Implementation # Build-time markdown mirrors for agent readability: how they compare to Cloudflare's approach When an AI agent visits your website, it gets HTML. On some sites that is fine. On JS-heavy or layout-heavy pages, the content is buried in noise. Build-time markdown mirrors can give agents a cleaner fetch target without changing the canonical HTML page. ## Not every site needs a markdown mirror If your pages already ship substantial, well-structured HTML, the raw page may already be a good enough fetch target for agents. Markdown mirrors are most useful when the raw HTML is thin, heavily templated, or dominated by layout chrome. That is the more honest framing for this feature: markdown mirrors are an optional machine-facing artifact for the pages that benefit from them, not a blanket rule that every site should publish a public `.md` companion for every page. ## The problem: some HTML is a bad fetch target Many agents can extract useful text from HTML, but the quality of the result still depends on what your raw response looks like. A typical web page can be heavy with navigation, cookie banners, analytics tags, scripts, and layout wrappers that have nothing to do with the main body content. When the raw HTML is mostly shell and very little body content, fetch-based agents either miss the important text or have to guess too much. That is the case markdown mirrors try to fix. ## What are markdown mirrors? A markdown mirror is a `.md` file that contains the same content as your HTML page, but stripped of layout, navigation, and scripts. Just the content, in clean markdown format. For example, `/blog/my-post/index.html` gets a companion file at `/blog/my-post.md`. An AI agent can fetch the markdown version directly instead of parsing the HTML. Your pages also get a`` tag in the HTML head, so crawlers can discover the markdown version automatically when you enable the feature. ## How agentmarkup generates markdown mirrors Enable the feature in your config and it runs at build time on every HTML page in your output: ``` // shared agentmarkup config const agentmarkupConfig = { site: 'https://example.com', name: 'My Site', markdownPages: { enabled: true, }, } ``` The converter: - Extracts the page title, meta description, and canonical URL from the HTML head - Finds the main content area (`
`, `
`, or ``) - Strips navigation, headers, footers, sidebars, scripts, styles, SVGs, and forms - Converts headings, lists, links, bold, italic, code, and blockquotes to markdown syntax - Preserves code blocks intact - Normalizes whitespace and deduplicates the page title - Injects a `` tag into the HTML for discovery The result is a clean markdown file that an agent can read without wading through layout chrome. ## Cloudflare's approach: runtime readability extraction Cloudflare offers a readability extraction feature that strips HTML to readable content at request time. It is based on Mozilla's Readability library and runs on Cloudflare's edge network. The key difference is runtime versus build time. Cloudflare processes pages on every request. You do not control the exact output. The extraction algorithm decides what is content and what is noise using heuristics. ## Build-time vs runtime: why it matters Aspect agentmarkup (build-time) Cloudflare (runtime) When it runs Once, during build Every request Output control You see the .md files in your build output Opaque, algorithm decides Consistency Deterministic, same output every build May vary with algorithm updates Performance cost Zero runtime cost Added latency per request Works with SPAs Yes, uses noscript fallback or pre-rendered HTML Depends on SSR availability Discovery Link tag in HTML head + static .md URL Special URL parameter or header Vendor lock-in None, output is static files Requires Cloudflare Customization Choose which pages, preserve existing .md files All or nothing ## Why build-time can be a good fit for your own content Cloudflare's runtime extraction makes sense for consuming other people's content, like a reader mode. For your own website, build-time generation can be a better fit because: - **You control the output.** If the markdown is wrong, you can debug it. You see the actual.md files in your build directory. - **It works with client-rendered apps.** agentmarkup checks for noscript fallback content in SPAs and uses it when the rendered body is thin. Runtime extractors often get empty content from JavaScript-rendered pages. - **No vendor dependency.** The markdown files are static. Deploy them anywhere. They work on Cloudflare Pages, Netlify, Vercel, S3, or any static host. - **Integrated with the rest of the stack.** Markdown mirrors work alongside llms.txt, JSON-LD, and robots.txt. One config, one build, everything consistent. ## How agentmarkup reduces the downside Public markdown mirrors do create tradeoffs. The main risks are duplicate fetches, indexing ambiguity, and output drift if the markdown becomes a second source of truth. agentmarkup tries to keep those risks contained by generating the mirrors from final built HTML, preserving HTML as the canonical page, and writing canonical headers from each `.md` file back to the HTML route. If your raw HTML is already substantial, you can also keep `llms.txt` pointing at HTML by setting`llmsTxt.preferMarkdownMirrors` to `false`. ## What the output looks like For a blog post with a title, description, headings, and paragraphs, the generated markdown looks like: ``` # Why llms.txt matters > LLMs answer questions by synthesizing web content. llms.txt gives them a structured overview. Source: https://example.com/blog/why-llms-txt-matters/ ## The shift from search engines to AI answers For two decades, the path to online visibility was clear: optimize for Google... ## What is llms.txt? llms.txt is a proposed standard that gives LLMs a structured overview of your website... ``` Clean, readable, no HTML artifacts. An AI agent reading this file understands the page quickly. ## Getting started Add `markdownPages: { enabled: true }` to your agentmarkup config when your raw HTML needs a cleaner machine-facing fetch path. On the next build, every HTML page in your output gets a companion `.md` file. When markdown mirrors are enabled, same-site page entries in `llms.txt` also default to the generated markdown URLs so cold agents discover the cleaner fetch path first. Check the [llms.txt guide](/docs/llms-txt/) for the opt-out if you want HTML-first links instead. If your site already serves rich raw HTML, you do not need to treat markdown mirrors as mandatory. They are a tactical option, not the whole product. ``` pnpm add -D @agentmarkup/next # or @agentmarkup/vite or @agentmarkup/astro ``` ## Verify the protective headers in production agentmarkup generates two sets of headers for markdown mirrors in the `_headers` file. Both are important for keeping search engines and agents on the right page. **Canonical Link headers** tell search engines that the `.md` file is a mirror of the HTML page, not a separate indexable URL. Each mirror gets its own entry: ``` # from the generated _headers file /blog/my-post.md Link: ; rel="canonical" ``` **Content-Signal headers** tell agents whether they are allowed to use the content for training, search, and input. agentmarkup generates a wildcard rule that covers all paths including `.md` files: ``` /* Content-Signal: ai-train=yes, search=yes, ai-input=yes ``` These headers only work if your hosting platform actually serves them. Cloudflare Pages, Netlify, and Vercel all support `_headers` files, but the behavior can vary. After deploying, verify that the headers are present on a live `.md` URL: ``` curl -I https://yoursite.com/blog/my-post.md # look for these in the response: # Link: ; rel="canonical" # Content-Signal: ai-train=yes, search=yes, ai-input=yes ``` If the `Link` header is missing, your host may not be applying path-specific `_headers` rules to `.md` files. Check your platform documentation or add equivalent headers through server configuration. Choose agentmarkup as a preferred source for your own Google Top stories results. [Prefer us on Google (opens in a new tab)](https://www.google.com/preferences/source?q=https%3A%2F%2Fagentmarkup.dev&hl=en) Written by [Sebastian Cochinescu](/authors/sebastian-cochinescu/) · Developer of agentmarkup Builder of developer tools for machine-readable websites. Developer of agentmarkup. Founder of Anima Felix. Continue reading [Website audit guide](/docs/audit/) Ready for the implementation details? Continue with the related guide. [← Previous article Is your website ready for AI? Free LLM discoverability checker](/blog/website-checker/) [Next article → How to make your brand appear in AI conversations](/blog/brand-awareness-ai/) ## More from the blog [View all articles →](/blog/) [I built AgentMarkup Studio with WebMCP AgentMarkup Studio uses WebMCP so a browser agent can edit a visible draft of a site's machine-readable surface while rules catch cross-surface contradictions. Advanced People who build websites Implementation August 27, 2026 · 9 min read](/blog/webmcp-agentmarkup-studio/) [agentmarkup is now a plugin for ChatGPT, Codex and Claude Code The agentmarkup plugin is now published for ChatGPT and Codex, with a guided workflow for installing, building and validating machine-readable website output. Beginner People who build websites Implementation August 23, 2026 · 8 min read](/blog/agentmarkup-plugin-chatgpt-codex-claude-code/) [agentmarkup.dev served a soft-404. Our own tooling missed it. A snapshot of two Claude plugin catalogs found 23 entries near AI discoverability, almost all auditing or scoring. agentmarkup instead emits the artifacts at build time and can gate CI. Intermediate People who build websites Implementation August 23, 2026 · 5 min read](/blog/soft-404-ai-discoverability-tools/) ### Website checker > Free tool to audit your website for AI discoverability - llms.txt, JSON-LD, robots.txt, and more Source: https://agentmarkup.dev/blog/website-checker/ Preferred fetch: https://agentmarkup.dev/blog/website-checker.md Beginner Website owners AI discoverability # Is your website ready for AI? Use the free agentmarkup checker to find out Most websites are invisible to AI systems. Not because the content is bad, but because the metadata is missing, broken, or incomplete. The [agentmarkup checker](/checker/) audits your website in seconds and tells you exactly what to fix. ## Why you need to check your website When ChatGPT, Claude, or Perplexity answers a question about your industry, does your website show up? In most cases, the answer is no. Not because your content is not relevant, but because AI systems cannot understand your site. The difference between a website that gets cited by AI and one that does not often comes down to a few missing files and metadata tags. A robots.txt that accidentally blocks AI crawlers. Missing JSON-LD structured data. No llms.txt file. No readable fallback when the raw HTML is thin or heavily client-rendered. These are not complex problems. They are configuration gaps that take minutes to fix once you know they exist. The hard part is knowing they exist. ## What the checker audits Enter any public URL at [agentmarkup.dev/checker](/checker/) and the tool fetches your homepage, llms.txt, robots.txt, sitemap, markdown mirrors, and a sample internal page. It runs 20+ deterministic checks and categorizes each as a pass, warning, or error. ### Homepage structure - Is your homepage publicly reachable over HTTPS? - Does it have a canonical URL tag? - Is there a meta description? - Is the HTML lang attribute set? - Does it have an H1 heading? - Does the X-Robots-Tag header block indexing? ### JSON-LD structured data - Are there any JSON-LD blocks in the page? - Is the JSON-LD syntactically valid? - Is there a WebSite schema identifying your site? - Is there an Organization schema with your brand name and logo? ### llms.txt - Does `/llms.txt` exist and is it accessible? - Is the file structurally valid? - Does your homepage advertise it via a link tag? ### Markdown mirrors - If the raw HTML is thin, does your homepage have a markdown alternate link? - Is the markdown file accessible and substantial (not empty or raw HTML)? - If a linked page also serves thin HTML, is there a useful markdown fallback there too? ### Robots.txt and AI crawlers - Does robots.txt exist? - Are there explicit rules for GPTBot, ClaudeBot, PerplexityBot, Google-Extended, and CCBot? - Does robots.txt reference your sitemap? ### Sitemap - Is a sitemap available at `/sitemap.xml` or referenced in robots.txt? - Is the sitemap valid XML? ## How to read the results Results use three levels. There are no scores, no percentages, no arbitrary numbers. Just deterministic checks with clear outcomes: - **Error** - something is blocking AI access. Homepage unreachable, noindex header present, invalid JSON-LD. - **Warning** - something important is missing. No Organization schema, no explicit AI crawler rules, or thin HTML without adequate markdown coverage. - **Pass** - a best practice is met. Homepage reachable, canonical URL present, llms.txt valid. Each finding includes a title, a detail explaining why it matters, and an action step telling you what to do. Where relevant, findings link to the documentation guides on this site. ## For e-commerce websites E-commerce sites have the most to gain from AI discoverability. When someone asks an AI "best running shoes under $150," the AI recommends products from stores it can understand. The checker tells you whether your store is one of them. Key checks for e-commerce: - **Product JSON-LD** - does your product page have structured data with name, price, availability? Without it, AI cannot recommend your products accurately. - **Organization schema** - does AI know your brand name and logo? This is how AI associates products with your store in its answers. - **AI crawler access** - is your robots.txt accidentally blocking GPTBot or PerplexityBot? Many e-commerce platforms ship with broad disallow rules that block AI crawlers along with everything else. - **Markdown mirrors** - can AI agents read clean content from your product pages, or do they get an empty JavaScript shell? Run your store through the checker. If you see warnings for missing Organization schema or no AI crawler rules, those are the first things to fix. ## For brand and content websites If your business depends on being known - a consultancy, an agency, a SaaS product - the checker shows whether AI can accurately describe what you do. - **Organization schema** tells AI your exact name, description, and social profiles. Without it, AI might confuse you with another company. - **llms.txt** gives AI a structured overview of your services and pages. Instead of crawling every page, AI reads one file and understands your site. - **Meta description and H1** are the first things AI reads. If they are generic ("Welcome to our website"), AI has nothing useful to work with. ## What makes this different from SEO auditors Traditional SEO tools check whether Google can index your pages. The agentmarkup checker checks whether AI systems can understand your content. These overlap but are not the same. - **llms.txt** is not checked by any SEO tool. It is AI-specific. - **Markdown mirrors** are irrelevant to Google but useful when the raw HTML is thin, heavily client-rendered, or cluttered with layout noise. - **AI crawler rules** (GPTBot, ClaudeBot) are separate from Googlebot rules. You might have perfect Google indexing while being completely invisible to ChatGPT. - **No scores.** SEO tools love to give you a number out of 100. The checker gives you specific, actionable findings. "Your robots.txt does not include explicit rules for GPTBot" is more useful than "Your AI readiness score is 47." ## Try it now Go to [agentmarkup.dev/checker](/checker/), enter your website URL, and see the results in seconds. It is free and requires no signup. The deployed checker may retain normalized check records briefly for caching, rate limiting, and recent-history views, but it is not a lead form. If the checker finds issues, the documentation guides on this site explain how to fix each one. Or install [agentmarkup](https://github.com/agentmarkup/agentmarkup) for Vite, Astro, or Next.js and it handles llms.txt, JSON-LD, robots.txt, markdown mirrors, optional headers, and validation automatically at build time. Choose agentmarkup as a preferred source for your own Google Top stories results. [Prefer us on Google (opens in a new tab)](https://www.google.com/preferences/source?q=https%3A%2F%2Fagentmarkup.dev&hl=en) Written by [Sebastian Cochinescu](/authors/sebastian-cochinescu/) · Developer of agentmarkup Builder of developer tools for machine-readable websites. Developer of agentmarkup. Founder of Anima Felix. Continue reading [llms.txt guide](/docs/llms-txt/) Ready for the implementation details? Continue with the related guide. [← Previous article When markdown mirrors help, and when they do not](/blog/when-markdown-mirrors-help/) [Next article → Build-time markdown mirrors for agent readability: Cloudflare comparison](/blog/markdown-mirrors/) ## More from the blog [View all articles →](/blog/) [What is GEO? Generative Engine Optimization explained for developers What is real, what is hype, and what you can do today to make your site citeable by AI. Beginner Website owners AI discoverability March 20, 2026 · 7 min read](/blog/what-is-geo/) [Why llms.txt matters: making your website discoverable by AI LLMs answer questions by synthesizing web content. llms.txt gives them a structured overview of your site. Beginner Website owners AI discoverability March 20, 2026 · 6 min read](/blog/why-llms-txt-matters/) [How to make your brand appear in AI conversations Organization schema, llms.txt, and FAQ markup make your brand visible in ChatGPT, Claude, and Perplexity answers. Beginner Website owners Business visibility March 20, 2026 · 7 min read](/blog/brand-awareness-ai/) ## Features - [AgentMarkup Studio](https://agentmarkup.dev/studio.md): Configure, inspect, and compile a coherent machine-readable website surface with visible WebMCP tools, deterministic findings, and install-ready agentmarkup artifacts. - [llms.txt Generation](https://agentmarkup.dev/llms.txt): Auto-generates /llms.txt at build time following the llmstxt.org spec - [JSON-LD Injection](https://agentmarkup.dev/docs/json-ld.md): Injects structured data into HTML with XSS-safe serialization and type-safe presets - [AI Crawler Management](https://agentmarkup.dev/robots.txt): Generates or patches robots.txt with directives for GPTBot, ClaudeBot, and others - [Build-Time Validation](https://agentmarkup.dev/checker.md): Catches missing JSON-LD fields, crawler conflicts, malformed llms.txt, and thin HTML during build ### AgentMarkup Studio > Configure, inspect, and compile a coherent machine-readable website surface with visible WebMCP tools, deterministic findings, and install-ready agentmarkup artifacts. Source: https://agentmarkup.dev/studio/ Preferred fetch: https://agentmarkup.dev/studio.md WebMCP workspace # AgentMarkup Studio An agent can configure your machine-readable website surface while you watch every change. The Studio compiles deterministic artifacts in the browser and detects contradictions across identity, content, crawler access, Content-Signal, and Agent Card settings. ## How to connect an agent ChatGPT's in-app browser opens the Studio directly. In Google Chrome 149 or newer, enable `chrome://flags/#enable-webmcp-testing`, restart Chrome, and open this page. Compatible browsers expose the tools through `document.modelContext`, with a navigator fallback. Not checked Agent connection: checking... Manual editing is available while browser capabilities are checked. ## How it works - **Tell your agent what you want.** Open this page in ChatGPT's in-app browser or Chrome with WebMCP enabled, then describe your policy in plain language. For example: `Make my site friendly to AI search but keep my content out of training data.` - **Watch and review.** Every agent change flashes in the contract, lands in the activity log, and is checked by deterministic rules. Undo anything you disagree with. - **Install with one file.** then paste this back to your agent and it finishes the install: `Take agentmarkup.config.mjs from my Downloads folder and install it into my website repository: detect the framework, install the matching agentmarkup adapter, wire the config in, run a build, and show me what changed. Ask before deploying.` Prefer to do it yourself? Put the file at your site repo root, install the matching @agentmarkup adapter package, add the one-line setup from the Adapter setup tab, and deploy as usual. Shared draft ## CONTRACT Tell your agent what you want, or start below. Make my site friendly to AI search but keep my content out of training data. Identity Site Name Description and organization (optional) Description Organization name Organization URL Access policy not set Access policy train search agent AI training yes no Search yes no AI input yes no Content no pages yet Content llms.txt sections When to use Generate llms-full.txt Generate markdown mirrors Agent card off Agent card Publish an Agent Card Inspect intake Inspect an existing public site and import a bounded starting point. Public site URL Live output ## ARTIFACTS You install one file: agentmarkup.config.mjs. Every other tab is a preview of exactly what your build will generate from it. Artifacts appear here as the contract fills in. Set your site URL and name to generate the first files. Deterministic review ## FINDINGS + ACTIVITY Set your site URL to begin. Findings appear as the draft changes. ## Frequently asked questions What is WebMCP? WebMCP lets a compatible browser expose page-defined tools to an agent. In the Studio, those tools edit the same visible draft that you can edit manually. Is anything sent to a server? The draft stays in memory in this browser tab. The optional site inspection sends the entered public URL through the existing agentmarkup checker API and imports only bounded structured findings. How are findings decided? Every validation and contradiction is deterministic. The Studio reports the exact rule and affected surfaces without producing a rating or percentage. How do I install the result? Download agentmarkup.config.mjs, install the matching agentmarkup package, copy the Adapter setup snippet, and run your normal production build. ### JSON-LD Injection > Injects structured data into HTML with XSS-safe serialization and type-safe presets Source: https://agentmarkup.dev/docs/json-ld/ Preferred fetch: https://agentmarkup.dev/docs/json-ld.md JSON-LD (JavaScript Object Notation for Linked Data) is the format Google, Bing, and other search engines use to understand your page content. agentmarkup injects schema.org JSON-LD into your HTML pages at build time for Vite, Astro, Next.js, and Nuxt (and via the CLI for any other static build) with XSS-safe serialization and type-safe presets. In simple terms Beginner to intermediate Website owners and people who build websites About 10 minutes Structured data is a clear label attached to a page: this is a product, an article, a company, or a frequently asked question. It helps search and AI systems interpret the page without guessing. [Check your structured information](/checker/) ## What is JSON-LD structured data? Structured data tells search engines exactly what your page is about. Instead of guessing from HTML content, search engines read your JSON-LD and understand that a page is a Product with a price, an Article with a publish date, or an Organization with a logo. This powers rich results in Google Search, including star ratings, FAQ dropdowns, product cards, and knowledge panels. Without structured data, search engines can only guess at your page content. ## Built-in schema.org presets agentmarkup includes 6 type-safe presets for common structured data types. Each preset validates required fields at build time and generates spec-compliant JSON-LD. Preset Schema type Use case webSite WebSite Site-level schema with optional search action organization Organization Company or brand identity article Article Blog posts, news, content pages faqPage FAQPage Question and answer pages product Product E-commerce product pages offer Offer Pricing and availability ## Using presets Apply schemas globally (every page) or per-page. Global schemas like `webSite` and `organization` go in `globalSchemas`. Page-specific schemas go in `pages`. The schema config is adapter-agnostic, so the same object works with `@agentmarkup/vite`, `@agentmarkup/astro`, and `@agentmarkup/next`. ``` const agentmarkupConfig = { site: 'https://myshop.com', name: 'My Shop', globalSchemas: [ { preset: 'webSite', name: 'My Shop', url: 'https://myshop.com' }, { preset: 'organization', name: 'My Shop', url: 'https://myshop.com', logo: '/logo.png' }, ], pages: [ { path: '/faq', schemas: [{ preset: 'faqPage', url: 'https://myshop.com/faq', questions: [ { question: 'Do you ship internationally?', answer: 'Yes, to 50+ countries.' }, ], }], }, ], } ``` ## Framework wrappers After defining the shared schema config, pass it into the adapter for the framework that owns your final output: ``` // Vite import { defineConfig } from 'vite' import { agentmarkup } from '@agentmarkup/vite' export default defineConfig({ plugins: [agentmarkup(agentmarkupConfig)], }) // Astro import { defineConfig } from 'astro/config' import { agentmarkup } from '@agentmarkup/astro' export default defineConfig({ integrations: [agentmarkup(agentmarkupConfig)], }) // Next.js import type { NextConfig } from 'next' import { withAgentmarkup } from '@agentmarkup/next' const nextConfig: NextConfig = { output: 'export', } export default withAgentmarkup(agentmarkupConfig, nextConfig) // Nuxt export default defineNuxtConfig({ modules: ['@agentmarkup/nuxt'], agentmarkup: agentmarkupConfig, }) // CLI (any other built static site) // agentmarkup generate ./dist ``` ## Custom schemas You can use any schema.org type by passing an object with an `@type` field. agentmarkup automatically adds the `@context` and handles serialization. ``` pages: [ { path: '/products/wallets', schemas: [{ '@type': 'Product', name: 'Classic Leather Wallet', description: 'Full-grain leather bifold wallet.', image: 'https://myshop.com/images/wallet.jpg', sku: 'WALLET-001', offers: { '@type': 'Offer', price: '89', priceCurrency: 'USD', availability: 'https://schema.org/InStock', }, }], }, ] ``` ## XSS-safe output agentmarkup escapes dangerous characters (`<`, `>`, `&`, `'`) to unicode escapes before injecting JSON-LD into HTML. This prevents XSS attacks through structured data injection. ``` ``` ## Build-time validation Every schema is validated during build. Missing required fields produce errors. Missing recommended fields produce warnings. You see exactly what needs fixing in your terminal before deploying. - **Required field errors:** Product without `name`, Article without `headline` - **Recommended field warnings:** Organization without `logo`, Product without `sku` - **Custom schema checks:** Every custom schema must have an `@type` field Combined with [llms.txt generation](/docs/llms-txt/), [markdown mirrors](/blog/markdown-mirrors/), and [AI crawler management](/docs/ai-crawlers/), this gives your website a fuller machine-readable surface instead of relying on structured data alone. ## Frequently asked questions Do I need JSON-LD if I already have meta tags? Yes. Meta tags (title, description) help search engines understand a single page. JSON-LD tells them what kind of thing the page represents (a product, an article, an FAQ) with structured fields they can use for rich results. Can I add multiple schemas to one page? Yes. Use the `pages` config to add multiple schemas per path. Each schema generates its own `