Published by Qomvia, , 3 min read
Discovery before parsing
An agent's first contact with your site is an HTTP response. Before it has parsed a byte of the body it can read the headers, and one of those headers can be a list of related resources. That is what the Link header, defined in RFC 8288, does: it carries typed links, each with a target and a rel that says what the target is.
The same links can live in the HTML head. The difference is who can read them. A fetcher that only wants the API description, or that received a Markdown response with no head, or that is checking a HEAD request, still gets the header. Cloudflare's readiness scanner lists Link headers under Discoverability for that reason.
What to link
HTTP/1.1 200 OK
Content-Type: text/html; charset=utf-8
Link: </.well-known/api-catalog>; rel="api-catalog",
</llms.txt>; rel="llms-txt"; type="text/markdown",
</.well-known/mcp.json>; rel="mcp",
</openapi.json>; rel="service-desc"; type="application/openapi+json",
</api/score/example-com>; rel="alternate"; type="application/json"- `rel="api-catalog"` is registered by RFC 9727 and points at your API catalog. This is the one relation the emerging scanners specifically look for. The API catalog article covers the document itself.
- `rel="service-desc"` (RFC 8631) points at a machine-readable description of a service, typically an OpenAPI file.
rel="service-doc"points at its human documentation. - `rel="alternate"` with a
typenames another representation of this page, for example a JSON version. Qomvia's site pages use it to point at/api/score/<slug>. - `rel="llms-txt"` and `rel="mcp"` are not IANA-registered relations. Extension relations are allowed by RFC 8288 and should strictly be URIs, but scanners match on the short form, and no registered relation covers these resources yet.
Relative targets (</llms.txt>) resolve against the request URL, so one header value works across hosts. Multiple links can share one header separated by commas, or be sent as repeated Link headers; both are valid.
Where to set it
The header belongs on HTML responses, at minimum the homepage. Set it once in the layer that fronts all pages rather than per route.
const link = [
'</.well-known/api-catalog>; rel="api-catalog"',
'</llms.txt>; rel="llms-txt"; type="text/markdown"',
'</.well-known/mcp.json>; rel="mcp"',
].join(", ");
export default {
async headers() {
return [{ source: "/:path*", headers: [{ key: "Link", value: link }] }];
},
};add_header Link '</.well-known/api-catalog>; rel="api-catalog", </llms.txt>; rel="llms-txt"' always;Do not use Link for rel=preload of large assets on the same header line you use for discovery; some HTTP/2 servers turn preload links into server push or early hints, and that is a different mechanism with different costs.
What Qomvia checks
Link response headers point at machine resources under Agent protocols reads the Link header on the homepage response fetched as a declared crawler and passes when at least one relation matches api-catalog, llms, mcp, service-desc, describedby, openid, oauth or alternate. The relations found are recorded on your site page. It is a 1-point check: cheap to add, and a reliable sign that a site has thought about non-browser readers.
Questions
- Is a Link header the same as <link> in the head?
- Same data model, different transport. RFC 8288 defines both serialisations. The header is readable without parsing HTML and survives when the body is not HTML.
- Will Link headers affect browsers or SEO?
- Browsers act on a few relations such as preload and preconnect and ignore the rest. Search engines read rel=canonical from the header for non-HTML resources; discovery relations are ignored by them.
- Do I need the resources to exist before I link them?
- Yes. A Link to a 404 is worse than no link. Publish the catalog, llms.txt or MCP document first, then advertise it.
Score your own site against the rubric this is written from.
Is your site agent-ready?
Free score against the same rubric, in under a minute.
Sign up free to keep the fixes and track the score.
AI monitor
PreviewHow often each model names your site across 11 tracked questions.