> ## 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.

# Agno

> KeenableTools, a web search and page-reading toolkit built into Agno, with no API key required.

*Toolkit in Agno*

`KeenableTools` gives Agno agents Keenable web search and page reading. It ships in [Agno](https://github.com/agno-agi/agno) itself, so there is nothing extra to install, and it runs without an API key.

→ [KeenableTools in the Agno repository](https://github.com/agno-agi/agno/blob/main/libs/agno/agno/tools/keenable.py)

## Install

```bash theme={"system"}
pip install -U "agno>=3.1.5" openai
```

`KeenableTools` ships in Agno 3.1.5 and later.

The examples use Agno's default OpenAI model, so set `OPENAI_API_KEY`, or pass any other model to `Agent(model=...)`.

## Give it to an agent

```python theme={"system"}
from agno.agent import Agent
from agno.tools.keenable import KeenableTools

agent = Agent(tools=[KeenableTools()], markdown=True)
agent.print_response("What changed in the latest Python release?")
```

`KeenableTools()` registers `web_search`. Each result comes back with its title, URL and the first 500 characters of the page text, as markdown, or as JSON with `format="json"`.

## Search and read pages

```python theme={"system"}
agent = Agent(tools=[KeenableTools(all=True)], markdown=True)
agent.print_response("Find the Agno docs page on toolkits and summarize it, with the link")
```

`all=True` adds `fetch_url_content`, which returns a page's main content as markdown under its title. Private and internal addresses are refused. Async variants are registered under the same names, so `agent.arun()` and `agent.aprint_response()` work unchanged.

## Options

| Parameter | Default | What it does |
| - | - | - |
| `api_key` | `None` | Keenable API key. Falls back to `KEENABLE_API_KEY`; with neither, the keyless public endpoints are used. |
| `enable_search` | `True` | Register `web_search`. |
| `enable_fetch` | `False` | Register `fetch_url_content`. |
| `all` | `False` | Register both. |
| `max_results` | `5` | Default number of search results. The agent can ask for a different number per call. |
| `max_snippet_chars` | `500` | Page text kept per result. `0` keeps it all. |
| `format` | `"markdown"` | `"markdown"` or `"json"` for search results. |
| `timeout` | `30` | Request timeout in seconds. |

> [!NOTE]
>
> Without a key, calls run on the shared public tier at [lower rate limits](/rate-limits). Set `KEENABLE_API_KEY`, or pass `KeenableTools(api_key=...)`, to use your organization's limits and remove the hourly cap.


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.