AI
llms.txt के साथ अपने डॉक्स को मशीन-पठनीय बनाएँ, एक वैकल्पिक इन-पेज Ask AI सहायक जोड़ें, और कोडिंग एजेंट्स के लिए एक होस्टेड MCP सर्वर उपलब्ध कराएँ।
Blume में कुछ AI सुविधाएँ हैं: बाहरी टूल्स के लिए मशीन-पठनीय डॉक्स (llms.txt, डिफ़ॉल्ट रूप से चालू), एक इन-पेज Ask AI सहायक, और कोडिंग एजेंट्स के लिए एक होस्टेड MCP सर्वर। Ask AI और MCP ऑप्ट-इन हैं, और जब तक आप कोई सुविधा चालू नहीं करते, स्टैटिक डॉक्स पूरी तरह स्टैटिक बने रहते हैं।
llms.txt
Blume आपके डॉक्स के मशीन-पठनीय संस्करण उत्सर्जित करता है जिन्हें कोडिंग एजेंट और चैट सहायक उपभोग कर सकते हैं। यह डिफ़ॉल्ट रूप से चालू है; इसे बंद करने के लिए llmsTxt: false सेट करें:
ai: {
llmsTxt: false,
}
सक्षम होने पर, blume build आपकी साइट के रूट में दो फ़ाइलें लिखता है:
/llms.txt— एक संक्षिप्त इंडेक्स: आपकी साइट का शीर्षक और विवरण, फिर हर पेज की एक लिंक की गई सूची उसके सारांश के साथ, ऐसे अनुभागों में व्यवस्थित जो आपके साइडबार को प्रतिबिंबित करते हैं — फ़ोल्डर और समूह शीर्षक बन जाते हैं, इसलिए एजेंट को डॉक्स की संरचना दिखती है, एक सपाट ढेर नहीं।/llms-full.txt— पूरा संग्रह: हर पेज का पूरा Markdown मुख्य भाग, उसके स्रोत URL के साथ, एक ही फ़ाइल में।
ड्राफ़्ट पेज बाहर रखे जाते हैं। deployment.site सेट करें ताकि लिंक और स्रोत URL निरपेक्ष पतों में हल हों।
llmsTxt एक ऑब्जेक्ट रूप भी लेता है जिसमें यह नियंत्रित करने के विकल्प हैं कि फ़ाइलों में क्या शामिल हो। यदि आपका API संदर्भ किसी प्लेसहोल्डर या उदाहरण स्पेक का दस्तावेज़ीकरण करता है, तो उसके जनरेट किए गए पेजों को दोनों फ़ाइलों से बाहर रखने के लिए openapi: false सेट करें:
ai: {
llmsTxt: {
enabled: true, // default
openapi: false, // exclude generated API reference pages
},
}
किसी एक पेज को दोनों फ़ाइलों से बाहर रखने के लिए, उसके फ़्रंटमैटर में ai.exclude सेट करें:
---
title: Internal notes
ai:
exclude: true
---
पेज फिर भी रेंडर होता है, खोज में बना रहता है, और साइटमैप में अपना स्थान बनाए रखता है — केवल llms.txt फ़ाइलें ही इसे छोड़ती हैं।
किसी भी फ़ाइल पर पूर्ण नियंत्रण लेने के लिए, अपने public/ फ़ोल्डर में अपनी स्वयं की llms.txt या llms-full.txt जोड़ें। कस्टम फ़ेविकॉन की तरह, इसे स्वचालित रूप से उठा लिया जाता है और जनरेट की गई फ़ाइल के स्थान पर भेजा जाता है — एक को ओवरराइड करें और Blume फिर भी दूसरी जनरेट करता है।
कच्चा Markdown
किसी भी पेज के URL में .md या .mdx जोड़ें ताकि उसका कच्चा Markdown स्रोत प्राप्त हो — LLMs, कोडिंग एजेंट्स और “copy as Markdown” वर्कफ़्लो के लिए एकदम सही। यह हर पेज के लिए, dev और production दोनों में, बिना किसी कॉन्फ़िगरेशन के उपलब्ध है।
| URL | क्या लौटाता है |
|---|---|
/quickstart |
रेंडर किया गया पेज |
/quickstart.md |
सादा Markdown, कंपोनेंट्स परिवर्तित किए हुए |
/quickstart.mdx |
कच्चा MDX स्रोत, ठीक वैसा ही जैसा लिखा गया |
नेस्टेड रूट्स भी उसी तरह काम करते हैं (/content/syntax.md), और होम पेज /index.md पर सर्व किया जाता है।
.md वैरिएंट उन उपभोक्ताओं के लिए कंपोनेंट्स को सादे Markdown में डाउनलेवल करता है जो JSX की व्याख्या नहीं कर सकते: <TypeTable> एक Markdown तालिका बन जाती है, <Callout> एक लेबल किया गया ब्लॉककोट, <Steps> एक क्रमबद्ध सूची, <Tabs> बोल्ड-लेबल वाले अनुभाग, और <YouTube> एक लिंक। प्रॉप्स का मूल्यांकन पेज के frontmatter को स्कोप में रखकर किया जाता है, इसलिए title={frontmatter.status} जैसा प्रॉप उसी मान में हल होता है जो रेंडर किया गया पेज दिखाता है। जो कुछ भी सटीक रूप से परिवर्तित नहीं किया जा सकता — कोई कस्टम कंपोनेंट, या किसी इम्पोर्ट से गणना किया गया प्रॉप — उसे जस का तस छोड़ दिया जाता है, और फ़ेंस किए गए कोड ब्लॉक्स के भीतर के कंपोनेंट मार्कअप को कभी नहीं छुआ जाता। यही रूपांतरण llms-full.txt और MCP सर्वर के get_page टूल पर भी लागू होता है, इसलिए हर एजेंट-सामने वाली सतह साफ़ Markdown पढ़ती है। जब आपको अपरिवर्तित स्रोत चाहिए, तो .mdx वैरिएंट का उपयोग करें।
कंटेंट नेगोशिएशन
एजेंट्स को .md परंपरा जानने की ज़रूरत नहीं है: किसी पेज के अपने URL को Accept: text/markdown हेडर के साथ अनुरोध करने पर उसी पते पर Markdown वैरिएंट सर्व होता है, Vary: Accept के साथ ताकि कैश दोनों को अलग रखें। dev सर्वर हेडर को बिना किसी सेटअप के सम्मानित करता है, और एक Vercel या Cloudflare सर्वर बिल्ड उसी नेगोशिएशन को डिप्लॉय में स्वचालित रूप से जोड़ देता है — Vercel पर रूटिंग नियम, Cloudflare पर एक जनरेट किया गया Worker — किसी कॉन्फ़िगरेशन की आवश्यकता नहीं। होमपेज हमेशा नेगोशिएट करता है, तब भी जब वह किसी कंटेंट पेज के बजाय एक कस्टम लैंडिंग पेज हो: उसका Markdown प्रतिबिंब llms.txt इंडेक्स पर वापस गिरता है, इसलिए साइट रूट से Markdown माँगने वाले एजेंट को साइट का मशीन-पठनीय नक्शा मिलता है। Markdown प्रतिक्रियाएँ एक x-markdown-tokens हेडर भी ले जाती हैं — एक अनुमानित टोकन गणना (~4 अक्षर प्रति टोकन), Cloudflare के Markdown for Agents की परंपरा का अनुसरण करते हुए — हर उस सतह पर जहाँ Blume प्रतिक्रिया हेडर नियंत्रित करता है: dev सर्वर, सर्वर-रेंडर की गई प्रतिक्रियाएँ, और Vercel तथा Cloudflare पर नेगोशिएट किया गया होमपेज। अन्य डिप्लॉय लक्ष्य पूर्व-रेंडर किए गए पेजों को एक स्टैटिक परत से सर्व करते हैं जिसमें अनुरोध-समय का कोई हुक नहीं होता, इसलिए वहाँ एजेंट सीधे .md URL लाते हैं; एजेंट रीडेबिलिटी मैनिफ़ेस्ट केवल उन डिप्लॉयमेंट्स पर contentNegotiation का विज्ञापन करता है जो हेडर को सम्मानित करते हैं।
कस्टम कंपोनेंट सीरियलाइज़र
ai.markdownComponents के साथ अपने स्वयं के कंपोनेंट्स को एक Markdown रूप दें — JSX नाम से सीरियलाइज़र का एक मानचित्र। प्रत्येक सीरियलाइज़र कंपोनेंट के props (MDX एट्रिब्यूट्स से स्थैतिक रूप से मूल्यांकित, पेज के frontmatter को स्कोप में रखकर), उसके children (पहले ही Markdown में डाउनलेवल किए हुए), और पेज का frontmatter डेटा प्राप्त करता है, और प्रतिस्थापन लौटाता है — या JSX को जस का तस छोड़ने के लिए null:
import { defineConfig } from "blume";
import type { ComponentMarkdown } from "blume";
const chart: ComponentMarkdown = ({ props }) =>
``;
export default defineConfig({
ai: {
markdownComponents: {
Chart: chart,
},
},
});
कंटेनर कंपोनेंट्स के लिए, childComponents("Name") टैग के अनुसार सीधे चिल्ड्रन निकालता है — ठीक उसी तरह जैसे अंतर्निर्मित <Steps> सीरियलाइज़र अपने <Step> आइटम एकत्र करता है। समान नाम वाली एक प्रविष्टि अंतर्निर्मित सीरियलाइज़र को बदल देती है, इसलिए आप बदल सकते हैं कि <Callout> कैसे डाउनलेवल होता है — या किसी एक को पूरी तरह बाहर करने के लिए null लौटा सकते हैं।
सीरियलाइज़र blume.config.ts में रहते हैं, components.tsx में नहीं: कॉन्फ़िग फ़ाइल बिल्ड समय पर निष्पादित होती है, जबकि कंपोनेंट्स फ़ाइल का केवल स्थैतिक विश्लेषण किया जाता है (यह .astro फ़ाइलें इम्पोर्ट कर सकती है, जो साइट बिल्ड के बाहर नहीं चल सकतीं)। आपके कंपोनेंट्स स्वयं पहले की तरह ही components.tsx में पंजीकृत रहते हैं — markdownComponents केवल उनका एजेंट-सामने वाला Markdown रूप जोड़ता है।
Copy as Markdown
हर पेज पर एक Copy as Markdown क्रिया होती है — विषय-सूची के नीचे पेज क्रियाओं में — जो पेज का कच्चा Markdown क्लिपबोर्ड पर कॉपी करती है। यह वही स्रोत है जो ऊपर .md URL पर सर्व किया जाता है, किसी LLM, किसी इशू, या आपके नोट्स में पेस्ट करने के लिए तैयार। यह हर पेज पर, dev और production दोनों में, बिना किसी कॉन्फ़िगरेशन के उपलब्ध है।
चैट में खोलें
Open in chat क्रिया वर्तमान पेज को किसी AI सहायक में खोलती है — v0, ChatGPT, Claude, T3 Chat, Scira, या Cursor — एक ऐसे प्रॉम्प्ट के साथ पहले से भरा हुआ जो उसे पेज के कच्चे Markdown की ओर इंगित करता है ताकि वह उसके बारे में सवालों का जवाब दे सके जो आप पढ़ रहे हैं:
Read
https://your-site/this-page.mdso I can ask you questions about this page.
Copy as Markdown की तरह, इसे किसी सेटअप की ज़रूरत नहीं है। सहायक पेज को उसके सार्वजनिक URL से लाता है, इसलिए यह पेज डिप्लॉय होते ही काम करने लगता है।
अपनी सामग्री में इनलाइन एक कॉपी-करने-योग्य प्रॉम्प्ट एम्बेड करने के लिए — पूरे-पेज की क्रिया के बजाय — Prompt कंपोनेंट का उपयोग करें, जो एक Copy prompt बटन और एक वैकल्पिक open-in-Cursor लिंक के साथ एक लेबल की गई पंक्ति रेंडर करता है।
Ask AI
एक सहायक जोड़ें जो पाठकों के सवालों का जवाब एक इन-पेज चैट पैनल में देता है, जिसके पीछे एक स्ट्रीमिंग सर्वर एंडपॉइंट और AI SDK है:
ai: {
ask: {
enabled: true,
provider: "gateway", // default
model: "openai/gpt-5.5",
},
}
सुझाए गए प्रश्न
खाली स्थिति को कुछ शुरुआती प्रॉम्प्ट्स से भरें। प्रत्येक एक क्लिक-योग्य सुझाव के रूप में रेंडर होता है — भेजने के लिए किसी एक पर क्लिक करें — लेबल के बगल में एक वैकल्पिक Lucide आइकन के साथ:
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 वह प्रश्न है जो पूछा जाता है; icon वैकल्पिक है। suggestions को अनसेट (या खाली) छोड़ दें और पैनल एक सादे इनपुट के साथ खुलता है।
ग्राउंडिंग
Ask AI आपके डॉक्स में ग्राउंडेड है। हर प्रश्न के लिए यह सबसे प्रासंगिक पेज पुनःप्राप्त करता है — वही लेक्सिकल Orama इंडेक्स उपयोग करते हुए जो ऑन-पेज खोज को शक्ति देता है — और उन्हें मॉडल के सिस्टम प्रॉम्प्ट में डालता है, ताकि उत्तर मॉडल के अपने ज्ञान के बजाय आपकी सामग्री से आएँ। सहायक को कहा जाता है कि वह केवल पुनःप्राप्त पेजों से उत्तर दे, बताए कि कब कोई बात कवर नहीं है, और जिन पेजों से उसने लिया है उनका उद्धरण दे।
पाठक वर्तमान में जिस पेज पर है, उसे सबसे पहले संदर्भ में जोड़ा जाता है और पुनःप्राप्ति को उस पेज की भाषा तक सीमित करने के लिए उपयोग किया जाता है, ताकि उत्तर इस बात के अनुरूप रहें कि वे डॉक्स में कहाँ हैं। पुनःप्राप्ति अनुरोध समय पर बिल्ड में पकाए गए एक स्नैपशॉट से चलती है, इसलिए यह आपके खोज प्रदाता की परवाह किए बिना काम करती है — तब भी जब खोज none पर सेट हो — और इसे किसी कॉन्फ़िगरेशन की ज़रूरत नहीं है।
Inkeep को छोड़कर हर बैकएंड के लिए ग्राउंडिंग चालू है, जो अपने डैशबोर्ड में आपके द्वारा इंडेक्स की गई सामग्री पर अपनी स्वयं की पुनःप्राप्ति चलाता है।
बाहरी एंडपॉइंट
क्या आपके पास पहले से AI के लिए एक API बैकएंड है? पैनल को उसकी ओर इंगित करें और डॉक्स बिल्ड को स्टैटिक रखें:
ai: {
ask: {
enabled: true,
endpoint: "https://api.example.com/v1/docs/ask",
},
}
Blume वही POST बॉडी भेजता है जो उसका अंतर्निर्मित रूट भेजता है:
{
"messages": [{ "role": "user", "content": "How do I deploy?" }],
"page": { "path": "/deployment" }
}
एक सफल प्रतिक्रिया लौटाएँ जिसकी बॉडी एक सादी UTF-8 टेक्स्ट स्ट्रीम हो। यदि एंडपॉइंट किसी अन्य ऑरिजिन पर है, तो CORS के साथ डॉक्स ऑरिजिन की अनुमति दें: OPTIONS और POST स्वीकार करें, content-type अनुरोध हेडर की अनुमति दें, और प्रीफ़्लाइट तथा स्ट्रीम की गई प्रतिक्रिया दोनों पर CORS हेडर लौटाएँ। endpoint सेट होने पर, Blume चैट UI जनरेट करता है लेकिन कोई सर्वर रूट, ग्राउंडिंग स्नैपशॉट, प्रदाता निर्भरता, या प्रदाता-सीक्रेट चेतावनी नहीं; आपका बैकएंड पुनःप्राप्ति, प्रमाणीकरण, दर सीमा, मॉडल एक्सेस और उद्धरणों का स्वामी होता है।
सर्वर आउटपुट आवश्यक
Blume का अंतर्निर्मित Ask AI बैकएंड एक सर्वर रूट (POST /api/ask) है, इसलिए यह स्टैटिक बिल्ड पर नहीं चल सकता। सर्वर आउटपुट पर स्विच करें और एक एडाप्टर चुनें:
deployment: {
output: "server",
adapter: "vercel",
}
Ask AI सक्षम और बिना बाहरी endpoint वाला एक स्टैटिक बिल्ड तुरंत विफल हो जाता है, एक संदेश के साथ जो आपको deployment.output को server पर सेट करने के लिए कहता है। एडाप्टर्स के लिए Deployment देखें।
बैकएंड्स
डिफ़ॉल्ट रूप से Ask AI Vercel AI Gateway के माध्यम से रूट होता है: model एक provider/model स्ट्रिंग है, इसलिए आप इसे बदलकर मॉडल बदलते हैं (openai/gpt-5.5, anthropic/claude-sonnet-4-5, इत्यादि) और कोई प्रदाता SDK इंस्टॉल नहीं करना पड़ता। गेटवे आपके परिवेश से AI_GATEWAY_API_KEY पढ़ता है और जब आप Vercel पर डिप्लॉय करते हैं तो स्वचालित रूप से जुड़ जाता है।
Ask AI को कहीं और इंगित करने के लिए provider सेट करें। प्रत्येक बैकएंड अपनी API कुंजी एक परिवेश चर से पढ़ता है, और मेल खाने वाला प्रदाता SDK बिल्ड करते समय स्वचालित रूप से आपके प्रोजेक्ट के रनटाइम में जोड़ दिया जाता है — केवल वही जिसका आप उपयोग करते हैं:
provider |
model |
API कुंजी env चर |
|---|---|---|
gateway (डिफ़ॉल्ट) |
AI Gateway के माध्यम से एक provider/model स्ट्रिंग |
AI_GATEWAY_API_KEY |
openrouter |
कोई भी OpenRouter मॉडल | OPENROUTER_API_KEY |
llmgateway |
कोई भी LLMGateway मॉडल | LLMGATEWAY_API_KEY |
inkeep |
एक Inkeep QA मॉडल | INKEEP_API_KEY |
openai-compatible |
जो कुछ भी आपका एंडपॉइंट सर्व करता है | apiKeyEnv से सेट करें |
उदाहरण के लिए, OpenRouter उपयोग करने के लिए:
ai: {
ask: {
enabled: true,
provider: "openrouter",
model: "anthropic/claude-sonnet-4-5",
},
}
कोई भी OpenAI-संगत एंडपॉइंट openai-compatible के माध्यम से काम करता है — baseUrl और उसकी कुंजी रखने वाला env चर दें:
ai: {
ask: {
enabled: true,
provider: "openai-compatible",
baseUrl: "https://my-gateway.example.com/v1",
apiKeyEnv: "MY_GATEWAY_API_KEY",
model: "gpt-4o",
},
}
किसी भिन्न env चर या प्रॉक्सी की ओर इंगित करने के लिए किसी भी बैकएंड पर apiKeyEnv (और, नामित प्रदाताओं के लिए, baseUrl) सेट करें।
कुंजियाँ process.env से पढ़ी जाती हैं, जो Node, Vercel और Netlify एडाप्टर्स को कवर करता है। Cloudflare पर, कुंजी को प्लेटफ़ॉर्म के रनटाइम बाइंडिंग के माध्यम से उपलब्ध कराएँ। Ask AI सक्षम करने से इन-पेज आइलैंड के लिए React भी चालू हो जाता है — देखें Customization।
दर सीमा
POST /api/ask एंडपॉइंट अप्रमाणित है — इसे होना ही पड़ता है, ताकि इन-पेज सहायक इसे कॉल कर सके। Blume हर अनुरोध को मान्य करता है — विकृत बॉडी अस्वीकार करते हुए, इसे 1–40 संदेशों तक सीमित करते हुए, और केवल user/assistant भूमिकाएँ स्वीकार करते हुए ताकि कोई कॉलर अपना सिस्टम प्रॉम्प्ट इंजेक्ट करके रूट को एक सामान्य LLM प्रॉक्सी में न बदल सके — ताकि यह सीमित रहे कि एक कॉल आपके मॉडल के विरुद्ध कितना खर्च कर सकता है, लेकिन यह किसी को बार-बार एंडपॉइंट कॉल करने से नहीं रोक सकता। यदि लागत का दुरुपयोग चिंता का विषय है, तो रूट को किसी दर सीमक के पीछे रखें — आपके होस्ट की (जैसे Vercel की) एज दर सीमा, कोई मिडलवेयर, या आपके मॉडल प्रदाता की प्रति-कुंजी खर्च सीमाएँ।
MCP सर्वर
एक Model Context Protocol सर्वर होस्ट करें ताकि कोडिंग एजेंट (Claude Code, Cursor, VS Code, claude.ai कनेक्टर्स) आपके डॉक्स को सीधे खोज और पढ़ सकें — बिना स्क्रैपिंग के:
ai: {
mcp: {
enabled: true,
route: "/mcp", // where the server is mounted
},
}
| विकल्प | डिफ़ॉल्ट | विवरण |
|---|---|---|
enabled |
false |
MCP सर्वर जनरेट और होस्ट करें। |
route |
/mcp |
वह पथ जिस पर Streamable-HTTP एंडपॉइंट माउंट होता है। |
name |
title | क्लाइंट्स को दिखाया जाने वाला सर्वर नाम (डिफ़ॉल्ट title)। |
instructions |
— | कनेक्ट होने वाले एजेंट्स को दिया जाने वाला वैकल्पिक सिस्टम संकेत। |
सर्वर केवल-पढ़ने योग्य टूल उपलब्ध कराता है — search_docs, get_page, list_pages, और get_navigation — और /.well-known/mcp.json तथा /.well-known/mcp/server-card.json पर डिस्कवरी दस्तावेज़ प्रकाशित करता है। सर्वर कार्ड SEP-2127 Server Card एक्सटेंशन स्कीमा का अनुसरण करता है (रिवर्स-DNS name, remotes ट्रांसपोर्ट एंडपॉइंट्स), साथ ही प्रस्ताव के पूर्ववर्ती संशोधन के विरुद्ध बनाए गए स्कैनर्स के लिए initialize-आकार वाले संगतता फ़ील्ड (serverInfo, capabilities, transports) के साथ। हर पेज का Connect to MCP मेनू Claude Code, Cursor, VS Code और Codex के लिए कॉपी-एंड-गो इंस्टॉल प्रदान करता है (deployment.site सेट होने पर दिखता है)।
search_docs अपना स्वयं का पूर्ण-पाठ इंडेक्स चलाता है, इसलिए यह आपके खोज प्रदाता की परवाह किए बिना काम करता है — और तब भी जब खोज none पर सेट हो। MCP सर्वर ऑन-पेज खोज से एक अलग सुविधा है।
search_docs और list_pages दोनों एक वैकल्पिक contentTypes फ़िल्टर स्वीकार करते हैं, जो परिणामों को दिए गए फ़्रंटमैटर types वाले पेजों तक सीमित करता है — ["rfc"], ["blog", "changelog"] — ताकि ऐसी साइट पर काम करने वाला एजेंट जो डॉक्स को RFCs, रनबुक्स या नीतियों के साथ मिलाती है, पुनःप्राप्ति को उस प्रकार के पेज तक सीमित कर सके जिसकी उसे ज़रूरत है। हर परिणाम अपना कंटेंट प्रकार बताता है, और list_pages का आउटपुट उपयोग में मौजूद प्रकार दिखाता है।
दोनों टूल एक filters ऑब्जेक्ट भी स्वीकार करते हैं जो उन फ़ेसेट्स के विरुद्ध मिलान करता है जिन्हें कोई साइट प्रति कंटेंट प्रकार घोषित करती है (content.types.<type>.facets) — कस्टम फ़्रंटमैटर कुंजियाँ जिनके मान फ़िल्टर करने योग्य मेटाडेटा बन जाते हैं:
{
"query": "OpenAPI request schemas",
"contentTypes": ["rfc"],
"filters": { "domain": "architecture", "status": "enforced" }
}
हर filters प्रविष्टि का मेल खाना आवश्यक है (परिणाम अपने फ़ेसेट मान साथ रखते हैं, और list_pages हर पेज के मान दिखाता है), इसलिए एक नॉलेज बेस प्रोग्रेसिव-डिस्क्लोज़र एजेंट वर्कफ़्लो चला सकता है — लागू मानकों की गणना करें, केवल उन्हीं के भीतर खोजें — अपने किसी सर्वर के बिना।
सर्वर आउटपुट आवश्यक
MCP सर्वर एक लाइव एंडपॉइंट (/mcp) है, इसलिए यह स्टैटिक बिल्ड पर नहीं चल सकता। सर्वर आउटपुट पर स्विच करें और एक एडाप्टर चुनें:
deployment: {
output: "server",
adapter: "node", // or "vercel" | "netlify" | "cloudflare"
site: "https://docs.example.com",
}
ai.mcp.enabled वाला एक स्टैटिक बिल्ड तुरंत विफल हो जाता है, एक संदेश के साथ जो आपको deployment.output को server पर सेट करने के लिए कहता है। एडाप्टर्स के लिए Deployment देखें। डिप्लॉय होने के बाद, Claude Code से इस तरह कनेक्ट करें:
claude mcp add --transport http my-docs https://docs.example.com/mcp
एजेंट रीडेबिलिटी
Blume आपकी साइट के रूट पर एक /agent-readability.json मैनिफ़ेस्ट लिखता है जो इस पेज पर वर्णित एजेंट-सामने वाली सतह को इंडेक्स करता है — ताकि एक एजेंट परंपराओं का अनुमान लगाने या HTML स्क्रैप करने के बजाय इसे एक ही फ़ेच में खोज सके। llms.txt की तरह, यह डिफ़ॉल्ट रूप से चालू है:
seo: {
agentReadability: true,
}
मैनिफ़ेस्ट केवल वही सूचीबद्ध करता है जो आपने सक्षम किया है — कच्चा Markdown प्रतिबिंब पैटर्न, llms.txt और llms-full.txt, MCP सर्वर और उसका डिस्कवरी दस्तावेज़, Ask AI एंडपॉइंट, साइटमैप, और RSS फ़ीड्स — साथ ही आपकी साइट का नाम, विवरण, स्रोत रिपॉज़िटरी, और content-signal उपयोग नीति। deployment.site सेट होने पर URL निरपेक्ष होते हैं और अन्यथा रूट-सापेक्ष:
{
"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"
}
contentNegotiation फ़ील्ड केवल तब प्रकट होता है जब डिप्लॉय की गई साइट वास्तव में Accept: text/markdown हेडर को सम्मानित करती है — देखें कंटेंट नेगोशिएशन; हर दूसरे डिप्लॉयमेंट पर मैनिफ़ेस्ट केवल .md प्रतिबिंब पैटर्न का विज्ञापन करता है।
इसे छोड़ने के लिए seo.agentReadability को false सेट करें, या नियंत्रण लेने के लिए अपनी स्वयं की public/agent-readability.json भेजें — Blume कभी भी उस फ़ाइल को अधिलेखित नहीं करता जिसे आप public/ में रखते हैं।
डिस्कवरी Link हेडर
जो एजेंट किसी साइट की जाँच करते हैं उन्हें मैनिफ़ेस्ट खोजने का पता नहीं होता — इसलिए Blume होमपेज पर एक RFC 8288 Link प्रतिक्रिया हेडर में भी इसका विज्ञापन करता है, IANA-पंजीकृत संबंध प्रकारों का उपयोग करते हुए:
Link: </agent-readability.json>; rel="describedby"; type="application/json",
</llms.txt>; rel="describedby"; type="text/plain",
</index.md>; rel="alternate"; type="text/markdown"
प्रत्येक प्रविष्टि केवल तभी दिखती है जब उसकी सुविधा चालू हो। alternate लिंक होमपेज के Markdown प्रतिबिंब की ओर इंगित करता है — जब होम रूट एक कंटेंट पेज हो तो पेज का अपना कच्चा Markdown, या जब वह लैंडिंग पेज हो तो संश्लेषित llms.txt फ़ॉलबैक। जो साइटें APIs भी प्रकाशित करती हैं उन्हें जनरेट किए गए API कैटलॉग की ओर इंगित करने वाली एक rel="api-catalog" प्रविष्टि भी मिलती है। हेडर हर उस सतह पर जाता है जिसे Blume नियंत्रित करता है: dev सर्वर (curl -I localhost:4321 से जाँचें), उत्सर्जित _headers फ़ाइल के माध्यम से स्टैटिक बिल्ड (Netlify और Cloudflare), और डिप्लॉय के रूटिंग नियमों के माध्यम से Vercel सर्वर बिल्ड। जो होस्ट स्टैटिक आउटपुट पर _headers को अनदेखा करते हैं (GitHub Pages, S3) वे कस्टम प्रतिक्रिया हेडर भेज ही नहीं सकते — वहाँ, एजेंट फिर भी साइट रूट पर llms.txt और agent-readability.json के माध्यम से सब कुछ ढूँढ लेते हैं।
API कैटलॉग
जब साइट APIs प्रकाशित करती है, तो Blume /.well-known/api-catalog पर एक RFC 9727 API कैटलॉग जनरेट करता है — एक linkset जो एजेंट्स को केवल डोमेन से आपके APIs की गणना करने देता है, हर बिल्ड सतह पर उसके पंजीकृत application/linkset+json मीडिया प्रकार के साथ सर्व किया जाता है। कॉन्फ़िगर करने को कुछ नहीं है: कैटलॉग उसी से व्युत्पन्न होता है जो पहले से blume.config.ts में है। प्रत्येक OpenAPI या AsyncAPI संदर्भ अपने रेंडर किए गए डॉक्स रूट पर एंकर की गई एक प्रविष्टि बन जाता है, जिसमें service-doc उन डॉक्स की ओर और service-desc स्पेक की ओर इंगित करता है जब वह किसी फ़ेच-योग्य URL पर रहता हो; MCP सर्वर अपने डिस्कवरी दस्तावेज़ को सेवा विवरण के रूप में लेकर एक प्रविष्टि बन जाता है:
{
"linkset": [
{
"anchor": "https://docs.example.com/reference",
"service-doc": [
{ "href": "https://docs.example.com/reference", "type": "text/html" }
],
"service-desc": [{ "href": "https://api.example.com/openapi.json" }]
},
{
"anchor": "https://docs.example.com/mcp",
"service-desc": [
{
"href": "https://docs.example.com/.well-known/mcp.json",
"type": "application/json"
}
],
"service-doc": [
{ "href": "https://docs.example.com/", "type": "text/html" }
]
}
]
}
बिना किसी API संदर्भ और बिना MCP सर्वर वाली साइट कोई कैटलॉग उत्सर्जित नहीं करती — उसमें कुछ होता ही नहीं। हर जगह की तरह, आपके द्वारा स्वयं भेजी गई public/.well-known/api-catalog फ़ाइल जनरेट की गई फ़ाइल पर भारी पड़ती है।
WebMCP
WebMCP एक उभरता हुआ ब्राउज़र API है जो किसी पेज को सीधे एक एजेंटिक ब्राउज़र के साथ टूल्स पंजीकृत करने देता है — किसी अलग सर्वर कनेक्शन की ज़रूरत नहीं। हर Blume पेज डॉक्स की केवल-पढ़ने योग्य सतह को पेज के मॉडल संदर्भ पर पंजीकृत करता है: search_docs (साइट खोज), get_page (किसी पेज का कच्चा Markdown), और list_pages (llms.txt इंडेक्स)। स्क्रिप्ट बहुत छोटी है, जब तक कोई टूल वास्तव में कॉल न हो तब तक कोई खोज मशीनरी लोड नहीं करती, और API के बिना हर ब्राउज़र में चुपचाप no-op हो जाती है — जो आज Chrome के अर्ली प्रीव्यू के बाहर सभी ब्राउज़र हैं। यह उसी सतह पर पंजीकृत होती है जिसे अस्थिर स्पेक उपलब्ध कराता है (navigator.modelContext या document.modelContext), provideContext या प्रति-टूल registerTool के माध्यम से।
यह डिफ़ॉल्ट रूप से चालू है; ऑप्ट आउट करने के लिए webmcp: false सेट करें:
ai: {
webmcp: false,
}
स्किल्स डिस्कवरी
यदि आपका प्रोजेक्ट एजेंट स्किल्स भेजता है — Blume रिपॉज़िटरी स्वयं भेजती है — तो ai.skills को उस डायरेक्टरी की ओर इंगित करें जो उन्हें रखती है, और बिल्ड उन्हें Agent Skills Discovery RFC के अनुसार डिस्कवरी के लिए प्रकाशित करता है:
ai: {
skills: "./skills",
}
पथ आपके प्रोजेक्ट रूट के सापेक्ष हल होता है, और SKILL.md वाली प्रत्येक उपडायरेक्टरी एक प्रकाशित स्किल बन जाती है। जो स्किल केवल एक अकेली SKILL.md है, उसे शब्दशः /.well-known/agent-skills/<name>/SKILL.md (type: "skill-md") पर कॉपी किया जाता है; सहायक संसाधनों (scripts/, references/, assets/) वाली स्किल को एक नियतात्मक .tar.gz (type: "archive") में बंडल किया जाता है ताकि अनपैक करने के बाद उसके सापेक्ष संदर्भ हल हों, स्क्रिप्ट एक्ज़ीक्यूट बिट्स संरक्षित रखते हुए। /.well-known/agent-skills/index.json पर डिस्कवरी इंडेक्स v0.2.0 $schema रखता है और, प्रति स्किल, उसका नाम, प्रकार, विवरण (SKILL.md फ़्रंटमैटर से), आर्टिफ़ैक्ट URL, और SHA-256 डाइजेस्ट जिसके विरुद्ध क्लाइंट डाउनलोड सत्यापित करते हैं।
जिन स्किल्स का name/description अनुपस्थित या स्पेक-अमान्य है, उन्हें टूटी हुई प्रकाशित करने के बजाय एक बिल्ड चेतावनी के साथ छोड़ दिया जाता है, और आपके द्वारा स्वयं भेजी गई public/.well-known/agent-skills/index.json पूरी सतह पर नियंत्रण ले लेती है।
DNS-आधारित डिस्कवरी (DNS-AID)
DNS for AI Discovery एक उभरता हुआ IETF ड्राफ़्ट है जो एजेंट्स को एक भी HTTP अनुरोध किए बिना किसी साइट की AI सतह खोजने देता है, एक well-known DNS प्रवेश-बिंदु पर ServiceMode SVCB/HTTPS रिकॉर्ड्स की क्वेरी करके। DNS रिकॉर्ड आपके ज़ोन में रहते हैं, बिल्ड में नहीं, इसलिए यह एकमात्र डिस्कवरी सतह है जिसे Blume आपके लिए प्रकाशित नहीं कर सकता — इसके बजाय, अपने DNS प्रदाता के साथ एक रिकॉर्ड जोड़ें:
_index._agents.docs.example.com. 3600 IN HTTPS 1 docs.example.com. alpn=h2
यदि आपका प्रदाता HTTPS रिकॉर्ड प्रकार प्रदान करता है तो उसका उपयोग करें (Vercel DNS करता है; यह सादे SVCB प्रकार का समर्थन नहीं करता), अन्यथा alpn और port पैरामीटर्स वाला एक ServiceMode SVCB रिकॉर्ड। ड्राफ़्ट यह भी अनुशंसा करता है कि ज़ोन को DNSSEC से हस्ताक्षरित किया जाए ताकि सत्यापन करने वाले रिज़ॉल्वर प्रमाणित उत्तर लौटाएँ — Cloudflare जैसे प्रदाता इसे एक क्लिक में सक्षम कर देते हैं, जबकि कुछ (Vercel DNS सहित) इसका समर्थन बिल्कुल नहीं करते।
blume audit --url <origin> यह आपके लिए जाँचता है: जब deployment.site सेट हो, तो नेटवर्क स्तर DNS-over-HTTPS के माध्यम से प्रवेश-बिंदु की क्वेरी करता है और यदि कोई मौजूद न हो तो प्रकाशित करने योग्य सटीक रिकॉर्ड बताता है, साथ ही यह भी कि उत्तर DNSSEC-प्रमाणित हैं या नहीं। यदि आपका नेटवर्क सार्वजनिक रिज़ॉल्वर (Google, Cloudflare) ब्लॉक करता है तो लुकअप को अपने स्वयं के रिज़ॉल्वर की ओर इंगित करने के लिए BLUME_DOH_URL सेट करें।
Web Bot Auth
Web Bot Auth दूसरी दिशा में काम करता है: यह एजेंट्स द्वारा आपके डॉक्स पढ़ने के बारे में नहीं है, बल्कि आपके संगठन के एजेंट्स द्वारा स्वयं की पहचान बताने के बारे में है जब वे कहीं और अनुरोध करते हैं। आपके एजेंट अपने अनुरोधों पर HTTP Message Signatures से हस्ताक्षर करते हैं, और प्राप्त करने वाली साइटें उन्हें आपके डोमेन पर प्रकाशित एक सार्वजनिक-कुंजी निर्देशिका के विरुद्ध सत्यापित करती हैं। यदि आपका संगठन एजेंट चलाता है और आपकी Blume साइट उसी डोमेन पर है जिसके रूप में वे पहचान बताते हैं, तो उनकी सार्वजनिक कुंजियाँ प्रकाशित करें:
ai: {
webBotAuth: {
keys: [{ kty: "OKP", crv: "Ed25519", x: "JrQLj5P_89iXES9-vFgrIy29c…" }],
},
}
फिर Blume हर बिल्ड सतह पर JWKS को /.well-known/http-message-signatures-directory पर उसके पंजीकृत मीडिया प्रकार के साथ सर्व करता है। निर्देशिका परिभाषा से ही सार्वजनिक है, इसलिए कॉन्फ़िग केवल सार्वजनिक कुंजियाँ ही स्वीकार करता है — निजी सामग्री (d, p, q, …) वाली JWK एक लीक हुई क्रेडेंशियल भेजने के बजाय एक त्रुटि के साथ सत्यापन में विफल हो जाती है। एक Ed25519 जोड़ी इस तरह जनरेट करें:
node -e 'const { generateKeyPairSync } = require("node:crypto"); const { publicKey, privateKey } = generateKeyPairSync("ed25519"); console.log("public: ", JSON.stringify(publicKey.export({ format: "jwk" }))); console.log("private:", JSON.stringify(privateKey.export({ format: "jwk" })))'
सार्वजनिक JWK ऊपर दिए गए कॉन्फ़िग में जाती है; निजी वाली वहाँ जाती है जहाँ आपका हस्ताक्षर करने वाला एजेंट चलता है (एक सीक्रेट मैनेजर, कभी भी रिपॉज़िटरी नहीं)। यदि आपका संगठन एजेंट संचालित नहीं करता, तो इसे छोड़ दें — एक खाली निर्देशिका सत्यापित करने योग्य कुछ भी विज्ञापित नहीं करती।
चूँकि blume.config.ts बिल्ड समय पर निष्पादित होता है, कुंजी को हार्डकोड करना ज़रूरी नहीं है — इसे बिल्ड-समय के परिवेश चर से लोड करें ताकि कॉन्फ़िग कुंजी ब्लॉब्स से मुक्त रहे और बिना किसी कमिट के रोटेट किया जा सके:
const webBotAuthKey = process.env.WEB_BOT_AUTH_PUBLIC_JWK;
export default defineConfig({
ai: {
webBotAuth: {
keys: webBotAuthKey ? [JSON.parse(webBotAuthKey)] : [],
},
},
});
जिन परिवेशों में यह चर नहीं है वे कोई निर्देशिका प्रकाशित नहीं करते, और इस तरह लोड की गई कुंजी को ठीक वैसे ही सत्यापित किया जाता है जैसे किसी इनलाइन कुंजी को — निजी-सामग्री जाँच सहित। (सार्वजनिक कुंजी कोई रहस्य नहीं है, इसलिए इसे इनलाइन कमिट करना भी उतना ही ठीक है; env चर एक सुविधा-संबंधी विकल्प है, सुरक्षा-संबंधी नहीं।)
एजेंट स्किल
किसी कोडिंग एजेंट की मदद से Blume साइट बना रहे हैं? Blume एजेंट स्किल इंस्टॉल करें ताकि उसे पता हो कि Blume कैसे काम करता है, बिना आपके समझाए:
npx skills add haydenbleasel/blume
स्किल एजेंट को सिखाती है कि Blume क्या है और किसी साइट को कैसे स्कैफ़ोल्ड, लिखा और कॉन्फ़िगर किया जाए, और उसे इंस्टॉल किए गए पैकेज में बंडल किए गए पूरे डॉक्स की ओर इंगित करती है (blume के भीतर की docs/ डायरेक्टरी, जहाँ भी आपका पैकेज मैनेजर उसे इंस्टॉल करता है)।
यह Blume द्वारा भेजी जाने वाली एजेंट स्किल्स में से एक है, साथ ही एक अनुसूचित एजेंट रन से आपके उत्पाद के साथ डॉक्स को समन्वित रखने वाली स्किल भी है।