.do

Configuration & Deployment

Server configuration, deployment, and management

Complete guide to configuring, deploying, and managing MCP.do server.

Server Configuration

Environment Variables

# OAuth Configuration
OAUTH_SERVER_URL=https://oauth.do

# Rate Limiting
ANON_RATE_LIMIT=10          # Anonymous: 10 req/min
AUTH_RATE_LIMIT=100         # Authenticated: 100 req/min

# Timeouts
ANON_TIMEOUT_MS=10000       # Anonymous: 10 seconds
AUTH_TIMEOUT_MS=30000       # Authenticated: 30 seconds

# Human Functions
HUMAN_WORKER_URL=https://humans.do

# Admin Access
ADMIN_ROLE=admin            # Role name for admin users

Wrangler Configuration

wrangler.jsonc:

{
  "name": "mcp",
  "main": "src/index.ts",
  "compatibility_date": "2024-01-15",
  "node_compat": true,

  "vars": {
    "OAUTH_SERVER_URL": "https://oauth.do",
    "ANON_RATE_LIMIT": "10",
    "AUTH_RATE_LIMIT": "100",
    "ANON_TIMEOUT_MS": "10000",
    "AUTH_TIMEOUT_MS": "30000",
    "HUMAN_WORKER_URL": "https://humans.do"
  },

  "durable_objects": {
    "bindings": [
      {
        "name": "MCP_OBJECT",
        "class_name": "PublicMcpAgent",
        "script_name": "mcp"
      },
      {
        "name": "rateLimiter",
        "class_name": "RateLimiter",
        "script_name": "mcp"
      }
    ]
  },

  "services": [
    {
      "binding": "api",
      "service": "api",
      "environment": "production"
    }
  ],

  "routes": [
    {
      "pattern": "mcp.do/*",
      "zone_name": "do"
    }
  ]
}

Local Development

Installation

# Clone repository
git clone https://github.com/youraccount/platform
cd platform/workers/mcp

# Install dependencies
pnpm install

Running Locally

# Start development server
pnpm dev

# Server runs at http://localhost:8787

Testing Locally

# Run unit tests
pnpm test

# Run integration tests
pnpm test:integration

# Test MCP connection
node test-mcp.js

Test Script

test-mcp.js:

import { MCPClient } from '@modelcontextprotocol/sdk/client/index.js'
import { SSEClientTransport } from '@modelcontextprotocol/sdk/client/sse.js'

const transport = new SSEClientTransport(new URL('http://localhost:8787'), {})

const client = new MCPClient({ name: 'test-client', version: '1.0.0' }, {})

await client.connect(transport)

// List tools
const tools = await client.listTools()
console.log('Available tools:', tools)

// Execute do tool
const result = await client.callTool('do', {
  script: 'await db.list("Business")',
})
console.log('Result:', result)

await client.close()

Deployment

Deploy to Cloudflare

# Deploy to production
pnpm deploy

# Deploy with specific environment
pnpm deploy:production

# Deploy with environment variables
wrangler deploy --var ANON_RATE_LIMIT:20

CI/CD Deployment

GitHub Actions workflow:

.github/workflows/deploy-mcp.yml:

name: Deploy MCP

on:
  push:
    branches: [main]
    paths:
      - 'workers/mcp/**'

jobs:
  deploy:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4

      - name: Setup pnpm
        uses: pnpm/action-setup@v2

      - name: Install dependencies
        run: pnpm install

      - name: Run tests
        run: pnpm test
        working-directory: workers/mcp

      - name: Deploy
        run: pnpm deploy
        working-directory: workers/mcp
        env:
          CLOUDFLARE_API_TOKEN: ${{ secrets.CLOUDFLARE_API_TOKEN }}

Staged Deployment

Deploy to staging first:

# Deploy to staging
wrangler deploy --env staging

# Test staging
curl https://staging.mcp.do/health

# Promote to production
wrangler deploy --env production

Custom Domains

Add Custom Domain

# Add route in wrangler.jsonc
{
  "routes": [
    {
      "pattern": "mcp.yourdomain.com/*",
      "zone_name": "yourdomain.com"
    }
  ]
}

# Deploy
wrangler deploy

SSL Configuration

SSL is automatic via Cloudflare:

  • Automatic HTTPS
  • HTTP/2 and HTTP/3 support
  • SSL certificates managed by Cloudflare

