Run Claude Code CLI in isolated Cloudflare containers with a web-based terminal interface.
Designed to be embedded in ServiceNow as a single-page application:
flowchart LR
subgraph ServiceNow
A[React SPA]
end
subgraph Browser
A --> B[xterm.js]
end
subgraph Cloudflare
C[Worker] --> D[Durable Object]
D --> E[Container]
end
subgraph Container
F[WebSocket Server] --> G[node-pty]
G --> H[Claude Code CLI]
end
A -->|POST /api/connect| C
B <-->|WebSocket ttyd protocol| F
Flow:
- User opens the React app (hosted in ServiceNow or standalone)
- User enters ServiceNow credentials and clicks Connect (the credentials will be passed to Claude Code so it can work with the ServiceNow instance)
- Frontend POSTs to Cloudflare Worker
/api/connect - Worker creates a Durable Object which spawns a container
- Container starts Claude Code CLI with a WebSocket server
- Frontend establishes WebSocket connection for real-time terminal I/O
ServiceNow update set that contains a frontend app can be downloaded here
Tech Stack: React + Vite + Tailwind CSS + xterm.js
The frontend is a single-page application that provides:
- ConnectForm - Credential input with localStorage persistence
- Terminal - xterm.js terminal emulator with ttyd protocol support
- StatusBar - Connection status and session info
Vite is configured with vite-plugin-singlefile to produce a single index.html file with all JS, CSS, and images inlined as base64. This makes deployment to ServiceNow straightforward.
npm run build # Outputs frontend/dist/index.htmlThe frontend is deployed to ServiceNow using the reference architecture at: https://github.com/elinsoftware/servicenow-react-app
Note: The backend must be deployed to Cloudflare - it cannot run locally. Cloudflare Containers are only available in the Cloudflare production environment. The frontend can be developed locally and will connect to your deployed Cloudflare Worker.
Tech Stack: Cloudflare Workers + Durable Objects + Containers
The backend consists of:
- HTTP request router
- WebSocket upgrade handling
- Routes requests to Durable Objects
- Manages container lifecycle (create, connect, destroy)
- Proxies WebSocket connections between frontend and container
- Handles session persistence
- Node.js 20 base image
- Runs
server.js- a WebSocket server using node-pty - Claude Code CLI installed globally
- Receives credentials via environment variables
Important: The backend (Cloudflare Worker + Containers) cannot run locally. Cloudflare Containers require deployment to Cloudflare's production environment. For development:
- Deploy the worker to Cloudflare first:
npm run deploy - Run the frontend locally and point it to your deployed worker URL
# Install dependencies
npm install
# Deploy backend to Cloudflare (required first)
npm run deploy
# Run frontend locally (port 5173)
npm run dev:frontendThe frontend dev server will proxy API requests to your deployed Cloudflare Worker.
# Deploy worker to Cloudflare
npm run deploy
# Build frontend for ServiceNow
npm run build| Endpoint | Method | Description |
|---|---|---|
/api/connect |
POST | Create session, returns sessionId + wsUrl |
/api/terminal/:sessionId |
WebSocket | Terminal I/O (ttyd protocol) |
/api/disconnect |
POST | Stop container |
/health |
GET | Health check |
Request:
{
"instance": "dev12345.service-now.com",
"username": "admin",
"password": "...",
"anthropicApiKey": "sk-ant-..."
}Response:
{
"sessionId": "uuid",
"wsUrl": "wss://worker.workers.dev/api/terminal/uuid"
}The container runs a WebSocket server implementing the ttyd protocol:
Client → Server:
"0" + data- Terminal input (keystrokes)"1" + JSON- Resize event{"columns": 80, "rows": 24}
Server → Client:
[0x00] + data- Terminal output (binary)[0x01] + data- Window title[0x02] + data- Preferences
- Containers auto-sleep after 10 minutes of inactivity
- Sessions identified by UUID, enabling reconnection
- Credentials stored in localStorage (frontend) and passed to container as env vars
- Frontend auto-detects ServiceNow instance from
window.location.hostname
MIT License - see LICENSE for details.
Contact: info@elinsoftware.com

