# jurl — curl that reads the page for you

Tell it what you want. It picks it out of the page.

```
$ jurl --find "a cathedral" en.wikipedia.org/wiki/Cologne
https://thumb.wikimedia.org/wikipedia/commons/thumb/2/27/Kdom.jpg/250px-Kdom.jpg
```

73 images looked at · 2.3 s · $0.002

- Install: `brew install rayoplateado/tap/jurl`
- Code: https://github.com/rayoplateado/jurl (MIT or Apache-2.0)
- All flags: https://github.com/rayoplateado/jurl#reference
- Try it in the browser, no key needed: https://jurl.dev/#try

## It picks. It doesn't write.

jurl doesn't use a chatbot. It uses decision models: Jev reads the text and Clef looks at the images. Neither writes a word. They only say how likely each paragraph, link or image is to be what you want, and jurl prints the winners exactly as they appear on the page. No summary that drifts, no URL that doesn't exist.

- **It's fast.** Most pages take under a second, end to end. (`jurl <url>` · 0.6–1 s)
- **It's cheap.** About a thousand pages per dollar of API usage. (`jurl <url>` · $0.0004–0.0013)

## Same command. Six things to ask for.

| You want | Command |
|---|---|
| The gist | `jurl url` |
| One answer | `-q "…"` |
| Just the code | `--code` |
| Links worth following | `--links` |
| The real images | `--image` |
| A photo, by description | `--find "…"` |

Pages built by JavaScript just work. jurl spots the empty app shell and renders it in Lightpanda, a fast headless browser it fetches the first time one shows up.

### The point of a long blog post

Cloudflare's "Introducing Markdown for Agents", with its navigation, author bios and related posts. jurl gives the title, what kind of page it is, and the blocks that carry it · 0.6 s

```
jurl -n 3 blog.cloudflare.com/markdown-for-agents/
```

### How to read a file line by line in Python

The whole tutorial chapter on input and output. jurl gives that paragraph and that loop · 0.6 s

```
jurl -q "how do I read a file line by line?" -n 2 docs.python.org/3/tutorial/inputoutput.html
```

### To install uv

uv's whole README on GitHub. jurl gives the install commands · 0.9 s

```
jurl --code -q "install" -n 2 github.com/astral-sh/uv
```

### Paul Graham's essays about startups

The list of all his essays. jurl gives the ones about startups · 0.8 s

```
$ jurl --links -q "essays about startups" -n 4 paulgraham.com/articles.html
https://paulgraham.com/start.html
https://paulgraham.com/startupmistakes.html
https://paulgraham.com/startupideas.html
https://paulgraham.com/13sentences.html
```

### The photos in an article

Wikipedia's Golden Gate Bridge article, with its logos and icons. jurl gives the photos of the bridge · 0.6 s

```
jurl --image -n 3 en.wikipedia.org/wiki/Golden_Gate_Bridge
```

Judged by file name, alt text and caption, so it costs almost nothing. Add `--vision` and Clef looks at the pixels too.

### A photo of the cathedral

Wikipedia's Cologne article, 73 images. jurl gives the three that show it, one with no caption at all · 2.3 s

```
jurl --find "a cathedral" -n 3 en.wikipedia.org/wiki/Cologne
```

| | Image | Why it matched | p |
|---|---|---|---|
| 1 | Kdom.jpg | Cologne Cathedral | 0.96 |
| 2 | Köln_um_1890.jpg | The 1890 skyline, the cathedral towering over it | 0.95 |
| 3 | Kranhäuser_Cologne_April_2018.jpg | The Rhine at dusk, the lit cathedral on the right. No alt text, no caption. | 0.95 |

When nothing matches, jurl says so instead of handing you the least-bad photo.

## Plain text out. Pipes in.

Everything prints plain text or plain URLs, so jurl fits in a pipe — or in an agent's toolbox.

```
# Read the top 3 Hacker News stories, one key paragraph each
jurl -l -n 3 news.ycombinator.com | xargs -n1 jurl -n 1

# Download the photo that matches
jurl -f "a bridge over a river" en.wikipedia.org/wiki/Cologne | xargs curl -sO

# Every chart in a post
jurl -f "a chart or graph" -n 10 blog.cloudflare.com/markdown-for-agents/ | xargs -n1 curl -sO

# Only the confident answers, for scripts
jurl --json -q "installation" github.com/BurntSushi/ripgrep | jq -r '.blocks[] | select(.p > 0.8) | .text'
```

## Under a second. A fraction of a cent.

| Command | Typical time | Typical cost |
|---|---|---|
| `jurl <url>` | 0.6–1 s | $0.0004–0.0013 |
| `jurl -i <url>` | 0.5–0.7 s | $0.00004 |
| `jurl --vision <url>` | 1.3–1.9 s | $0.0002 |
| `jurl --find "…" <url>` (73 images) | 2.2–2.9 s | $0.002 |
| JavaScript apps | +3–6 s | same |

Measured on 2026-10-04. Run any command with `-t` to see your own numbers.

## Two lines. That's the whole setup.

```
brew install rayoplateado/tap/jurl                                                     # macOS, Linux
curl -LsSf https://github.com/rayoplateado/jurl/releases/latest/download/jurl-installer.sh | sh   # no Homebrew
```

Windows: `powershell -ExecutionPolicy Bypass -c "irm https://github.com/rayoplateado/jurl/releases/latest/download/jurl-installer.ps1 | iex"` · From source: `cargo install --git https://github.com/rayoplateado/jurl`

The first run asks for a TypeSafe API key (https://console.typesafe.ai), checks it and saves it. For `--vision` and `--find`, run `jurl init` and add a Cloudflare Workers AI token.

## No server. No account.

jurl talks to the model APIs directly, with your keys.

- **Who you pay:** TypeSafe for Jev ($0.042 per million input tokens) and Cloudflare for Clef-flash ($0.09 per million). Output is free on both.
- **What leaves your machine:** The text of the page goes to TypeSafe. With `--vision` or `--find`, the images go to Cloudflare too. Keep that in mind for internal pages.
- **What jurl can't read:** It sends no cookies, so pages behind a login are out of reach.

## One yes-or-no question per candidate.

1. **Fetch: split the page.** jurl asks for markdown first. Otherwise its own extractor drops navigation, footers and scripts, and splits the rest into blocks, links and images. Empty JavaScript app? It renders it in Lightpanda.
2. **Ask: two judges, at once.** Jev reads text ("is block 12 the point?" p = 0.97). Clef looks at images ("does this show a cathedral?" p = 0.96). Every question goes to Jev in a single request, so asking 100 takes about as long as asking one. Clef looks at the pixels while Jev reads, not after.
3. **Print: keep the winners.** What clears the threshold, in page order. A heading comes back only when something in its section does. Verbatim, always.

Models choose, they don't write. That's why the output is safe to pipe into xargs curl.

---

Made with love in Murcia by Ray García. jurl can't make things up. Ray can: he saves it for his novels — [La Única Verdad](https://www.amazon.es/dp/B08LQYLVLK) (en español), [La Única Realidad](https://www.amazon.es/dp/B0BMJH7MF6) (en español), [The Only Truth](https://www.amazon.com/dp/B0C8TSVW7F) (in English).

[Blog](https://ray-garcia.fika.bar) · [@rayoplateado on X](https://x.com/rayoplateado) · [LinkedIn](https://www.linkedin.com/in/rayg/) · ray@rayoplateado.com

MIT or Apache-2.0. Lightpanda, which jurl downloads for JavaScript pages, is a separate program under AGPL-3.0.
