diff --git a/Gemfile b/Gemfile
index 56e0f1b4..0e904547 100644
--- a/Gemfile
+++ b/Gemfile
@@ -2,5 +2,5 @@
source 'https://rubygems.org'
-gem 'html2rss', git: 'https://github.com/html2rss/html2rss.git'
+gem 'html2rss', '~> 0.26'
gem 'html2rss-configs', git: 'https://github.com/html2rss/html2rss-configs.git'
diff --git a/Gemfile.lock b/Gemfile.lock
index e89e020a..4b93f2f9 100644
--- a/Gemfile.lock
+++ b/Gemfile.lock
@@ -1,36 +1,10 @@
GIT
remote: https://github.com/html2rss/html2rss-configs.git
- revision: d9e3dc55b38514eb9cd4a17cb0285d9ef73bc9d5
+ revision: ebda084dfdb87627091f0336208553204d073c7b
specs:
html2rss-configs (0.2.0)
html2rss
-GIT
- remote: https://github.com/html2rss/html2rss.git
- revision: aa974733c6e88a5c934f445516d9752dfa316067
- specs:
- html2rss (0.25.0)
- addressable (~> 2.7)
- brotli
- dry-validation
- faraday (> 2.0.1, < 3.0)
- faraday-follow_redirects
- faraday-gzip (~> 3)
- kramdown
- mcp (~> 1.0)
- mime-types (> 3.0)
- nokogiri (>= 1.10, < 2.0)
- rack (~> 3.0)
- rackup (~> 2.0)
- regexp_parser
- reverse_markdown (~> 3.0)
- rss
- sanitize
- thor
- tzinfo
- webrick (~> 1.9)
- zeitwerk
-
GEM
remote: https://rubygems.org/
specs:
@@ -87,6 +61,27 @@ GEM
faraday-net_http (3.4.4)
net-http (~> 0.5)
hana (1.3.7)
+ html2rss (0.26.0)
+ addressable (~> 2.7)
+ brotli
+ dry-validation
+ faraday (> 2.0.1, < 3.0)
+ faraday-follow_redirects
+ faraday-gzip (~> 3)
+ kramdown
+ mcp (~> 1.0)
+ mime-types (> 3.0)
+ nokogiri (>= 1.10, < 2.0)
+ rack (~> 3.0)
+ rackup (~> 2.0)
+ regexp_parser
+ reverse_markdown (~> 3.0)
+ rss
+ sanitize
+ thor
+ tzinfo
+ webrick (~> 1.9)
+ zeitwerk
json (2.21.2)
json_schemer (2.5.0)
bigdecimal
@@ -138,7 +133,7 @@ PLATFORMS
x86_64-linux
DEPENDENCIES
- html2rss!
+ html2rss (~> 0.26)
html2rss-configs!
BUNDLED WITH
diff --git a/astro.config.mjs b/astro.config.mjs
index 10284381..81b8a06d 100644
--- a/astro.config.mjs
+++ b/astro.config.mjs
@@ -14,7 +14,7 @@ export default defineConfig({
"/components/html2rss-configs": "/creating-custom-feeds/",
"/components": "/",
"/web-application/how-to/deployment": "/web-application/deployment/",
- "/web-application/how-to/automatic-updates": "/web-application/deployment/#auto-update-with-watchtower",
+ "/web-application/how-to/automatic-updates": "/web-application/deployment/",
"/web-application/how-to/use-automatic-feed-generation":
"/web-application/guides/use-the-feed-directory/",
"/web-application/how-to": "/web-application/guides/",
diff --git a/src/components/docs/DockerComposeSnippet.astro b/src/components/docs/DockerComposeSnippet.astro
index ee161f5c..f8b58ebd 100644
--- a/src/components/docs/DockerComposeSnippet.astro
+++ b/src/components/docs/DockerComposeSnippet.astro
@@ -1,9 +1,9 @@
---
import { Code } from "@astrojs/starlight/components";
-import { botasaurusImage, caddyImage, watchtowerImage, webImage } from "../../data/docker";
+import { botasaurusImage, caddyImage, webImage } from "../../data/docker";
interface Props {
- variant: "minimal" | "productionCaddy" | "secure" | "watchtower" | "resourceGuardrails";
+ variant: "minimal" | "productionCaddy" | "secure" | "resourceGuardrails";
}
const { variant } = Astro.props;
@@ -78,15 +78,6 @@ volumes:
botasaurus:
image: ${botasaurusImage}
restart: unless-stopped`,
- watchtower: `services:
- watchtower:
- image: ${watchtowerImage}
- restart: unless-stopped
- volumes:
- - /var/run/docker.sock:/var/run/docker.sock:ro
- # Optional for private registries only:
- # - "\${HOME}/.docker/config.json:/config.json:ro"
- command: --cleanup --interval 7200 html2rss-web botasaurus caddy`,
resourceGuardrails: `services:
html2rss-web:
image: ${webImage}
diff --git a/src/content/docs/creating-custom-feeds.mdx b/src/content/docs/creating-custom-feeds.mdx
index 22422ece..f2dd76d2 100644
--- a/src/content/docs/creating-custom-feeds.mdx
+++ b/src/content/docs/creating-custom-feeds.mdx
@@ -31,11 +31,12 @@ When existing feeds or auto-sourcing are not enough, write a YAML config for the
## Recommended Workflow
1. **Inspect the live page** in your browser developer tools
-2. **Write the smallest useful config** that extracts items, titles, and links
-3. **Validate the config** with `html2rss validate your-config.yml`
-4. **Render the feed** with `html2rss feed your-config.yml`
-5. **Add it to `html2rss-web`** so you can use it through your normal instance
-6. **Escalate request strategy when needed**: use a browser-based rendering strategy only when troubleshooting requires it
+2. **Optionally draft with capture** — `html2rss capture https://example.com/articles > your-config.yml` (see [Capturing Feed Configs](/ruby-gem/guides/capturing-feed-configs/))
+3. **Write or refine the smallest useful config** that extracts items, titles, and links
+4. **Validate the config** with `html2rss validate your-config.yml`
+5. **Render the feed** with `html2rss feed your-config.yml`
+6. **Add it to `html2rss-web`** so you can use it through your normal instance
+7. **Escalate request strategy when needed**: use Botasaurus (`strategy: botasaurus` or `auto` with `BOTASAURUS_SCRAPER_URL`) only when troubleshooting requires browser rendering
This order keeps iteration fast and makes it easier to see whether the problem is the page structure, your
selectors, or the fetch strategy.
@@ -188,8 +189,34 @@ there.
**Help the community by sharing your config:**
1. Go to [html2rss-configs on GitHub](https://github.com/html2rss/html2rss-configs)
-2. Click "Fork" → "Add file" → Create `domain.com.yml`
-3. Paste your config → "Commit new file" → "Open pull request"
+2. Click "Fork" → "Add file" → Create `domain.com/name.yml` under `lib/html2rss/configs/`
+3. Include top-level `directory.topics` (required for Feed Directory configs) using the controlled vocabulary below
+4. Paste your config → "Commit new file" → "Open pull request"
+
+Example catalog metadata:
+
+
+
+Allowed `directory.topics` values (prefer 1–2 primary topics): `sports`, `energy`, `tech`, `science`, `news`, `entertainment`, `jobs`, `finance`, `security`, `travel`, `environment`, `consumer`, `civic`, `product`, `research`.
**Need help?** See our [contribution guide](/get-involved/contributing/) for detailed instructions.
diff --git a/src/content/docs/feed-directory/index.mdx b/src/content/docs/feed-directory/index.mdx
index 1efdcb18..ffbe6045 100644
--- a/src/content/docs/feed-directory/index.mdx
+++ b/src/content/docs/feed-directory/index.mdx
@@ -14,7 +14,7 @@ import FeedDirectory from "../../../components/FeedDirectory.astro";
---
-Need the main onboarding path first? Start with [Getting Started](/web-application/getting-started/) and create a feed from your own page URL. The directory below is the packaged fallback/catalog path for fast demos, known sample sources, or cases where the catalog already covers your site.
+Need the main onboarding path first? Start with [Getting Started](/web-application/getting-started/) and create a feed from your own page URL. The directory below is the packaged fallback path for fast demos, known sample sources, or cases where a curated config already covers your site. Use the topic and language filters to narrow the list; export OPML when you want to subscribe to several feeds at once.
Need a different instance? You can use the built-in default, self-host your own, or find more options on the [community-run wiki](https://github.com/html2rss/html2rss-web/wiki/Instances).
diff --git a/src/content/docs/get-involved/contributing.mdx b/src/content/docs/get-involved/contributing.mdx
index 1dbeca90..b764dbf2 100644
--- a/src/content/docs/get-involved/contributing.mdx
+++ b/src/content/docs/get-involved/contributing.mdx
@@ -26,10 +26,12 @@ Are you missing an RSS feed for a website? You can create your own feed config a
**The easiest way to contribute:**
1. Go to [html2rss-configs on GitHub](https://github.com/html2rss/html2rss-configs)
-2. Click "Fork" → "Add file" → Create `domain.com.yml`
-3. Paste your config → "Commit new file" → "Open pull request"
+2. Click "Fork" → "Add file" → Create `domain.com/name.yml` under `lib/html2rss/configs/`
+3. Include top-level `directory.topics` (non-empty) from the controlled vocabulary (`tech`, `news`, `security`, `research`, … — see [Creating Custom Feeds](/creating-custom-feeds/#sharing-your-config))
+4. Prefer setting `channel.language` when the page language is clear
+5. Paste your config → "Commit new file" → "Open pull request"
-**Need help writing configs?** See our [Creating Custom Feeds](/creating-custom-feeds/) guide.
+**Need help writing configs?** Start from [Capturing Feed Configs](/ruby-gem/guides/capturing-feed-configs/) or the [Creating Custom Feeds](/creating-custom-feeds/) guide.
**Want to test your config first?** Use the [Ruby gem](/ruby-gem/installation/) to test it locally:
diff --git a/src/content/docs/ruby-gem/guides/ai-agent-workflows.mdx b/src/content/docs/ruby-gem/guides/ai-agent-workflows.mdx
new file mode 100644
index 00000000..df090b5b
--- /dev/null
+++ b/src/content/docs/ruby-gem/guides/ai-agent-workflows.mdx
@@ -0,0 +1,103 @@
+---
+title: AI Agent Workflows with MCP
+description: Guide to integrating html2rss with AI agents, Claude Desktop, and Cursor using the Model Context Protocol (MCP).
+---
+
+import { Code } from "@astrojs/starlight/components";
+
+`html2rss` includes a native [Model Context Protocol (MCP)](https://modelcontextprotocol.io/) server. This allows AI assistants in tools like Cursor, Claude Desktop, and GitHub Copilot to scrape pages, capture feed configurations, and generate RSS feeds autonomously.
+
+## Why Use MCP?
+
+Without MCP, agents must invoke shell commands, manage output buffers, and parse unstructured text. With MCP:
+
+- The agent automatically discovers available tools, arguments, and return types.
+- Responses are structured (JSON Feed objects, configuration schemas, and RSS XML).
+- Agents can inspect, capture, validate, and verify feeds iteratively in a closed feedback loop.
+
+## Client Setup
+
+### 1. Version Manager Shims (mise, asdf, rbenv, chruby)
+
+Because version managers manage Ruby runtimes and gem paths through environment shims, configure your MCP client to invoke the version manager executable rather than a bare `html2rss` command.
+
+
+
+### 2. Cursor Configuration
+
+Add `html2rss` to your Cursor MCP settings (`~/.cursor/mcp.json` or `.cursor/mcp.json`):
+
+
+
+_(If using `asdf`, replace `"command": "mise"` with `"asdf"` and `"args": ["exec", "html2rss", "mcp"]`.)_
+
+### 3. Claude Desktop Configuration
+
+Add `html2rss` to your Claude Desktop configuration (`~/Library/Application Support/Claude/claude_desktop_config.json` on macOS or `%APPDATA%\\Claude\\claude_desktop_config.json` on Windows):
+
+
+
+## Autonomous Workflow Patterns
+
+### Pattern A: One-Shot Content Scraping
+
+When an agent needs articles immediately without saving a feed configuration:
+
+1. The agent calls `scrape_url` with the target URL.
+2. `html2rss` runs auto-source extraction (Schema.org, JSON state, semantic HTML) and returns a JSON Feed items array.
+3. If the page is protected or rendered with JavaScript, the agent calls `inspect_url` to diagnose the structure, then retries `scrape_url` with `strategy: "botasaurus"`.
+
+### Pattern B: Iterative Feed Config Authoring
+
+When an agent is tasked with creating a durable YAML feed configuration:
+
+1. **Inspect:** The agent calls `inspect_url` to check content type, SST node counts, and eligible scrapers.
+2. **Capture:** The agent runs `capture_config` to derive CSS selectors for items, title, link, and description.
+3. **Refine:** The agent reviews the derived selectors or asks the human user for domain-specific adjustments.
+4. **Validate:** The agent passes the configuration to `validate_config` to verify schema conformance.
+5. **Apply:** The agent tests the final configuration with `apply_config` to produce and inspect live RSS XML.
+
+## JavaScript-Rendered Sites (Botasaurus)
+
+For dynamic JavaScript single-page applications or sites protected by anti-bot measures, launch the Botasaurus scrape service:
+
+
+
+Ensure `BOTASAURUS_SCRAPER_URL` is accessible (typically `http://127.0.0.1:4010`) in the environment where the MCP server runs. Agents can then pass `strategy: "botasaurus"` to `scrape_url`, `inspect_url`, and `capture_config`.
diff --git a/src/content/docs/ruby-gem/guides/backward-compatibility.mdx b/src/content/docs/ruby-gem/guides/backward-compatibility.mdx
index 9357cf48..39ebd2b4 100644
--- a/src/content/docs/ruby-gem/guides/backward-compatibility.mdx
+++ b/src/content/docs/ruby-gem/guides/backward-compatibility.mdx
@@ -7,6 +7,13 @@ import { Code } from "@astrojs/starlight/components";
This page outlines recent breaking changes, purged legacy aliases, and migration steps for older feed configurations.
+## 0.26.0
+
+Upgrade notes for configs and integrators targeting gem **0.26.0**:
+
+1. **Browserless strategy removal** — The `browserless` strategy, `puppeteer-ruby` dependency, interaction budgets, and `request.browserless.*` options have been completely removed.
+2. **Botasaurus as browser transport** — Browser-based scraping and anti-bot bypassing now run through `botasaurus` (`BOTASAURUS_SCRAPER_URL`). Use `strategy: auto` (which tries `faraday` -> `botasaurus`) or pin `strategy: botasaurus` directly.
+
## 0.25.0
Upgrade notes for configs and integrators targeting gem **0.25.0**:
@@ -67,11 +74,11 @@ Update any occurrences of `link`, `pubDate`, or `updated` in your `selectors` bl
# Deprecated / Removed
channel:
url: "https://example.com/articles"
- strategy: browserless
+ strategy: botasaurus
headers:
User-Agent: "CustomAgent/1.0"
# Current & Required
- strategy: browserless
+ strategy: botasaurus
headers:
User-Agent: "CustomAgent/1.0"
channel:
@@ -84,10 +91,10 @@ Update any occurrences of `link`, `pubDate`, or `updated` in your `selectors` bl
When upgrading to modern `html2rss` releases:
-1. **Rename URL selectors**: Ensure article URL selectors use `url` rather than `link`.
-2. **Rename date selectors**: Ensure date selectors use `published_at` rather than `updated` or `pubDate`.
-3. **Move channel-level transport keys**: Ensure `strategy` and `headers` are defined at the top level of the YAML file.
-4. **Pin Browserless when needed**: If you relied on `auto` falling through to Browserless, set `strategy: browserless` (or `--strategy browserless`).
+1. **Migrate Browserless to Botasaurus**: Update any feeds using `strategy: browserless` or `request.browserless` to `strategy: botasaurus` or `strategy: auto` with `BOTASAURUS_SCRAPER_URL`.
+2. **Rename URL selectors**: Ensure article URL selectors use `url` rather than `link`.
+3. **Rename date selectors**: Ensure date selectors use `published_at` rather than `updated` or `pubDate`.
+4. **Move channel-level transport keys**: Ensure `strategy` and `headers` are defined at the top level of the YAML file.
5. **Use `enclosure` for RSS media**: Do not rely on `image` becoming an RSS ``; select podcast/media URLs with `enclosure`.
6. **Prefer `feed_result` for dual-format / cache**: Integrators that need RSS + JSON Feed from one scrape (or Marshal caching) should use `Html2rss.feed_result` and `status.to_h`.
7. **Validate configurations**: Run `html2rss validate config.yml` to ensure your YAML conforms to the current schema.
diff --git a/src/content/docs/ruby-gem/guides/capturing-feed-configs.mdx b/src/content/docs/ruby-gem/guides/capturing-feed-configs.mdx
new file mode 100644
index 00000000..9b8bb7ce
--- /dev/null
+++ b/src/content/docs/ruby-gem/guides/capturing-feed-configs.mdx
@@ -0,0 +1,116 @@
+---
+title: Capturing Feed Configs
+description: Derive a reusable YAML feed config from a URL with html2rss capture, then validate and refine selectors.
+---
+
+import { Aside, Code } from "@astrojs/starlight/components";
+
+`html2rss capture` analyzes a page through the auto-source pipeline and prints a reusable feed config with derived CSS selectors. Use it when you want a first draft faster than hand-writing selectors from scratch.
+
+
+
+## When to Capture
+
+Use capture when:
+
+- you are writing a new custom feed and want a starting YAML
+- auto-source finds articles, but you want durable selectors for review
+- an AI agent or MCP client should produce a config before `validate` / `apply`
+
+Prefer [automatic feed generation](/web-application/guides/use-automatic-feed-generation/) when you only need items now and do not need a saved config.
+
+## CLI
+
+Print YAML to stdout:
+
+ my-feed.yml
+`}
+ lang="bash"
+/>
+
+Common options:
+
+- `--strategy` — `auto`, `faraday`, `botasaurus`, or `local_file` (default `auto`)
+- `--items_selector` — CSS selector hint for item cards
+- `--limit` — maximum articles kept while deriving selectors
+- `--max-redirects` / `--max-requests` — request budget overrides
+- `--input` — local HTML file (sets `local_file` strategy)
+
+See the [CLI reference](/ruby-gem/reference/cli-reference/#capture) for the full flag list.
+
+## Ruby API
+
+
+
+## How It Works
+
+1. **Request** — fetches the page with the chosen strategy
+2. **Discover** — runs AutoSource to extract articles
+3. **Analyze** — normalizes the page into an SST document and maps segment positions back to articles
+4. **Derive** — builds CSS selectors from SST tag paths for items, title, link, and description
+5. **Assemble** — returns a config hash ready for YAML or `Html2rss.feed`
+
+Capture segment discovery currently uses the list Segmenter strategy only (not AutoSource cluster/semantic heuristics). When the draft is weak, pass `--items_selector` or refine selectors by hand.
+
+## What Capture Derives
+
+Capture focuses on:
+
+- `channel.url` (and related channel defaults)
+- `selectors.items`
+- `selectors.title`
+- `selectors.url` (derived href selector)
+- `selectors.description` when a distinct description root exists
+
+It does not invent author, `published_at`, categories, or enclosure selectors. Add those manually when the page exposes them reliably.
+
+Description is omitted when it would resolve to the invalid CSS selector `.` (item root equals description root).
+
+## Recommended Follow-Up
+
+1. Validate: `html2rss validate my-feed.yml`
+2. Render: `html2rss feed my-feed.yml`
+3. Tighten selectors, strategy, or `request.botasaurus` options if needed
+4. For Feed Directory contributions, add `directory.topics` (see [Creating Custom Feeds](/creating-custom-feeds/#sharing-your-config))
+
+## Related
+
+- [CLI reference — Capture](/ruby-gem/reference/cli-reference/#capture)
+- [AI agent workflows (MCP `capture_config`)](/ruby-gem/guides/ai-agent-workflows/)
+- [Creating custom feeds](/creating-custom-feeds/)
+- [Auto Source](/ruby-gem/reference/auto-source/)
diff --git a/src/content/docs/ruby-gem/guides/custom-http-requests.mdx b/src/content/docs/ruby-gem/guides/custom-http-requests.mdx
index 3c385a00..e9302d8b 100644
--- a/src/content/docs/ruby-gem/guides/custom-http-requests.mdx
+++ b/src/content/docs/ruby-gem/guides/custom-http-requests.mdx
@@ -73,8 +73,7 @@ Request budgets are configured under `request`, not as top-level keys:
- `request.max_redirects` limits redirect hops
- `request.max_requests` limits the total request budget for the feed build
-- `request.browserless.*` is reserved for Browserless-only behavior such as preload actions
-- `request.botasaurus.*` is reserved for Botasaurus-only behavior such as navigation mode and retries
+- `request.botasaurus.*` is reserved for Botasaurus-only behavior such as navigation mode, retries, header/cookie forwarding, and scroll options
## Common Use Cases
diff --git a/src/content/docs/ruby-gem/guides/handling-dynamic-content.mdx b/src/content/docs/ruby-gem/guides/handling-dynamic-content.mdx
index fbe522f4..dd206831 100644
--- a/src/content/docs/ruby-gem/guides/handling-dynamic-content.mdx
+++ b/src/content/docs/ruby-gem/guides/handling-dynamic-content.mdx
@@ -1,6 +1,6 @@
---
title: Handling Dynamic Content
-description: "Learn how to handle JavaScript-heavy websites and dynamic content with html2rss using browser-based extraction strategies."
+description: "Learn how to handle JavaScript-heavy websites and dynamic content with html2rss using Botasaurus browser-based extraction strategies."
---
import { Code } from "@astrojs/starlight/components";
@@ -9,26 +9,25 @@ Some websites load their content dynamically using JavaScript. Static fetch path
## Solution
-Default `strategy: auto` already tries `faraday` then `botasaurus` (when `BOTASAURUS_SCRAPER_URL` is configured). That covers many JS-rendered listing pages without pinning a strategy.
+Default `strategy: auto` automatically tries `faraday` first, then falls back to `botasaurus` when `BOTASAURUS_SCRAPER_URL` is configured. This handles many JS-rendered listing pages without needing custom configuration.
-Pin [`browserless`](/ruby-gem/reference/strategy/#browserless) when you need headless Chrome with preload (wait, click, scroll) or other Browserless-only controls — Browserless is not part of the `auto` chain.
-
-Keep the strategy at the top level and put request-specific options under `request`:
+When a site requires browser rendering or anti-bot bypass by default, you can explicitly set `strategy: botasaurus` and configure request controls under `request.botasaurus`:
-## When to Use Browser-Based Extraction
+## When to Use Botasaurus Extraction
-A browser-based extraction strategy is necessary when:
+Botasaurus extraction is ideal when:
-- **Content loads after page load** - JavaScript fetches data from APIs
+- **Content loads after page load** - JavaScript fetches data dynamically
- **Single Page Applications (SPAs)** - React, Vue, Angular apps
-- **Infinite scroll** - Content loads as you scroll
-- **Dynamic forms** - Content changes based on user interaction
+- **Anti-bot interstitials** - Cloudflare, Google search referrers, or challenge pages
+- **Scroll-triggered content** - Infinite scroll lists (`scroll_to_bottom: true`)
-## Preload Actions
+## Botasaurus Request Controls
-For dynamic sites, rendering once is often not enough. Use `request.browserless.preload` to wait, click, or scroll before the
-HTML snapshot is taken.
+Configure browser actions under `request.botasaurus`:
-### Wait Before Capturing Dynamic Content
+### Wait for Elements
-### Click "Load More" Buttons
+### Scroll for Infinite Content
-### Scroll Infinite Lists
+### Anti-Bot Bypass Navigation Modes
-These preload steps can be combined in a single config when a site needs several interactions before all items appear.
+### JSON Loaded Over XHR
+
+When Botasaurus uses the browser tier, captured JSON XHR/fetch bodies feed AutoSource `xhr_articles` automatically (enabled by default). Prefer `strategy: botasaurus` (or `auto` with `BOTASAURUS_SCRAPER_URL`) for SPA listing pages that hydrate article lists over the network rather than embedding them in HTML. See [Auto Source](/ruby-gem/reference/auto-source/) and [Strategy](/ruby-gem/reference/strategy/#botasaurus).
## Performance Considerations
-Browser-based extraction is slower than default static HTTP fetching because it:
+Browser-based extraction uses more resources than static HTTP fetching because it:
-- Launches a headless Chrome browser
-- Renders the full page with JavaScript
-- Takes more memory and CPU resources
+- Renders pages in an automated Chrome instance
+- Executes JavaScript and handles DOM events
+- Manages browser pools and network emulation
-**Use static HTTP fetching for static content** and switch to browser-based extraction when needed. See the [Strategy Reference](/ruby-gem/reference/strategy/) for concrete transports, defaults, and environment requirements.
+Use static HTTP fetching (`faraday`) for static content, and lean on `auto` or explicit `botasaurus` strategies when browser rendering is required. See the [Strategy Reference](/ruby-gem/reference/strategy/) for details.
## Related Topics
- **[Strategy Reference](/ruby-gem/reference/strategy/)** - Complete strategy documentation
- **[Troubleshooting](/troubleshooting/troubleshooting/)** - Common issues with dynamic content
-- **[Advanced Features](/ruby-gem/guides/advanced-features/)** - Performance optimization tips
diff --git a/src/content/docs/ruby-gem/index.mdx b/src/content/docs/ruby-gem/index.mdx
index 4fe10115..91ce54fb 100644
--- a/src/content/docs/ruby-gem/index.mdx
+++ b/src/content/docs/ruby-gem/index.mdx
@@ -23,5 +23,5 @@ If you are getting started with `html2rss`, we recommend starting with the [**fi
## Documentation Sections
- **[Tutorials](/ruby-gem/tutorials/your-first-feed/)**: Step-by-step guides to help you get started with `html2rss`.
-- **[Guides](/ruby-gem/guides/)**: Practical examples and solutions for common tasks.
-- **[Reference](/ruby-gem/reference/)**: Detailed information on configuration options.
+- **[Guides](/ruby-gem/guides/)**: Practical examples and solutions for common tasks, including [capturing feed configs](/ruby-gem/guides/capturing-feed-configs/) and [AI agent workflows](/ruby-gem/guides/ai-agent-workflows/).
+- **[Reference](/ruby-gem/reference/)**: Detailed information on configuration options, CLI commands, and the [MCP server](/ruby-gem/reference/mcp-server/).
diff --git a/src/content/docs/ruby-gem/reference/auto-source.mdx b/src/content/docs/ruby-gem/reference/auto-source.mdx
index 605804a3..ce9c9bc6 100644
--- a/src/content/docs/ruby-gem/reference/auto-source.mdx
+++ b/src/content/docs/ruby-gem/reference/auto-source.mdx
@@ -28,18 +28,20 @@ To enable it, add `auto_source: {}` to your configuration:
4. **`schema`:** Parses `