> ## Documentation Index
> Fetch the complete documentation index at: https://gateway.forceaisecurity.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Search tools

> Give agents and keys governed web search. Configure a provider once, call it at /v1/search/{name}, and grant access per key or team.

A search tool is a configured **web-search provider** that the gateway can call to fetch live results from the internet. You set up a provider once (with its API key, if it needs one), and it becomes a governed endpoint that keys and agents can use for retrieval-augmented answers. The gateway logs, budgets, and guardrails the search call like any other request

<Info>
  A search tool is something an agent or your app explicitly calls, not automatic web search bolted onto every chat completion. Sending a plain `/v1/chat/completions` request does not make the model go search the web; the agent's tool loop (or your code) has to invoke the search tool
</Info>

## Providers

Pick from the built-in list (Tools -> Search Tools -> Add New Search Tool -> Search Provider). The "Search Provider" box is a dropdown of these, not a free-text field:

```
perplexity, tavily, parallel_ai, exa_ai, brave, google_pse, dataforseo,
firecrawl, fastcrw, searxng, linkup, duckduckgo, searchapi, serper,
you_com, apiserpent, tinyfish
```

### Which are free

* **DuckDuckGo** needs no signup and no API key at all. Best for a quick test. It can rate-limit from server IPs, so results are occasionally empty, but it works
* **Tavily** (`tavily.com`) is the most reliable free option: a generous free tier, no credit card, quick signup for an API key
* **SearXNG** is keyless but you have to run or point at your own instance

For anything production-facing, use a provider with a real API key (Tavily, Brave, Serper, Perplexity, ...); ForceAI does not do the searching itself, it proxies to that provider with the key you store

## Add a search tool

<Steps>
  <Step title="Get a provider key (skip for DuckDuckGo)">
    Sign up with the provider and copy its API key. DuckDuckGo needs none
  </Step>

  <Step title="Create the tool">
    Tools -> Search Tools -> **Add New Search Tool**: give it a name (e.g. `tavily-news`), pick the provider from the dropdown, paste the key, click **Test Connection**, then **Add Search Tool**. By API:

    ```bash theme={null}
    curl -X POST http://localhost:4001/search_tools \
      -H "Authorization: Bearer $ADMIN_KEY" -H "Content-Type: application/json" \
      -d '{"search_tool": {"search_tool_name": "ddg-web", "litellm_params": {"search_provider": "duckduckgo"}}}'
    ```

    For a keyed provider add `"api_key": "..."` inside `litellm_params`
  </Step>

  <Step title="Reload the gateway">
    The data plane loads search tools from the database at startup. A tool created through the UI or control-plane API is not in the gateway's router until it reloads, so a fresh tool 500s with `not found in router.search_tools` until you restart the gateway (`docker compose restart forceai-gateway`)
  </Step>
</Steps>

<Warning>
  The gateway-reload step is easy to miss. If `POST /v1/search/{name}` returns `Search tool '{name}' not found in router.search_tools`, the tool exists in the DB but the gateway has not picked it up yet; restart the gateway
</Warning>

## Use it

Once loaded, call the tool by name:

```bash theme={null}
curl -X POST http://localhost:4000/v1/search/ddg-web \
  -H "Authorization: Bearer $FORCEAI_KEY" -H "Content-Type: application/json" \
  -d '{"query": "latest Anthropic Claude model", "max_results": 5}'
```

It returns `{"object": "search", "results": [...]}`. An agent uses a search tool the same way: its tool-calling loop (or your application code) hits `/v1/search/{name}` when it decides to search, then feeds the results back into the model. Search tools are a standalone endpoint; the model does not auto-invoke one during a plain chat completion

## Grant access

Access is a two-level allowlist, the same shape as MCP servers:

1. **Team allowlist** - open a team's Search Tool Settings and add the approved tools. That team's keys may only use tools on this list
2. **Key-level** - a virtual key can be scoped to specific search tools, and if the team has an allowlist the key's set must stay within it

This keeps the provider key central while letting your agents search without holding the credential. Spend and usage show up in **Logs**, filterable by Team ID and search tool name

## Verify end to end

DuckDuckGo, no signup, proven live:

```
POST /search_tools/test_connection {"litellm_params":{"search_provider":"duckduckgo"}}  -> success
POST /search_tools  (create "ddg-web")                                                   -> saved
docker compose restart forceai-gateway
POST /v1/search/ddg-web {"query":"openai"}             -> 5 results, 200 OK
POST /v1/search/ddg-web {"query":"python programming"} -> 22 results, 200 OK
```
