Architecture
How MyClaude is built: Next.js 16 with dual Firebase SDKs, Stripe Connect payments, Cloudflare R2 storage, and the CONDUIT publishing pipeline.
MyClaude uses a dual Firebase SDK architecture with server-side rendering, Stripe Connect for payments, Cloudflare R2 for product files, and automated content scanning via the CONDUIT pipeline.
System overview
MyClaude is a marketplace with eight moving parts. Each component has a single responsibility and communicates through well-defined boundaries. Here is the full picture:
+------------------+
| myclaude.sh |
| (Web App) |
| Next.js 16 |
+--------+---------+
|
+-------------+-------------+
| |
+--------+--------+ +--------+--------+
| Server Components| | Client Components|
| (SSR pages) | | ("use client") |
| Firebase Admin | | Firebase Client |
+--------+--------+ +--------+---------+
| |
+-------------+-------------+
|
+--------+---------+
| API Layer |
| /api/ routes |
| Firebase Admin |
+--------+---------+
|
+-----------+-----------+-----------+-----------+
| | | | |
+-----+-----+ +--+---+ +----+----+ +----+----+ +----+----+
| Firestore | | R2 | | Firebase| | Stripe | | CONDUIT |
| (Database) | |(Files)| | Storage | | Connect | |(Pipeline)|
+------------+ +------+ | (Assets)| +---------+ +---------+
+---------+ +------------------+
| @myclaude-cli |
| (CLI) |
+--------+---------+
|
+--------+---------+
| API Layer |
| /api/ routes |
+------------------+The CLI is a thin client. It authenticates, then calls the same API routes that the web application uses. There is no separate backend for CLI operations.
Components
Web application
The web application is a Next.js 16 App Router project deployed on Vercel. It uses two rendering strategies depending on the page:
| Page | Rendering | Reason |
|---|---|---|
/explore | Server-side (SSR) | SEO — product listings must be indexable |
/p/[slug] | Server-side (SSR) | SEO — individual product pages with OpenGraph metadata |
/u/[username] | Server-side (SSR) | SEO — creator profiles |
/dashboard | Client-side | Authenticated-only, no SEO value |
/publish | Client-side | Authenticated-only |
/login, /register | Client-side | Auth forms |
Server-rendered pages use the Firebase Admin SDK to fetch data, strip sensitive fields (producing SafeProduct and SafeUserProfile types), and pass the sanitized data to client islands for interactivity like liking or downloading.
Dual Firebase SDK pattern
This is the most important architectural decision in MyClaude. Two Firebase SDKs coexist in the same codebase, strictly separated:
src/lib/
server/ # Firebase Admin SDK — server only
firebase-admin.ts # Initialization (lazy proxy pattern)
products.ts # getProduct(), listProducts(), getProductBySlug()
users.ts # getUserProfile(), getUserByUsername()
stripe.ts # Stripe server SDK
rate-limit.ts # In-memory rate limiter
client/ # Firebase Client SDK — browser only
firebase.ts # Client initialization
auth.ts # signIn, signOut, onAuthChange
firestore.ts # Client-side reads, real-time listeners
product-service.ts # toggleLike, trackDownload, createProduct
user-service.ts # updateProfile, createProfile
storage.ts # File uploads| Context | SDK | Location |
|---|---|---|
| Server Components (SSR) | Firebase Admin | lib/server/ |
| API Routes (mutations) | Firebase Admin | lib/server/ |
| Client Components (browser) | Firebase Client | lib/client/ |
| Stripe Webhooks | Firebase Admin | lib/server/ |
The Admin SDK runs with full privileges on the server. The Client SDK runs in the browser with permissions enforced by Firestore security rules. These two SDKs never import each other. A server file importing from lib/client/ or a client file importing from lib/server/ is a bug.
API layer
All mutations flow through Next.js API routes under /api/. Every mutation route follows the same verification sequence:
- Extract
Authorization: Bearer {token}from the request header - Verify the token with
admin.auth().verifyIdToken(token) - Confirm the caller is authorized for the specific operation
- Return
401if the token is missing, expired, or invalid
Rate limiting protects all mutation endpoints. Stripe webhook routes verify the webhook signature instead of a user token.
Database (Cloud Firestore)
Firestore stores four primary collections:
| Collection | Purpose | Read access | Write access |
|---|---|---|---|
products | Product listings, metadata, stats | Public (published) | Owner via Admin SDK |
users | Profiles, preferences, XP | Public (profile data) | Owner via Admin SDK |
orders | Purchase records | Owner only | Webhook only (Admin SDK) |
reviews | Product reviews and ratings | Public | Authenticated buyers |
Firestore security rules enforce ownership at the database level, independent of application logic. Even if application code has a bug, a user cannot read another user's orders or modify another user's products.
Storage (hybrid architecture)
MyClaude uses two storage backends:
| Backend | Purpose | Access method |
|---|---|---|
| Cloudflare R2 | Product files (skills, agents, bundles) | Signed URLs generated server-side |
| Firebase Storage | User assets (avatars, screenshots) | Client SDK with security rules |
Product files for paid products are never exposed directly to the browser. The fileUrl field is stripped from all client-facing responses. Downloads go through /api/products/download, which verifies the caller's purchase order before generating a time-limited signed URL.
Payments (Stripe Connect Express)
MyClaude uses Stripe Connect Express for marketplace payments. Creators connect their own Stripe accounts and receive payouts directly from Stripe — MyClaude never holds creator funds.
Purchase flow:
Buyer clicks "Buy"
|
v
POST /api/stripe/checkout (auth token)
|
v
API verifies token, creates Checkout Session
|
v
Buyer completes payment on Stripe
|
v
Stripe fires webhook → POST /api/stripe/webhooks
|
v
Webhook handler creates order in Firestore
|
v
Buyer returns to product page → order verified → download availableThe platform retains an 8% fee via Stripe's application fee mechanism. The remaining 92% goes directly to the creator's connected Stripe account.
Orders are created exclusively by the webhook handler. There is no client-side code path that can create an order. This is a security invariant.
Authentication (Firebase Auth)
Firebase Auth handles user identity. Supported providers:
- Email and password
- Google OAuth
When a user logs in, Firebase issues a JWT (JSON Web Token) valid for 1 hour, automatically refreshed by the client SDK. Every API request includes this token in the Authorization header. The Admin SDK verifies it server-side.
Unauthenticated users can browse all public product listings and creator profiles. Any write operation — publishing, purchasing, reviewing, downloading paid files — requires a valid token.
Content pipeline (CONDUIT)
CONDUIT is the publishing pipeline that every product passes through before appearing on the marketplace. When a creator runs myclaude publish, the pipeline executes in sequence:
myclaude publish
|
v
Validate vault.yaml (schema, required fields, version format)
|
v
Content scan (secrets, malicious patterns, policy violations)
|
v
Upload product files to storage
|
v
Create or update product listing in Firestore
|
v
Product live on marketplaceProducts that fail validation or scanning are rejected before listing. The creator receives a specific error message identifying the issue. Details on what the scanner checks are in the Security Model.
Design principles
Three principles guided the architecture:
Security first. Every trust boundary is enforced at the infrastructure level, not just application logic. Firestore rules, storage rules with allow read: if false, and webhook-only order creation all ensure that a bug in application code cannot bypass security controls.
SSR for discoverability. Product listings, individual product pages, and creator profiles are server-rendered. Search engines and AI systems receive fully rendered HTML with structured metadata. Authenticated dashboard pages, which have no SEO value, render client-side to reduce server load.
Thin client, thick server. The CLI, browser client components, and any future integrations all call the same API routes. Business logic lives in one place: the server. Clients are presentation layers.
Technology choices
| Layer | Choice | Rationale |
|---|---|---|
| Framework | Next.js 16 (App Router) | Server components for SSR, API routes in the same project, Vercel deployment |
| Language | TypeScript | Type safety across server and client boundaries |
| Database | Cloud Firestore | Real-time listeners, security rules, no server to manage |
| Auth | Firebase Auth | JWT-based, multiple providers, Admin SDK for server verification |
| Payments | Stripe Connect Express | Marketplace-native, PCI compliant, creator payouts without holding funds |
| Product storage | Cloudflare R2 | S3-compatible, no egress fees, signed URL support |
| Asset storage | Firebase Storage | Integrated with Firebase Auth, client SDK for direct uploads |
| CSS | Tailwind v4 | Utility-first, design token integration, zero runtime |
| UI components | shadcn/ui | Accessible, composable, source-owned (not a dependency) |
| Deploy | Vercel | Zero-config Next.js deployment, edge network, preview deploys |
Data flow: browse, purchase, publish
Browsing a product
Browser → GET /explore
→ Next.js Server Component
→ Firebase Admin SDK reads Firestore (products collection)
→ Strips sensitive fields → SafeProduct[]
→ Renders HTML server-side
→ Sends to browser with hydration islands for interactivityPurchasing a product
Browser → POST /api/stripe/checkout (Bearer token)
→ Admin SDK verifies token
→ Creates Stripe Checkout Session (8% application fee)
→ Returns checkout URL → Browser redirects to Stripe
→ Buyer pays → Stripe webhook fires
→ POST /api/stripe/webhooks → Verifies signature
→ Creates order in Firestore → Buyer can downloadPublishing a product
CLI → myclaude publish
→ Reads vault.yaml → Validates schema
→ Runs myclaude scan → Checks secrets, patterns, policy
→ POST /api/products (Bearer token)
→ Admin SDK verifies token and authorization
→ Uploads files to R2 → Creates listing in Firestore
→ Product live on /explore and /p/[slug]Related pages
- Concepts Overview — the mental model behind the marketplace
- Security Model — detailed security controls and enforcement
- CLI Commands — full command reference
- vault.yaml Specification — product manifest format