Content Accessibility

Markdown for Agents

Content negotiation: server serves Markdown instead of HTML when an AI agent requests it via Accept header.

What is Markdown for Agents?

Markdown for Agents is a pattern in which a web server supports HTTP content negotiation and returns a page in Markdown format for AI agents that request Accept: text/markdown.

GET /blog/article HTTP/1.1
Accept: text/markdown

HTTP/1.1 200 OK
Content-Type: text/markdown

# Article Title
Content without navigation, ads, or JS...

Why does a site need Markdown for Agents?

HTML pages contain navigation, ads, and scripts — “noise” that degrades AI model parsing quality. Markdown is clean structured text that LLMs process more effectively.

Supporting content negotiation lets a single URL serve both humans (HTML) and agents (Markdown) without duplicating content.

How to implement Markdown for Agents?

Express.js / Node.js:

app.get('/article/:slug', (req, res) => {
  const accept = req.headers['accept'] ?? '';
  if (accept.includes('text/markdown')) {
    res.setHeader('Content-Type', 'text/markdown');
    return res.send(getMarkdownContent(req.params.slug));
  }
  res.send(getHtmlPage(req.params.slug));
});

Next.js App Router:

// app/blog/[slug]/route.ts
export async function GET(req: Request, { params }: { params: { slug: string } }) {
  const accept = req.headers.get('accept') ?? '';
  if (accept.includes('text/markdown')) {
    const md = await getMarkdownContent(params.slug);
    return new Response(md, {
      headers: { 'Content-Type': 'text/markdown; charset=utf-8' },
    });
  }
  // fallback to page render
}

Astro SSR:

// src/pages/blog/[slug].ts
export async function GET({ params, request }: APIContext) {
  const accept = request.headers.get('accept') ?? '';
  if (accept.includes('text/markdown')) {
    const md = await getMarkdownContent(params.slug);
    return new Response(md, {
      headers: { 'Content-Type': 'text/markdown; charset=utf-8' },
    });
  }
}

Cloudflare Workers (via Markdown for Agents): Workers AI supports the pattern natively — check the documentation.

How do we check Markdown for Agents?

The scanner performs GET / with the header Accept: text/markdown and inspects the response.

  1. Content-Type: text/markdown — the server acknowledges the request and responds with Markdown
  2. Non-empty content — the response body is not empty
  3. Markdown structure — the body starts with # or contains Markdown markup

Status pass — server returned Content-Type: text/markdown with a non-empty body. Status fail — server returned HTML or ignored the Accept header.

Sources and specifications