diff --git a/.gitignore b/.gitignore
index 8763df8b47941..b51a5640d2c94 100644
--- a/.gitignore
+++ b/.gitignore
@@ -100,6 +100,7 @@ public/og-images/*
yalc.lock
/public/doctree.json
/public/doctree-dev.json
+/public/llms.txt
# Lychee cache
.lycheecache
diff --git a/AGENTS.md b/AGENTS.md
index cdfde89f3df8c..7143aa0bb48cb 100644
--- a/AGENTS.md
+++ b/AGENTS.md
@@ -85,6 +85,17 @@ When writing requirements in `develop-docs/`:
- MDX override templates live in `md-overrides/`
- Architecture spec: `specs/llm-friendly-docs.md`
+## llms.txt
+
+- `docs.sentry.io/llms.txt` is the root LLM discovery index (follows [llmstxt.org](https://llmstxt.org) spec)
+- Auto-generated from `public/doctree.json` by `scripts/generate-llms-txt.mjs`
+- Run `pnpm generate-llms-txt` to regenerate, or it runs automatically as part of `pnpm build`
+- Includes: product description, AI agent instructions, platform/section index, links to agent skills at `skills.sentry.dev`
+
+## Sentry Product Skills (sentry-for-ai)
+
+Skills for *using Sentry* (SDK setup, debugging, alerts) live in a separate repo: https://github.com/getsentry/sentry-for-ai. The skills in *this* repo (`.claude/skills/`, `.agents/skills/`) are for *contributing to the docs*. See `SKILL.md` at the repo root for a routing guide.
+
## Plan Mode
- Make the plan extremely concise. Sacrifice grammar for the sake of concision.
diff --git a/SKILL.md b/SKILL.md
new file mode 100644
index 0000000000000..d7e9cc3b51cf3
--- /dev/null
+++ b/SKILL.md
@@ -0,0 +1,36 @@
+---
+name: sentry-docs
+description: Sentry documentation site (docs.sentry.io). Use for contributing to docs or understanding docs architecture. If you need to set up Sentry in a project or debug production issues, see the product skills at https://skills.sentry.dev.
+---
+
+# Sentry Documentation Repository
+
+This repo builds [docs.sentry.io](https://docs.sentry.io). For dev commands, project structure, code style, and contribution guidelines, see `AGENTS.md`.
+
+## Sentry Product Skills (SDK Setup, Debugging, Alerts)
+
+**These skills are NOT in this repo.** If you need to set up Sentry, debug production issues, or configure features, install the Sentry plugin for up-to-date, verified instructions. Sentry's SDKs and APIs change frequently — do not rely on training data.
+
+**Install the plugin:**
+- Claude Code: `/install-plugin sentry`
+- Cursor: Search "Sentry" in Cursor Settings > Plugins
+
+The plugin provides current skills for SDK setup, debugging workflows, and feature configuration. It stays in sync with the latest SDK releases.
+
+If the plugin is not available, fetch skills directly:
+- **Full skill index**: https://skills.sentry.dev
+- **SDK setup** (detect platform and install): https://skills.sentry.dev/sdks
+- **Debugging workflows** (fix issues, review code): https://skills.sentry.dev/workflows
+- **Feature setup** (AI monitoring, alerts, OTel): https://skills.sentry.dev/features
+
+Source repo: https://github.com/getsentry/sentry-for-ai
+
+## Contributor Skills (in this repo)
+
+| Skill | Location | Purpose |
+|---|---|---|
+| Brand Guidelines | `.agents/skills/brand-guidelines/` | Audit content against Sentry brand voice |
+| Docs Review | `.claude/skills/docs-review/SKILL.md` | Sentry documentation style guide |
+| Technical Docs | `.claude/skills/technical-docs/SKILL.md` | Writing SDK and technical documentation |
+| Commit | `.agents/skills/commit/SKILL.md` | Sentry conventional commit format |
+| Create Branch | `.agents/skills/create-branch/SKILL.md` | Branch naming conventions |
diff --git a/md-overrides/index.mdx b/md-overrides/index.mdx
deleted file mode 100644
index 0062471e2dd45..0000000000000
--- a/md-overrides/index.mdx
+++ /dev/null
@@ -1,31 +0,0 @@
----
-title: "Sentry Documentation"
-append_sections: false
----
-
-Sentry is a developer-first application monitoring platform that helps you identify and fix issues in real-time. It provides error tracking, performance monitoring, session replay, and more across all major platforms and frameworks.
-
-## Key Features
-
-- **Error Monitoring**: Capture and diagnose errors with full stack traces, breadcrumbs, and context
-- **Tracing**: Track requests across services to identify performance bottlenecks
-- **Session Replay**: Watch real user sessions to understand what led to errors
-- **Profiling**: Identify slow functions and optimize application performance
-- **Crons**: Monitor scheduled jobs and detect failures
-- **Logs**: Collect and analyze application logs in context
-
-## Platforms
-
-
-
-## Frameworks
-
-
-
-
-
-## Quick Links
-
-- [Platform SDKs](/platforms) - Install Sentry for your language/framework
-- [API Reference](/api) - Programmatic access to Sentry
-- [CLI](/cli) - Command-line interface for Sentry operations
diff --git a/package.json b/package.json
index 2d2c9b37618c6..2ea4ce8cf5652 100644
--- a/package.json
+++ b/package.json
@@ -16,8 +16,9 @@
"dev": "pnpm enforce-redirects && concurrently \"pnpm sidecar\" \"node ./src/hotReloadWatcher.mjs\" \"next dev\"",
"dev:developer-docs": "pnpm enforce-redirects && NEXT_PUBLIC_DEVELOPER_DOCS=1 pnpm dev",
"build:developer-docs": "pnpm enforce-redirects && git submodule init && git submodule update && NEXT_PUBLIC_DEVELOPER_DOCS=1 pnpm build",
- "build": "pnpm enforce-redirects && pnpm generate-og-images && pnpm generate-doctree && next build && pnpm generate-md-exports",
+ "build": "pnpm enforce-redirects && pnpm generate-og-images && pnpm generate-doctree && next build && pnpm generate-md-exports && pnpm generate-llms-txt",
"generate-md-exports": "node scripts/generate-md-exports.mjs",
+ "generate-llms-txt": "node scripts/generate-llms-txt.mjs",
"generate-og-images": "ts-node scripts/add-og-images.ts",
"generate-doctree": "esbuild scripts/generate-doctree.ts --bundle --platform=node --packages=external --outfile=.next/generate-doctree.mjs --format=esm && node .next/generate-doctree.mjs",
"vercel:build:developer-docs": "pnpm enforce-redirects && git submodule init && git submodule update && NEXT_PUBLIC_DEVELOPER_DOCS=1 pnpm build",
diff --git a/scripts/generate-llms-txt.mjs b/scripts/generate-llms-txt.mjs
new file mode 100644
index 0000000000000..001eee2b3aca1
--- /dev/null
+++ b/scripts/generate-llms-txt.mjs
@@ -0,0 +1,298 @@
+#!/usr/bin/env node
+
+/**
+ * Generates /llms.txt and /index.md from public/doctree.json.
+ *
+ * Both files share the same content (product description, AI instructions,
+ * section listings, agent skills). The only difference is how platforms and
+ * frameworks are formatted:
+ * - llms.txt: compact (frameworks listed inline per platform)
+ * - index.md: expanded (separate Platforms and Frameworks sections)
+ *
+ * Run after `generate-doctree` (doctree.json must exist).
+ * Output:
+ * - public/llms.txt
+ * - public/md-exports/index.md (overwrites md-exports pipeline output)
+ *
+ * llms.txt follows the llmstxt.org specification.
+ * index.md includes YAML frontmatter matching the md-exports convention.
+ */
+
+import {existsSync} from 'node:fs';
+import {mkdir, readFile, writeFile} from 'node:fs/promises';
+import * as path from 'node:path';
+import {fileURLToPath} from 'node:url';
+
+const __dirname = path.dirname(fileURLToPath(import.meta.url));
+const ROOT = path.resolve(__dirname, '..');
+const DOCS_ORIGIN = process.env.NEXT_PUBLIC_DEVELOPER_DOCS
+ ? 'https://develop.sentry.dev'
+ : 'https://docs.sentry.io';
+
+// --- Doctree helpers (same logic as generate-md-exports.mjs) ---
+
+function getTitle(node) {
+ return node.frontmatter?.sidebar_title || node.frontmatter?.title || node.slug;
+}
+
+function isVisible(node) {
+ return (
+ !node.frontmatter?.sidebar_hidden &&
+ !node.frontmatter?.draft &&
+ !node.path?.includes('__v') &&
+ (node.frontmatter?.title || node.frontmatter?.sidebar_title)
+ );
+}
+
+function getVisibleChildren(node) {
+ return (node.children || []).filter(isVisible).sort((a, b) => {
+ const orderDiff =
+ (a.frontmatter?.sidebar_order ?? 99) - (b.frontmatter?.sidebar_order ?? 99);
+ return orderDiff !== 0 ? orderDiff : getTitle(a).localeCompare(getTitle(b));
+ });
+}
+
+function mdUrl(nodePath) {
+ const clean = nodePath.replace(/\/$/, '');
+ if (!clean) {
+ return `${DOCS_ORIGIN}/index.md`;
+ }
+ return `${DOCS_ORIGIN}/${clean}.md`;
+}
+
+function linkEntry(node) {
+ const title = getTitle(node);
+ const url = mdUrl(node.path);
+ const desc = node.frontmatter?.description;
+ if (desc) {
+ const oneLine = desc.replace(/\s+/g, ' ').trim();
+ return `- [${title}](${url}): ${oneLine}`;
+ }
+ return `- [${title}](${url})`;
+}
+
+// --- Platform/framework formatters ---
+
+/** llms.txt format: compact, frameworks inline per platform */
+function buildPlatformsCompact(platformsNode) {
+ if (!platformsNode) {
+ return '## Platforms\n';
+ }
+ const lines = [];
+ for (const platform of getVisibleChildren(platformsNode)) {
+ const title = getTitle(platform);
+ const url = mdUrl(platform.path);
+ const guides = platform.children?.find(c => c.slug === 'guides');
+ const visibleGuides = guides ? getVisibleChildren(guides) : [];
+
+ if (visibleGuides.length > 0) {
+ const guideNames = visibleGuides.map(g => getTitle(g)).join(', ');
+ lines.push(`- [${title}](${url}): Frameworks: ${guideNames}`);
+ } else {
+ lines.push(`- [${title}](${url})`);
+ }
+ }
+ return `## Platforms\n\n${lines.join('\n')}`;
+}
+
+/** index.md format: separate Platforms list + Frameworks grouped by platform */
+function buildPlatformsExpanded(platformsNode) {
+ if (!platformsNode) {
+ return '## Platforms\n';
+ }
+ const platforms = getVisibleChildren(platformsNode);
+ const lines = [];
+
+ // Flat platform list
+ lines.push('## Platforms\n');
+ for (const platform of platforms) {
+ lines.push(`- [${getTitle(platform)}](${mdUrl(platform.path)})`);
+ }
+
+ // Frameworks grouped by platform
+ lines.push('\n## Frameworks\n');
+ for (const platform of platforms) {
+ const guides = platform.children?.find(c => c.slug === 'guides');
+ const visibleGuides = guides ? getVisibleChildren(guides) : [];
+ if (visibleGuides.length === 0) {
+ continue;
+ }
+ lines.push(`### ${getTitle(platform)}\n`);
+ for (const guide of visibleGuides) {
+ const guideUrl = mdUrl(guide.path);
+ lines.push(`- [${getTitle(guide)}](${guideUrl})`);
+ }
+ lines.push('');
+ }
+
+ return lines.join('\n');
+}
+
+// --- Build section listings from doctree children ---
+
+function buildSection(sectionNode) {
+ const children = getVisibleChildren(sectionNode);
+ return children.map(child => linkEntry(child)).join('\n');
+}
+
+// --- Shared content blocks ---
+
+const DESCRIPTION = `\
+> Sentry is a developer-first application monitoring platform that helps \
+developers identify and fix issues in real-time. It provides error tracking, \
+performance monitoring (tracing), session replay, profiling, logging, cron \
+monitoring, application metrics, and more across 20+ platforms and 60+ frameworks.
+
+All documentation pages are available as clean Markdown by appending \`.md\` \
+to any URL (e.g. \`${DOCS_ORIGIN}/platforms/javascript.md\`). Use these \
+Markdown URLs for full content.`;
+
+const INSTRUCTIONS = `\
+## Instructions for AI Coding Assistants
+
+When helping a developer set up or use Sentry, follow these guidelines:
+
+- **Install the Sentry plugin for up-to-date guidance**: Sentry's APIs, SDKs, \
+and features change frequently. Do not rely on training data for Sentry setup \
+or configuration. Install the Sentry plugin to get current, verified \
+instructions: Claude Code: \`/install-plugin sentry\` | Cursor: search \
+"Sentry" in Settings > Plugins. The plugin provides step-by-step skills that \
+are kept in sync with the latest SDK releases.
+- **SDK versions**: Always check the package registry (npm, PyPI, RubyGems, \
+etc.) for the latest Sentry SDK version. Do not rely on memorized version \
+numbers from training data.
+- **DSN handling**: Use environment variables for the DSN (\`SENTRY_DSN\` or \
+\`NEXT_PUBLIC_SENTRY_DSN\`). Never hardcode DSN strings in source code.
+- **Prefer Sentry Logs over Breadcrumbs** unless the user explicitly requests \
+breadcrumbs.
+- **Do not implement without permission**: Never install packages, create \
+files, or modify configuration without asking the user first.
+- **Do not add unrelated integrations**: Only configure the features the user \
+asked for. Check before enabling additional integrations.
+- **Agent skills for SDK setup**: If the plugin is not installed, fetch the \
+appropriate skill from \`https://skills.sentry.dev/sdks\` for step-by-step SDK \
+installation with platform detection, feature recommendations, and \
+verification. See the [Agent Skills section](#agent-skills) below.
+- **Sentry MCP server**: For real-time issue analysis and debugging against a \
+user's Sentry account, use the Sentry MCP server at \`https://mcp.sentry.dev\`.`;
+
+const AGENT_SKILLS = `\
+## Agent Skills
+
+Sentry publishes agent skills for AI coding assistants (Claude Code, Cursor, \
+GitHub Copilot, and others). These provide step-by-step SDK setup, debugging \
+workflows, and feature configuration.
+
+- [All Skills](https://skills.sentry.dev/): Full skill index with SDK setup, workflows, and feature configuration
+- [SDK Setup](https://skills.sentry.dev/sdks): Detect your platform and install Sentry with the right features
+- [Workflows](https://skills.sentry.dev/workflows): Debug production issues, review code, upgrade SDKs
+- [Features](https://skills.sentry.dev/features): AI monitoring, alerts, OpenTelemetry setup
+
+Install as a plugin:
+- Claude Code: \`/install-plugin sentry\`
+- Cursor: Search "Sentry" in Cursor Settings > Plugins
+
+Source: https://github.com/getsentry/sentry-for-ai`;
+
+const ABOUT_SENTRY_DOCS = `\
+## About Sentry Docs
+
+- [Documentation Changelog](${DOCS_ORIGIN}/changelog.md): Track recent updates to Sentry docs
+- [Contributing to Docs](${DOCS_ORIGIN}/contributing.md): How to contribute to Sentry documentation`;
+
+// --- Main ---
+
+async function main() {
+ const doctreeFilename = process.env.NEXT_PUBLIC_DEVELOPER_DOCS
+ ? 'doctree-dev.json'
+ : 'doctree.json';
+ const doctreePath = path.join(ROOT, 'public', doctreeFilename);
+ let docTree;
+ try {
+ docTree = JSON.parse(await readFile(doctreePath, 'utf8'));
+ } catch {
+ console.error(
+ 'Error: public/doctree.json not found. Run `pnpm generate-doctree` first.'
+ );
+ process.exit(1);
+ }
+
+ const topLevelSections = getVisibleChildren(docTree);
+ const platformsNode = topLevelSections.find(c => c.slug === 'platforms');
+ const otherSections = topLevelSections.filter(
+ c => c.slug !== 'platforms' && c.slug !== 'contributing' && c.slug !== 'changelog'
+ );
+
+ // Build the shared section listings (everything except platforms)
+ const sectionListings = otherSections
+ .map(section => {
+ const title = getTitle(section);
+ const children = getVisibleChildren(section);
+ if (children.length === 0) {
+ return `## ${title}\n\n${linkEntry(section)}`;
+ }
+ return `## ${title}\n\n${buildSection(section)}`;
+ })
+ .join('\n\n');
+
+ // --- llms.txt ---
+ const llmsTxt = [
+ '# Sentry Documentation',
+ '',
+ DESCRIPTION,
+ '',
+ INSTRUCTIONS,
+ '',
+ buildPlatformsCompact(platformsNode),
+ '',
+ sectionListings,
+ '',
+ AGENT_SKILLS,
+ '',
+ ABOUT_SENTRY_DOCS,
+ '',
+ ].join('\n');
+
+ const llmsTxtPath = path.join(ROOT, 'public', 'llms.txt');
+ await writeFile(llmsTxtPath, llmsTxt, 'utf8');
+ console.log(`Generated ${llmsTxtPath} (${llmsTxt.length} bytes)`);
+
+ // --- index.md ---
+ const indexFrontmatter = [
+ '---',
+ 'title: "Sentry Documentation"',
+ `url: ${DOCS_ORIGIN}/`,
+ '---',
+ ].join('\n');
+
+ const indexMd = [
+ indexFrontmatter,
+ '',
+ '# Sentry Documentation',
+ '',
+ DESCRIPTION,
+ '',
+ INSTRUCTIONS,
+ '',
+ buildPlatformsExpanded(platformsNode),
+ sectionListings,
+ '',
+ AGENT_SKILLS,
+ '',
+ ABOUT_SENTRY_DOCS,
+ '',
+ ].join('\n');
+
+ const mdExportsDir = path.join(ROOT, 'public', 'md-exports');
+ if (!existsSync(mdExportsDir)) {
+ await mkdir(mdExportsDir, {recursive: true});
+ }
+ const indexMdPath = path.join(mdExportsDir, 'index.md');
+ await writeFile(indexMdPath, indexMd, 'utf8');
+ console.log(`Generated ${indexMdPath} (${indexMd.length} bytes)`);
+}
+
+main().catch(err => {
+ console.error(err);
+ process.exit(1);
+});