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

# Agent tools

> The lookup and search tools generated from your columns, and how to give them to an agent.

Open a table and go to **Agent tools**. Everything there is generated from the columns you declared — nothing is hand-written, and nothing is editable.

Copy a tool and paste it into an agent's `tools` array. **A table no agent references is not reachable by any agent**, so this step is the whole handoff.

## What gets generated

### The lookup tool

`lookup_<table>` fetches one row by its key.

```json theme={null}
{
  "name": "lookup_plans",
  "description": "Look up a single plans record by its plan_id.",
  "properties": {
    "plan_id": { "type": "string", "description": "The plan id of the record" }
  },
  "required": ["plan_id"]
}
```

The parameter is named after your key column — `plan_id`, not `row_key` — so the model sees something meaningful.

### The search tool

`search_<table>` filters, sorts and returns several rows. It gets one parameter per declared column, plus `_min`/`_max` bounds for numbers and dates, plus a `limit`.

```json theme={null}
{
  "name": "search_plans",
  "properties": {
    "name":              { "type": "string" },
    "region":            { "type": "string", "enum": ["EU", "US", "APAC"] },
    "monthly_price_min": { "type": "number" },
    "monthly_price_max": { "type": "number" },
    "available":         { "type": "boolean" },
    "limit":             { "type": "integer" }
  }
}
```

**Every filter is optional.** The model fills in what the caller mentioned; the rest disappear. Asking for one constraint gives a one-constraint search, not a search with a handful of empty equalities that match nothing.

Your **descriptions** and **allowed values** come through onto the parameters, which is why filling them in on the schema matters — that text is what the model reads when deciding how to call the tool.

### Stored query tools

Any [stored query](/custom-data/stored-queries) that is validated and switched on also appears here, as its own tool. Same tab, because this page is meant to be the complete answer to *"what can an agent do with this table?"*.

Queries that are drafts, broken, or need revalidating do **not** appear — handing an agent a tool that fails mid-call is worse than not having it.

## Giving them to an agent

Copy one tool, or **Copy all**, and paste into the agent's tool configuration. They're ordinary tools — they work on voice, chat and email agents alike.

<Note>
  Tools are copied, not linked. Editing the table's schema later does **not** change any agent that already has them. That's deliberate: nothing silently alters a live agent's abilities. When you want an agent to pick up a schema change, come back here and copy the regenerated tool.
</Note>

## Writing the prompt around them

The tools describe *what* they do. Your prompt decides *when*.

```
When a caller asks about pricing, use search_plans with their region.
Never quote a plan where available is false.
If they give a plan code, use lookup_plans instead — it's exact.
```

Worth saying explicitly in the prompt:

* **Which tool for which question.** Models reach for search when lookup is exact and cheaper.
* **What not to say.** Rows an agent can read but shouldn't quote — internal margin, a discontinued flag.
* **What to do when nothing matches.** An empty result is a normal answer, and without guidance a model may invent something.

## When a lookup returns nothing

An agent gets a structured answer, not an error:

```json theme={null}
{ "found": false, "reason": "no record matching 'pro-eu'" }
```

That's on purpose. An agent mid-call can recover from *"no matching records"* and cannot recover from a tool that threw. The same applies if the lookup couldn't complete — the agent is told the lookup isn't available right now rather than the turn ending.

## Testing

The **Rows** tab has the same filters the search tool uses. If a filter returns what you expect there, the agent's tool returns the same thing — it's the same query underneath.

Then test with the agent itself: ask the question a caller would ask, in the words a caller would use, and check it picks the right tool. Most failures at this stage are prompt or description problems, not data problems.
