Get started
Agent mode
A built-in agent, on any model LiteLLM supports, that searches and reads with Frankensurf and answers with sources. Plus LLM extraction and summaries.
Frankensurf is built for agents, but you don’t need one to use it. In agent mode a model you choose does the searching and reading for you: ask a question, get an answer with the pages it came from, and a plain list of anything it couldn’t read.
pip install "frankensurf[agent]"export FRANKENSURF_AGENT_MODEL=openrouter/google/gemini-2.5-flash # any LiteLLM model, or pass model=export OPENROUTER_API_KEY=... # the provider's key, as LiteLLM reads itimport frankensurf as fs
answer = fs.ask("What revenue did NVIDIA report for its most recent quarter?")print(answer["answer"]) # cites [1], [2] ... with a source listprint(answer["sources"]) # the pages it read: url, title, trace_idprint(answer["couldnt_read"]) # pages no tool could read, and whyprint(answer["llm_cost_usd"]) # what the model calls cost (None if the provider doesn't say)frankensurf ask "What revenue did NVIDIA report for its most recent quarter?"The model gets two tools, Frankensurf’s search and read (pages come back as markdown), and is
told to read before it answers. If it tries to answer from search snippets alone, it’s sent back to
read the pages first. A page no tool could read reaches it as “Could not read this page (CODE)”,
with the instruction to say so instead of filling it in. Each answer lists the pages it read, so
you can check them.
Extract and summarize
Section titled “Extract and summarize”data = fs.extract(["https://example.com/pricing"], prompt="the plans and their monthly prices", schema={"type": "object", "properties": {"plans": {"type": "array"}}})data["data"] # checked against the schema; one retry with the errors if it doesn't fit
summary = fs.summarize("https://example.com/post")["summary"]frankensurf serve --model ... gives Firecrawl’s summary and json scrape formats and its
/v1/extract and /v2/extract jobs the same engine (Firecrawl-compatible API).
Options
Section titled “Options”model= (or FRANKENSURF_AGENT_MODEL), max_steps= (8 tool rounds, then a final answer),
paid= and max_cost= for Frankensurf’s own paid tools. Anything else goes to
litellm.acompletion (temperature, api_base for a local model, and so on).