AI
Machine-readable docs with llms.txt and an optional in-page Ask AI assistant.
Blume has a few AI features: machine-readable docs for external tools (llms.txt, on by default), an in-page Ask AI assistant, and a hosted MCP server for coding agents. Ask AI and MCP are opt-in, and static docs stay fully static until you turn a feature on.
llms.txt
Blume emits machine-readable versions of your docs that coding agents and chat assistants can consume. This is on by default; set llmsTxt: false to turn it off:
ai: {
llmsTxt: false,
}
While enabled, blume build writes two files to the root of your site:
/llms.txt— a compact index: your site title and description, then a linked list of every page with its summary./llms-full.txt— the entire corpus: each page’s full Markdown body, with its source URL, in one file.
Draft pages are excluded. Set deployment.site so the links and source URLs resolve to absolute addresses.
Raw Markdown
Append .md or .mdx to any page’s URL to fetch its raw Markdown source — perfect for LLMs, coding agents, and “copy as Markdown” workflows. It’s available for every page, in dev and production, with no configuration.
| URL | Returns |
|---|---|
/quickstart |
The rendered page |
/quickstart.md |
The raw Markdown source |
/quickstart.mdx |
The raw Markdown source |
Nested routes work the same way (/content/syntax.md), and the home page is served at /index.md.
Copy as Markdown
Every page carries a Copy as Markdown action — in the page actions beneath the table of contents — that copies the page’s raw Markdown to the clipboard. It’s the same source served at the .md URL above, ready to paste into an LLM, an issue, or your notes. It’s available on every page, in dev and production, with no configuration.
Open in chat
The Open in chat action opens the current page in an AI assistant — v0, ChatGPT, Claude, T3 Chat, Scira, or Cursor — pre-filled with a prompt that points it at the page’s raw Markdown so it can answer questions about what you’re reading:
Read
https://your-site/this-page.mdso I can ask you questions about this page.
Like Copy as Markdown, it needs no setup. The assistant fetches the page over its public URL, so it works as soon as the page is deployed.
To embed a ready-to-copy prompt inline in your content — rather than a whole-page action — use the Prompt component, which renders a labelled row with a Copy prompt button and an optional open-in-Cursor link.
Ask AI
Add an assistant that answers reader questions in an in-page chat panel, backed by a streaming server endpoint and the AI SDK:
ai: {
ask: {
enabled: true,
provider: "gateway", // default
model: "openai/gpt-5.5",
},
}
Suggested questions
Seed the empty state with a few starter prompts. Each renders as a clickable suggestion — click one to send it — with an optional Lucide icon beside the label:
ai: {
ask: {
enabled: true,
suggestions: [
{ label: "What is Blume?", icon: "rocket" },
{ label: "How do I write a docs page?", icon: "file-text" },
{ label: "How do I configure the theme?", icon: "settings" },
],
},
}
label is the question that gets asked; icon is optional. Leave suggestions unset (or empty) and the panel opens to a plain input.
Grounding
Ask AI is grounded in your docs. For each question it retrieves the most relevant pages — using the same lexical Orama index that powers on-page search — and injects them into the model’s system prompt, so answers come from your content instead of the model’s own knowledge. The assistant is told to answer only from the retrieved pages, to say when something isn’t covered, and to cite the pages it drew from.
The page the reader is currently on is added to the context first and used to scope retrieval to that page’s language, so answers stay relevant to where they are in the docs. Retrieval runs at request time from a snapshot baked into the build, so it works regardless of your search provider — even when search is set to none — and needs no configuration.
Grounding is on for every backend except Inkeep, which runs its own retrieval over the content you’ve indexed in its dashboard.
Server output required
Ask AI is a server route (POST /api/ask), so it can’t run on a static build. Switch to server output and pick an adapter:
deployment: {
output: "server",
adapter: "vercel",
}
A static build with Ask AI enabled fails fast with a message telling you to set deployment.output to server. See Deployment for the adapters.
Backends
By default Ask AI routes through the Vercel AI Gateway: model is a provider/model string, so you switch models by changing it (openai/gpt-5.5, anthropic/claude-sonnet-4-5, and so on) with no provider SDK to install. The gateway reads AI_GATEWAY_API_KEY from your environment and is wired up automatically when you deploy on Vercel.
Set provider to point Ask AI somewhere else. Each backend reads its API key from an environment variable, and the matching provider SDK is added to your project’s runtime automatically when you build — only the one you use:
provider |
model |
API key env var |
|---|---|---|
gateway (default) |
a provider/model string via the AI Gateway |
AI_GATEWAY_API_KEY |
openrouter |
any OpenRouter model | OPENROUTER_API_KEY |
llmgateway |
any LLMGateway model | LLMGATEWAY_API_KEY |
inkeep |
an Inkeep QA model | INKEEP_API_KEY |
openai-compatible |
whatever your endpoint serves | set with apiKeyEnv |
For example, to use OpenRouter:
ai: {
ask: {
enabled: true,
provider: "openrouter",
model: "anthropic/claude-sonnet-4-5",
},
}
Any OpenAI-compatible endpoint works through openai-compatible — supply the baseUrl and the env var holding its key:
ai: {
ask: {
enabled: true,
provider: "openai-compatible",
baseUrl: "https://my-gateway.example.com/v1",
apiKeyEnv: "MY_GATEWAY_API_KEY",
model: "gpt-4o",
},
}
Set apiKeyEnv (and, for the named providers, baseUrl) on any backend to point at a different env var or proxy.
Keys are read with process.env, which covers the Node, Vercel, and Netlify adapters. On Cloudflare, expose the key through the platform’s runtime binding. Enabling Ask AI also turns on React for the in-page island — see Customization.
Rate limiting
The POST /api/ask endpoint is unauthenticated — it has to be, so the in-page assistant can call it. Blume validates each request — rejecting malformed bodies, capping it to 1–40 messages, and accepting only user/assistant roles so a caller can’t inject their own system prompt and repurpose the route as a general LLM proxy — to bound how much a single call can spend against your model, but it can’t stop someone from calling the endpoint repeatedly. If cost abuse is a concern, put the route behind a rate limiter — your host’s (e.g. Vercel’s) edge rate limiting, a middleware, or your model provider’s per-key spend limits.
MCP server
Host a Model Context Protocol server so coding agents (Claude Code, Cursor, VS Code, claude.ai connectors) can search and read your docs directly — no scraping:
mcp: {
enabled: true,
route: "/mcp", // where the server is mounted
}
| Option | Default | Description |
|---|---|---|
enabled |
false |
Generate and host the MCP server. |
route |
/mcp |
Path the Streamable-HTTP endpoint is mounted on. |
name |
title | Server name shown to clients (defaults to title). |
instructions |
— | Optional system hint passed to connecting agents. |
The server exposes four read-only tools — search_docs, get_page, list_pages, and get_navigation — and publishes discovery documents at /.well-known/mcp.json and /.well-known/mcp/server-card.json. Each page’s Connect to MCP menu offers copy-and-go install for Claude Code, Cursor, and VS Code (shown once deployment.site is set).
search_docs runs its own full-text index, so it works regardless of your search provider — and even when search is set to none. The MCP server is a separate feature from on-page search.
Server output required
The MCP server is a live endpoint (/mcp), so it can’t run on a static build. Switch to server output and pick an adapter:
deployment: {
output: "server",
adapter: "node", // or "vercel" | "netlify" | "cloudflare"
site: "https://docs.example.com",
}
A static build with mcp.enabled fails fast with a message telling you to set deployment.output to server. See Deployment for the adapters. Once deployed, connect from Claude Code with:
claude mcp add --transport http my-docs https://docs.example.com/mcp
Agent readability
Blume writes an /agent-readability.json manifest at your site root that indexes the agent-facing surface described on this page — so an agent can discover it in a single fetch instead of guessing at conventions or scraping HTML. Unlike the features above, it’s on by default:
seo: {
agentReadability: true,
}
The manifest lists only what you’ve enabled — the raw Markdown mirror pattern, llms.txt and llms-full.txt, the MCP server and its discovery document, the Ask AI endpoint, the sitemap, and RSS feeds — alongside your site name, description, source repository, and the content-signal usage policy. URLs are absolute when deployment.site is set and root-relative otherwise:
{
"artifacts": {
"markdown": {
"contentNegotiation": "text/markdown",
"pattern": "https://docs.example.com/{route}.md"
},
"llmsFullTxt": "https://docs.example.com/llms-full.txt",
"llmsTxt": "https://docs.example.com/llms.txt",
"mcp": {
"discovery": "https://docs.example.com/.well-known/mcp.json",
"url": "https://docs.example.com/mcp"
}
},
"description": "Docs for the Acme API.",
"generator": "blume@1.0.0",
"name": "Acme Docs",
"site": "https://docs.example.com",
"contentUsage": { "search": true, "ai-input": true, "ai-train": true },
"repository": "https://github.com/acme/docs"
}
Set seo.agentReadability to false to skip it, or ship your own public/agent-readability.json to take over — Blume never overwrites a file you place in public/.
Agent skill
Building a Blume site with the help of a coding agent? Install the Blume agent skill so it knows how Blume works without you explaining it:
npx skills add haydenbleasel/blume
The skill teaches the agent what Blume is and how to scaffold, write, and configure a site, and points it at the full docs bundled in the installed package (node_modules/blume/docs).
It’s one of the agent skills Blume ships, alongside skills for migrating an existing docs site to Blume and keeping docs in sync with your product from a scheduled agent run.