Providers
Jina
Jina's s.jina.ai for search and r.jina.ai for reading, the default reader, with an optional key.
- env var
- JINA_API_KEY
- auth
- Bearer header, optional for read
- operations
- search · read
- results
- 10, up to 20
Address it
import { create, readUrl } from "@agntn/web";
const jina = 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.
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.