Sendook is one Cloudflare Worker plus a D1 database, a Durable Object class, and an Email Routing rule. End-to-end deployment is a wrangler deploy and three Cloudflare console clicks.
bun (preferred) or pnpm. Do not use npm.wrangler@4 (the repo pins it as a devDependency).git clone https://github.com/StreamlinedStartup/sendook
cd sendook/worker
bun install
Create the prod D1 database, then add its database_id to worker/wrangler.jsonc:
bun wrangler d1 create sendook
# copy the printed database_id into the d1_databases[0].database_id field
Apply the migrations:
bun wrangler d1 migrations apply sendook --remote
bun wrangler secret put MASTER_KEY # e.g. openssl rand -base64 32
bun wrangler secret put API_KEY_HASH_PEPPER # e.g. openssl rand -base64 32
Update the vars block in worker/wrangler.jsonc to point at your real domain:
"vars": {
"VERSION": "1.0.0",
"DEFAULT_EMAIL_DOMAIN": "agents.yourdomain.com",
"ALLOWED_ORIGINS": "https://app.yourdomain.com"
}
DEFAULT_EMAIL_DOMAIN is the suffix attached to every new agent's address. ALLOWED_ORIGINS is the comma-separated list of browser origins permitted to call the API; set to your dashboard's origin.
bun wrangler deploy
The Worker will be available at the route configured in wrangler.jsonc (or the *.workers.dev URL printed at deploy time).
In the Cloudflare dashboard for your domain:
sendook-worker.From for outbound mail (Send Email binding requires this for new domains).Once MX propagates, mail to *.yourdomain.com will hit the Worker's email() handler, which routes by recipient to the matching agent.
Create your first agent and send mail to yourself:
export SENDOOK_HOST=https://api.yourdomain.com
export SENDOOK_MASTER_KEY=...
curl -sX POST "$SENDOOK_HOST/agents" \
-H "Authorization: Bearer $SENDOOK_MASTER_KEY" \
-H "Content-Type: application/json" \
-d '{"name":"Smoke"}'
Then send a real email from another address to the agent's address and verify it lands:
curl -s "$SENDOOK_HOST/agents/<agent_id>/messages" \
-H "Authorization: Bearer $SENDOOK_MASTER_KEY" | jq .
wrangler dev runs the Worker on http://localhost:8787 with miniflare-backed D1 and DO storage. Pair it with the Nuxt dashboard at app/ (bun run dev in that directory) and it will talk to the local Worker via useApi.
cd worker
bun run dev
| Variable | Type | Description |
|---|---|---|
MASTER_KEY | secret | Bearer token for POST /agents, GET /agents, DELETE /agents/:id. |
API_KEY_HASH_PEPPER | secret | HMAC pepper for hashing per-agent API keys before storing. |
DEFAULT_EMAIL_DOMAIN | var | Suffix appended to each new agent's address. |
ALLOWED_ORIGINS | var | Comma-separated browser origins allowed by CORS. |
VERSION | var | Surfaced via GET /health for build-tracking. |