This guide covers everything you need to deploy Translation Helps MCP to production on Cloudflare Workers.
Translation Helps MCP v4.3.0+ uses a revolutionary HTTP-based MCP architecture that runs perfectly on Cloudflare Workers without WebSockets or long-lived connections.
- HTTP MCP Endpoint:
https://tc-helps.mcp.servant.bible/api/mcp - Interactive Test UI:
https://tc-helps.mcp.servant.bible/mcp-http-test - Main Site:
https://tc-helps.mcp.servant.bible
The project uses shared business logic that can run on multiple platforms:
translation-helps-mcp/
├── src/functions/ # 🎯 Platform-agnostic business logic
│ ├── platform-adapter.ts # Platform abstraction layer
│ ├── handlers/ # Individual endpoint handlers
│ └── services/ # Business logic services
├── netlify/ # Netlify-specific wrappers (legacy)
└── ui/src/routes/api/ # SvelteKit API routes (Cloudflare)
Platform Adapter Benefits:
- Single codebase for multiple platforms
- Consistent behavior across environments
- Easy platform switching via build commands
- Shared testing and validation
Automatic GitHub Integration:
- Connect Repository: Link your GitHub repo to Cloudflare Pages
- Build Settings:
Build command: npm run build Output directory: ui/build Root directory: /
- Environment Variables: None required (all APIs are public)
- Deploy: Automatic on git push to main
Manual Deploy:
# Build for Cloudflare
npm run build
# Deploy using Wrangler
npx wrangler pages deploy ui/build --project-name translation-helps-mcp# Build for Netlify
npm run build:netlify
# Deploy using Netlify CLI
npx netlify deploy --prod --dir=distCritical Fixes for Production:
-
No Node.js File System APIs:
// ❌ DON'T - Breaks in Cloudflare Workers import fs from "fs"; const version = fs.readFileSync("package.json"); // ✅ DO - Use static imports import { version } from "./version.js";
-
No Process APIs:
// ❌ DON'T - process doesn't exist in Workers const uptime = process.uptime(); // ✅ DO - Use Worker-compatible alternatives const startTime = Date.now(); const uptime = Date.now() - startTime;
-
Safe Environment Variable Access:
// ❌ DON'T - process might not exist const nodeEnv = process.env.NODE_ENV; // ✅ DO - Check existence first const nodeEnv = typeof process !== "undefined" ? process.env.NODE_ENV : "production";
Cloudflare KV Caching (Recommended):
Current setup uses memory-only caching which doesn't persist across cold starts. Implementing Cloudflare KV provides:
- Persistent cache across cold starts
- Global distribution via Cloudflare edge network
- 10x performance improvement for repeated requests
- Cost efficiency at scale
Implementation Plan:
- Set up KV namespace in Cloudflare dashboard
- Update caching layer to use KV as fallback
- Configure appropriate TTL values (5-10 minutes for translation resources)
- Monitor performance improvements
Expected Results:
- Cold start performance: Improved by 3-5x
- Cached response times: 30-40ms consistently
- Throughput: 38+ RPS sustained
Setup:
# .github/workflows/deploy.yml
name: Deploy to Cloudflare Pages
on:
push:
branches: [main]
pull_request:
branches: [main]
jobs:
deploy:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- uses: actions/setup-node@v3
with:
node-version: "18"
- run: npm ci
- run: npm run build
- uses: cloudflare/pages-action@v1
with:
apiToken: ${{ secrets.CLOUDFLARE_API_TOKEN }}
accountId: ${{ secrets.CLOUDFLARE_ACCOUNT_ID }}
projectName: translation-helps-mcp
directory: ui/buildBenefits:
- Pull Requests: Test builds with preview URLs
- Main Branch: Auto-deploy to production
- Fast CI: Parallel testing and deployment
- Zero Configuration: Works out of the box
curl https://your-deployment.pages.dev/api/healthcurl "https://your-deployment.pages.dev/api/fetch-scripture?reference=John%203:16&language=en&organization=unfoldingWord"curl -X POST https://your-deployment.pages.dev/api/mcp \
-H "Content-Type: application/json" \
-d '{"method": "tools/list"}'# Load testing (if you have artillery installed)
npx artillery quick --count 10 --num 5 https://your-deployment.pages.dev/api/healthCause: Node.js APIs being used in Worker environment
Solution:
- Remove all
fs,path,processusage - Use static imports instead of dynamic file reading
- Check Worker compatibility for all dependencies
Cause: Memory-only caching doesn't persist
Solution:
- Implement Cloudflare KV caching
- Use edge-compatible data structures
- Optimize bundle size to reduce cold start time
Cause: Missing CORS headers for browser requests
Solution:
// Add to all API responses
headers: {
'Access-Control-Allow-Origin': '*',
'Access-Control-Allow-Methods': 'GET, POST, OPTIONS',
'Access-Control-Allow-Headers': 'Content-Type',
}Key Metrics to Track:
- Response Times: < 2s for resource loading, < 1s for languages
- Cache Hit Rate: > 80% for repeated requests
- Error Rate: < 1% for all endpoints
- Throughput: 30+ RPS sustained
Monitoring Tools:
- Cloudflare Analytics Dashboard
- Worker Logs via
wrangler tail - Custom health check endpoints
- Performance testing with load tools
- Translation Helps Complete Guide - Technical implementation patterns
- Implementation Guide - Setup and development guide
- Archive - Historical deployment documentation (Netlify, etc.)
🎯 Success Criteria: When your deployment can consistently serve 30+ RPS with sub-2s response times and >80% cache hit rate, you've achieved production readiness!