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

# Tool library

> Skills Zavu hosts and runs, with no webhook to build

A [webhook tool](/guides/ai-agents/tools) is powerful and it is also an
afternoon of work: an endpoint to write, somewhere to host it, a secret to
verify. That work sits between "I made an agent" and "my agent booked a
meeting", and it is where most people stop.

Library skills have no webhook. Zavu runs them. You add one from the agent's
**Tools** tab and it works on a phone call and in a thread, with the same
behaviour on both.

## What is available

| Skill                | What it does                                  | Needs      |
| -------------------- | --------------------------------------------- | ---------- |
| `check_availability` | Reads open slots from your connected calendar | A calendar |
| `book_meeting`       | Books a slot and sends the invitation         | A calendar |

<Note>
  Library skills are added from the dashboard. The REST API and the CLI manage
  webhook tools, which is what `zavu agents tools list` shows.
</Note>

## Connect a calendar

Both booking skills read one calendar per project. Open the agent's **Tools**
tab, then **Library**, then **Connect one** on either skill.

### Cal.com

You need two things from Cal.com:

* an **API key** — Settings, then Developer, then API keys
* the **event type id** — the number in the event type's own URL

Cal.com keeps its own availability rules, buffers and limits. Zavu asks it for
open slots and books them; it never second-guesses them.

### Google Calendar

Connecting is an OAuth grant. Zavu asks for two scopes: read your busy times,
and write the events the agent books. Nothing else.

Your working window is yours to set, because Google has no concept of one: the
agent will only offer times inside the days and hours you configure.

<Warning>
  Times are resolved in the time zone on the connection, and the agent always says
  the zone out loud. Set it to the business's zone, not yours, if they differ.
</Warning>

## What the agent does with them

`check_availability` returns open slots and the zone they are in. `book_meeting`
takes one of those slots plus a name and an email.

The important part is what happens when a booking is not accepted. A Cal.com
event type that requires confirmation answers `pending`, which is **not** a
booking. The skill tells the agent exactly that, and the agent says the time is
held but not confirmed. An agent that reports `pending` as booked sends someone
to a meeting that may never exist, which is the worst outcome available on that
call.

The same rule covers the rest: no calendar connected, a slot in the past, a
calendar that cannot be reached. Each one comes back as something the agent can
say, never as a silent success.

## Draft a custom tool from a description

For anything the library does not cover you still write a webhook, but you do
not have to write the schema. In **Tools**, **Custom tool**, describe what it
should do:

```
Look up an order by its number and return the status and delivery date
```

You get a name, a description written for the model, and a parameter schema, all
filled into the form for you to review before saving. Whatever it changed to
make the definition valid is listed underneath: a renamed parameter, a nested
object flattened to text, a required field dropped because it was not declared.

It does not invent the endpoint. Where the tool sends its arguments is the one
thing only you know, and a guessed URL produces a tool that looks finished and
does nothing.

## Where to go next

<CardGroup cols={2}>
  <Card title="Webhook tools" icon="webhook" href="/guides/ai-agents/tools">
    Build a tool against your own endpoint.
  </Card>

  <Card title="Voice agents" icon="phone" href="/guides/voice-agents/overview">
    Where skills matter most, because the caller is waiting.
  </Card>
</CardGroup>
