Skip to main content
Cloudflare Workers provide edge computing with near-zero cold starts and global distribution. This guide covers deploying AgentDoor with Hono to Cloudflare Workers.

Quick Start

Deploy a new Cloudflare Worker with AgentDoor:
1

Clone Template

git clone https://github.com/0xaron/agentdoor
cd agentdoor/packages/template-cloudflare/template
2

Install Dependencies

npm install
3

Configure Wallet

Edit wrangler.toml and set your wallet address:
[vars]
X402_WALLET = "0xYourWalletAddress"
4

Deploy

npm run deploy

Manual Setup

For custom deployments or integration into existing Workers:

1. Install Dependencies

npm install hono @agentdoor/hono
npm install -D wrangler typescript

2. Create Worker Application

Create src/index.ts with AgentDoor middleware:
import { Hono } from 'hono';
import { cors } from 'hono/cors';
import { agentDoor } from '@agentdoor/hono';

type Bindings = {
  X402_WALLET: string;
  DB?: D1Database; // Optional D1 database binding
};

const app = new Hono<{ Bindings: Bindings }>();

// Enable CORS
app.use('*', cors());

// AgentDoor middleware
app.use(
  '/api/*',
  agentDoor({
    scopes: [
      { id: 'data.read', description: 'Read worker data', price: '$0.001/req' },
      { id: 'data.write', description: 'Write worker data', price: '$0.01/req' },
      { id: 'compute', description: 'Run computations', price: '$0.005/req' },
    ],
    service: {
      name: 'Agent-Ready Worker',
      description: 'Cloudflare Worker with AgentDoor authentication',
    },
    x402: {
      network: 'base',
      currency: 'USDC',
      paymentAddress: (c) => c.env.X402_WALLET || '0xYourWalletAddress',
    },
  })
);

// Routes
app.get('/', (c) => {
  return c.json({
    name: 'Agent-Ready Worker',
    discovery: '/.well-known/agentdoor',
  });
});

app.get('/api/data', (c) => {
  const agentId = c.req.header('x-agentdoor-agent-id') || 'anonymous';
  
  return c.json({
    success: true,
    data: [/* your data */],
    meta: { agent: agentId }
  });
});

export default app;

3. Configure Wrangler

Create wrangler.toml in your project root:
name = "agentdoor-worker"
main = "src/index.ts"
compatibility_date = "2024-01-01"

# Environment variables
[vars]
X402_WALLET = "0xYourWalletAddress"

# D1 Database binding (optional)
[[d1_databases]]
binding = "DB"
database_name = "agentdoor"
database_id = "your-database-id"

4. Add Scripts to package.json

{
  "scripts": {
    "dev": "wrangler dev",
    "deploy": "wrangler deploy"
  }
}

Storage Configuration

Cloudflare Workers require edge-compatible storage. Choose based on your needs: D1 is Cloudflare’s serverless SQLite database with automatic replication.
1

Create D1 Database

wrangler d1 create agentdoor
Copy the database ID from the output.
2

Update wrangler.toml

[[d1_databases]]
binding = "DB"
database_name = "agentdoor"
database_id = "your-database-id-here"
3

Create Schema

Create schema.sql with AgentDoor tables:
CREATE TABLE IF NOT EXISTS agents (
  id TEXT PRIMARY KEY,
  public_key TEXT UNIQUE NOT NULL,
  api_key_hash TEXT UNIQUE NOT NULL,
  x402_wallet TEXT,
  scopes_granted TEXT NOT NULL,
  status TEXT NOT NULL DEFAULT 'active',
  reputation INTEGER DEFAULT 100,
  total_requests INTEGER DEFAULT 0,
  total_x402_paid REAL DEFAULT 0,
  rate_limit_requests INTEGER DEFAULT 100,
  rate_limit_window INTEGER DEFAULT 60,
  metadata TEXT,
  created_at TEXT NOT NULL,
  last_auth_at TEXT,
  updated_at TEXT NOT NULL
);

CREATE TABLE IF NOT EXISTS challenges (
  agent_id TEXT PRIMARY KEY,
  challenge TEXT NOT NULL,
  expires_at TEXT NOT NULL
);
4

Execute Schema

wrangler d1 execute agentdoor --file=schema.sql
5

Configure Storage

import { D1Store } from '@agentdoor/cloudflare';

app.use('/api/*', agentDoor({
  // ... other config
  storage: (c) => new D1Store({ database: c.env.DB })
}));

Workers KV (Simple Key-Value)

For simpler use cases, use Workers KV:
[[kv_namespaces]]
binding = "KV"
id = "your-kv-namespace-id"
import { KVStore } from '@agentdoor/cloudflare';

app.use('/api/*', agentDoor({
  // ... other config
  storage: (c) => new KVStore({ namespace: c.env.KV })
}));
KV has eventual consistency. For strong consistency, use D1.

Durable Objects (Advanced)

For advanced use cases requiring coordination:
[[durable_objects.bindings]]
name = "AGENTS"
class_name = "AgentStore"
script_name = "agentdoor-worker"
See Cloudflare Durable Objects docs for implementation.

Environment Variables

Manage environment variables via wrangler.toml and secrets.

Public Variables (wrangler.toml)

For non-sensitive configuration:
[vars]
X402_WALLET = "0xYourWalletAddress"
NODE_ENV = "production"

Secrets (Encrypted)

For sensitive values like API keys:
# Add a secret
wrangler secret put DATABASE_URL
# Enter value when prompted

