What it is
RFC 8288 defines the Link header, which carries typed hyperlinks in HTTP responses. It's cheap for agents to consume because it doesn't require HTML parsing. Useful rel values for agents:
api-catalog— points to/.well-known/api-catalogmcp-server-card— points to the MCP cardagent-skills— points to the skills indexdescribedby— schema/docs resourcecanonical— canonical URL of this resourceauthor,license,alternate(e.g.alternate type="text/markdown")
Why it matters
Agents routinely issue a HEAD or first-byte request before committing to fetch a full body. Link headers let them orient themselves in one round trip. Without them, the agent is forced to parse HTML (expensive) or guess well-known URLs (brittle).
Remediation Prompt
I want to improve my site's agent readiness. Please implement the following fix for HTTP Link Headers across our codebase. Instructions: Please fix the HTTP Link Headers issue on my site so it is agent-ready.
How we test it
HEAD https://<host>/(the canonical URL after scan ingress).- If
HEADreturns 405/403/not-allowed, fall back toGETwithRange: bytes=0-0and a 512-byte body cap. - Parse
Linkheaders (there can be multiple). Split on top-level commas outside angle brackets.
Pass Warn Fail Matrix
| Condition | Status | Score |
|---|---|---|
≥1 agent-relevant rel (see list above) present |
pass | 1.0 |
Only canonical / alternate present (useful but minimal) |
warn | 0.6 |
No Link header at all |
fail | 0.0 |
| Header present but malformed | fail | 0.2 |
Sub Tests
| id | Weight | Pass when |
|---|---|---|
header-present |
0.4 | At least one Link: header |
has-agent-rels |
0.4 | ≥1 of: api-catalog, mcp-server-card, agent-skills, describedby |
well-formed |
0.2 | Every <URI>; rel=... entry parses to a valid absolute or relative URI |
Remediation Prompt
Please add HTTP Link response headers to my site so AI agents can discover resources without parsing HTML. Set them at the edge (CDN rule, reverse proxy, or framework middleware) on every 2xx response from the homepage at minimum.
Include (where applicable):
Link: </.well-known/api-catalog>; rel="api-catalog"
Link: </.well-known/mcp/server-card.json>; rel="mcp-server-card"; type="application/json"
Link: </.well-known/agent-skills/index.json>; rel="agent-skills"; type="application/json"
Link: </llms.txt>; rel="alternate"; type="text/plain"
Only include the ones that are actually served. Do not invent URLs.
Implementation Examples
Next.js middleware
// middleware.ts
import { NextResponse } from 'next/server';
export function middleware() {
const r = NextResponse.next();
r.headers.append('Link', '</.well-known/mcp/server-card.json>; rel="mcp-server-card"; type="application/json"');
r.headers.append('Link', '</.well-known/agent-skills/index.json>; rel="agent-skills"; type="application/json"');
return r;
}Cloudflare Transform Rule
Add a Response Header Transform matching http.request.uri.path eq "/" that appends the headers.
nginx
add_header Link '</.well-known/mcp/server-card.json>; rel="mcp-server-card"; type="application/json"' always;
Common Mistakes
- Overwriting rather than appending
Linkheaders (breaks other middleware's values). - Using quoted-string when spec needs token (
rel=api-catalognotrel="api catalog"). - Returning
Linkon a 3xx redirect response that agents may drop before following. - Typos in
relvalues — agents look for exact matches.
Test Fixtures
pass-multiple-rels.jsonwarn-canonical-only.jsonfail-missing.jsonfail-malformed.json