Configuration Overview
Mirobody Health uses YAML-based configuration files for all system settings. This guide covers all configuration options and how to set them up properly.
Configuration changes require restarting the application to take effect.
Configuration File Structure
Mirobody Health uses environment-specific configuration files:
.env - Specifies which configuration to use
config.[env].yaml - Your environment-specific configuration
config.yaml - Base configuration (immutable, do not edit)
Setup Steps
Create .env file
echo "ENV=localdb" > .env
The ENV variable determines which config file to load:
ENV=localdb → loads config.localdb.yaml
ENV=production → loads config.production.yaml
ENV=staging → loads config.staging.yaml
Create your configuration file
Create config.localdb.yaml (or match your ENV value): touch config.localdb.yaml
Configure essential settings
Add at least one LLM API key and configure agents: # ============ LLM API Keys (At least one required) ============
GOOGLE_API_KEY : '' # For Gemini models
OPENAI_API_KEY : '' # For GPT models
OPENROUTER_API_KEY : '' # For Claude, DeepSeek, etc.
# ============ Agent Configuration ============
MCP_TOOL_DIRS :
- mirobody/pub/tools
- mirobody/pub/tools_health
MCP_RESOURCE_DIRS :
- mirobody/pub/resources
AGENT_DIRS :
- mirobody/pub/agents
Do not edit config.yaml - This is the base configuration file that should remain unchanged. All customizations go in your environment-specific file (e.g., config.localdb.yaml).
Agent Configuration
Mirobody Health includes two agent types: DeepAgent (LangChain-based) and BaselineAgent (native Gemini/MiroThinker).
DeepAgent Configuration
DeepAgent supports multiple LLM providers and is recommended for complex tasks:
# API Keys for DeepAgent
GOOGLE_API_KEY : 'your_google_api_key' # For Gemini models
OPENAI_API_KEY : 'your_openai_api_key' # For GPT models
OPENROUTER_API_KEY : 'your_openrouter_key' # For Claude, DeepSeek, etc.
# Provider Configurations for DeepAgent
PROVIDERS_DEEP :
gemini-3-flash :
llm_type : google-genai
api_key : GOOGLE_API_KEY
model : gemini-3-flash-preview
temperature : 1.0
gpt-5.1 :
llm_type : openai
api_key : OPENAI_API_KEY
base_url : https://api.openai.com/v1/
model : gpt-5.1
temperature : 0.1
claude-sonnet :
llm_type : openai
api_key : OPENROUTER_API_KEY
base_url : https://openrouter.ai/api/v1
model : anthropic/claude-sonnet-4.5
temperature : 0.1
# Optional: Custom prompts
PROMPTS_DEEP :
- mirobody/pub/agents/deep/prompts/theta_health.jinja
# Optional: Tool filtering
ALLOWED_TOOLS_DEEP : [] # Leave empty to allow all
DISALLOWED_TOOLS_DEEP : [] # Specify tools to disable
BaselineAgent Configuration
BaselineAgent is optimized for lightweight operations:
# API Keys for BaselineAgent
GOOGLE_API_KEY : 'your_google_api_key' # For Gemini models
MIROTHINKER_API_KEY : 'your_mirothinker_key' # For MiroThinker
# Provider Configurations for BaselineAgent
PROVIDERS_BASELINE :
gemini-3-flash :
api_key : GOOGLE_API_KEY
model : gemini-3-flash-preview
gemini-2.5-flash :
api_key : GOOGLE_API_KEY
model : gemini-2.5-flash
miro-thinker :
api_key : MIROTHINKER_API_KEY
model : miro-thinker
OAuth Provider Configuration
To integrate health device providers, you need OAuth credentials from each provider’s developer portal.
Garmin Connect
Register as a Garmin Developer
Visit Garmin Connect Developer Portal
Sign in with your Garmin account
Navigate to “Applications” and create a new application
Fill in application details and submit for approval
Garmin approval process can take several business days.
Get OAuth Credentials
Once approved, you’ll receive:
Consumer Key (Client ID)
Consumer Secret (Client Secret)
Configure Callback URL
Set your callback URL in the Garmin developer portal: http://your-domain.com/api/v1/pulse/theta/theta_garmin/callback
For local development: http://localhost:18080/api/v1/pulse/theta/theta_garmin/callback
Add to your config file
# Garmin OAuth1 Configuration
GARMIN_CLIENT_ID : 'your_consumer_key'
GARMIN_CLIENT_SECRET : 'your_consumer_secret'
GARMIN_REDIRECT_URI : 'http://localhost:18080/api/v1/pulse/theta/theta_garmin/callback'
# API Endpoints (usually don't need to change)
GARMIN_AUTH_URL : 'https://connect.garmin.com/oauthConfirm/'
GARMIN_TOKEN_URL : 'https://connectapi.garmin.com/oauth-service/oauth/request_token'
GARMIN_ACCESS_TOKEN_URL : 'https://connectapi.garmin.com/oauth-service/oauth/access_token'
GARMIN_API_BASE_URL : 'https://apis.garmin.com/wellness-api/rest'
Whoop
Register as a Whoop Developer
Visit Whoop Developer Portal
Create a developer account
Create a new application
Set required scopes:
offline (for refresh tokens)
read:recovery
read:sleep
read:cycles
read:profile
read:workout
read:body_measurement
Configure Redirect URI
Set your redirect URI in the Whoop developer portal: http://your-domain.com/api/v1/pulse/theta/theta_whoop/callback
For local development: http://localhost:18080/api/v1/pulse/theta/theta_whoop/callback
Add to your config file
# Whoop OAuth2 Configuration
WHOOP_CLIENT_ID : 'your_client_id'
WHOOP_CLIENT_SECRET : 'your_client_secret'
WHOOP_REDIRECT_URI : 'http://localhost:18080/api/v1/pulse/theta/theta_whoop/callback'
# Scopes (space-separated)
WHOOP_SCOPES : 'offline read:recovery read:sleep read:cycles read:profile read:workout read:body_measurement'
# API Endpoints (usually don't need to change)
WHOOP_AUTH_URL : 'https://api.prod.whoop.com/oauth/oauth2/auth'
WHOOP_TOKEN_URL : 'https://api.prod.whoop.com/oauth/oauth2/token'
WHOOP_API_BASE_URL : 'https://api.prod.whoop.com/developer/v2'
Leave the client ID and secret empty ('') to disable a provider. The system will automatically skip disabled providers.
AI Provider Configuration
Mirobody Health supports multiple AI providers for chat functionality.
OpenAI
# OpenAI Configuration
OPENAI_API_KEY : 'sk-...'
OPENAI_API_KEY_RTC : 'sk-...' # For real-time API (optional)
Get API Key
Sign up at OpenAI Platform
Navigate to API Keys section
Create a new API key
Google AI (Gemini)
# Google AI Configuration
GOOGLE_API_KEY : 'AIza...'
OpenRouter
# OPENROUTER Configuration
OPENROUTER_API_KEY : 'sk-or-...' # For AI chat and agents
Get OpenRouter API Key
Sign up at OpenRouter
Navigate to Keys section
Create a new API key
Anthropic (Claude)
# Anthropic Configuration
ANTHROPIC_API_KEY : 'sk-ant-...'
Database Configuration
PostgreSQL
# PostgreSQL Configuration
PG_HOST : 'db' # 'localhost' for non-Docker setup
PG_PORT : 5432
PG_USER : 'holistic_user'
PG_DBNAME : 'holistic_db'
PG_PASSWORD : 'REPLACE_THIS_VALUE_IN_PRODUCTION' # Change in production!
PG_SCHEMA : 'theta_ai'
PG_MIN_CONNECTION : 5
PG_MAX_CONNECTION : 20
PG_ENCRYPTION_KEY : 'REPLACE_THIS_VALUE_IN_PRODUCTION' # Change in production!
For production, always use strong, unique passwords and encryption keys.
Redis
# Redis Configuration
REDIS_HOST : 'redis' # 'localhost' for non-Docker setup
REDIS_PORT : 6379
REDIS_DB : 0
REDIS_PASSWORD : 'REPLACE_THIS_VALUE_IN_PRODUCTION' # Change in production!
REDIS_SSL : false
REDIS_SSL_CHECK_HOSTNAME : false
REDIS_SSL_CERT_REQS : 'none'
Server Configuration
HTTP Server Settings
# HTTP Server Configuration
HTTP_SERVER_NAME : 'mirobody'
HTTP_SERVER_VERSION : '1.0.1'
HTTP_HOST : '0.0.0.0' # Listen on all interfaces
HTTP_PORT : 18080 # Change if port is in use
HTTP_URI_PREFIX : '' # Optional URL prefix
# CORS Configuration
HTTP_HEADERS :
Access-Control-Allow-Origin : '*'
Access-Control-Allow-Credentials : 'true'
Access-Control-Allow-Methods : '*'
Access-Control-Allow-Headers : '*'
Access-Control-Max-Age : '86400'
For production, restrict Access-Control-Allow-Origin to specific domains instead of '*'.
Public URLs
# Public URLs (adjust for your domain)
MCP_FRONTEND_URL : 'http://localhost:18080'
MCP_PUBLIC_URL : 'http://localhost:18080'
DATA_PUBLIC_URL : 'http://localhost:18080'
QR_LOGIN_URL : '' # Optional QR code login URL
Security Configuration
JWT and Encryption
# Security Keys
DATABASE_DECRYPTION_KEY : 'REPLACE_THIS_VALUE_IN_PRODUCTION' # 32 characters minimum
JWT_KEY : 'myjwtkey' # Strong secret key
JWT_PRIVATE_KEY : '' # Optional RSA private key
Important Security Practices:
Use strong, randomly generated keys
Never commit production keys to version control
Rotate keys periodically
Use environment variables for sensitive values
Generating Secure Keys
# Generate a random 32-character key
openssl rand -hex 32
# Generate RSA key pair
openssl genrsa -out private_key.pem 2048
openssl rsa -in private_key.pem -pubout -out public_key.pem
Authentication Providers
Google OAuth
Apple Sign In
GOOGLE_CLIENT_ID : 'your_client_id.apps.googleusercontent.com'
FIREBASE_PROJECT_ID : 'your_project_id'
Get credentials from Google Cloud Console . APPLE_TEAM_ID : 'your_team_id'
APPLE_KEY_ID : 'your_key_id'
APPLE_PRIVATE_KEY : 'your_private_key'
APPLE_CLIENT_ID : 'com.yourapp.service'
APPLE_AUTH_CLIENT_ID : 'com.yourapp.client'
Get credentials from Apple Developer Portal .
Logging Configuration
# Logging Configuration
LOG_NAME : '' # Leave empty for default
LOG_DIR : '' # Leave empty for stdout
LOG_LEVEL : 'INFO' # DEBUG, INFO, WARNING, ERROR, CRITICAL
Log Levels
Example Configuration
Level Description Use Case DEBUG Detailed information Development, debugging INFO General information Production monitoring WARNING Warning messages Production alerts ERROR Error messages Production errors CRITICAL Critical failures System failures
For development: LOG_LEVEL : 'DEBUG'
LOG_DIR : './logs'
For production: LOG_LEVEL : 'INFO'
LOG_DIR : '/var/log/mirobody'
Cloud Storage (Optional)
Configure S3-compatible storage for backups and assets:
# S3 Configuration
S3_KEY : 'your_access_key'
S3_TOKEN : 'your_secret_key'
S3_REGION : 'us-east-1'
S3_BUCKET : 'your-bucket-name'
S3_PREFIX : 'mirobody/'
S3_CDN : 'https://cdn.yourdomain.com'
S3 configuration is optional. The system works without cloud storage.
MCP Protocol Configuration
# MCP Tool and Resource Directories
MCP_TOOL_DIRS :
- 'mirobody/pub/tools'
- 'tools' # Optional custom tools directory
MCP_RESOURCE_DIRS :
- 'mirobody/pub/resources'
# Agent Directories
AGENT_DIRS :
- 'mirobody/pub/agents'
# Provider Directories
THETA_PROVIDER_DIRS :
- 'connect/theta' # Your custom providers
Email Configuration (Optional)
For sending email notifications and codes:
# Email Configuration
EMAIL_FROM : '[email protected] '
EMAIL_FROM_NAME : 'Mirobody Health'
EMAIL_TEMPLATE : '' # Path to email templates
EMAIL_SMTP_PASS : 'your_smtp_password'
# Predefined verification codes (development only)
EMAIL_PREDEFINE_CODES :
[email protected] : '777777'
Never use predefined codes in production!
Additional API Services
Serper (Web Search)
SERPER_API_KEY : '' # From serper.dev
E2B (Code Execution)
E2B_API_KEY : '' # From e2b.dev
FAL (AI Generation)
FAL_KEY : '' # From fal.ai
OAuth Behavior Configuration
# OAuth temporary state TTL (seconds)
OAUTH_TEMP_TTL_SECONDS : 900 # 15 minutes
# Provider-specific settings
WHOOP_MAX_DETAIL_RECORDS : 50 # Max records to fetch in detail
WHOOP_CONCURRENT_REQUESTS : 5 # Concurrent API requests
WHOOP_REQUEST_TIMEOUT : 30 # Request timeout in seconds
# Allowed/Disallowed MCP Tools
ALLOWED_TOOLS_SYNERGY :
- tool_name_1
- tool_name_2
DISALLOWED_TOOLS_SYNERGY :
- dangerous_tool
Leave these arrays empty to allow all tools by default.
Environment-Specific Configuration
# Development Settings
LOG_LEVEL : 'DEBUG'
HTTP_HOST : '0.0.0.0'
HTTP_PORT : 18080
# Use local services
PG_HOST : 'localhost'
REDIS_HOST : 'localhost'
# Relaxed CORS
HTTP_HEADERS :
Access-Control-Allow-Origin : '*'
# Production Settings
LOG_LEVEL : 'INFO'
HTTP_HOST : '0.0.0.0'
HTTP_PORT : 443
# Use production services
PG_HOST : 'your-db-host.rds.amazonaws.com'
REDIS_HOST : 'your-redis.cache.amazonaws.com'
# Strict CORS
HTTP_HEADERS :
Access-Control-Allow-Origin : 'https://yourdomain.com'
# Strong security
DATABASE_DECRYPTION_KEY : '[generated-secure-key]'
JWT_KEY : '[generated-secure-key]'
REDIS_PASSWORD : '[strong-password]'
PG_PASSWORD : '[strong-password]'
# SSL/TLS
REDIS_SSL : true
Configuration Validation
After updating config.yaml, validate your configuration:
Check syntax
python -c "import yaml; yaml.safe_load(open('config.yaml'))"
No output means the YAML syntax is valid.
Test database connection
docker-compose exec backend python -c "
from mirobody.utils.config import global_config
import asyncio
async def test():
cfg = global_config()
db = await cfg.get_db()
print('Database connection: OK')
asyncio.run(test())
"
Test Redis connection
docker-compose exec redis redis-cli ping
Should return PONG.
Configuration Best Practices
Use Environment Variables
For sensitive values, use environment variables: OPENAI_API_KEY : ${OPENAI_API_KEY}
PG_PASSWORD : ${POSTGRES_PASSWORD}
Then set in .env: OPENAI_API_KEY = sk-...
POSTGRES_PASSWORD = secure_password
✅ Commit config.example.yaml
❌ Never commit config.yaml with real credentials
✅ Add config.yaml to .gitignore
✅ Document all required configuration keys
Use strong, randomly generated keys
Rotate credentials periodically
Limit CORS origins in production
Enable SSL/TLS for external connections
Use secrets management (AWS Secrets Manager, HashiCorp Vault, etc.)
Next Steps