import { readFileSync } from "fs"; function env(key: string, fallback?: string): string { const val = process.env[key] ?? fallback; if (val === undefined) throw new Error(`Missing required env var: ${key}`); return val; } function envOptional(key: string, fallback = ""): string { return process.env[key] ?? fallback; } export const config = { port: parseInt(envOptional("PORT", "4100")), host: envOptional("HOST", "0.0.0.0"), // JWT jwtSecret: env("JWT_SECRET"), jwtExpiresIn: envOptional("JWT_EXPIRES_IN", "7d"), // Database dbUrl: env("DATABASE_URL"), // Redis redisUrl: envOptional("REDIS_URL", "redis://localhost:6379"), // Encryption key for LiteLLM virtual keys stored in DB (32-byte hex) encryptionKey: env("ENCRYPTION_KEY"), // LiteLLM litellmUrl: envOptional("LITELLM_URL", "http://litellm:4000"), litellmMasterKey: env("LITELLM_MASTER_KEY"), // Self-referencing URL for MCP demux (used in LiteLLM MCP server registration) agilitonAccountUrl: envOptional("AGILITON_ACCOUNT_URL", "http://agiliton-account:4100"), // Shared secret used by LiteLLM when calling /mcp/demux/:id/mcp mcpBridgeSecret: env("MCP_BRIDGE_SECRET"), // Google OAuth googleClientId: env("GOOGLE_CLIENT_ID"), googleClientSecret: env("GOOGLE_CLIENT_SECRET"), // Microsoft OAuth msClientId: envOptional("MS_CLIENT_ID"), msTenantId: envOptional("MS_TENANT_ID", "common"), // Default budget per customer (USD, 30 days) defaultBudgetUsd: parseFloat(envOptional("DEFAULT_BUDGET_USD", "30.0")), defaultBudgetDuration: envOptional("DEFAULT_BUDGET_DURATION", "30d"), defaultRpmLimit: parseInt(envOptional("DEFAULT_RPM_LIMIT", "30")), defaultModels: envOptional( "DEFAULT_MODELS", "claude-sonnet-4-6,claude-opus-4-6,grok-heavy" ).split(","), // WebSocket MCP bridge timeout (ms) mcpBridgeTimeoutMs: parseInt(envOptional("MCP_BRIDGE_TIMEOUT_MS", "15000")), } as const;