AI Integration
Expose your content to coding agents and chat models via /llms.txt and Markdown endpoints.
Coding agents are now a primary audience for documentation. Claude, Cursor, and GitHub Copilot all read docs when answering questions about a library — but only if those docs are exposed in a way agents can consume.
The /llms.txt convention
Anthropic, Cloudflare, and a growing list of sites have standardized on a simple pattern: a text endpoint at /llms.txt that lists every page on the site in Markdown, with links to full-text versions.
This site exposes two endpoints:
/llms.txt
A directory — every page's title, URL, and one-line description.
/llms-full.txt
The full text of every page concatenated, ready for an agent to ingest in one fetch.
When to use which
Use /llms.txt for agents that can navigate (they'll fetch individual pages on demand).
Use /llms-full.txt when an agent needs to load the whole library into context at once —
for a code review on a small codebase, for instance.
How they're built
Both endpoints are static Next.js routes. The directory is one line per page; the full version concatenates the rendered Markdown.
import { source } from "@/lib/source";
import { llms } from "fumadocs-core/source";
export const revalidate = false;
export function GET() {
return new Response(llms(source).index());
}import { source } from "@/lib/source";
import { getLLMText } from "@/lib/get-llm-text";
export const revalidate = false;
export async function GET() {
const pages = source.getPages();
const scanned = await Promise.all(pages.map(getLLMText));
return new Response(scanned.join("\n\n"), {
headers: { "Content-Type": "text/plain; charset=utf-8" },
});
}revalidate: false makes these endpoints fully static — they're generated at build time and never re-run.
Why static text instead of HTML?
Three reasons:
- Token cost. Stripping HTML cuts the size by 60–80% on a typical page. For an agent paying per-token to ingest your docs, that's the difference between a viable read and an abandoned one.
- Parser robustness. Markdown has fewer edge cases than HTML. Less ambiguity means fewer parse errors in the agent.
- Cache friendliness. Plain text compresses better and serves from edge caches without negotiation headers.
Customizing what agents see
The getLLMText function in lib/get-llm-text.ts decides what goes into /llms-full.txt. The default is title + description + body, but you can:
- Strip code blocks if your audience is a doc-querying chat and not a code-completion model
- Add metadata — last-updated date, tags, author — that doesn't appear in the user-facing page
- Filter pages — exclude internal docs, draft folders, or 404s
export async function getLLMText(page) {
const description = page.data.description
? `\n> ${page.data.description}\n`
: "";
return `# ${page.data.title} (${page.url})${description}`;
}Privacy
These endpoints make your content trivially scrapable. If any of your docs are sensitive — internal architecture, security postures — make sure they're behind auth and not in the index.
Future: native chat integration
Fumadocs is working on a <AskAI> widget that mounts directly in the sidebar — readers ask questions in plain English and get answers grounded in the site's content. It uses the same /llms-full.txt endpoint as a context source.
Track the Fumadocs AI integrations page for the latest.
How is this guide?
Scaling LLM Inference
A practitioner's account of taking a 70B-parameter model from a research notebook to 10,000 requests per second.
Claude Memory Architecture
How Claude combines a 200k-token context window with multi-layered memory and RAG to deliver accurate, personalised, context-aware responses at scale.