Page to JSON
Paste a link. Get one page back as structured JSON — its title, H1 and meta description, its plain text, every hyperlink with the words people click, and every image with its alt text. No signup, no key.
Fetches the page server-side and takes it apart. Usually about a second.
Anchor text and alt text are the point
Plenty of things will give you a list of URLs on a page. The useful part is what those URLs were called — anchor text is how both readers and search engines decide what a link means, and it is the first thing lost when a page is reduced to a list of hrefs. Same for images: the src tells you a picture exists, the alt tells you what it shows, and whether anyone bothered to say.
So links come back as { href, text } and images as { src, alt }, alongside the title, H1, description and the page's plain text. Missing anchor text and missing alt text are both called out rather than left as empty strings you have to notice.
Want the whole site instead of one page? Website to JSON. Want it as prose for a model? URL to Markdown. Built with the Hyperlambda Generator and callable by your own agents over MCP. Run the platform yourself:
curl -fsSL https://hyperlambda.dev/docker-compose.yaml | docker compose -f - up
The whole backend, printed
No scraping service, no parsing library glued together. This page calls one endpoint, and this is that endpoint in full — generated from a plain-English description and verified before it was saved:
.arguments
url:string
validators.mandatory:x:@.arguments/*/url
http.get:x:@.arguments/*/url
html2lambda:x:@http.get/*/content
.title
set-value:x:@.title
get-value:x:@html2lambda/*/html/*/head/*/title/*/#text
.h1
set-value:x:@.h1
strings.join:x:@html2lambda/*/html/*/body/**/h1/[0,1]/**/#text
.:" "
.description
set-value:x:@.description
get-value:x:"@html2lambda/*/html/*/head/*/meta/*/\\@name/=description/./*/\\@content"
.text
set-value:x:@.text
strings.join:x:@html2lambda/*/html/*/body/**/#text
.:" "
.links
for-each:x:@html2lambda/*/html/*/body/**/a
strings.join:x:@.dp/#/**/#text
.:" "
unwrap:x:+/*/*/*
add:x:@.links
.
.
href:x:"@.dp/#/*/\\@href"
text:x:@strings.join
.images
for-each:x:@html2lambda/*/html/*/body/**/img
unwrap:x:+/*/*/*
add:x:@.images
.
.
src:x:"@.dp/#/*/\\@src"
alt:x:"@.dp/#/*/\\@alt"
yield
title:x:@.title
h1:x:@.h1
description:x:@.description
text:x:@.text
links:x:@.links/*
images:x:@.images/*
Describe an endpoint in a sentence, and the Hyperlambda Generator writes and deploys it — then it is a tool your own agents can call over MCP.
More free tools
Taking a page apart into structured JSON is one of nine free tools here, all of them built the same way and callable by your own agents. See all of them — no signup on any of it.
Questions
Why are some links relative?
Because that is what the page says. Hrefs come back exactly as written in the HTML, so /pricing stays /pricing — resolving it would quietly discard the information that the link was relative in the first place. The table shows the resolved address so you can still follow it.
Why does it flag empty anchor text?
A link whose text is empty is usually an icon or an image wrapped in an anchor. It works with a mouse and tells a screen reader, a search engine and a language model nothing at all. Same reasoning as the missing alt flag.
Does it run JavaScript on the page?
No. It reads the server-rendered HTML, which is also what most crawlers see. A page that builds itself in the browser will come back with very little in it — the AI crawler check is the tool for diagnosing that.
Can my AI agent call this directly?
Yes. On a Magic cloudlet every endpoint is also an MCP tool, filtered by role, so an agent can pull a page apart the same way this page does.