FIRST CH TOOLS / Text / 57 HTML → Markdown

HTML → Markdown

Paste a page's HTML on the left and the Markdown appears on the right. Headings, lists, tables, links, images and code blocks are converted; script, style and presentational div / span wrappers are dropped. For moving existing web copy into Markdown, and for tidying up a page an agent has just fetched.

Paste and it converts as you type

HTML
Markdown
0
Headings
Links
0
Images
0
Tables
0
Code blocks
0
Characters out
What was read

    The HTML you paste never leaves your browser — it is parsed and rebuilt on this page. Loading a file reads it locally; nothing is uploaded. Directly callable via URL parameters: /en/html-md/?html=%3Ch1%3EA%3C%2Fh1%3E / /en/html-md/?main=1&base=https://example.com/

    How to Use

    1. Paste the HTMLPage source, HTML copied from devtools, or the body field out of a CMS — into the box on the left. You can also drop an .html file onto it.
    2. Set it up for the destinationTick "Main content only" when you pasted a whole page, and put the page's address in "Base URL" so links and images become absolute.
    3. Copy the MarkdownThe result appears on the right. Copy it or save it as .md. Anything left as HTML, and every table that could not be converted, is listed under "What was read".

    About This Tool

    The HTML is not parsed by the browser. Tools like this normally read HTML with DOMParser or innerHTML; this one carries its own tokeniser and tree builder. There are two reasons. First, the same logic runs inside an MCP server on Node.js, where there is no DOM — depending on one would make the browser and the agent disagree. Second, safety: putting pasted HTML into innerHTML lets things like <img onerror> execute on this page. An implementation that only parses never runs what you paste.

    Broken HTML still produces a result. Real pages are full of unclosed <li> and <p> elements, closing tags with nothing to close, and unterminated quotes. Like a browser, this tool closes what was left open and discards stray closing tags and carries on — but it does not do so silently: the counts appear under "What was read". The one case it refuses to guess is an unterminated attribute quote, because continuing would swallow the rest of the document as a single attribute value.

    Whatever Markdown cannot express is reported, not quietly dropped. Merged cells, definition lists, superscripts, iframes — there will always be elements with no Markdown equivalent. This tool lets you choose between keeping them as HTML, reducing them to text and removing them, and then tells you what happened every time. In a migration the dangerous outcome is not a failed conversion; it is losing something and not noticing until it is published.

    Relative URLs are the most common casualty. A link to /about/ works perfectly inside its own page and points somewhere else entirely once the Markdown lands in a repository README or another domain's CMS. Give the tool a base URL and links and images are rewritten as absolute URLs, leaving anchors and already-absolute URLs untouched.

    It is also a post-processing step for agents. Feeding raw HTML to an LLM spends most of the tokens on tags and attributes. Extracting the main content as Markdown usually cuts the length to a fraction of that while keeping the headings and tables intact. The same conversion is available as the MCP tool html_to_markdown, so an agent can call it without opening a browser.

    Going the other way, Markdown → PDF and Marp Markdown → Slides turn Markdown into something you can hand over. For tables alone see Markdown Table Formatter, and for the special characters themselves see HTML Entity Escape.

    From AI Agents

    This conversion is also available as the html_to_markdown tool of the MCP (Model Context Protocol) server @first-ch/tools-mcp, so an AI agent can call it directly instead of driving a browser. Hand it the HTML of a page you fetched and it returns the main content as Markdown (it never touches the network itself — fetching stays on the agent's side). See Using these tools from AI agents for setup.

    Install

    claude mcp add firstch-tools -- npx -y @first-ch/tools-mcp

    Examples

    # An HTML fragment to Markdown
    html_to_markdown(html="<h1>Title</h1><p>Body</p>")
    
    # Keep the article only and make relative URLs absolute
    html_to_markdown(path="/tmp/page.html", main_only=true, base_url="https://example.com/blog/1/")
    
    # Prose only, for summarising: no links, no images
    html_to_markdown(html="...", links="strip", images="drop")
    
    # For a CommonMark-only destination (tables stay as HTML)
    html_to_markdown(path="/tmp/page.html", gfm=false, outputPath="/tmp/page.md")

    Other Tools