# Some SEO Plugins Claim Markdown for AI but Ignore the Accept Header

A few months back, Bun announced they were serving their documentation as raw Markdown to AI agents, cutting token usage by 10x. We shipped the same thing on the Roots docs shortly after.

Since then, the WordPress SEO plugin world has caught on to “Markdown for AI” as a feature. Some of them aren’t actually doing it right.

> **What this should look like:** [Post Content to Markdown](https://roots.io/serve-your-wordpress-posts-as-markdown/) — the canonical URL stays canonical, `.md` variants are noindexed and advertised via `Link` headers and `<link rel="alternate">`, and AI agents that send `Accept: text/markdown` just get Markdown back.

## Claude Code, Cursor, OpenCode, and OpenClaw already speak this protocol

Anthropic’s Boris Cherny [confirmed in November 2025](https://x.com/bcherny/status/1988860326306087102) that the latest Claude Code automatically adds `Accept: "text/markdown, */*"` to requests its WebFetch tool makes, so sites that serve Markdown get token-efficient responses. The client asks for Markdown in the header, and servers that understand the header respond appropriately.

Here’s what that actually looks like in our own access log:

```
GET /sage/docs/installation/ HTTP/1.1
User-Agent: Claude-User (claude-code/2.1.107; +https://support.anthropic.com/)
Accept: text/markdown, text/html, */*
```

That’s the `Accept: text/markdown` header. It’s how AI agents say “I’d prefer Markdown if you have it, HTML otherwise.” This is [RFC 7231 content negotiation](https://www.rfc-editor.org/rfc/rfc7231#section-5.3), using the media type defined in [RFC 7763](https://www.rfc-editor.org/rfc/rfc7763).

Cursor, OpenCode, and OpenClaw also support this protocol. See the [acceptmarkdown.com status page](https://acceptmarkdown.com/status) to keep an eye on adoption.

## What AIOSEO actually does

AIOSEO added a Markdown feature and [WPBeginner wrote about it](https://www.wpbeginner.com/plugins/how-to-add-a-markdown-version-of-your-wordpress-site/):

> Once configured, AIOSEO will dynamically generate a Markdown version whenever an AI system requests it by adding `.md` to your post URL.

The AI agent is expected to append `.md` to the URL. There's no content negotiation happening, it's a separate URL, not a separate representation. An AI agent sending `Accept: text/markdown` to the canonical URL gets HTML back, because AIOSEO never looks at the header — and the HTML response doesn't advertise the `.md` alternate either, via `Link: rel="alternate"` header or a `<link rel="alternate" type="text/markdown">` in `<head>`. An AI agent that doesn't already know the `.md` convention has no way to discover it.

You can verify this in one line. WPBeginner uses AIOSEO on their own site — they say so in the post itself: "Expert Tip: We use AIOSEO on WPBeginner to manage our SEO." That makes their post about the feature a perfect test case:

```
curl -sI -H "Accept: text/markdown" \
  https://www.wpbeginner.com/plugins/how-to-add-a-markdown-version-of-your-wordpress-site/ \
  | grep -i content-type
```

```
content-type: text/html; charset=UTF-8 🚨
```

[AIOSEO's founder Syed Balkhi framed the `.md` feature as giving AI agents what they need](https://x.com/syedbalkhi/status/2043664841739513887) — but the Accept header isn't mentioned. "Add `.md` to the URL" is not a standard. It's a convention a few sites have adopted, and while it has the advantage of working even when the client doesn't send the right header, AI agents have to be taught about it on a per-site basis. Content negotiation is the standard, and it’s the one every HTTP client already knows how to speak. AI agents following the spec get HTML and never see the Markdown version unless someone has hardcoded a URL rewrite for that specific site.

You also end up with two URLs for the same resource, which is exactly what content negotiation was designed to avoid — and the kind of thing SEO plugins usually spend their time *preventing*.

None of this would matter if the plugin vendors were clearer about what they'd built. Generating `.md` companion URLs is a useful feature. But calling it "Markdown whenever an AI system requests it" overstates it.

## WordPress.org got it right

WordPress.org itself just shipped the correct implementation. As [announced on the Meta blog](https://make.wordpress.org/meta/2026/03/03/markdown-now-available-on-wordpress-org/), the WP.org docs now respect `Accept: text/markdown` on their canonical URLs. Here’s what I saw [fetching one of their docs](https://x.com/retlehs/status/2029401943311778088) with and without the header:

| Format | Raw size | Estimated tokens |
|---|---|---|
| HTML (default) | 271,268 bytes | ~67,800 |
| Markdown (`Accept: text/markdown`) | 44,841 bytes | ~11,200 |

Same URL, with an 84% reduction in bytes and roughly 6x fewer tokens for any AI agent that asks for Markdown.

## How we did it on our site

Our docs implementation is a [first-party Acorn (Laravel within WordPress) controller](https://acceptmarkdown.com/recipes/laravel) that reads the `Accept` header, resolves the matching Markdown source file, and either returns it as `text/markdown` or passes it through a CommonMark renderer for the HTML response.

Same route, same canonical URL, with `Vary: Accept` set so caches and CDNs fan out correctly. (The `.md` suffix sidesteps this complexity by using separate URLs, but that tradeoff creates the duplicate-URL problems SEO plugins usually exist to prevent.)

You can see the two representations on the same URL:

```
curl -sI -H "Accept: text/markdown" https://roots.io/sage/docs/installation/ | grep -i content-type
# content-type: text/markdown; charset=UTF-8

curl -sI -H "Accept: text/html" https://roots.io/sage/docs/installation/ | grep -i content-type
# content-type: text/html; charset=UTF-8
```

We also packaged the same approach as a standalone WordPress plugin: [roots/post-content-to-markdown](https://github.com/roots/post-content-to-markdown). It handles content negotiation on canonical URLs for single posts, feeds, and filterable post types, and advertises a `.md` URL suffix via `Link` headers and `<link>` tags so AI agents that don't yet send `Accept: text/markdown` can still find the Markdown version. See [Serve Your WordPress Posts as Markdown](https://roots.io/serve-your-wordpress-posts-as-markdown/) for a full walkthrough.

## What to ask your SEO plugin

If you’re evaluating a WordPress SEO plugin’s “AI-ready” or “Markdown for AI agents” claims, ask one question: does it respect `Accept: text/markdown` on the canonical URL? If the answer is “no, but you can add `.md` to the URL,” it’s a `.md` mirror feature, not content negotiation — and the AI agents hitting your site today already know how to ask for what they want. Some plugins just aren’t answering the header.

## Want to see if your site is AI-ready?

Run your site through [acceptmarkdown.com](https://acceptmarkdown.com/) to confirm everything's being advertised the way AI agents expect.