# List secrets
wrangler secret list

# Delete a secret
wrangler secret delete DATABASE_URL
Access secrets in your worker:
type Bindings = {
  X402_WALLET: string;
  DATABASE_URL: string; // Secret
};

app.get('/api/data', (c) => {
  const dbUrl = c.env.DATABASE_URL; // Access secret
});

Custom Domains

1

Add Domain to Cloudflare

Ensure your domain is managed by Cloudflare DNS.
2

Add Route

In Cloudflare dashboard:
  1. Navigate to Workers & Pages
  2. Select your worker
  3. Click TriggersAdd Custom Domain
  4. Enter your domain (e.g., api.yourdomain.com)
3

Configure DNS

Cloudflare automatically configures DNS records for your domain.
Or via wrangler.toml:
routes = [
  { pattern = "api.yourdomain.com/*", zone_name = "yourdomain.com" }
]

Development Workflow

Local Development

Run your worker locally with hot reload:
npm run dev
Access at http://localhost:8787.

Testing with D1

Test with local D1 database:
# Create local database
wrangler d1 execute agentdoor --local --file=schema.sql

# Run with local D1
wrangler dev --local

Remote Development

Test against production resources:
wrangler dev --remote

Deployment

Deploy to Production

# Deploy to production
npm run deploy

# Deploy with custom name
wrangler deploy --name my-custom-worker

Environment-Specific Deployments

Create multiple environments in wrangler.toml:
# Production
name = "agentdoor-worker"

[env.staging]
name = "agentdoor-worker-staging"
[env.staging.vars]
X402_WALLET = "0xStagingWallet"

[env.production]
name = "agentdoor-worker-production"
[env.production.vars]
X402_WALLET = "0xProductionWallet"
Deploy to specific environment:
wrangler deploy --env staging
wrangler deploy --env production

Edge Considerations

Execution Time Limits

Cloudflare Workers have execution time limits:
  • Free tier: 10ms CPU time per request
  • Paid tier: 50ms CPU time per request
  • Maximum duration: 30s (free), 15m (paid with Durable Objects)
Long-running operations may hit time limits. Consider using Durable Objects or queue-based processing.

Memory Limits

Workers have a 128MB memory limit. Optimize for:
  • Minimal dependencies
  • Streaming responses for large payloads
  • Offloading heavy computation to Durable Objects

Cold Starts

Workers have near-zero cold starts (<10ms), but optimize by:
  • Lazy-loading dependencies
  • Caching frequently accessed data
  • Using module workers (automatic with Wrangler)

Monitoring and Logs

Viewing Logs

Stream logs in real-time:
# Production logs
wrangler tail

# Staging logs
wrangler tail --env staging

# Filter logs
wrangler tail --status error

Analytics

View analytics in Cloudflare dashboard:
  1. Navigate to Workers & Pages
  2. Select your worker
  3. Click Metrics tab
Metrics include:
  • Request volume
  • Error rate
  • CPU time
  • Duration

Custom Logging

Add structured logging:
app.use('*', async (c, next) => {
  const start = Date.now();
  await next();
  const duration = Date.now() - start;
  
  console.log(JSON.stringify({
    method: c.req.method,
    path: c.req.path,
    status: c.res.status,
    duration,
    agent: c.req.header('x-agentdoor-agent-id')
  }));
});

Scaling and Performance

Automatic Scaling

Workers automatically scale to handle traffic with no configuration required.

Performance Optimization

  1. Enable Caching: Cache responses at the edge
    app.get('/api/data', (c) => {
      c.header('Cache-Control', 'public, max-age=60');
      return c.json({ data: [] });
    });
    
  2. Use Smart Placement: Enable Smart Placement for optimal routing
    [placement]
    mode = "smart"
    
  3. Minimize Bundle Size: Use tree-shaking and code splitting
    // Lazy load heavy dependencies
    const heavyLib = await import('./heavy-lib');
    

Troubleshooting

Worker Not Deploying

Check common issues:
  1. Syntax errors: Run wrangler publish --dry-run
  2. Size limits: Workers have a 1MB size limit after compression
  3. Compatibility date: Ensure compatibility_date is recent

D1 Connection Issues

Verify D1 configuration:
# List D1 databases
wrangler d1 list

# Check database info
wrangler d1 info agentdoor

# Query database directly
wrangler d1 execute agentdoor --command "SELECT * FROM agents"

CORS Errors

Ensure CORS is properly configured:
import { cors } from 'hono/cors';

app.use('*', cors({
  origin: '*', // Or specify allowed origins
  allowMethods: ['GET', 'POST', 'PUT', 'DELETE', 'OPTIONS'],
  allowHeaders: ['Content-Type', 'Authorization', 'X-AgentDoor-Token'],
}));

Best Practices

  1. Use D1 for Production: D1 provides reliable, serverless storage for agent data.
  2. Enable Smart Placement: Improves performance by routing requests optimally.
  3. Monitor CPU Time: Watch for CPU time spikes that may hit limits.
  4. Use Secrets for Sensitive Data: Never commit secrets to wrangler.toml.
  5. Test Locally: Use wrangler dev --local to test with local D1.
  6. Version Your Worker: Use git tags to track deployed versions.

Next Steps

Hono Framework

Learn more about Hono for Cloudflare Workers

D1 Storage

Configure D1 storage for AgentDoor

Rate Limiting

Configure rate limits for edge workers

Cloudflare Docs

Official Cloudflare Workers documentation

Build docs developers (and LLMs) love