Markdown for agents
Every page available as raw Markdown via `.md` URL suffix or `Accept: text/markdown`. ~10× token reduction for AI coding assistants.
~ 2 min read
Markdown for agents
When a coding assistant fetches a docs page, it doesn’t want HTML. It wants the source — the same Markdown the page was written in, without the chrome, navigation, or rendered components getting in the way.
Tangly serves it. Two ways, both wired up by default:
.mdURL suffix. Append.mdto any page URL. Works on every static host, no config required.Accept: text/markdownheader. Same URL, content-negotiated. Works intangly dev; production needs a one-line CDN config (recipes below).
The .md files are emitted at build time alongside the HTML, so deploys to Vercel, Cloudflare Pages, Netlify, S3, or GitHub Pages get this for free.
Why it matters
A typical docs page renders to ~16k tokens of HTML (nav, sidebar, footer, embedded JS). The same page as raw Markdown is ~3k tokens — an 80% reduction. Bun reported a 10× drop in their own measurements.
Coding assistants like Claude Code, OpenCode, Cursor, and Aider already send Accept: text/markdown on docs requests. Tangly responds in kind.
How to use it
From a coding assistant
Read https://docs.example.com/installation.md
Or — for any agent that respects Accept headers:
curl -H "Accept: text/markdown" https://docs.example.com/installationBoth return the raw .mdx source with frontmatter intact and a URL: preamble identifying the page.
Discovery
Every HTML page advertises its Markdown twin in the <head>:
<link rel="alternate" type="text/markdown" href="/installation.md">RFC 8288-aware crawlers find the .md without needing to send Accept headers. The HTML response also includes:
Vary: Accept
Link: </llms.txt>; rel="llms-txt", </llms-full.txt>; rel="llms-full-txt"
X-Llms-Txt: /llms.txt
Same wire format as Mintlify and Cloudflare’s “Markdown for Agents.”
What gets emitted
For each page, Tangly writes <slug>.md to dist/:
dist/
installation/
index.html
installation.md ← agent-facing source
guides/
deploying/
index/
index.html
index.md
The .md file contains the raw on-disk source plus a one-line URL preamble:
URL: /installation
---
title: Installation
description: Install Tangly into a new or existing project.
---
# Installation
...Frontmatter is preserved (agents use title and description as context). MDX components stay in their JSX form — agents handle that fine, and keeping the file byte-identical to source means no surprises.
What’s excluded
Same rules as llms.txt and sitemap.xml:
- Pages with
noindex: truein frontmatter. - Drafts (
draft: true) when not building with--include-drafts.
The .md variant also gets X-Robots-Tag: noindex on dev responses so it never competes with the HTML page in search results.
Production content negotiation
The static .md files work everywhere. If you also want Accept: text/markdown on the same URL (so agents don’t have to know about the .md suffix), add a one-line rewrite at the CDN.
Cloudflare Pages
Add to _headers:
/*
Vary: Accept
Link: </llms.txt>; rel="llms-txt", </llms-full.txt>; rel="llms-full-txt"
X-Llms-Txt: /llms.txt
And in _redirects:
/:path /:path.md 200 Accept=*text/markdown*
Vercel
In vercel.json:
{
"rewrites": [
{
"source": "/:path*",
"has": [
{ "type": "header", "key": "accept", "value": ".*text/markdown.*" }
],
"destination": "/:path*.md"
}
],
"headers": [
{
"source": "/(.*)",
"headers": [
{ "key": "Vary", "value": "Accept" },
{ "key": "Link", "value": "</llms.txt>; rel=\"llms-txt\", </llms-full.txt>; rel=\"llms-full-txt\"" },
{ "key": "X-Llms-Txt", "value": "/llms.txt" }
]
}
]
}Netlify
In _redirects:
/* /:splat.md 200! Accept=*text/markdown*
Relation to llms.txt
The two work together:
/llms.txt— index. “Here are all the pages.”/llms-full.txt— bulk. “Here is every page concatenated.”/<slug>.md— per-page. “Here is one specific page.”
An agent typically fetches /llms.txt once to discover the IA, then pulls individual .md files as the conversation needs them.
See llms.txt for the index format.
Disabling
There’s no opt-out flag. The .md files are byte-cheap and harmless — the same content already in /llms-full.txt just split per page. If a specific page shouldn’t ship, mark it noindex: true and it’s excluded from all four (sitemap, llms.txt, llms-full.txt, <slug>.md).