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

# Pipecat

> KeenableWebSearch — low-latency web search for Pipecat voice agents.

*Voice-agent service*

`KeenableWebSearch` gives Pipecat voice agents web search and page fetch as function-call tools, tuned for the latency budget of a spoken conversation. It ships in Pipecat itself — a thin wrapper over `MCPClient` pointed at the hosted Keenable MCP server, so the tools register themselves on the LLM context.

→ [View the change on GitHub](https://github.com/pipecat-ai/pipecat/pull/4942)

## Install

### Install the extra

```bash theme={"dark"}
pip install "pipecat-ai[keenable]"
```

<Note>
  `KeenableWebSearch` is merged upstream and ships in Pipecat **1.8.0**, which is not released yet. Until it is, install from `main`:

  ```bash theme={"dark"}
  pip install "pipecat-ai[keenable] @ git+https://github.com/pipecat-ai/pipecat"
  ```
</Note>

### Add it to the context

```python theme={"dark"}
from pipecat.processors.aggregators.llm_context import LLMContext
from pipecat.services.keenable.search import KeenableWebSearch


async def run_bot(transport):
    search = KeenableWebSearch()
    context = LLMContext(messages=[...], tools=await search.tools())
    ...
```

`tools()` is a coroutine, so it belongs inside the async entry point your bot already runs in. It connects on first use and returns the tool schemas with their handlers attached, so the LLM auto-registers `search_web_pages` and `fetch_page_content`. The connection closes at pipeline teardown — call `close()` only to release it earlier.

### Pick a search mode

Keyless calls run in `pro` mode. Pass an API key to raise the limits and unlock `realtime`, the lower-latency mode built for voice:

```python theme={"dark"}
search = KeenableWebSearch(api_key="keen_<your_key>", mode="realtime")
```

The mode is pinned per call and hidden from the model. With a key and no `mode`, `realtime` is the default — so if your account is not entitled to it, pass `mode="pro"` explicitly, or every search fails.

<Note>
  Set an `api_key` to authenticate — this removes the hourly request cap. Without a key, calls run on the shared public tier at [lower rate limits](/rate-limits).
</Note>

→ [Full example in the Pipecat repo](https://github.com/pipecat-ai/pipecat/blob/main/examples/features/features-keenable-web-search.py)
