[FEATURE] Add a SearchApi (searchapi.io) search tool
Nobody has claimed this yet.
- Dominant language
- Python
- Stars
- 58.8k
- Forks
- 8.5k
- Avg merge
- 1d 15h
- Merged PRs (30d)
- 109
Description
AI disclosure: this issue and the PR that follows it were authored with an AI coding assistant (Claude Code). Per CONTRIBUTING the
llm-generatedlabel applies; as an outside contributor I cannot set labels myself, so please apply it.
Feature Area
Integration with external tools
Is your feature request related to a an existing bug? Please link it here.
NA
Describe the solution you'd like
crewai-tools ships tools for Serper, SerpApi, Brave, Tavily, Exa, LinkUp and Oxylabs, but nothing for SearchApi.
SearchApi is a little different from the rest: one endpoint (GET https://www.searchapi.io/api/v1/search) fronts many engines, chosen with an engine parameter. So a single tool covers Google web search, news, scholar, jobs and shopping, plus Bing, YouTube, Baidu, DuckDuckGo and the rest of their engine list, instead of one tool per surface. Today a CrewAI user who has a SearchApi key has to write a custom BaseTool for it.
Proposed: a SearchApiTool next to the other search tools, taking SEARCHAPI_API_KEY, defaulting to engine="google", and returning the engine's own JSON so the response lines up with SearchApi's documentation.
Two details worth building in rather than leaving to each user:
- Do not put the key in the query string. SearchApi accepts
api_keyas a query parameter, but it also acceptsAuthorization: Bearer. The header keeps the key out of request logs and out of therequest_urlthat SearchApi echoes back insidesearch_metadata. - Strip inline
data:URIs before the response reaches an agent. SearchApi returns favicons and thumbnails as base64 strings on most result items, and a single one can run to tens of kilobytes of context that means nothing to the model. Long strings and result-list lengths are worth capping for the same reason.
One thing to get right: a successful search that found nothing comes back as HTTP 200 with an error message such as "Google didn't return any results." (documented in their OpenAPI spec as part of the 200 SearchResponse, alongside dmca_messages). That is a no-results signal, not a transport failure, so it should be passed through to the agent rather than raised.
Describe alternatives you've considered
- Using
SerperDevToolorSerpApiGoogleSearchToolinstead. They work, but they are separate accounts and separate keys; this does not help a team already paying for SearchApi. - Writing a custom
BaseToolper project. That is what people do now, and it means each of them re-solves the base64 stripping and the empty-page case, usually by not solving them.
Additional context
I have an implementation ready and would like to open a PR against this issue: the tool, 14 unit tests, a tool README, and docs pages for en, ar, ko and pt-BR with the docs.json navigation entries. ruff, ruff format and strict mypy are clean, and tool.specs.json is regenerated.
Willingness to Contribute
Yes, I'd be happy to submit a pull request
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Start by reviewing the existing Serper, SerpApi, Brave, Tavily, Exa, LinkUp and Oxylabs search tools, then compare their patterns with SearchApi's documented search endpoint and engine parameter. Done means adding the SearchApiTool, 14 unit tests, the tool README, docs pages for en, ar, ko and pt-BR with docs.json navigation entries, and regenerated tool.specs.json while keeping ruff, formatting and strict mypy clean.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- python
- Domain
- api, tooling
- Issue type
- Feature
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Active
- Clarity
- Mostly clear
- Newbie friendliness
- 63/100