Providers
Jina
Jina's s.jina.ai for search and r.jina.ai for reading, the default reader, with an optional key.
Provider
Jina
- create("jina")
- JINA_API_KEY
- Auth
- Bearer header, optional for read
- Results
- 10, up to 20 · one page
- Free tier
- key required for search, optional for read
Options
- Filters
includeDomains, category - Fields
publishedDate, image, text, metadata - Category
web, images, news - Read
markdown, text, html · format, maxTokens, targetSelector, removeSelector, timeout, noCache
Address it
import { create, readUrl } from "@agntn/web";
const jina = await create("jina"); // JINA_API_KEY, required for search
const results = await jina.search("model context protocol", { category: "news" });
const page = await readUrl("https://modelcontextprotocol.io", { format: "markdown" }); // Jina first, no key needed
The key is sent as a Bearer token. Search needs it, reading works without one and sends it when present.
What it reads
| Call | Endpoint |
|---|---|
search | GET https://s.jina.ai/… with Accept: application/json |
read | GET https://r.jina.ai/<url> with X-Return-Format, X-Target-Selector, X-Remove-Selector, X-Timeout, X-No-Cache |
The reader host is derived from the search host, so a custom baseURL for s. moves r. with it.
What comes back
Search results carry the page content in text, plus publishedDate, image and metadata. includeDomains and a category of web, images or news work. Reads give markdown, text or html and take maxTokens natively, as a budget: a longer page fails with a 409 instead of coming back cut.
Gotchas
- Without a key r.jina.ai is rate limited per address. With a key, an empty balance answers 402, which is eligible for fallback to the next configured reader.
- A 409 from the reader (could not fetch the page right now) is eligible for fallback too.
texton search results is the whole page. Ten results can be huge, keepmaxResultslow.
Where it lives
src/providers/jina.ts, the template for a reader.