Stirrup
Stirrup's built-in web_search calls the Brave Search API and needs BRAVE_API_KEY. Pass a SpecStream Tool in the Agent's tools argument and the same web_search name runs on the SpecStream Search API instead: one Python file, no fork, and a direct answer with its page on top of the results.
What you need
- Python and Stirrup 0.2.1 or later (
pip install stirrup). The MCP option below also needspip install 'stirrup[mcp]' 'mcp<2'. - A SpecStream account. New accounts get $10 of credit on sign-up, no card. Create one.
- 1
1. Create an API key
In your SpecStream workspace, open Agents & API, go to the API keys tab, and click Create API key. Keep the permissions that are already on, including Authorize paid work, and click Set a total limit to cap what this key can spend. Copy the key from the next screen. SpecStream shows it once.
Set it in the environment where the agent runs. Leave
BRAVE_API_KEYunset: without it, Stirrup'sWebToolProviderreturns only its page fetch tool, so the SpecStream tool is the one namedweb_search.Terminal - 2
2. Define the SpecStream search tool
A Stirrup
Toolis a name, a description, a Pydantic parameters model and an executor, and the executor can be async. This one sends the query toPOST https://api.specstream.ai/v1/web-searchand returns XML in the same form as Stirrup's Brave tool: one<result>with<title>,<url>and<description>for each page. When SpecStream finds one answer to the question, an<answer>with the value and the page that prints it comes first.Stirrup already depends on
httpxandpydantic, so the file needs nothing new installed:specstream_tools.py - 3
3. Pass it in the Agent's tools argument
default_tools()isLocalCodeExecToolProvider()andWebToolProvider(). List those two yourself and addWEB_SEARCH_TOOL. The agent keepscode_execandfetch_web_page, and itsweb_searchcalls now go to SpecStream:agent.py - 4
4. Run it
Run
python agent.py. Themetadatathatsession.runreturns counts theweb_searchcalls under that name, as it did with Brave. Every charged call is kept in your account's search history, with its query, answer and price.
What changes from Brave
Stirrup's own tool asks Brave for 5 results and returns each one's title, URL and description. The SpecStream tool returns its results in the same tags, and adds the answer and the page it was read from when the question has one. Search operators in the query hold on every result: site:, -site:, -word, "phrase", filetype:, and after: or before: with a date. A query in another language is searched in that language.
The 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 Benchmarks.
Read pages with the Extract API
Stirrup's fetch_web_page reads a page from your own machine with one plain request. To read pages through SpecStream instead, add this tool to specstream_tools.py. It sends up to 20 URLs to POST https://api.specstream.ai/v1/extract and returns each page's main text as markdown. A page that refuses a plain read is tried as a browser would ask for it, then in a real browser, then from the site's own feed, then from its newest public archive capture. PDF, Word and Excel files come back as text too.
Use both tools without WebToolProvider
With the Extract API reading pages, leave WebToolProvider out:
Or connect the SpecStream MCP server
Install the extra with pip install 'stirrup[mcp]' 'mcp<2'. Stirrup 0.2.1 imports streamablehttp_client, which the 2.x releases of the mcp package no longer have, so stirrup.tools.mcp fails to import on them. MCPToolProvider connects to a remote server over Streamable HTTP when the config has a url. Build the config in code so the key comes from the environment. Each tool is named after the server, so the agent gets specstream__search_web, specstream__read_pages, and the Deep Search tools that return every match on the live web as structured rows.
Deep Search quotes the most a request can cost, and nothing runs until that maximum is approved. Add USER_INPUT_TOOL so the agent asks you before it approves one:
Cost
Each web_search call is one Search API call at $5 per 1,000 searches of up to 10 results. Each page read is one Extract API page at $0.80 per 1,000 pages, and a page with no text is not charged. Both come out of your balance with no quote and no approval, and a call that returns nothing costs nothing. New accounts start with $10 of credit, no card. To search at a fifth of the price, add "speed": "fast" to the JSON body: the results come back without the answer. Get your key on the Search API screen of your workspace, and read Balance, quotes, and billing for the details.
When a call fails
401: no key was sent, or the key is unknown, expired or revoked. CheckSPECSTREAM_API_KEY.402: the balance is empty, or the call would pass the account's monthly limit.403: the call would pass the key's spending limit, or the key cannot spend. Raise the limit under Agents & API.503withRetry-After: wait that many seconds and send it again. Nothing is charged.- The tool returns the error body with
success=False, so the agent sees the reason and can try again.
Remove
Take WEB_SEARCH_TOOL out of tools, or go back to tools=default_tools(), and set BRAVE_API_KEY again. To stop the key everywhere, delete it under Agents & API. Other tools to connect are in Connect your tools. Questions go to [email protected].
More
SpecStream for Stirrup covers what it does in Stirrup 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].