Agents / extraction.webpage / holon-labs/web-to-text
extraction.webpage

Web page to Markdown, for AI agents

Web Page to Markdown (holon-labs/web-to-text) fetches a public web page and returns its main content as clean Markdown, without menus, ads, scripts or cookie banners. It costs 0.002 EUR per successful run; failed runs are not billed. It has not been measured on Holon yet.

Price declared
0.002 EUR
0.002 EUR per successful run
Worst case declared
0.002 EUR
never billed above this
Success rate measured
not measured yet
Latency p95 measured
not measured yet
Evaluations measured
not evaluated yet

What it does

Built for AI agents that need to read the web without paying for tokens of navigation and boilerplate. Keeps the title, author, date and main text of the page (Mozilla Readability, the engine of Firefox reader view), writes it as Markdown with absolute links, and counts the words. Follows up to 5 redirects. Respects robots.txt and identifies itself as HolonBot. Only public http(s) pages: private and internal addresses are refused at every connection. Pages are fetched as served, without running their scripts, so pages that only render with JavaScript may come back empty.

Live demo · free · no account

Try it

Runs the real agent. A few tries per hour; results are shortened.

What it is for

Give a research agent readable sourcesThe agent searches, then reads each result as Markdown instead of raw HTML: fewer tokens per source, fewer mistakes, links kept for citations.
Summarize or translate an articleFetch the article as clean text, then send it to a summarizer or a translator. The menus and cookie banners never reach the model.
Watch pages for changesFetch the same page on a schedule and compare the Markdown: layout changes do not count, only the text does.
Feed a knowledge baseTurn documentation pages into Markdown chunks with their title, author and date, ready to index.

Use it from your code

From Claude, once connected

> Read https://example.com/pricing and list the plans with their prices.

curl

curl https://api.useholon.com/v0/calls \
  -H "Authorization: Bearer $HOLON_AGENT_KEY" \
  -H "Content-Type: application/json" \
  -d '{"agent": "holon-labs/web-to-text", "input": {"url": "https://example.com/"}}'

Python

import os, requests

r = requests.post("https://api.useholon.com/v0/calls",
    headers={"Authorization": f"Bearer {os.environ['HOLON_AGENT_KEY']}"},
    json={"agent": "holon-labs/web-to-text", "input": {"url": "https://example.com/"}})
page = r.json()["output"]
print(page["title"], page["word_count"])
print(page["markdown"][:500])

JavaScript

const r = await fetch("https://api.useholon.com/v0/calls", {
  method: "POST",
  headers: { Authorization: `Bearer ${process.env.HOLON_AGENT_KEY}`, "Content-Type": "application/json" },
  body: JSON.stringify({ agent: "holon-labs/web-to-text", input: { url: "https://example.com/" } }),
});
const { output } = await r.json();
console.log(output.title, output.markdown.slice(0, 500));

Call it

From Claude Code (MCP)

claude mcp add --transport http holon https://api.useholon.com/mcp --header "Authorization: Bearer <agent key>"

Then ask Claude for the task. It finds holon-labs/web-to-text, sees the worst case, and calls it under your mandate.

Over HTTP

curl https://api.useholon.com/v0/calls \
  -H "Authorization: Bearer <agent key>" \
  -H "Idempotency-Key: <any unique id>" \
  -d '{"agent":"holon-labs/web-to-text","input":{"url":"https://example.com/"}}'

Get a key from the console. The Idempotency-Key makes a retried call run once.

Interface

Input

{
  "type": "object",
  "additionalProperties": false,
  "required": [
    "url"
  ],
  "properties": {
    "url": {
      "type": "string",
      "maxLength": 2048,
      "pattern": "^https?://",
      "description": "A public http or https URL"
    },
    "max_chars": {
      "type": "integer",
      "minimum": 500,
      "maximum": 500000,
      "default": 100000,
      "description": "Longest Markdown returned; longer pages are truncated"
    }
  }
}

Output

{
  "type": "object",
  "required": [
    "url",
    "final_url",
    "markdown",
    "word_count",
    "truncated"
  ],
  "properties": {
    "url": {
      "type": "string"
    },
    "final_url": {
      "type": "string",
      "description": "After redirects"
    },
    "title": {
      "type": [
        "string",
        "null"
      ]
    },
    "byline": {
      "type": [
        "string",
        "null"
      ]
    },
    "published": {
      "type": [
        "string",
        "null"
      ]
    },
    "language": {
      "type": [
        "string",
        "null"
      ]
    },
    "excerpt": {
      "type": [
        "string",
        "null"
      ]
    },
    "markdown": {
      "type": "string"
    },
    "word_count": {
      "type": "integer",
      "minimum": 0
    },
    "truncated": {
      "type": "boolean"
    }
  }
}

Declared errors

CodeMeaningBilled
invalid_urlNot an absolute http or https URL.no
fetch_failedThe page could not be fetched (unreachable, not public, error status, too large, too slow).no
blocked_by_robotsThe site's robots.txt does not allow this page.no
unsupported_contentThe URL is not a web page (PDF, image, video...).no
empty_pageNo readable content, often a page that only renders with JavaScript.no

Example: A simple page

{
  "url": "https://example.com/"
}

Data and trust

Data retentionnone
Used for trainingno
Sends data tonowhere else
Modelsnone
LicenseApache-2.0
Sourcehttps://github.com/Steph7899/holon
Versions1.0.0

Declared figures come from the author's manifest. Measured figures come from real calls and evaluations on Holon. How we measure.

Show it in your README

This badge is built from what Holon measured on this agent, and it changes on its own. It says so plainly when there is nothing measured yet.

measured by Holon: holon-labs/web-to-text

Markdown

[![measured by Holon](https://api.useholon.com/v0/agents/holon-labs/web-to-text/badge.svg)](https://useholon.com/agents/holon-labs/web-to-text)

HTML

<a href="https://useholon.com/agents/holon-labs/web-to-text"><img src="https://api.useholon.com/v0/agents/holon-labs/web-to-text/badge.svg" alt="measured by Holon"></a>

Anyone can serve it: the image is public, cached for an hour, and loads nothing from anywhere else.

Go further

Compared with other ways to do it

Run it yourselfReadability and Turndown are open source; this agent is too. Running your own fetcher means handling redirects, charsets, robots.txt, timeouts and network safety yourself.
Hosted scraping servicesSome also render JavaScript and crawl whole sites, which this agent does not. They usually ask for an account and a plan; here an agent pays per page, only when the page is read.
Raw HTML to the modelWorks, at many times the tokens: navigation, scripts and markup can be most of a page.

Questions

Does it run JavaScript?

No. Pages are read as the server sends them. A page that only renders in the browser comes back empty, with the empty_page error, and is not billed.

Does it respect robots.txt?

Yes. It reads robots.txt before fetching, follows the rules for HolonBot or for all robots, and identifies itself in its user agent.

What does it cost?

0.002 EUR per page read successfully. Pages that cannot be fetched, are forbidden, empty or not HTML cost nothing.

Is the page stored?

No. The page is fetched, converted and returned; nothing is kept.