Admin Subdomain

Configure admin-only subdomain:

DNS Configuration

# Add CNAME record
admin.mcp.do -> CNAME -> mcp.do

Access Control

// In worker
if (url.hostname === 'admin.mcp.do' && !auth.isAdmin) {
  return new Response(
    JSON.stringify({
      error: 'forbidden',
      error_description: 'Admin access required',
    }),
    { status: 403 }
  )
}

Monitoring

Health Checks

# Health endpoint
curl https://mcp.do/health

# Response
{
  "status": "ok",
  "timestamp": "2024-01-15T10:30:00Z"
}

Metrics Dashboard

Monitor in Cloudflare dashboard:

  • Request rate
  • Error rate
  • Response time (p50, p95, p99)
  • Durable Object usage

Analytics

# View analytics
wrangler tail --format=pretty

# Filter errors
wrangler tail --format=pretty --status=error

# View specific requests
wrangler tail --format=pretty --search="tools/call"

Custom Logging

// In worker
console.log('Tool call:', {
  tool: toolName,
  auth: auth.type,
  userId: auth.id,
  duration: Date.now() - startTime,
})

Scaling

Automatic Scaling

Cloudflare Workers scale automatically:

  • No configuration needed
  • Handles millions of requests
  • Global distribution

Rate Limit Scaling

Adjust rate limits based on load:

# Increase auth rate limit
wrangler secret put AUTH_RATE_LIMIT
# Enter: 200

# Deploy changes
wrangler deploy

Durable Object Scaling

Durable Objects scale per user:

  • One rate limiter per user
  • One sandbox per request
  • Automatic cleanup

Backup & Recovery

Configuration Backup

# Backup wrangler.jsonc
cp wrangler.jsonc wrangler.jsonc.backup

# Backup environment variables
wrangler secret list > secrets.txt

Durable Object Backup

# Export Durable Object data
wrangler d1 export mcp-do-data

# Import on recovery
wrangler d1 import mcp-do-data < backup.sql

Security Hardening

API Key Rotation

# Generate new admin key
wrangler secret put ADMIN_API_KEY

# Revoke old keys in admin dashboard

Rate Limit Tuning

# Stricter anonymous limits
ANON_RATE_LIMIT=5

# Monitor and adjust
wrangler tail --format=pretty --status=429

IP Allowlisting

Add IP restrictions in Cloudflare:

// In worker
const allowedIPs = ['1.2.3.4', '5.6.7.8']
const clientIP = request.headers.get('CF-Connecting-IP')

if (!allowedIPs.includes(clientIP)) {
  return new Response('Forbidden', { status: 403 })
}

Troubleshooting

Common Issues

Issue: Rate limit exceeded

# Check rate limiter state
wrangler tail --format=pretty --search="rate limit"

# Increase limit temporarily
wrangler secret put AUTH_RATE_LIMIT

Issue: Timeout errors

# Increase timeout
wrangler secret put AUTH_TIMEOUT_MS
# Enter: 60000 (60 seconds)

Issue: OAuth validation failing

# Check OAuth server connectivity
curl https://oauth.do/health

# Verify environment variable
wrangler secret list | grep OAUTH

Debug Mode

Enable debug logging:

// In wrangler.jsonc
{
  "vars": {
    "DEBUG": "true"
  }
}

View logs:

wrangler tail --format=pretty

Performance Profiling

# Monitor response times
wrangler tail --format=pretty --search="duration"

# Identify slow operations
wrangler tail --format=pretty --search="timeout"

Cost Optimization

Workers Pricing

Cloudflare Workers:

  • Free tier: 100,000 requests/day
  • Paid: $5/month for 10M requests
  • Durable Objects: $0.15/million requests

Optimization Tips

  1. Cache documentation responses:
// Note: Use KV or Durable Objects for persistent caching across requests
// KV example:
if (script.endsWith('.md')) {
  const cached = await env.CACHE_KV.get(script)
  if (cached) return JSON.parse(cached)

  // ... generate response ...

  await env.CACHE_KV.put(script, JSON.stringify(response), {
    expirationTtl: 3600, // 1 hour
  })
}
  1. Batch operations:
// Use ai.batch() instead of multiple ai.generate() calls
await ai.batch(requests)
  1. Limit result sizes:
// Limit list queries
await db.list('Order', { limit: 100 })

Next Steps