Architecture Overview
High-Level Architecture
Section titled “High-Level Architecture”Browser → Cloudflare Access (auth) → App Worker (Hono API + SPA) ↓ Cloudflare D1 (SQLite)
AI Clients → MCP Worker (mcp.nucleus.fast) → App Worker API → D1(Claude Desktop, OAuth 2.0 / PKCE + KV Cursor, Claude Code) 120+ tools + query_nucleusThe platform is a single-page application (React) served by a Cloudflare Worker (Hono). The Worker handles both static asset serving and API requests. All authentication happens at the edge via Cloudflare Access.
The MCP server (apps/mcp/) is a separate Worker that exposes all Nucleus data to AI assistants via the Model Context Protocol. It authenticates users with OAuth 2.0 / PKCE backed by CF Access, then proxies all tool calls to the main app’s API — no direct D1 access, full permission enforcement reused from the existing layer.
Project Structure
Section titled “Project Structure”nucleus/├── apps/│ ├── app/ # Main Nucleus platform│ │ ├── src/ # React SPA (React 19, TanStack Router, shadcn/ui)│ │ │ ├── components/ # UI components (ui/, layout/, per-tool)│ │ │ ├── routes/ # File-based routes (TanStack Router)│ │ │ └── hooks/ # TanStack Query hooks per tool│ │ ├── worker/ # Hono API (Cloudflare Workers)│ │ │ ├── routes/ # 72 API route handlers│ │ │ ├── middleware/ # Auth + permission middleware│ │ │ └── lib/ # CF Access JWT, AI helpers, integrations│ │ └── db/ # D1 schema, seed data, migrations│ ├── mcp/ # MCP server — AI assistant integration│ │ └── src/│ │ ├── index.ts # Hono entry: OAuth + MCP endpoint│ │ ├── auth/ # OAuth 2.0 / PKCE + CF Access + KV sessions│ │ ├── mcp/ # McpServer factory + API proxy│ │ ├── tools/ # 46 tool modules (~120 tools)│ │ └── resources/ # 7 MCP resources (config lookups)│ ├── admin/ # Orchestrator dashboard (React + Hono)│ ├── portal/ # Client portal (React + Hono)│ ├── agents/ # Autonomous Cloudflare Workers│ │ ├── analytics/ # AI analytics agent│ │ ├── dev/ # Dev agent│ │ ├── marketing/ # Marketing automation│ │ ├── product/ # Product management│ │ └── release/ # Release management│ ├── orchestrator/ # Build system (Cloudflare Containers)│ ├── docs/ # Starlight documentation site│ └── site/ # Static landing page├── .conventions/ # UI/API pattern documentation├── tsconfig.base.json # Shared TypeScript config└── pnpm-workspace.yaml # Workspace definitionsRequest Flow — Web App
Section titled “Request Flow — Web App”- User visits
app.nucleus.fast - Cloudflare Access intercepts, authenticates via Google Workspace
- Request reaches the Worker with a signed JWT in
Cf-Access-Jwt-Assertionheader - Auth middleware validates JWT, upserts user in D1
- Permission middleware checks tool-level access for the requested action
- Route handler processes request, scopes data by access level
- Response returned to the frontend
Request Flow — MCP
Section titled “Request Flow — MCP”- AI client discovers OAuth metadata at
mcp.nucleus.fast/.well-known/oauth-authorization-server - Client registers via dynamic client registration (
POST /oauth/clients) - User authenticates via browser → CF Access Google SSO → JWT cookie
- MCP Worker captures JWT, issues OAuth auth code (60s KV TTL)
- Client exchanges code + PKCE verifier for bearer token (8h KV TTL)
- Client calls
POST /mcpwithAuthorization: Bearer <token> - MCP Worker resolves CF Access JWT from KV, creates
McpServer+WebStandardStreamableHTTPServerTransport - Tool calls proxy to
app.nucleus.fast/api/*with JWT forwarded — full permission enforcement applies
Key Design Decisions
Section titled “Key Design Decisions”- SPA over SSR: Internal tool with authenticated users — no SEO needed, simpler deployment
- Single Worker: One deployment serves both API and SPA via Wrangler
[assets]config - D1 over KV: Relational data (users, permissions, scorecards) benefits from SQL
- Cloudflare Access over custom OAuth: Eliminates auth code, session management, login UI
- shadcn/ui over component library: Owned components, full customisation, no version lock-in
- MCP proxies API, not D1: Permission enforcement, validation, and business logic stay in one place; the MCP layer stays thin
- Stateless MCP transport: No Durable Objects — each request creates a fresh
McpServerinstance