AgentOwl
Getting Started

Getting Started

Set up AgentOwl from scratch — install the CLI, authenticate, create tenants, bind channels, and route inbound messages.

This guide walks you through setting up AgentOwl from scratch — installing the CLI, authenticating, creating your first tenant, provisioning communication channels, and routing inbound messages to your application.

Prerequisites

  • Node.js 18+ (ES module support required)
  • npm (included with Node.js)
  • A running AgentOwl Worker instance (local or deployed)

For local development, you also need:

  • Wrangler CLI (npm install -g wrangler) for running the Cloudflare Worker locally
  • Provider credentials (Telnyx API key, Cloudflare API token) if you want to test real inbound messages

1. Install the CLI

From source (development)

git clone <repo-url> && cd agentowl-dev
npm install
npm run build

# Link the CLI globally
cd packages/cli
npm link

After linking, the agentowl command is available globally.

Run without installing

cd packages/cli
npm run dev -- <command> [args]

Verify installation

agentowl --version
# 0.1.0

2. Start the Worker locally

cd packages/worker
cp .dev.vars.example .dev.vars

Edit .dev.vars with your provider credentials:

TELNYX_PUBLIC_KEY=<your-telnyx-public-key>
TELNYX_API_KEY=<your-telnyx-api-key>
CLOUDFLARE_API_TOKEN=<your-cloudflare-api-token>
CLOUDFLARE_ACCOUNT_ID=<your-cloudflare-account-id>
AGENTOWL_INGRESS_BASE_URL=http://localhost:8787

Start the local development server:

npm run dev
# Worker running at http://localhost:8787

The Worker automatically creates the D1 database and applies migrations on first run.

3. Authenticate

You need a bearer token to interact with the API. In a production deployment, tokens are provisioned by a platform admin. For local development, you can create one directly in KV.

Option A: CLI login

agentowl login --url http://localhost:8787
# Opens the browser/device-code flow and saves config to ~/.agentowl/config.json

This opens the browser authorization flow by default. Use --token only for CI or pre-issued credentials.

Option B: Direct token

agentowl login --token <your-bearer-token> --url http://localhost:8787

Option C: Environment variables

mkdir -p ~/.agentowl
cat > ~/.agentowl/config.json <<'EOF'
{
  "token": "<your-bearer-token>",
  "api_url": "http://localhost:8787"
}
EOF
chmod 600 ~/.agentowl/config.json

Verify connectivity

agentowl version

If the server is reachable, this prints both the CLI and server versions.

4. Create a tenant

Tenants are the top-level isolation boundary. Every binding, endpoint, route, and policy belongs to exactly one tenant. Any authenticated user can create a tenant.

agentowl tenant create acme --display-name "Acme Corp"

Or sign in at admin.agentowl.dev. If you do not have a tenant yet, onboarding will create your first workspace and drop you into the guided dashboard flow.

Output:

tenant_id      t_abc123...
slug           acme
display_name   Acme Corp
status         active
created_at     2026-03-24T12:00:00Z

Preview without creating:

agentowl tenant create acme --display-name "Acme Corp" --dry-run

List all tenants:

agentowl tenant list

5. Create an endpoint

An endpoint is where inbound messages are delivered. The most common type is a webhook — a URL in your application that receives POST requests with the normalized event payload.

agentowl endpoint create webhook my-webhook https://app.acme.com/hooks/inbound \
  --tenant acme

Other endpoint types: agent-runtime, queue, sip, email-forward, hosted-page, dead-letter.

List endpoints:

agentowl endpoint list --tenant acme

6. Bind a communication channel

Bindings connect a communication identity (email address, phone number) to a tenant. Once bound and provisioned, inbound messages to that identity flow through AgentOwl.

Bind an email address

agentowl email bind acme support@acme.com

Bind a domain (catch-all)

agentowl email domain add acme acme.com

This creates a binding for *@acme.com.

Bind an SMS number

agentowl messaging bind acme --number +15551234567 --capability sms

Auto-assign an SMS number

agentowl messaging bind acme --capability sms voice

When no --number is specified, AgentOwl requests an auto-assigned number from the provider.

Import an existing phone number

agentowl messaging import-number acme +15559876543 --capability sms voice

List all bindings for a tenant:

agentowl email inspect <binding_id>
agentowl messaging inspect <binding_id>

7. Create a route

Routes connect bindings to endpoints. When an inbound message arrives on a binding, the route determines which endpoint receives it.

agentowl route create \
  --tenant acme \
  --binding <binding_id> \
  --endpoint <endpoint_id> \
  --priority 100

Lower priority numbers are evaluated first. Routes can have a fallback policy (dead-letter, drop, or quarantine) for when the endpoint fails.

List routes:

agentowl route list --tenant acme

8. Publish the runtime config

After creating your bindings, endpoints, and routes, publish the runtime configuration so the ingress workers can use it:

agentowl config publish acme

This snapshots the current desired state and distributes it to KV for all ingress workers.

In the admin UI, this is the explicit Activate routing step in the guided setup flow.

9. Verify with doctor

Run a health check to confirm everything is correctly configured:

agentowl doctor acme

This checks API connectivity, tenant status, published config, and provider drift.

Declarative configuration (apply)

Instead of running individual commands, you can define your entire configuration in a YAML file and apply it in one step.

Create acme.yaml:

tenant:
  slug: acme
  display_name: "Acme Corp"

endpoints:
  - name: main-webhook
    type: webhook
    config:
      url: https://app.acme.com/hooks/inbound

bindings:
  - address_or_number: support@acme.com
    provider: cloudflare
    channels:
      - email
    capabilities:
      - email
  - address_or_number: "+15551234567"
    provider: telnyx
    channels:
      - sms
    capabilities:
      - sms

routes:
  - binding_address: support@acme.com
    endpoint_name: main-webhook
    priority: 100
    fallback_policy: dead-letter
  - binding_address: "+15551234567"
    endpoint_name: main-webhook
    priority: 100
    fallback_policy: dead-letter

Validate

agentowl validate -f acme.yaml

Preview changes

agentowl plan -f acme.yaml

Apply

agentowl apply -f acme.yaml --auto-approve

This creates the tenant (if needed), endpoints, bindings, routes, and publishes the runtime config.

What's next

On this page