Production Claude API Platform
Express.js v5 · Claude API · WebSockets · node-pty · Supabase · React 18 · Ubuntu VPS · 2025
Overview
A full-stack admin platform (jimmycc.com) with Claude API as a core feature — not a chatbot bolted onto a website, but an AI-integrated operations dashboard. Streaming responses, 16 custom tool definitions spanning system operations, database queries, and git workflows, plus a WebSocket terminal with real PTY access.
Architecture
The platform runs on an Ubuntu VPS with nginx reverse proxy, SSL via Let's Encrypt, and pm2 process management. The Claude integration is server-side — the React frontend sends requests to Express endpoints, which stream responses from the Anthropic API back to the browser.
| Layer | Technology | Purpose |
|---|---|---|
| Frontend | React 18, Radix UI, Tailwind | Chat UI, tool approval, terminal |
| Backend | Express.js v5, Node.js | API routes, Claude streaming, auth |
| AI | Anthropic Claude API | Streaming chat, tool use |
| Terminal | WebSockets, node-pty | Real-time PTY shell access |
| Database | Supabase (PostgreSQL) | Conversations, auth, data |
| Auth | Discord OAuth via Supabase | Admin whitelist + JWT verification |
| Infra | Ubuntu VPS, nginx, pm2, SSL | Production hosting |
16 Custom Tool Definitions
Read-only tools (no approval required):
supabaseQuery, supabaseSchema, readFile, listFiles, searchFiles, gitLog, gitStatus, httpCheck, readLogs
Write tools (require explicit approval):
supabaseInsert, supabaseUpdate, supabaseDelete, writeFile, gitCommit, gitPush, pm2Restart
The tool approval workflow is a key design decision: read-only operations execute automatically (Claude can query the database, read logs, check git status), but anything that mutates state requires explicit user approval in the UI. This gives Claude broad observability while maintaining human control over actions.
WebSocket Terminal
The platform includes a real terminal — not a simulated shell, but a full PTY session via node-pty. The browser connects over WebSocket, and keystrokes are forwarded to a real bash/PowerShell process on the server. xterm.js renders the terminal in the browser with proper ANSI escape handling. Claude can suggest commands, the user executes them in the terminal, and both see the results.
Conversation Persistence
Conversations auto-save to Supabase after each assistant turn. The sidebar provides:
- Search across all conversations
- Date grouping (Today, Yesterday, This Week, Older)
- Auto-generated titles from first message
- Full CRUD via API endpoints (GET list, GET by ID, POST, PUT, DELETE)
- All endpoints protected by requireAdmin middleware
Key Design Decisions
- Server-side Claude integration — API key never touches the browser
- Lazy Anthropic client init — client created on first request, not at server startup (avoids crashes if env var missing)
- Express v5 wildcard routing — uses
/{*splat}syntax for SPA fallback - Streaming via Server-Sent Events — responses stream token-by-token to the frontend