Skip to content

Commit 1897194

Browse files
authored
feat: gem v0.26.0 updates (drop browserless, capture, mcp, botasaurus improvements) (#1232)
* feat: drop browserless * docs(adapters): document new botasaurus options and header/cookie forwarding Add execution_mode, organic_get, scroll, scroll_to_bottom, block_trackers, headers, and cookies to the botasaurus options table in strategy reference. Update the custom HTTP requests guide to mention header/cookie forwarding. These options were added in commits 9ca09a0 and a41ab3f of the core repo. * docs(adapters): document capture and mcp in cli and mcp server references * docs(use-cases): add guide for ai agent workflows with mcp * docs(reference): reinforce schema resource links and json error details in mcp docs * docs(use-cases): add capture guide and XHR dynamic-content path Document html2rss capture as a draft-config workflow and note that Botasaurus browser-tier XHR JSON feeds AutoSource xhr_articles. * docs(domain): document xhr_articles auto_source scraper Describe always-on Botasaurus XHR captures as a first-class AutoSource strategy alongside json_state, with enable toggle and limitations. * docs(adapters): require directory.topics for Feed Directory configs Document the controlled topics vocabulary, capture-first authoring workflow, and topic/language filters on the Feed Directory page. * docs(infrastructure): document Botasaurus XHR capture and DataDome Explain xhr_responses forwarding into captured_responses and add DataDome blocked-surface recovery steps in troubleshooting. * style: format capturing-feed-configs guide * docs(ruby-gem): restore 0.24.0 migration notes in backward-compatibility guide * chore: html2rss 0.26.0 * docs(web-application): remove dead Watchtower auto-update guidance * chore: update html2rss-configs * Apply suggestions from code review Co-authored-by: Gil Desmarais <gildesmarais@users.noreply.github.com>
1 parent 708e634 commit 1897194

23 files changed

Lines changed: 1475 additions & 478 deletions

Gemfile

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,5 +2,5 @@
22

33
source 'https://rubygems.org'
44

5-
gem 'html2rss', git: 'https://github.com/html2rss/html2rss.git'
5+
gem 'html2rss', '~> 0.26'
66
gem 'html2rss-configs', git: 'https://github.com/html2rss/html2rss-configs.git'

Gemfile.lock

Lines changed: 23 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -1,36 +1,10 @@
11
GIT
22
remote: https://github.com/html2rss/html2rss-configs.git
3-
revision: d9e3dc55b38514eb9cd4a17cb0285d9ef73bc9d5
3+
revision: ebda084dfdb87627091f0336208553204d073c7b
44
specs:
55
html2rss-configs (0.2.0)
66
html2rss
77

8-
GIT
9-
remote: https://github.com/html2rss/html2rss.git
10-
revision: aa974733c6e88a5c934f445516d9752dfa316067
11-
specs:
12-
html2rss (0.25.0)
13-
addressable (~> 2.7)
14-
brotli
15-
dry-validation
16-
faraday (> 2.0.1, < 3.0)
17-
faraday-follow_redirects
18-
faraday-gzip (~> 3)
19-
kramdown
20-
mcp (~> 1.0)
21-
mime-types (> 3.0)
22-
nokogiri (>= 1.10, < 2.0)
23-
rack (~> 3.0)
24-
rackup (~> 2.0)
25-
regexp_parser
26-
reverse_markdown (~> 3.0)
27-
rss
28-
sanitize
29-
thor
30-
tzinfo
31-
webrick (~> 1.9)
32-
zeitwerk
33-
348
GEM
359
remote: https://rubygems.org/
3610
specs:
@@ -87,6 +61,27 @@ GEM
8761
faraday-net_http (3.4.4)
8862
net-http (~> 0.5)
8963
hana (1.3.7)
64+
html2rss (0.26.0)
65+
addressable (~> 2.7)
66+
brotli
67+
dry-validation
68+
faraday (> 2.0.1, < 3.0)
69+
faraday-follow_redirects
70+
faraday-gzip (~> 3)
71+
kramdown
72+
mcp (~> 1.0)
73+
mime-types (> 3.0)
74+
nokogiri (>= 1.10, < 2.0)
75+
rack (~> 3.0)
76+
rackup (~> 2.0)
77+
regexp_parser
78+
reverse_markdown (~> 3.0)
79+
rss
80+
sanitize
81+
thor
82+
tzinfo
83+
webrick (~> 1.9)
84+
zeitwerk
9085
json (2.21.2)
9186
json_schemer (2.5.0)
9287
bigdecimal
@@ -138,7 +133,7 @@ PLATFORMS
138133
x86_64-linux
139134

140135
DEPENDENCIES
141-
html2rss!
136+
html2rss (~> 0.26)
142137
html2rss-configs!
143138

144139
BUNDLED WITH

astro.config.mjs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ export default defineConfig({
1414
"/components/html2rss-configs": "/creating-custom-feeds/",
1515
"/components": "/",
1616
"/web-application/how-to/deployment": "/web-application/deployment/",
17-
"/web-application/how-to/automatic-updates": "/web-application/deployment/#auto-update-with-watchtower",
17+
"/web-application/how-to/automatic-updates": "/web-application/deployment/",
1818
"/web-application/how-to/use-automatic-feed-generation":
1919
"/web-application/guides/use-the-feed-directory/",
2020
"/web-application/how-to": "/web-application/guides/",

src/components/docs/DockerComposeSnippet.astro

Lines changed: 2 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,9 @@
11
---
22
import { Code } from "@astrojs/starlight/components";
3-
import { botasaurusImage, caddyImage, watchtowerImage, webImage } from "../../data/docker";
3+
import { botasaurusImage, caddyImage, webImage } from "../../data/docker";
44
55
interface Props {
6-
variant: "minimal" | "productionCaddy" | "secure" | "watchtower" | "resourceGuardrails";
6+
variant: "minimal" | "productionCaddy" | "secure" | "resourceGuardrails";
77
}
88
99
const { variant } = Astro.props;
@@ -78,15 +78,6 @@ volumes:
7878
botasaurus:
7979
image: ${botasaurusImage}
8080
restart: unless-stopped`,
81-
watchtower: `services:
82-
watchtower:
83-
image: ${watchtowerImage}
84-
restart: unless-stopped
85-
volumes:
86-
- /var/run/docker.sock:/var/run/docker.sock:ro
87-
# Optional for private registries only:
88-
# - "\${HOME}/.docker/config.json:/config.json:ro"
89-
command: --cleanup --interval 7200 html2rss-web botasaurus caddy`,
9081
resourceGuardrails: `services:
9182
html2rss-web:
9283
image: ${webImage}

src/content/docs/creating-custom-feeds.mdx

Lines changed: 34 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -31,11 +31,12 @@ When existing feeds or auto-sourcing are not enough, write a YAML config for the
3131
## Recommended Workflow
3232

3333
1. **Inspect the live page** in your browser developer tools
34-
2. **Write the smallest useful config** that extracts items, titles, and links
35-
3. **Validate the config** with `html2rss validate your-config.yml`
36-
4. **Render the feed** with `html2rss feed your-config.yml`
37-
5. **Add it to `html2rss-web`** so you can use it through your normal instance
38-
6. **Escalate request strategy when needed**: use a browser-based rendering strategy only when troubleshooting requires it
34+
2. **Optionally draft with capture**`html2rss capture https://example.com/articles > your-config.yml` (see [Capturing Feed Configs](/ruby-gem/guides/capturing-feed-configs/))
35+
3. **Write or refine the smallest useful config** that extracts items, titles, and links
36+
4. **Validate the config** with `html2rss validate your-config.yml`
37+
5. **Render the feed** with `html2rss feed your-config.yml`
38+
6. **Add it to `html2rss-web`** so you can use it through your normal instance
39+
7. **Escalate request strategy when needed**: use Botasaurus (`strategy: botasaurus` or `auto` with `BOTASAURUS_SCRAPER_URL`) only when troubleshooting requires browser rendering
3940

4041
This order keeps iteration fast and makes it easier to see whether the problem is the page structure, your
4142
selectors, or the fetch strategy.
@@ -188,8 +189,34 @@ there.
188189
**Help the community by sharing your config:**
189190

190191
1. Go to [html2rss-configs on GitHub](https://github.com/html2rss/html2rss-configs)
191-
2. Click "Fork" → "Add file" → Create `domain.com.yml`
192-
3. Paste your config → "Commit new file" → "Open pull request"
192+
2. Click "Fork" → "Add file" → Create `domain.com/name.yml` under `lib/html2rss/configs/`
193+
3. Include top-level `directory.topics` (required for Feed Directory configs) using the controlled vocabulary below
194+
4. Paste your config → "Commit new file" → "Open pull request"
195+
196+
Example catalog metadata:
197+
198+
<Code
199+
code={`
200+
directory:
201+
topics:
202+
- tech
203+
- research
204+
channel:
205+
url: https://example.com/blog
206+
language: en
207+
selectors:
208+
items:
209+
selector: "article.post"
210+
title:
211+
selector: "h2 a"
212+
url:
213+
selector: "h2 a"
214+
extractor: "href"
215+
`}
216+
lang="yaml"
217+
/>
218+
219+
Allowed `directory.topics` values (prefer 1–2 primary topics): `sports`, `energy`, `tech`, `science`, `news`, `entertainment`, `jobs`, `finance`, `security`, `travel`, `environment`, `consumer`, `civic`, `product`, `research`.
193220

194221
**Need help?** See our [contribution guide](/get-involved/contributing/) for detailed instructions.
195222

src/content/docs/feed-directory/index.mdx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ import FeedDirectory from "../../../components/FeedDirectory.astro";
1414

1515
---
1616

17-
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.
17+
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.
1818

1919
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).
2020

src/content/docs/get-involved/contributing.mdx

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -26,10 +26,12 @@ Are you missing an RSS feed for a website? You can create your own feed config a
2626
**The easiest way to contribute:**
2727

2828
1. Go to [html2rss-configs on GitHub](https://github.com/html2rss/html2rss-configs)
29-
2. Click "Fork" → "Add file" → Create `domain.com.yml`
30-
3. Paste your config → "Commit new file" → "Open pull request"
29+
2. Click "Fork" → "Add file" → Create `domain.com/name.yml` under `lib/html2rss/configs/`
30+
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))
31+
4. Prefer setting `channel.language` when the page language is clear
32+
5. Paste your config → "Commit new file" → "Open pull request"
3133

32-
**Need help writing configs?** See our [Creating Custom Feeds](/creating-custom-feeds/) guide.
34+
**Need help writing configs?** Start from [Capturing Feed Configs](/ruby-gem/guides/capturing-feed-configs/) or the [Creating Custom Feeds](/creating-custom-feeds/) guide.
3335

3436
**Want to test your config first?** Use the [Ruby gem](/ruby-gem/installation/) to test it locally:
3537

Lines changed: 103 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,103 @@
1+
---
2+
title: AI Agent Workflows with MCP
3+
description: Guide to integrating html2rss with AI agents, Claude Desktop, and Cursor using the Model Context Protocol (MCP).
4+
---
5+
6+
import { Code } from "@astrojs/starlight/components";
7+
8+
`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.
9+
10+
## Why Use MCP?
11+
12+
Without MCP, agents must invoke shell commands, manage output buffers, and parse unstructured text. With MCP:
13+
14+
- The agent automatically discovers available tools, arguments, and return types.
15+
- Responses are structured (JSON Feed objects, configuration schemas, and RSS XML).
16+
- Agents can inspect, capture, validate, and verify feeds iteratively in a closed feedback loop.
17+
18+
## Client Setup
19+
20+
### 1. Version Manager Shims (mise, asdf, rbenv, chruby)
21+
22+
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.
23+
24+
<Code
25+
code={`
26+
# Install the gem in your global environment
27+
mise exec -- gem install html2rss
28+
# Or add it to your project Gemfile
29+
mise exec -- bundle add html2rss
30+
`}
31+
lang="bash"
32+
/>
33+
34+
### 2. Cursor Configuration
35+
36+
Add `html2rss` to your Cursor MCP settings (`~/.cursor/mcp.json` or `.cursor/mcp.json`):
37+
38+
<Code
39+
code={`
40+
{
41+
"mcpServers": {
42+
"html2rss": {
43+
"command": "mise",
44+
"args": ["exec", "--", "html2rss", "mcp"]
45+
}
46+
}
47+
}
48+
`}
49+
lang="json"
50+
/>
51+
52+
_(If using `asdf`, replace `"command": "mise"` with `"asdf"` and `"args": ["exec", "html2rss", "mcp"]`.)_
53+
54+
### 3. Claude Desktop Configuration
55+
56+
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):
57+
58+
<Code
59+
code={`
60+
{
61+
"mcpServers": {
62+
"html2rss": {
63+
"command": "mise",
64+
"args": ["exec", "--", "html2rss", "mcp"]
65+
}
66+
}
67+
}
68+
`}
69+
lang="json"
70+
/>
71+
72+
## Autonomous Workflow Patterns
73+
74+
### Pattern A: One-Shot Content Scraping
75+
76+
When an agent needs articles immediately without saving a feed configuration:
77+
78+
1. The agent calls `scrape_url` with the target URL.
79+
2. `html2rss` runs auto-source extraction (Schema.org, JSON state, semantic HTML) and returns a JSON Feed items array.
80+
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"`.
81+
82+
### Pattern B: Iterative Feed Config Authoring
83+
84+
When an agent is tasked with creating a durable YAML feed configuration:
85+
86+
1. **Inspect:** The agent calls `inspect_url` to check content type, SST node counts, and eligible scrapers.
87+
2. **Capture:** The agent runs `capture_config` to derive CSS selectors for items, title, link, and description.
88+
3. **Refine:** The agent reviews the derived selectors or asks the human user for domain-specific adjustments.
89+
4. **Validate:** The agent passes the configuration to `validate_config` to verify schema conformance.
90+
5. **Apply:** The agent tests the final configuration with `apply_config` to produce and inspect live RSS XML.
91+
92+
## JavaScript-Rendered Sites (Botasaurus)
93+
94+
For dynamic JavaScript single-page applications or sites protected by anti-bot measures, launch the Botasaurus scrape service:
95+
96+
<Code
97+
code={`
98+
docker compose -f docker-compose.botasaurus.yml up -d
99+
`}
100+
lang="bash"
101+
/>
102+
103+
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`.

src/content/docs/ruby-gem/guides/backward-compatibility.mdx

Lines changed: 13 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,13 @@ import { Code } from "@astrojs/starlight/components";
77

88
This page outlines recent breaking changes, purged legacy aliases, and migration steps for older feed configurations.
99

10+
## 0.26.0
11+
12+
Upgrade notes for configs and integrators targeting gem **0.26.0**:
13+
14+
1. **Browserless strategy removal** — The `browserless` strategy, `puppeteer-ruby` dependency, interaction budgets, and `request.browserless.*` options have been completely removed.
15+
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.
16+
1017
## 0.25.0
1118

1219
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
6774
# Deprecated / Removed
6875
channel:
6976
url: "https://example.com/articles"
70-
strategy: browserless
77+
strategy: botasaurus
7178
headers:
7279
User-Agent: "CustomAgent/1.0"
7380
# Current & Required
74-
strategy: browserless
81+
strategy: botasaurus
7582
headers:
7683
User-Agent: "CustomAgent/1.0"
7784
channel:
@@ -84,10 +91,10 @@ Update any occurrences of `link`, `pubDate`, or `updated` in your `selectors` bl
8491

8592
When upgrading to modern `html2rss` releases:
8693

87-
1. **Rename URL selectors**: Ensure article URL selectors use `url` rather than `link`.
88-
2. **Rename date selectors**: Ensure date selectors use `published_at` rather than `updated` or `pubDate`.
89-
3. **Move channel-level transport keys**: Ensure `strategy` and `headers` are defined at the top level of the YAML file.
90-
4. **Pin Browserless when needed**: If you relied on `auto` falling through to Browserless, set `strategy: browserless` (or `--strategy browserless`).
94+
1. **Migrate Browserless to Botasaurus**: Update any feeds using `strategy: browserless` or `request.browserless` to `strategy: botasaurus` or `strategy: auto` with `BOTASAURUS_SCRAPER_URL`.
95+
2. **Rename URL selectors**: Ensure article URL selectors use `url` rather than `link`.
96+
3. **Rename date selectors**: Ensure date selectors use `published_at` rather than `updated` or `pubDate`.
97+
4. **Move channel-level transport keys**: Ensure `strategy` and `headers` are defined at the top level of the YAML file.
9198
5. **Use `enclosure` for RSS media**: Do not rely on `image` becoming an RSS `<enclosure>`; select podcast/media URLs with `enclosure`.
9299
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`.
93100
7. **Validate configurations**: Run `html2rss validate config.yml` to ensure your YAML conforms to the current schema.

0 commit comments

Comments
 (0)