Cosmo Docs
Server

Server Overview

NestJS backend architecture, modules, and technology stack

The Cosmo backend is a NestJS REST API server located at packages/server. It serves all desktop, web, and CLI clients through a single API surface.

Technology Stack

LayerTechnology
FrameworkNestJS (Express adapter)
DatabasePostgreSQL via Prisma ORM
AuthClerk (cloud) + custom JWT (CLI)
LLMAnthropic Claude API
StorageCloudflare R2 / S3 (via S3-compatible SDK)
BillingStripe
Cache/QueueRedis (Upstash)
AnalyticsPostHog
WebhooksSvix (Clerk)
Port4000 (default)
Global prefixapi/v1

Module Map

AppModule
├── AuthModule        — JWT, OAuth, Clerk sync, org management
├── ChatModule        — LLM streaming via SSE
├── WorkspacesModule  — Workspace CRUD
├── TasksModule       — Task management + AI reprioritization
├── TeamsModule       — Team & membership management
├── ConnectorsModule  — MCP connector instances
├── ConnectorProvidersModule — Provider registry
├── MCPOAuthModule    — Server-mediated OAuth for integrations
├── WorkspaceSyncModule — File sync + SSE change feed
├── BillingModule     — Stripe subscriptions + webhooks
├── MeteringModule    — Token usage + quota enforcement
├── UpdatesModule     — Desktop app release management
└── AdminModule       — Internal enterprise + release admin

Startup (main.ts)

On bootstrap:

  1. Creates NestJS app with bodyParser: false to allow raw body access for webhook signature verification.
  2. Sets up raw body middleware for /api/v1/billing/webhook and /api/v1/auth/webhook (Stripe + Svix need the raw bytes).
  3. Configures CORS to allow requests from localhost:3000, localhost:5173, Electron app:// origin, and 127.0.0.1.
  4. Sets up Clerk Frontend API proxy at /__clerk/* — forwards to clerk.getcosmo.app with proxy headers. This lets the Electron desktop app load Clerk from localhost.
  5. Applies global exception filter (catches unhandled errors, sends 5xx to PostHog).
  6. Sets global prefix api/v1.
  7. Listens on process.env.PORT ?? 4000.

Auth Model

All endpoints (except webhooks and the public connector-providers list) require a Bearer token in the Authorization header.

Two token types are accepted by ClerkAuthGuard:

TypeFormatIssued by
Cosmo JWTCustom 30-day JWTPOST /api/v1/auth/exchange-token
Clerk JWTShort-lived Clerk session tokenClerk SDK

When a Clerk JWT is presented, the guard syncs user/org/membership data from Clerk into the local DB on first use. The guard attaches a RequestUser object to req.user:

interface RequestUser {
  userId: string;
  orgId: string;
  orgRole: OrgRole;
}

Tenant Isolation

Every query, every endpoint, every WebSocket message is scoped to orgId. There is no cross-tenant data access. The orgId is always derived from the verified JWT — it cannot be supplied by the client.

Storage Architecture

All file content lives in R2/S3 blob storage. PostgreSQL is a metadata index only — it holds StorageObject records with a storageKey (the blob key) but never the file bytes.

/{orgId}/shared/hub-memory/          ← Org-level hub memory
/{orgId}/shared/brand/               ← Brand assets
/{orgId}/shared/templates/           ← Shared templates
/{orgId}/teams/{teamId}/memory/      ← Team memory
/{orgId}/workspaces/{workspaceId}/   ← Workspace artifacts + memory
/{orgId}/personal/{userId}/          ← Personal drafts, user memory

Error Handling

GlobalExceptionFilter catches all unhandled exceptions:

  • Returns { statusCode, message, timestamp, path } JSON.
  • Sends only 5xx errors to PostHog (4xx errors are user mistakes, not bugs).

Environment Variables

VariableDescription
DATABASE_URLPostgreSQL connection string
CLERK_SECRET_KEYClerk backend secret
CLERK_PUBLISHABLE_KEYClerk public key
CLERK_PROXY_URLClerk Frontend API proxy URL
CLERK_FAPI_HOSTClerk Frontend API host
CLERK_WEBHOOK_SECRETSvix webhook verification secret
ANTHROPIC_API_KEYClaude API key
STRIPE_SECRET_KEYStripe backend secret
STRIPE_PUBLISHABLE_KEYStripe public key
STRIPE_WEBHOOK_SECRETStripe webhook signing secret
POSTHOG_API_KEYPostHog project API key
POSTHOG_HOSTPostHog host
PORTServer port (default: 4000)
COSMO_SERVER_URLServer's public URL
COSMO_WEB_URLWeb app URL
CORS_ORIGINSComma-separated allowed origins