AI SpeedForce

Markdown for agents: serving Markdown with content negotiation

Agents read Markdown far more cheaply than HTML. Serve a Markdown copy when a request asks for text/markdown, keep HTML the default, and link the copy from every page.

Markdown for agents means answering a request that says Accept: text/markdown with a Markdown version of the page, while everyone else still gets HTML. It is ordinary HTTP content negotiation: one URL, two representations, and the request decides which one comes back.

Why bother? An agent reading your HTML has to wade through navigation, scripts, styles and layout markup to find the text. A Markdown copy of the same page is a fraction of the size and keeps only what matters: headings, paragraphs, lists, links and tables. That means fewer tokens, lower cost for whoever runs the agent, and less room for the agent to misread your page.

How content negotiation works

HTTP has always let a client say which formats it prefers, through the Accept request header. A browser sends something like text/html,application/xhtml+xml. An agent that wants Markdown sends text/markdown. The server looks at the header and chooses what to return.

One URL, two representationsRequest arrives then Server reads Accept then Picks a version then RespondsONE URL, TWO REPRESENTATIONSRequest arrivessame page URLServer reads Accepttext/markdown or notPicks a versionMarkdown or HTMLRespondswith Vary: Accept
One URL, two representations

The important rule is that HTML stays the default. Browsers and search crawlers never ask for Markdown, so they keep receiving exactly what they received before. Only requests that explicitly ask get the Markdown version.

The headers to send

A correct Markdown response carries a few headers:

  • Content-Type: text/markdown; charset=utf-8 so the client knows what it received. text/markdown is a registered media type (RFC 7763).
  • Vary: Accept on both versions. This tells caches and CDNs that the response depends on the Accept header, so a cached Markdown copy is never served to a browser, or the other way round.
  • x-markdown-tokens, an informal header some implementations send, with an estimate of how many tokens the Markdown contains. It lets an agent decide whether to read the whole thing. It is a convention, not a standard, and an estimate is fine.
PieceWhat it does
Accept: text/markdownThe agent asks for Markdown
Content-Type: text/markdownThe server says what it sent
Vary: AcceptCaches keep the two versions apart
x-markdown-tokensTells the agent roughly how big it is
rel=alternate linkPoints to the Markdown copy from the HTML
The pieces and what each does

Cloudflare documents this pattern as Markdown for Agents, and agent-readiness checkers test for it by sending Accept: text/markdown to your home page and checking the response type.

Negotiation works when the agent knows to ask. A link in the page head works even when it does not:

<link rel="alternate" type="text/markdown" href="/services/seo/index.md">

An agent that loads the HTML sees the link and can fetch the lighter version for everything it reads next. Put one on every page, pointing at that page's own Markdown copy.

Publishing the copies at predictable URLs also helps on hosts that cannot inspect request headers. The llms.txt proposal suggests offering a Markdown version of a page at the same URL with .md appended. For folder-style URLs, appending index.md is a common variant, and it makes the copies easy to list in an llms.txt file.

How this site does it

You can see a working example on this site. The home page's Markdown copy is at /index.md, and every page links its own copy with rel="alternate". Requesting any page with Accept: text/markdown returns that same file with Content-Type: text/markdown, Vary: Accept and an x-markdown-tokens estimate.

Two decisions made it reliable:

  • The Markdown is generated from the finished HTML at build time, not written separately. It cannot drift from the page, because it is the page.
  • Page furniture is left out. Navigation, icons, buttons and decorative graphics do not help an agent understand the content, so the converter drops them and keeps headings, text, lists, tables and links.

On our host, the server cannot set response headers from its config file, so a small script answers negotiated requests. The static Markdown files do the rest. Whatever your stack, the outcome to aim for is the same.

What belongs in the Markdown copy

  • The page title as a top-level heading, and the meta description as a short summary.
  • The canonical URL, so an agent can cite the right page.
  • The main content in order: headings, paragraphs, lists, tables and links with absolute URLs.
  • FAQ questions as headings with their answers.

Leave out scripts, tracking, cookie banners and anything decorative. If you would not read it aloud to someone, it probably does not belong.

Test it

You can check the basics from a terminal with curl: request a page normally, then again with -H "Accept: text/markdown", and compare the Content-Type and Vary headers.

Test your setupPlain request still returns HTML; Accept: text/markdown returns Markdown; Content-Type is text/markdown; Vary: Accept is present; Each page links its Markdown copyTEST YOUR SETUPPlain request still returns HTMLAccept: text/markdown returns MarkdownContent-Type is text/markdownVary: Accept is presentEach page links its Markdown copy
Test your setup

Or run the free agent-readiness scan, which sends the Markdown request for you and also checks for the rel="alternate" link. For a wider view of how agents consume pages, see how AI agents read web pages.

Common mistakes

  • Serving Markdown to everyone. If the server returns Markdown for a plain request, browsers show raw text. Only answer with Markdown when the request asks for it.
  • Forgetting Vary: Accept. Without it, a cache in front of your site can store the Markdown response and hand it to the next browser, or the other way round.
  • Returning HTML labeled as Markdown. Some setups change the Content-Type but still send the HTML body. Check the body, not just the header.
  • Hand-written copies that drift. A Markdown page written once and never updated soon disagrees with the real page. Generate it from the same source.
  • Relative links. Links in the Markdown should be absolute, because an agent may read the file far from its original URL.

Next step

Start with the alternate link and generated Markdown copies, since they work on any host. Add negotiation on the same URLs when your server allows it. Then scan your site to confirm both pass. If you want it built into your stack, our web development work covers it.

01Asked

Questions about this topic

Will serving Markdown hurt my SEO?

Not if HTML stays the default. Browsers and search crawlers do not ask for text/markdown, so they keep getting the page they always got. Send Vary: Accept so caches do not mix the two.

Do I need a separate Markdown file for every page?

You need a Markdown version of every page, but it can be generated. We generate ours from the finished HTML at build time so it never drifts from the page.

What if my host cannot read the Accept header?

Publish the Markdown copies at predictable URLs, such as the page URL plus index.md, and link them with rel=alternate. Agents can still find and fetch them.

02Read

Related posts

Agent readiness

MCP servers for business: when you need one and how to keep it safe

An MCP server exposes your systems to AI agents through one standard interface. It is worth building when agents need to act inside your business, not just read about it.Read the post
Agent readiness

API catalogs and Link headers: how agents find your APIs

Two small standards tell agents where your APIs are: an HTTP Link header on the homepage, and a well-known api-catalog file that lists each API and its description.Read the post
Agent readiness

Agent skills and the ai-catalog: telling agents how to use your site

Agent skills are short instruction files that teach an agent to do one job with your site. A discovery index lists them, and the draft ai-catalog lets registries find them.Read the post

See how your own site scores

The free agent-readiness scan checks the files, headers and endpoints this blog writes about, and tells you what to fix first.

AI SpeedForce
Start a project Log in