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

# Quickstart — Deploy Your First Agent

> Pull a ready-made AI agent into your codebase, deploy it with one command, and have it answering a real channel in about ten minutes.

By the end of this page an agent you own, as editable TypeScript, is answering
messages on one of your channels.

<Info>
  Prefer to send messages from your own backend instead of deploying code here?
  Start with the [messaging quickstart](/quickstart-messaging).
</Info>

## 1. Install the CLI

<CodeGroup>
  ```sh npx (recommended) theme={null}
  # No install step. Always runs the current version.
  npx zavudev@latest --version
  ```

  ```sh Global install theme={null}
  npm install -g zavudev
  zavudev --version
  ```

  ```sh Standalone binary theme={null}
  # Download the binary for your platform from
  # https://github.com/zavudev/zavu-cli/releases
  # Then:
  chmod +x ./zavu-macos-arm64
  sudo mv ./zavu-macos-arm64 /usr/local/bin/zavudev
  ```
</CodeGroup>

<Tip>
  Working with a coding agent? Install the
  [skills](/tools/coding-agent-skills) first and it will know every command on
  this page, plus `defineAgent` and `defineTool`:

  ```sh theme={null}
  npx skills add zavudev/zavu-skills
  ```
</Tip>

## 2. Log in

```sh theme={null}
npx zavudev login
```

Your browser opens, you sign in, pick the project this agent will live in, and
authorize. The CLI stores the key in `~/.zavu/credentials.json` with mode
`0600`.

Confirm which project you are pointed at:

```sh theme={null}
npx zavudev whoami
```

## 3. Scaffold an agent

`agents init` is the guided path. It picks a factory agent, finds or creates the
sender it runs on, writes the files, and registers the function.

```sh theme={null}
npx zavudev agents init
```

To see what you can start from first:

```sh theme={null}
npx zavudev agents catalog
```

Seven factory agents ship today, across sales, support and front desk. Some are
voice agents that answer the phone; all of them also run on text channels.

<AccordionGroup>
  <Accordion title="Pull a specific agent">
    ```sh theme={null}
    npx zavudev agents pull fermi --sender <senderId>
    ```

    Scaffolds into `./fermi`, registers the function, and sets the `SENDER_ID`
    secret from the sender you passed. Use `--dir` to scaffold elsewhere.
  </Accordion>

  <Accordion title="Start from an empty function instead">
    ```sh theme={null}
    npx zavudev fn init
    ```

    Gives you a bare `index.ts` to write `defineAgent` yourself. The
    [Functions quickstart](/guides/functions/quickstart) walks that path in
    full.
  </Accordion>

  <Accordion title="I have no sender yet">
    An agent answers on a sender, and a sender needs at least one channel.
    The fastest channel to turn on needs no phone number and no external
    account:

    ```sh theme={null}
    npx zavudev senders create --data '{"name":"Agent","enableSmsOneway":true}'
    ```

    Recipients cannot reply on one-way SMS, so use it to verify the deploy
    works, then [add a real channel](/guides/senders/adding-channels).
    `npx zavudev agents init --buy-number` buys a number and creates the
    sender for you instead.
  </Accordion>
</AccordionGroup>

## 4. Install dependencies

```sh theme={null}
cd fermi
npm install
```

Deploy works without this, but every local check does not: `fn invoke`,
`tsc --noEmit`, and your editor all need the dev dependencies installed.

## 5. Look at what you got

The scaffold is one file, and it is the whole agent. (You can split it up later
— imports between your files are resolved on deploy.)

```ts index.ts theme={null}
import { defineAgent, defineTool } from "@zavudev/functions"

defineAgent({
  senderId: process.env.SENDER_ID!,
  name: "Fermi",
  provider: "zavu",
  model: "openai/gpt-4o-mini",
  prompt: "You are Fermi, a qualification agent...",
  channels: ["voice", "whatsapp"],
})

defineTool({
  name: "lookup_account",
  description: "Find an existing account by phone number.",
  parameters: {
    type: "object",
    properties: { phone: { type: "string" } },
    required: ["phone"],
  },
  handler: async ({ phone }) => {
    // replace with your real lookup
    return { found: false }
  },
})
```

<Tip>
  `provider: "zavu"` is our managed AI gateway. No API key of your own required;
  model usage is billed from your Zavu balance. Bring your own key by setting
  `provider` to `openai`, `anthropic`, `google` or `mistral`.
</Tip>

Any secret the agent needs beyond `SENDER_ID` is listed by `agents pull` when it
finishes. Set each one before deploying:

```sh theme={null}
npx zavudev fn secrets set CALENDAR_WEBHOOK_URL "https://..."
```

## 6. Try a tool without deploying

```sh theme={null}
npx zavudev fn invoke --tool lookup_account --args '{"phone":"+14155551234"}'
```

This runs the handler on your machine, with no cloud round-trip and nothing
charged. Use it to get the business logic right before anyone can talk to the
agent.

## 7. Deploy

```sh theme={null}
npx zavudev deploy
```

```
› status: bundling
› status: uploading
› status: publishing
› status: active
✓ Deployed in 14s
  Agents synced:
    + Fermi
  Tools synced:
    + lookup_account
```

<Warning>
  Read the lines **above** the checkmark. Deploy prints its warnings before the
  success line, and they cover the cases where a green deploy did not do what it
  looks like: tools attached to an agent whose channels will never call them, or
  a second agent landing on a sender that already has one.
</Warning>

Your code is now the source of truth. Every deploy reconciles the live agent to
match the file, so a `defineAgent` you delete deletes the agent.

## 8. Talk to it

Message the sender's number from your phone, or call it if the agent has voice
enabled. To check the reply without touching a real channel:

```sh theme={null}
npx zavudev agents test --sender "$SENDER_ID" --message "what do you do?"
```

<Note>
  A dry run never executes tools, because a test must not cause real side
  effects. It tells you so in its warnings. Live conversations on every channel
  do call them.
</Note>

## 9. Watch it run

```sh theme={null}
# What the agent did: tools called, tokens, cost, latency
npx zavudev agents executions --sender "$SENDER_ID"
```

```sh theme={null}
# Your handlers' console output, live
npx zavudev fn logs --tail
```

```sh theme={null}
# Every message in and out
npx zavudev messages list --limit 10
```

## Next steps

<CardGroup cols={2}>
  <Card title="How agents work" icon="sitemap" href="/concepts/agent-architecture">
    What a deploy actually does, and what happens when a message arrives
  </Card>

  <Card title="Defining agents" icon="robot" href="/guides/functions/defining-agents">
    Every field of `defineAgent`, including voice
  </Card>

  <Card title="Defining tools" icon="tool" href="/guides/functions/defining-tools">
    Give the agent access to your systems
  </Card>

  <Card title="Knowledge bases" icon="book" href="/guides/ai-agents/knowledge-base">
    Ground the answers in your own documents
  </Card>

  <Card title="Voice agents" icon="phone" href="/guides/voice-agents/overview">
    Answer and place phone calls with the same agent
  </Card>

  <Card title="Bring your framework" icon="arrows-exchange" href="/guides/frameworks/overview">
    Deploy an eve project without restructuring it
  </Card>
</CardGroup>
