Skip to main content

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:
  1. .env - Specifies which configuration to use
  2. config.[env].yaml - Your environment-specific configuration
  3. config.yaml - Base configuration (immutable, do not edit)

Setup Steps

1

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
2

Create your configuration file

Create config.localdb.yaml (or match your ENV value):
touch config.localdb.yaml
3

Configure essential settings

Add at least one LLM API key and configure agents:
config.localdb.yaml
# ============ 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:
config.localdb.yaml
# 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:
config.localdb.yaml
# 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
For detailed comparison of agent capabilities, see Tools Overview.

OAuth Provider Configuration

To integrate health device providers, you need OAuth credentials from each provider’s developer portal.

Garmin Connect

1

Register as a Garmin Developer

  1. Visit Garmin Connect Developer Portal
  2. Sign in with your Garmin account
  3. Navigate to “Applications” and create a new application
  4. Fill in application details and submit for approval
Garmin approval process can take several business days.
2

Get OAuth Credentials

Once approved, you’ll receive:
  • Consumer Key (Client ID)
  • Consumer Secret (Client Secret)
3

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
4

Add to your config file

config.localdb.yaml
# 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

1

Register as a Whoop Developer

  1. Visit Whoop Developer Portal
  2. Create a developer account
  3. Create a new application
  4. Set required scopes:
    • offline (for refresh tokens)
    • read:recovery
    • read:sleep
    • read:cycles
    • read:profile
    • read:workout
    • read:body_measurement
2

Get OAuth2 Credentials

You’ll receive:
  • Client ID
  • Client Secret
3

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
4

Add to your config file

config.localdb.yaml
# 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

config.yaml
# OpenAI Configuration
OPENAI_API_KEY: 'sk-...'
OPENAI_API_KEY_RTC: 'sk-...'  # For real-time API (optional)
1

Get API Key

  1. Sign up at OpenAI Platform
  2. Navigate to API Keys section
  3. Create a new API key

Google AI (Gemini)

config.yaml
# Google AI Configuration
GOOGLE_API_KEY: 'AIza...'
1

Get API Key

  1. Visit Google AI Studio
  2. Create a new API key

OpenRouter

config.yaml
# OPENROUTER Configuration
OPENROUTER_API_KEY: 'sk-or-...'  # For AI chat and agents
1

Get OpenRouter API Key

  1. Sign up at OpenRouter
  2. Navigate to Keys section
  3. Create a new API key

Anthropic (Claude)

config.yaml
# Anthropic Configuration
ANTHROPIC_API_KEY: 'sk-ant-...'
1

Get API Key

  1. Sign up at Anthropic Console
  2. Navigate to API Keys
  3. Create a new API key

Database Configuration

PostgreSQL

config.yaml
# 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

config.yaml
# 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

config.yaml
# 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

config.yaml
# 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

config.yaml
# 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:
  1. Use strong, randomly generated keys
  2. Never commit production keys to version control
  3. Rotate keys periodically
  4. 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

config.yaml
GOOGLE_CLIENT_ID: 'your_client_id.apps.googleusercontent.com'
FIREBASE_PROJECT_ID: 'your_project_id'
Get credentials from Google Cloud Console.

Logging Configuration

config.yaml
# Logging Configuration
LOG_NAME: ''                     # Leave empty for default
LOG_DIR: ''                      # Leave empty for stdout
LOG_LEVEL: 'INFO'                # DEBUG, INFO, WARNING, ERROR, CRITICAL
LevelDescriptionUse Case
DEBUGDetailed informationDevelopment, debugging
INFOGeneral informationProduction monitoring
WARNINGWarning messagesProduction alerts
ERRORError messagesProduction errors
CRITICALCritical failuresSystem failures

Cloud Storage (Optional)

Configure S3-compatible storage for backups and assets:
config.yaml
# 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

config.yaml
# 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:
config.yaml
# 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

config.yaml
SERPER_API_KEY: ''               # From serper.dev

E2B (Code Execution)

config.yaml
E2B_API_KEY: ''                  # From e2b.dev

FAL (AI Generation)

config.yaml
FAL_KEY: ''                      # From fal.ai

OAuth Behavior Configuration

config.yaml
# 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

Tool Management

config.yaml
# 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

config.yaml
# 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: '*'

Configuration Validation

After updating config.yaml, validate your configuration:
1

Check syntax

python -c "import yaml; yaml.safe_load(open('config.yaml'))"
No output means the YAML syntax is valid.
2

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())
"
3

Test Redis connection

docker-compose exec redis redis-cli ping
Should return PONG.

Configuration Best Practices

For sensitive values, use environment variables:
config.yaml
OPENAI_API_KEY: ${OPENAI_API_KEY}
PG_PASSWORD: ${POSTGRES_PASSWORD}
Then set in .env:
.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.)
  • Adjust database connection pool sizes based on load
  • Configure appropriate timeouts
  • Tune Redis cache settings
  • Monitor and adjust concurrent request limits

Next Steps