New to Exa? Try the Coding Agent Quickstart
to get started in under a minute.
Claude’s tool use allows models to call functions that you define in your code. The Exa SDKs ship ready-made web search and page reading tools for Anthropic, so you don’t have to hand-write the tool schema, parse
tool_use blocks, or format Exa results yourself.
Get started
1
Install the SDKs
2
Set up your API keys
Set the
EXA_API_KEY and ANTHROPIC_API_KEY environment variables. Visit the Anthropic console and the Exa dashboard to generate your API keys.Get your Exa API key
3
Add the Exa tools to your tool loop
Pass the tools in the request’s This is one round for brevity. A real agent keeps
tools list, then hand the assistant message to handle_tool_use. It executes every tool_use block in the message and returns the matching tool_result blocks, ready to send back in the next user message.web_search searches the web for pages the model hasn’t seen; get_contents reads pages it already has URLs for, whether from an earlier search or from the user. Register either or both.tools on every request and repeats the handler step until the model replies without tool_use blocks — that’s how a search result turns into a follow-up page read.Calling the factories with no arguments gives Exa’s recommended defaults: type="auto" with contents={"highlights": True} for search, and page text capped at 10,000 characters for contents.Configuring the tools
Keyword arguments are regular Exa options, passed through when the tool runs — search options toexa.search(), contents options to exa.get_contents():
query and the urls to read; everything else is bound when you create the tool, so it can’t change what gets crawled or extracted.
name (defaulting to "web_search" and "get_contents") and description instead override the tool definition the model sees. Anthropic requires tool names to be unique, so a custom name lets the Exa tool run alongside Anthropic’s built-in web_search_20250305 server tool, which reserves the web_search name:
Mixing in your own tools
handle_tool_use answers every tool_use block in the message: a block naming a tool it can’t resolve gets an Error: unknown tool "<name>" result instead of being dropped, so the follow-up request never omits a required tool result. If you run your own tools alongside Exa’s, replace those error results with your own before the next request.
Writing the loop by hand
If you’d rather own the tool schema and execution yourself, define the tool and process thetool_use blocks manually. exa.tools.web_search() and exa.tools.get_contents() give you the same provider-neutral tool specs (with a run method) for hand-rolled loops, or you can write everything from scratch:
Python