# Pierre MCP Server - Development Environment
# Copy this to .envrc for local development settings
# ============================================================================
# PROVIDER CONFIGURATION - Pluggable Provider Architecture (Phase 1)
# ============================================================================
# Default Provider
# Set which provider to use as default: "strava", "garmin", "synthetic"
# - "synthetic": Development without OAuth (default if not set)
# - "strava": Real OAuth testing with Strava
# - "garmin": Real OAuth testing with Garmin
export PIERRE_DEFAULT_PROVIDER=strava
# ----------------------------------------------------------------------------
# Strava Provider Configuration
# ----------------------------------------------------------------------------
# OAuth Credentials (required for Strava OAuth)
export PIERRE_STRAVA_CLIENT_ID=your-strava-client-id
export PIERRE_STRAVA_CLIENT_SECRET=your-strava-client-secret
# Advanced: Override default Strava endpoints (optional)
# Uncomment to customize for testing or proxy scenarios
# export PIERRE_STRAVA_AUTH_URL=https://www.strava.com/oauth/authorize
# export PIERRE_STRAVA_TOKEN_URL=https://www.strava.com/oauth/token
# export PIERRE_STRAVA_API_BASE_URL=https://www.strava.com/api/v3
# export PIERRE_STRAVA_REVOKE_URL=https://www.strava.com/oauth/deauthorize
# Advanced: Override default scopes (optional)
# export PIERRE_STRAVA_SCOPES="activity:read_all,profile:read_all"
# Legacy Variables (backward compatible - will be used if PIERRE_* vars not set)
export STRAVA_CLIENT_ID=your-strava-client-id
export STRAVA_CLIENT_SECRET=your-strava-client-secret
export STRAVA_REDIRECT_URI=http://localhost:8081/api/oauth/callback/strava
# ----------------------------------------------------------------------------
# Garmin Connect Provider Configuration
# ----------------------------------------------------------------------------
# OAuth Credentials (required for Garmin OAuth)
export PIERRE_GARMIN_CLIENT_ID=your-garmin-consumer-key
export PIERRE_GARMIN_CLIENT_SECRET=your-garmin-consumer-secret
# Advanced: Override default Garmin endpoints (optional)
# Uncomment to customize for testing or proxy scenarios
# export PIERRE_GARMIN_AUTH_URL=https://connect.garmin.com/oauthConfirm
# export PIERRE_GARMIN_TOKEN_URL=https://connectapi.garmin.com/oauth-service/oauth/access_token
# export PIERRE_GARMIN_API_BASE_URL=https://apis.garmin.com/wellness-api/rest
# export PIERRE_GARMIN_REVOKE_URL=https://connectapi.garmin.com/oauth-service/oauth/revoke
# Advanced: Override default scopes (optional)
# export PIERRE_GARMIN_SCOPES="wellness:read,activities:read"
# Legacy Variables (backward compatible - will be used if PIERRE_* vars not set)
export GARMIN_CLIENT_ID=your-garmin-consumer-key
export GARMIN_CLIENT_SECRET=your-garmin-consumer-secret
export GARMIN_REDIRECT_URI=http://localhost:8081/api/oauth/callback/garmin
# ----------------------------------------------------------------------------
# Synthetic Provider Configuration
# ----------------------------------------------------------------------------
# No OAuth credentials needed - synthetic provider works out of the box!
# Perfect for development, testing, and demos without external API dependencies.
# Just set PIERRE_DEFAULT_PROVIDER=synthetic (or omit it, as synthetic is the default)
# Bridge OAuth Callback Configuration
# After provider OAuth completes, server redirects to bridge callback server to trigger focus recovery
export OAUTH_CALLBACK_PORT=35535
# Weather Service Configuration
export OPENWEATHER_API_KEY="your-openweathermap-api-key"
# Server Configuration - Unified Single Port Architecture
export HTTP_PORT="8081"
export RUST_LOG="info"
# Database Configuration
export DATABASE_URL="sqlite:./data/users.db"
# For PostgreSQL: export DATABASE_URL="postgresql://user:pass@localhost/pierre_db"
export JWT_EXPIRY_HOURS="24"
# Admin Token Cache Configuration
# Cache validated admin tokens to reduce database lookups (seconds)
export ADMIN_TOKEN_CACHE_TTL_SECS="300" # Default: 300 (5 minutes)
# PostgreSQL Connection Pool Configuration (when using PostgreSQL)
# These values are automatically optimized for CI vs production environments
export POSTGRES_MAX_CONNECTIONS="10" # Default: 10 (prod), 5 (CI)
export POSTGRES_MIN_CONNECTIONS="0" # Default: 0 (prod), 1 (CI)
export POSTGRES_ACQUIRE_TIMEOUT="30" # Default: 30 (prod), 30 (CI)
# Master Encryption Key for persistent two-tier key management
# Generate with: openssl rand -base64 32
export PIERRE_MASTER_ENCRYPTION_KEY="your-base64-encoded-master-key"
# RSA Key Size for JWT signing (RS256)
# Production: 4096 (higher security, slower ~10s key generation)
# Testing: 2048 (faster ~250ms key generation, sufficient for dev/test)
export PIERRE_RSA_KEY_SIZE="2048" # Use 4096 for production
# Rate Limiting Configuration (tier-based burst limits)
export RATE_LIMIT_FREE_TIER_BURST="10"
export RATE_LIMIT_PROFESSIONAL_BURST="50"
export RATE_LIMIT_ENTERPRISE_BURST="100"
# Backup Configuration
export BACKUP_ENABLED="true"
export BACKUP_INTERVAL="21600" # 6 hours in seconds
export BACKUP_RETENTION="7"
export BACKUP_DIRECTORY="./backups"
# Activity Fetch Limits
export MAX_ACTIVITIES_FETCH="100"
export DEFAULT_ACTIVITIES_LIMIT="20"
# ============================================================================
# FITNESS CONFIGURATION - Environment-Only (Cloud-Native Approach)
# ============================================================================
# All fitness algorithm parameters are now configured via environment variables
# for easy cloud deployment. No TOML files - single source of truth.
# Fitness Effort Thresholds (1-10 scale for workout intensity classification)
export FITNESS_EFFORT_LIGHT_MAX="3.0"
export FITNESS_EFFORT_MODERATE_MAX="5.0"
export FITNESS_EFFORT_HARD_MAX="7.0"
# > 7.0 = very_high
# Heart Rate Zone Thresholds (percentage of max HR)
export FITNESS_ZONE_RECOVERY_MAX="60.0"
export FITNESS_ZONE_ENDURANCE_MAX="70.0"
export FITNESS_ZONE_TEMPO_MAX="80.0"
export FITNESS_ZONE_THRESHOLD_MAX="90.0"
# > 90.0 = vo2max
# Weather Integration Settings
export FITNESS_WEATHER_WIND_THRESHOLD="15.0"
export FITNESS_WEATHER_ENABLED="true"
export FITNESS_WEATHER_CACHE_DURATION_HOURS="24"
export FITNESS_WEATHER_REQUEST_TIMEOUT_SECONDS="10"
export FITNESS_WEATHER_RATE_LIMIT_PER_MINUTE="60"
# Personal Records Configuration
export FITNESS_PR_PACE_IMPROVEMENT_THRESHOLD="5.0"
# OAuth Login Form Defaults (for dev/test only - leave empty in production)
export OAUTH_DEFAULT_EMAIL="user@example.com"
export OAUTH_DEFAULT_PASSWORD="userpass123"
# Admin User Defaults (for dev/test scripts - leave empty in production)
export ADMIN_EMAIL="admin@pierre.mcp"
export ADMIN_PASSWORD="adminpass123"
# ============================================================================
# CACHE CONFIGURATION
# ============================================================================
# Cache TTL Configuration (seconds)
export CACHE_TTL_PROFILE_SECS="86400" # 24 hours - athlete profiles change infrequently
export CACHE_TTL_ACTIVITY_LIST_SECS="900" # 15 minutes - needs to be fresh for new activities
export CACHE_TTL_ACTIVITY_SECS="3600" # 1 hour - activity details rarely change
export CACHE_TTL_STATS_SECS="21600" # 6 hours - stats aggregate over time windows
# Cache General Settings
export CACHE_MAX_ENTRIES="10000"
export CACHE_CLEANUP_INTERVAL_SECS="300" # 5 minutes
# Redis Connection Configuration (when using Redis cache)
# export REDIS_URL="redis://localhost:6379"
export REDIS_CONNECTION_TIMEOUT_SECS="10"
export REDIS_RESPONSE_TIMEOUT_SECS="5"
export REDIS_RECONNECTION_RETRIES="5"
export REDIS_RETRY_EXPONENT_BASE="2"
export REDIS_MAX_RETRY_DELAY_MS="30000"
export REDIS_INITIAL_CONNECTION_RETRIES="3"
export REDIS_INITIAL_RETRY_DELAY_MS="500"
# ============================================================================
# HTTP CLIENT CONFIGURATION
# ============================================================================
# HTTP Client Timeouts (seconds)
export HTTP_CLIENT_TIMEOUT_SECS="30"
export HTTP_CLIENT_CONNECT_TIMEOUT_SECS="10"
export OAUTH_CLIENT_TIMEOUT_SECS="15"
export OAUTH_CLIENT_CONNECT_TIMEOUT_SECS="5"
export API_CLIENT_TIMEOUT_SECS="60"
export API_CLIENT_CONNECT_TIMEOUT_SECS="10"
export HEALTH_CHECK_TIMEOUT_SECS="5"
export OAUTH_CALLBACK_NOTIFICATION_TIMEOUT_SECS="5"
# HTTP Client Retry Configuration
export HTTP_CLIENT_ENABLE_RETRIES="true"
export HTTP_CLIENT_MAX_RETRIES="3"
export HTTP_CLIENT_RETRY_BASE_DELAY_MS="100"
export HTTP_CLIENT_RETRY_MAX_DELAY_MS="5000"
export HTTP_CLIENT_RETRY_JITTER_ENABLED="true"
# ============================================================================
# PROVIDER RETRY CONFIGURATION - Exponential Backoff
# ============================================================================
# These settings control retry behavior for provider API calls (Strava, Garmin, etc.)
# Uses exponential backoff with jitter to prevent thundering herd problems.
# Maximum retry attempts (not counting initial attempt)
# Valid range: 1-100, Default: 3
export PIERRE_RETRY_MAX_ATTEMPTS="3"
# Base delay for exponential backoff (milliseconds)
# Delay doubles with each retry: 1000ms, 2000ms, 4000ms...
# Valid range: 100-300000, Default: 1000
export PIERRE_RETRY_BASE_DELAY_MS="1000"
# Maximum delay between retries (milliseconds)
# Caps the exponential growth to prevent excessive waits
# Valid range: 1000-600000, Default: 30000
export PIERRE_RETRY_MAX_DELAY_MS="30000"
# Jitter factor (0.0 to 1.0) to randomize delays
# Prevents synchronized retries across multiple clients
# Valid range: 0.0-1.0, Default: 0.1
export PIERRE_RETRY_JITTER_FACTOR="0.1"
# ============================================================================
# SSE (SERVER-SENT EVENTS) CONFIGURATION
# ============================================================================
export SSE_CLEANUP_INTERVAL_SECS="300" # 5 minutes
export SSE_CONNECTION_TIMEOUT_SECS="600" # 10 minutes
export SSE_MAX_BUFFER_SIZE="1000"
export SSE_BUFFER_OVERFLOW_STRATEGY="drop_oldest" # Options: drop_oldest, drop_new, close_connection
export SSE_BROADCAST_CHANNEL_SIZE="1000"
export SSE_MAX_CONNECTIONS_PER_USER="5"
export SESSION_COOKIE_MAX_AGE_SECS="86400" # 24 hours
export SESSION_COOKIE_SECURE="false" # Set to true in production with HTTPS
# ============================================================================
# MCP SERVER CONFIGURATION
# ============================================================================
export MCP_PROTOCOL_VERSION="2025-06-18"
export SERVER_NAME="pierre-mcp-server"
export MCP_SESSION_CACHE_SIZE="100"
export MCP_MAX_REQUEST_SIZE="1048576" # 1MB
export MCP_MAX_RESPONSE_SIZE="10485760" # 10MB
export MCP_NOTIFICATION_CHANNEL_SIZE="100"
export MCP_WEBSOCKET_CHANNEL_CAPACITY="1000"
export TCP_KEEP_ALIVE_SECS="60"
# ============================================================================
# PROVIDER RATE LIMITS AND ACTIVITY SETTINGS
# ============================================================================
# Strava Provider Settings
export STRAVA_DEFAULT_ACTIVITIES_PER_PAGE="30"
export STRAVA_MAX_ACTIVITIES_PER_REQUEST="200"
export STRAVA_RATE_LIMIT_15MIN="100"
export STRAVA_RATE_LIMIT_DAILY="15000"
# Fitbit Provider Settings
export FITBIT_RATE_LIMIT_HOURLY="150"
export FITBIT_RATE_LIMIT_DAILY="1000"
# Garmin Provider Settings
export GARMIN_DEFAULT_ACTIVITIES_PER_PAGE="20"
export GARMIN_MAX_ACTIVITIES_PER_REQUEST="100"
export GARMIN_MAX_REQUESTS_PER_HOUR="100"
export GARMIN_MIN_LOGIN_INTERVAL_SECS="300" # 5 minutes
export GARMIN_RATE_LIMIT_BLOCK_DURATION_SECS="3600" # 1 hour
# ============================================================================
# OAUTH RATE LIMITING
# ============================================================================
export OAUTH_AUTHORIZE_RATE_LIMIT_RPM="60"
export OAUTH_TOKEN_RATE_LIMIT_RPM="30"
export OAUTH_REGISTER_RATE_LIMIT_RPM="10"
export OAUTH2_RATE_LIMIT_WINDOW_SECS="60"
export RATE_LIMITER_CLEANUP_THRESHOLD="1000"
export RATE_LIMITER_STALE_ENTRY_TIMEOUT_SECS="120"
# ============================================================================
# SYSTEM MONITORING
# ============================================================================
export MONITORING_MEMORY_WARNING_THRESHOLD="80.0" # Warn at 80% memory usage
export MONITORING_DISK_WARNING_THRESHOLD="85.0" # Warn at 85% disk usage
# ============================================================================
# ROUTE TIMEOUT CONFIGURATION
# ============================================================================
export ROUTE_TIMEOUT_DATABASE_SECS="30"
export ROUTE_TIMEOUT_PROVIDER_API_SECS="60"
export ROUTE_TIMEOUT_SSE_EVENT_SECS="5"
export ROUTE_TIMEOUT_OAUTH_SECS="15"
export ROUTE_TIMEOUT_DEFAULT_SECS="30"
export ROUTE_TIMEOUT_UPLOAD_SECS="300"
export ROUTE_TIMEOUT_LONG_POLLING_SECS="300"
export ROUTE_TIMEOUT_MCP_SAMPLING_SECS="30"
export ROUTE_TIMEOUT_GEOCODING_SECS="10"
# ============================================================================
# TOKIO RUNTIME CONFIGURATION
# ============================================================================
# Uncomment to customize Tokio runtime settings
# export TOKIO_WORKER_THREADS="" # Default: CPU count
# export TOKIO_THREAD_STACK_SIZE="" # Default: ~2MB
export TOKIO_THREAD_NAME="pierre-worker"
# ============================================================================
# SQLX CONNECTION POOL CONFIGURATION
# ============================================================================
# export SQLX_IDLE_TIMEOUT_SECS="" # Default: 10 min (PostgreSQL)
# export SQLX_MAX_LIFETIME_SECS="" # Default: 30 min
export SQLX_TEST_BEFORE_ACQUIRE="true"
# export SQLX_STATEMENT_CACHE_CAPACITY="" # Default: 100