| title | MCP Server Reference |
|---|---|
| description | Complete protocol reference for the html2rss Model Context Protocol (MCP) server, tools, resources, prompts, and transports. |
import { Code } from "@astrojs/starlight/components";
html2rss includes a built-in Model Context Protocol (MCP) server that exposes gem capabilities directly to AI agents, clients, and IDEs (such as Cursor, Claude Desktop, and GitHub Copilot).
The MCP server allows AI agents to inspect pages, capture reusable feed configurations, validate configs, and generate feeds without executing ad-hoc shell scripts or parsing CLI output.
<Code code={`
html2rss mcp
html2rss mcp --transport http --port 8080 `} lang="bash" />
The MCP server supports two transport mechanisms:
| Transport | Command | Default Port | Description |
|---|---|---|---|
stdio |
html2rss mcp --transport stdio |
N/A | Standard input/output communication. Recommended for Cursor and Claude Desktop. |
http |
html2rss mcp --transport http --port 8080 |
8080 |
Streamable HTTP transport bound strictly to 127.0.0.1 (loopback only). |
- Loopback binding: The HTTP transport only binds to
127.0.0.1. Never expose it to public interfaces without authentication and reverse proxy origin controls. - Dependencies: The HTTP transport requires the
rack,rackup, andwebrickgems. If they are not present, starting the server raises a descriptiveLoadError. - Logging: stdio JSON-RPC uses stdout. The daemon logs to stderr and defaults to
LOG_LEVEL=infounlessLOG_LEVELis set (debugfor more,warnto quiet).
scrape_url and capture_config with strategy: "auto" (the default) run Faraday → Botasaurus AutoFallback in one call.
inspect_url with auto uses Faraday for a cheap diagnostic. Pin strategy: "botasaurus" when you need browser rendering for inspect.
Read html2rss://runtime for botasaurus_configured (boolean only). Set BOTASAURUS_SCRAPER_URL on the MCP process env (see AI agent workflows).
Tool-call budget: scrape_url = 1 call. Durable config = capture_config → validate_config → apply_config. Call inspect_url only when scrape/capture is weak or you need recon. Follow envelope next_step / guidance rather than guessing the next tool.
Every tool returns the same JSON object in both the text content and structuredContent:
<Code
code={{ "ok": true, "next_step": "validate_config", "guidance": "...", "payload": {} }}
lang="json"
/>
isError matches ok: false. Scrape results expose articles in payload.items.
next_step is one of: done, inspect_url, validate_config, apply_config, scrape_url, capture_config, read_runtime.
The server registers 5 primary tools for AI agent orchestration.
One-shot article extraction as JSON Feed items. Use when you need articles immediately without authoring or saving a YAML feed config.
- Parameters:
url(string, required): Source page URL to scrape.strategy(string, optional): Request strategy (auto,faraday,botasaurus). Default:auto.limit(integer, optional): Maximum articles to keep. Default:25.items_selector(string, optional): CSS selector hint for items.
- Return value: Envelope with
payload.items(JSON Feed article objects:title,url,description,published_at,author,image,categories). Alsopayload.total,requested_strategy,channel_title, andadmission_dropswhen present. - Error handling: Unhandled exceptions return
isError: truewithpayload.class/payload.message. An empty item list is still success (ok: true; follownext_step, which may beinspect_urlorread_runtime).
Diagnostic page analysis plus recon from the same fetch. auto uses Faraday; pin botasaurus when you need browser rendering.
- Parameters:
url(string, required): Source page URL.strategy(string, optional): Request strategy (auto,faraday,botasaurus). Default:auto.
- Return value: Envelope whose
payloadis the diagnostic object:requested_url/final_url: requested URL vsResponse#urlafter redirects.status: HTTP status when the strategy reports one.scheme_downgrade:truewhen the fetch went https → http.alternate_feeds:rel=alternateRSS/Atom links from the document head (no/feedpath guessing).content_type/html_response/scraper_eligibility/sst_stats/sst.segment_stats.articles_countandadmission_dropswhen the response is HTML (Cleanup drop-reason counts).blocked_surfacewhen an interstitial signature is detected.xhr_capturewhen the inspect strategy isbotasaurus(count, redactedsample_endpoints,candidate_articles).
- next_step:
donewhen native alternate feeds exist,capture_configwhen articles were found, otherwisescrape_url.
Analyzes a target URL and derives a reusable YAML draft (items selector + enhance: true). Same serializer as CLI html2rss capture. Full schema options live in resource html2rss://schema.
- Parameters:
url(string, required): Source page URL.strategy(string, optional): Request strategy (auto,faraday,botasaurus). Default:auto.items_selector(string, optional): Optional CSS selector hint for items.
- Return value: Envelope with
payload.yaml(string keys; same serializer as CLIhtml2rss capture). Treat as a draft: catalog feeds still needdirectory.topicsand explicit channeltitle/url. Strive to keepenhance: true. - payload: Also
articles_count,channel_title,has_selectors,requested_strategy, and when presentsegment_strategy,selected_strategy,admission_drops. Follownext_step(validate_configorinspect_url).
Validates a feed configuration against the official html2rss JSON schema (html2rss://schema) and runtime constraints.
- Parameters (exactly one of
configoryaml):config(object, optional): Feed configuration object.yaml(string, optional): Feed configuration YAML (same form as CLI capture / catalog files).
- Return value: Envelope with empty
payloadon success (next_step:apply_config). - Error handling: Returns
isError: truewithpayload.errorsif schema validation fails, ornext_step: validate_configif both/neither argument is provided.
Executes a validated feed configuration against a page and returns RSS 2.0 XML. This is the ship gate: isError when the feed has zero items.
- Parameters:
url(string, required): Source page URL (populateschannel.urlif omitted from config).config(object, optional): Feed configuration object (XORyaml).yaml(string, optional): Feed configuration YAML (XORconfig).
- Return value: Envelope with
payload.rss(RSS 2.0 XML) andpayload.item_countfrom the rendered RSSitems(not a regex over the XML). - Error handling:
isError: truewhen the scrape produced no items (payload.item_count: 0,next_step: inspect_url), or on unhandled exceptions.
The MCP server exposes reference data under the html2rss:// URI scheme:
| URI | MIME Type | Description |
|---|---|---|
html2rss://schema |
application/json |
The complete JSON Schema for html2rss feed configurations, including selector rules, extractors, and request controls. |
html2rss://extractors |
application/json |
Alphabetical list of all registered extractor names (attribute, html, href, text, static, etc.). |
html2rss://strategies |
application/json |
Published MCP request strategies (auto, faraday, botasaurus). Does not list local_file. |
html2rss://runtime |
application/json |
Boolean botasaurus_configured from process env. Never includes the scraper URL. |
validate_config / apply_config reject strategy: local_file and request.local_file_path. Use CLI --input for fixtures.
The server publishes guided prompt workflows for AI assistants:
One scrape_url call with strategy: auto (AutoFallback already hops). Call inspect_url only if the result is weak or you need recon.
- Arguments:
url(string, required): Target URL to scrape.
Four-step workflow for a durable feed config:
- Call
capture_config— YAML ispayload.yaml. Checkpayload.articles_countandhas_selectors. Striveenhance: true. - If weak or you need recon, call
inspect_url(autouses Faraday; pinbotasaurusfor browser rendering). - Call
validate_configwithyaml(orconfig) — must not beisError. - Call
apply_config—isErrorif zero items. Confirmpayload.item_countbefore shipping.
If the destination is html2rss-configs, rewrite the draft with registry.id, directory.topics (non-empty), directory.title, and mirror channel.title (required for Feed Directory configs). Optional directory.summary (max 160 characters). Set explicit channel url.
- Arguments:
url(string, required): Target URL to analyze.