src/shared/config/env.schema.ts. Missing required fields prevent the server from booting
so we never run with half-configured dependencies.
Server & Runtime
| Variable | Required | Default | Description |
|---|---|---|---|
NODE_ENV | No | development | development, production, or test |
PORT | No | 8080 | Bun server port |
LOG_LEVEL | No | info | Logging verbosity: debug, info, warn, error |
Database (MongoDB)
| Variable | Required | Default | Description |
|---|---|---|---|
DATABASE_URL | Yes | - | MongoDB connection string |
MONGODB_URI | No | - | Alternative to DATABASE_URL |
MONGODB_DATABASE | No | handauncle | Database name override |
MONGODB_MAX_POOL_SIZE | No | 10 | Maximum connection pool size |
MONGODB_MIN_POOL_SIZE | No | 2 | Minimum connection pool size |
MONGODB_CONNECT_TIMEOUT | No | 10000 | Connection timeout in ms |
MONGODB_SERVER_SELECTION_TIMEOUT | No | 5000 | Server selection timeout in ms |
MONGODB_RETRY_WRITES | No | true | Enable retry writes |
MONGODB_RETRY_READS | No | true | Enable retry reads |
Redis / Caching
| Variable | Required | Default | Description |
|---|---|---|---|
REDIS_PROVIDER | No | redis | redis or upstash |
REDIS_URL | Conditional | - | Standard Redis connection string (when REDIS_PROVIDER=redis) |
REDIS_HOST | No | - | Redis host (alternative to URL) |
REDIS_PORT | No | - | Redis port |
REDIS_PASSWORD | No | - | Redis password |
REDIS_DB | No | - | Redis database number |
UPSTASH_REDIS_REST_URL | Conditional | - | Required when REDIS_PROVIDER=upstash |
UPSTASH_REDIS_REST_TOKEN | Conditional | - | Required when REDIS_PROVIDER=upstash |
URLs & Security
| Variable | Required | Default | Description |
|---|---|---|---|
FRONTEND_URL | No | - | Frontend application URL |
BACKEND_URL | No | - | Backend API URL (used for generating absolute links) |
APP_URL | No | - | Base URL for shared links |
SHARE_BASE_URL | No | - | Override for share link base URL |
BACKEND_SECRET | Yes | - | Secret for internal API auth (min 16 chars) |
WEBHOOK_SECRET | No | - | Secret for validating incoming webhooks |
Auth0 (Identity)
| Variable | Required | Default | Description |
|---|---|---|---|
AUTH0_DOMAIN | Yes | - | e.g. handauncle.us.auth0.com |
AUTH0_CLIENT_ID | Yes | - | API client ID for JWT verification |
AUTH0_CLIENT_SECRET | Yes | - | API client secret |
AUTH0_AUDIENCE | Yes | - | API identifier that must match Auth0 config |
AUTH0_MANAGEMENT_CLIENT_ID | Yes | - | Management API client ID |
AUTH0_MANAGEMENT_CLIENT_SECRET | Yes | - | Management API client secret |
AUTH0_MANAGEMENT_API_AUDIENCE | No | - | Management API audience |
AUTH0_PHONE_CONNECTION | No | - | Database connection for phone OTP users |
AUTH0_PHONE_EMAIL_DOMAIN | No | - | Domain for synthetic emails (phone users) |
AI Providers
| Variable | Required | Default | Description |
|---|---|---|---|
AI_PROVIDER | No | openai | openai, anthropic, or multi |
OpenAI
| Variable | Required | Default | Description |
|---|---|---|---|
OPENAI_API_KEY | Conditional | - | Required when AI_PROVIDER=openai or multi |
OPENAI_DEFAULT_MODEL | No | gpt-4o | Default model name |
OPENAI_MAX_TOKENS | No | 4096 | Max tokens per request |
OPENAI_TEMPERATURE | No | 0.7 | Temperature for generation |
Anthropic
| Variable | Required | Default | Description |
|---|---|---|---|
ANTHROPIC_API_KEY | Conditional | - | Required when AI_PROVIDER=anthropic or multi |
ANTHROPIC_DEFAULT_MODEL | No | claude-3-5-sonnet-20241022 | Default model name |
ANTHROPIC_MAX_TOKENS | No | 4096 | Max tokens per request |
ANTHROPIC_TEMPERATURE | No | 0.7 | Temperature for generation |
Other AI Services
| Variable | Required | Default | Description |
|---|---|---|---|
GOOGLE_GENERATIVE_AI_API_KEY | No | - | Gemini API key |
GROQ_API_KEY | No | - | Groq API key for query generation |
TAVILY_API_KEY | No | - | Tavily search API key |
Vector Database (Pinecone)
| Variable | Required | Default | Description |
|---|---|---|---|
PINECONE_API_KEY | Yes | - | Pinecone API key |
PINECONE_INDEX_NAME | No | handauncle-sparse | Index name for vector storage |
RERANK_MODEL | No | bge-reranker-v2-m3 | Reranking model for RAG |
Supermemory (Conversation Memory)
| Variable | Required | Default | Description |
|---|---|---|---|
SUPERMEMORY_API_KEY | Yes | - | Supermemory API key |
SUPERMEMORY_BASE_URL | No | - | Custom base URL |
SUPERMEMORY_PROVIDER_NAME | No | - | Provider name override |
SUPERMEMORY_PROVIDER_API_KEY | No | - | Provider API key override |
SUPERMEMORY_PROVIDER_BASE_URL | No | - | Provider base URL override |
SUPERMEMORY_MEMORY_WINDOW_SIZE | No | - | Memory window size |
SUPERMEMORY_ENABLE_SEMANTIC_SEARCH | No | true | Enable semantic search |
SUPERMEMORY_ENABLE_CROSS_CONVERSATION | No | true | Enable cross-conversation memory |
SUPERMEMORY_ENABLE_PROFILE_API | No | true | Enable profile API |
SUPERMEMORY_RETRIEVAL_LIMIT | No | - | Limit for memory retrieval |
SUPERMEMORY_CACHE_TTL | No | - | Cache TTL in seconds |
SUPERMEMORY_BATCH_SIZE | No | - | Batch size for operations |
SUPERMEMORY_USE_ROUTER | No | false | Enable memory router |
SUPERMEMORY_USE_API | No | true | Enable memory API |
RAG Configuration
| Variable | Required | Default | Description |
|---|---|---|---|
RAG_ENABLED | No | false | Enable retrieval augmented generation |
RAG_NAMESPACE | No | knowledge-base | Namespace for RAG documents |
LangFuse (Observability)
| Variable | Required | Default | Description |
|---|---|---|---|
LANGFUSE_PUBLIC_KEY | No | - | Public key for tracing |
LANGFUSE_SECRET_KEY | No | - | Secret key for tracing |
LANGFUSE_HOST | No | - | Custom host URL |
LANGFUSE_SYSTEM_PROMPT_NAME | No | financial-advisor-system | System prompt name |
LANGFUSE_PROMPT_LABEL | No | production | Prompt label for runs |
LANGFUSE_CACHE_TTL_SECONDS | No | 60 | Prompt cache duration |
LANGFUSE_WEBHOOK_SECRET | No | - | Secret for validating Langfuse webhooks |
Messaging (SMS/Email)
Exotel (OTP via SMS)
| Variable | Required | Default | Description |
|---|---|---|---|
EXOTEL_API_KEY | No | - | API Key from Exotel Dashboard |
EXOTEL_API_TOKEN | No | - | API Token from Exotel Dashboard |
EXOTEL_SID | No | - | Account SID (used in URL path) |
EXOTEL_FROM_NUMBER | No | - | Sender ID |
EXOTEL_SUBDOMAIN | No | api.exotel.com | api.exotel.com (Singapore) or api.in.exotel.com (Mumbai) |
OTP_EXPIRY_SECONDS | No | 300 | OTP expiry time (5 minutes) |
OTP_RESEND_COOLDOWN_SECONDS | No | 60 | Cooldown between resends |
OTP_MAX_ATTEMPTS | No | 5 | Max verification attempts per OTP |
Twilio & SendGrid (Fallback)
| Variable | Required | Default | Description |
|---|---|---|---|
TWILIO_ACCOUNT_SID | No | - | Twilio Account SID |
TWILIO_AUTH_TOKEN | No | - | Twilio Auth Token |
SENDGRID_API_KEY | No | - | SendGrid API key for emails |
Google Cloud Storage
| Variable | Required | Default | Description |
|---|---|---|---|
GCS_PROJECT_ID | No | - | GCP Project ID |
GCS_BUCKET_NAME | No | - | Storage bucket name |
GCS_KEY_FILENAME | No | - | Path to service account key file |
GCS_PUBLIC_ACCESS | No | false | Whether generated URLs are public |
Usage & Billing
| Variable | Required | Default | Description |
|---|---|---|---|
FREE_MESSAGE_THRESHOLD | No | 100 | Number of free AI messages returned by /app/launch |
Tips
- Keep secrets in
.env.development.local; Bun loads it automatically. - When switching Redis providers, only set the fields relevant to that provider to satisfy the schema refinements.
- If validation fails on boot, Bun logs every missing field—fix them before retrying.
- For
AI_PROVIDER=multi, both OpenAI and Anthropic keys are required.