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

> ## Agent Instructions
> The Exa API is served at https://api.exa.ai. Authenticate with `Authorization: Bearer $EXA_API_KEY` (or `x-api-key: $EXA_API_KEY`); create keys at https://dashboard.exa.ai/api-keys.
> Prefer the official SDKs, `exa-py` (`pip install exa-py`) and `exa-js` (`npm install exa-js`); both read `EXA_API_KEY` from the environment.
> Tool-using agents can call Exa without writing code through the hosted MCP server at https://mcp.exa.ai/mcp, or install the Exa agent skill with `npx skills add exa-labs/agent-skills` (skill file: https://exa.ai/docs/skill.md).
> The OpenAPI specs at https://exa.ai/docs/exa-spec.yaml and https://exa.ai/docs/team-management-spec.yaml are the source of truth for request and response schemas.

# AG2

> Give AG2 agents Exa search, contents, and answer tools with the built-in ExaToolkit.

[AG2](https://github.com/ag2ai/ag2) is an open-source framework for building agents and multi-agent applications. It ships `ExaToolkit`, built on the [Exa Python SDK](https://github.com/exa-labs/exa-py): pass it to an agent and the model can search the web, find similar pages, read page contents, and get cited answers through Exa. Calls run on your own Exa API key.

## Install

Install AG2 with your model provider's extra and the Exa Python SDK. Swap `openai` for your provider, such as `anthropic` or `gemini`.

```bash theme={null}
pip install "ag2[openai]" "exa-py>=2.12.1,<3"
```

Set `EXA_API_KEY` in your environment, or pass `api_key` to `ExaToolkit`.

<Card title="Get your Exa API key" icon="key" horizontal href="https://dashboard.exa.ai/api-keys">
  Create a key in the dashboard. New accounts start with free credits.
</Card>

## Add Exa to an agent

Passing the toolkit to an `Agent` registers all four Exa tools, and the model decides when to call them.

```python Python theme={null}
import asyncio

from ag2 import Agent
from ag2.config import OpenAIConfig
from ag2.extensions.tools.search import ExaToolkit

agent = Agent(
    "researcher",
    config=OpenAIConfig(model="gpt-5-mini"),
    tools=[ExaToolkit()],
)

async def main():
    reply = await agent.ask("What changed in the latest stable Python release?")
    print(await reply.content())

asyncio.run(main())
```

| Tool | What the model gets |
| - | - |
| `exa_search` | [Exa search](/docs/search/quickstart): ranked results with titles, URLs, and page text for a query |
| `exa_find_similar` | Pages similar to a URL the model already has |
| `exa_get_contents` | [Full page contents](/docs/contents/quickstart) for specific URLs |
| `exa_answer` | An answer to a question with cited sources |

## Configure the tools

`num_results` and `max_characters` on the constructor set defaults for `exa_search` and `exa_find_similar`. Each tool is also a factory method on the toolkit (`search()`, `find_similar()`, `get_contents()`, `answer()`), so you can give an agent only the tools it needs and bind filters per agent:

```python Python theme={null}
toolkit = ExaToolkit(num_results=10, max_characters=2000)

agent = Agent(
    "researcher",
    config=OpenAIConfig(model="gpt-5-mini"),
    tools=[
        toolkit.search(
            category="research paper",
            include_domains=["arxiv.org"],
            start_published_date="2025-01-01",
        ),
        toolkit.answer(),
    ],
)
```

| `search()` parameter | Use it to |
| - | - |
| `num_results` | Cap results per search |
| `max_characters` | Cap page text per result |
| `search_type` | Pick an Exa [search type](/docs/search/quickstart), such as `auto` or `deep` |
| `category` | Focus on a category: `company`, `research paper`, `news`, `pdf`, `personal site`, `financial report`, or `people` |
| `include_domains`, `exclude_domains` | Filter result domains |
| `start_published_date`, `end_published_date` | Filter by publish date |
| `start_crawl_date`, `end_crawl_date` | Filter by crawl date |
| `livecrawl` | Control fresh crawling: `never`, `fallback`, `always`, or `preferred` |

`find_similar()` takes `num_results`, `include_domains`, `exclude_domains`, `category`, and `exclude_source_domain`. Every parameter also accepts an AG2 `Variable`, resolved from the agent's context at call time.

## Resources

<Columns cols={2}>
  <Card title="AG2 Exa docs" icon="book-open" href="https://docs.ag2.ai/docs/user-guide/extensions/tools/search/exa/" cta="Open docs" arrow="true">
    AG2's reference for `ExaToolkit` and its factory methods.
  </Card>

  <Card title="AG2 on GitHub" icon="git-branch" href="https://github.com/ag2ai/ag2" cta="View source" arrow="true">
    View the framework source and the `ExaToolkit` implementation.
  </Card>
</Columns>
