Local Development
Practical setup for working on AgentOwl locally — prerequisites, workspace commands, environment variables, and database schema.
This document covers the practical setup for working on AgentOwl locally.
Prerequisites
- Node.js 20+ recommended
- npm
- A Cloudflare account and Wrangler credentials if you want real Worker resources
Install dependencies
npm installWorkspace commands
From the repository root:
npm run build
npm run lint
npm testPackage-specific development commands:
npm run dev -w @agentowl/worker
npm run dev -w @agentowl/cli -- --helpWorker setup
The Worker uses the bindings defined in packages/worker/wrangler.toml:
- D1 database bound as
DB - KV namespace bound as
RUNTIME_CONFIG - Queue producer/consumer bound as
EVENTS_QUEUE
The checked-in file contains the hosted deployment's resource IDs. Replace them with your own before deploying to your Cloudflare account. Per-role environments (env.email-ingress, env.sms-ingress, and so on) are defined there too but are optional.
Environment variables
The Worker reads these from .dev.vars locally and from Wrangler secrets in deployment. All are optional; the features that need them are disabled without them. They are defined in packages/worker/src/env.ts.
| Variable | Used for |
|---|---|
TELNYX_PUBLIC_KEY | Verifying Telnyx webhook signatures. SMS and voice ingress return 503 without it. |
TELNYX_API_KEY | Provisioning numbers and Call Control actions |
CLOUDFLARE_ACCOUNT_ID | Cloudflare deployment control |
AGENTOWL_INGRESS_BASE_URL | Public base URL that provider webhooks are pointed at |
PAYLOAD_ENCRYPTION_KEY | AES-256-GCM key (base64, 32 bytes) for payloads stored in KV |
SMTP_INTERNAL_TOKEN | Shared secret that sendmailrs sends as X-Internal-Token |
GITHUB_CLIENT_ID, GITHUB_CLIENT_SECRET | GitHub sign-in |
GOOGLE_CLIENT_ID, GOOGLE_CLIENT_SECRET | Google sign-in |
AUTH_SESSION_SECRET | Signing dashboard session cookies |
PLATFORM_ADMIN_EMAILS | Comma-separated emails granted the platform-admin role |
OTEL_ENABLED, OTEL_SERVICE_NAME | OpenTelemetry instrumentation |
TELEMETRY_COLLECTOR_URL, TELEMETRY_COLLECTOR_TOKEN | Telemetry collector used by the admin telemetry pages |
DEPLOYMENT_SCRIPTS, DEPLOYMENT_TOKEN_REF | Role deployments triggered through POST /v1/deployments |
AGENTOWL_BUILD_COMMIT, AGENTOWL_BUILD_REF, AGENTOWL_BUILD_TIME, AGENTOWL_BUILD_SOURCE_URL | Build metadata reported by the version endpoints |
Signing secret storage
The dedicated SECRETS_STORE KV namespace holds encrypted credentials that endpoints reference by secret_ref. Configure the binding on the API and queue-consumer Workers, with the same PAYLOAD_ENCRYPTION_KEY (a base64-encoded 32-byte AES key) on both. Keep this separate from the runtime-config namespace. The signing API returns 503 until both are configured.
For deployment, create the namespace with npx wrangler kv namespace create SECRETS_STORE from packages/worker, add its returned binding to wrangler.toml, and securely set PAYLOAD_ENCRYPTION_KEY with npx wrangler secret put PAYLOAD_ENCRYPTION_KEY. Reuse an existing encryption key if configured; replacing it makes previously encrypted secrets and payloads unreadable. Apply D1 migrations before deploying the Worker code. Local development needs the same binding and an encryption key in .dev.vars.
Signing-key preparation stores a candidate without changing active authentication. Activation is explicit, after receiver setup. Old encrypted active-key versions are retained for in-flight delivery compatibility; unused superseded candidates are deleted.
Database schema
The D1 schema is built by the numbered migrations in packages/worker/migrations/. Apply them before exercising API flows that persist state:
cd packages/worker
npx wrangler d1 migrations apply agentowl --localThe schema includes:
- tenants, bindings, endpoints, routes, and policies
- events, dead letters, and hosted-page events
- accounts, API keys, and OAuth clients, codes, and tokens
- audit log, deployments, reconcile jobs, usage counters, and analytics events
- external interactions (the per-event delivery timeline shown in the dashboard inbox)
Running the CLI against a local Worker
Sign in with agentowl login --url http://localhost:8787 (see Self-hosting), or set the target per command:
AGENTOWL_API_URL=http://localhost:8787 AGENTOWL_API_TOKEN=aok_... npm run dev -w @agentowl/cli -- versionWithout a saved URL or environment override, the CLI defaults to https://api.agentowl.dev; pass --url http://localhost:8787 when signing in to a local Worker. For a full walkthrough of creating a workspace, endpoint, binding, and route, see Set up with the CLI.
Notes on local confidence
Local code-level tests cover a good amount of API and service behavior, but not every external provider path is fully exercised in a realistic environment.
For changes touching any of the following, prefer verifying both tests and a manual local flow:
- Ingress handlers
- Routing behavior
- Replay behavior
- Provider adapters
- Runtime config publication
Cloudflare Email Routing rules for AgentOwl's own operational addresses are managed outside tenant provisioning. The Worker keeps its inbound email handler for those existing routes.
Signing secret storage
Configure a dedicated SECRETS_STORE KV binding and a PAYLOAD_ENCRYPTION_KEY before enabling managed webhook signing. Generate the key with openssl rand -base64 32 and install it as a Worker secret. The key must remain stable across deployments to decrypt stored credentials. In local development, put the key in .dev.vars, which must not be committed.
Use the dashboard Signing panel or the CLI prepare/activate commands to configure receivers before turning on v2 signatures. See webhook signing.