DR Tulu
Run DR Tulu's web search and page reading on SpecStream by changing one address in each of two files. Your Serper and Jina keys become one SpecStream key, and the model, prompts and tool parser stay as they are.
SpecStream for DR TuluAgent frameworks & buildersWhat you need
- DR Tulu's
agentlibrary installed from its repository withuv pip install -e ., as the README shows, so the files you edit are the ones Python runs. A copy installed from PyPI sits in site-packages and these steps do not change it. - A SpecStream key. Get your key on the Search API screen of your SpecStream workspace. New accounts start with $10 of credit, no card.
- 1
1. Point the Serper search at SpecStream
DR Tulu has no setting for its search address.
search_serperinagent/dr_agent/mcp_backend/apis/serper_apis.pyposts every search tohttps://google.serper.dev/search. From theagentdirectory, change that address to SpecStream's Serper route. On macOS, writesed -i ''in place ofsed -i.Shell, in dr-tulu/agent - 2
2. Point the Jina Reader browsing at SpecStream
fetch_webpage_content_jinainagent/dr_agent/mcp_backend/apis/jina_apis.pyreads a page by callinghttps://r.jina.ai/followed by the page's address. Change the prefix to SpecStream's Jina Reader route. The page's address stays on the end, as before.Shell, in dr-tulu/agent - 3
3. Put your SpecStream key in both variables
In
agent/.env, the file you copied from.env.example, setSERPER_API_KEYandJINA_API_KEYto your SpecStream key. DR Tulu sends the first in theX-API-KEYheader and the second as a Bearer token, and those are the places SpecStream reads the key on each route. Keep.envout of anything you commit.Leave
S2_API_KEYas it is. With the defaultsearch_tool_nameofserper, both of the agent's search tools,snippet_searchandgoogle_search, go through Serper.agent/.env - 4
4. Restart the MCP backend without its cache
The MCP backend reads both files when it starts, so stop a backend that is running and start it again. DR Tulu keeps API replies on disk for 10 days, so a question you asked before would come back from that cache. Start the backend with
--no-cachewhile you check the change.Shell, in dr-tulu/agent - 5
5. Ask DR Tulu
Start the workflow as the README does. It finds the backend on port 8000 and uses it. Ask about something from this week, and the answer cites pages read through SpecStream. Each call is in your account's request log with its route as the endpoint.
Shell, in dr-tulu/agent
What changes and what stays
Each SpecStream route answers in the shape DR Tulu already parses. The Serper route returns organic[] with title, link, snippet and position, and SerperSearchTool reads title, link and snippet. The Jina Reader route, asked with Accept: application/json as DR Tulu asks, returns data.title, data.url and data.content, and JinaBrowseTool passes content to the model. DR Tulu still sends gl, hl and num, and SpecStream reads them.
Keep browse_tool_name: "jina", as the shipped auto_search_sft.yaml sets it. The serper browse tool calls https://scrape.serper.dev, and the Scholar tool calls https://google.serper.dev/scholar. The two sed lines leave both addresses as they were, and the default workflow calls neither.
Evaluation runs
The repository's evaluation scripts run workflows/auto_search_sft.py with search_tool_name=serper and browse_tool_name=jina in --config-overrides. They reach the same two functions, so a benchmark run searches and reads through SpecStream with no other change. If several machines share one checkout, apply the two lines once in that checkout, and set the key in the environment each backend starts from.
What each call costs
- A search is one Search API call through a drop-in address: $1 per 1,000 searches of up to 10 results. The shipped config asks for 10 results (
number_documents_to_search: 10), so each search stays at that price. A search that returns no results costs nothing. - A page read is one Extract API page at $0.80 per 1,000 pages. A page that gives no text is not charged.
- The shipped config allows the agent 10 tool calls a question (
search_agent_max_tool_calls: 10), so one question costs at most 10 searches or page reads. - Calls come out of your balance with no quote and no approval, and every call, charged or not, is in your request log.
Why run DR Tulu on SpecStream
DR Tulu's README sends you to two services for two keys, one for search and one for reading pages. On SpecStream one key and one balance pay for both, and the request log shows every search and every page a run made, which helps when you compare runs.
SpecStream's search API scores 97.9 F-score on all 1,000 SimpleQA Verified questions and 64.0 item F1 on all 200 WideSearch tasks. Scores and method are on the benchmarks page.
Limits and errors
- When the account has used its calls for the minute, SpecStream answers
429withRetry-After, and nothing is charged. DR Tulu does not retry: the tool fails with an error that starts withAPI request failed with status 429. API request failed with status 401means the key is missing or wrong. CheckSERPER_API_KEYandJINA_API_KEYin the environment the backend starts from.- An old answer after the change means the backend served it from its cache. Restart it with
--no-cache.
Go back
Run git checkout -- dr_agent/mcp_backend/apis/serper_apis.py dr_agent/mcp_backend/apis/jina_apis.py in the agent directory, put your Serper and Jina keys back in .env, and restart the backend. Questions: [email protected].
More
SpecStream for DR Tulu covers what it does in DR Tulu on one page. Every other tool has its guide in Connect your tools. You see the most a request can cost before it starts, and the matches are paid from your balance. Billing has the details. For help, email [email protected].