Otto Docs
Reference

Environment Variables Reference

> Complete reference for all environment variables consumed by the Otto backend, ARQ workers, and Docker infrastructure.

Complete reference for all environment variables consumed by the Otto backend, ARQ workers, and Docker infrastructure.

Quick Start: Minimum Required

VariablePurpose
REDIS_URLRedis connection (queues, checkpoints, cache)
OPENAI_API_KEY or GOOGLE_API_KEY or USE_OLLAMA=trueAt least one LLM provider

Everything else has sensible defaults and is optional unless you enable specific integrations.


LLM Provider

One LLM provider is required. If multiple are configured, precedence is: Gemini > Ollama > OpenAI.

VariableDefaultRequiredDescription
OPENAI_API_KEY--Yes (if using OpenAI)OpenAI API key for LLM and embeddings
OPENAI_MODELgpt-5-miniNoOpenAI model name for the main agent
OPEN_AI_BASEhttps://api.openai.com/v1NoCustom OpenAI-compatible API base URL
USE_GEMINIfalseNoSet to true to use Google Gemini as LLM provider
GEMINI_MODELgemini-3.1-pro-preview-customtoolsNoGemini model name
GOOGLE_API_KEY--Yes (if USE_GEMINI=true)Google API key for Gemini LLM and embeddings
USE_OLLAMAfalseNoSet to true to use Ollama as local LLM provider
OLLAMA_MODELgpt-oss:latestNoOllama model name for the main agent
OLLAMA_BASE_URLhttp://localhost:11434NoOllama server base URL
MISTRAL_API_KEY--NoMistral API key (passed through docker-compose only)

Notes:

  • OPENAI_API_KEY is also used for embeddings when OpenAI is the active provider.
  • GOOGLE_API_KEY is only needed when USE_GEMINI=true.
  • OPEN_AI_BASE allows using OpenAI-compatible APIs (e.g., Azure OpenAI, local proxies).

Embeddings

VariableDefaultRequiredDescription
EMBEDDING_MODELmodels/gemini-embedding-001 (Gemini) or text-embedding-3-small (OpenAI)NoOverride the embedding model name; default depends on active LLM provider
OLLAMA_EMBED_MODELnomic-embed-text:latestNoEmbedding model for Ollama provider

The embedding provider is automatically selected based on the active LLM provider. These variables override the default model name only.


Database and Redis

VariableDefaultRequiredDescription
DATABASE_URLsqlite:///./otto.dbNoDatabase connection string (SQLite or PostgreSQL)
REDIS_URLredis://localhost:6379/0YesRedis connection URL for caching, queues, and checkpoints
REDIS_TYPEAuto-detected from URLNoRedis implementation type: standard or upstash
REDIS_PASSWORD--NoRedis authentication password. Used in docker-compose to configure both the Redis server and connection URLs
UPSTASH_REDIS_REST_URL--NoUpstash Redis REST URL (alternative to standard Redis)
UPSTASH_REDIS_REST_TOKEN--NoUpstash Redis REST token

Shared between services: REDIS_URL, DATABASE_URL, and REDIS_PASSWORD must match between the backend API and ARQ worker processes. Docker-compose handles this automatically.


Deployment and Networking

VariableDefaultRequiredDescription
DEPLOYMENT_MODEself-hostedNoself-hosted or hosted. Controls auth middleware, user limits, and Slack behavior
DEPLOYMENT_TYPEcloud_frontendNocloud_frontend or onprem_frontend. Controls CORS origin configuration
FRONTEND_URLhttps://otto.yourcompany.comNoFrontend URL, used for CORS and links in Slack messages
BACKEND_API_URL--NoBackend API URL (logged on startup for debugging)
ALLOWED_ORIGINS--NoComma-separated CORS origins. Fallback when DEPLOYMENT_TYPE is neither cloud_frontend nor onprem_frontend
DEMO_MODE--NoEnables demo mode (docker-compose only)
CLOUDFLARE_TUNNEL_TOKEN--NoCloudflare tunnel token for the tunnel service in docker-compose

Authentication behavior by mode:

DEPLOYMENT_MODEAuthenticationSwagger UI
self-hostedNone (all requests pass through)Available at /docs
hostedFirebase ID token required via Authorization: Bearer <token>Disabled

Storage

VariableDefaultRequiredDescription
STORAGE_BACKENDlocalNoStorage backend: local, gcs, or google_drive
LOCAL_STORAGE_PATH/tmp/otto-filesNoFile system path for local storage and sandbox
GCS_BUCKET_NAME--Yes (if STORAGE_BACKEND=gcs)Google Cloud Storage bucket name
GOOGLE_DRIVE_FOLDER_ID--Yes (if STORAGE_BACKEND=google_drive)Google Drive root folder ID
GOOGLE_SERVICE_ACCOUNT_JSON--ConditionalGoogle service account credentials as JSON or base64-encoded JSON
GOOGLE_SERVICE_ACCOUNT_FILE--ConditionalPath to Google service account JSON key file (alternative to GOOGLE_SERVICE_ACCOUNT_JSON)
STORAGE_QUOTA_GB0 (unlimited)NoMaximum storage quota in GB. 0 disables the limit

Notes:

  • GOOGLE_SERVICE_ACCOUNT_JSON and GOOGLE_SERVICE_ACCOUNT_FILE are mutually exclusive. Provide one or the other for GCS/Drive backends.
  • LOCAL_STORAGE_PATH is also used as the sandbox root for file tools and skill scripts.

Memory and Vector Store

VariableDefaultRequiredDescription
OTTO_MEMORY_DB<LOCAL_STORAGE_PATH>/otto_memory.dbNoPath to the SQLite vector memory database
COMPACTION_THRESHOLD12NoMessage count before conversation compaction triggers
MAX_RECENT_MESSAGES8NoNumber of recent messages to keep uncompacted

Slack Integration

VariableDefaultRequiredDescription
SLACK_MCP_XOXB_TOKEN--Yes (if using Slack)Slack bot user OAuth token (xoxb-...). Primary token used across all Slack functionality
SLACK_SIGNING_SECRET--Yes (if using Slack)Slack app signing secret for request HMAC verification
SLACK_BOT_USER_ID--NoSlack bot user ID for detecting self-mentions in channels
SLACK_BOT_TOKEN--NoLegacy; docker-compose only. Python code reads SLACK_MCP_XOXB_TOKEN instead
SLACK_MCP_XOXC_TOKEN--NoSlack user cookie token (MCP Slack tool, legacy)
SLACK_MCP_XOXD_TOKEN--NoSlack user session token (MCP Slack tool, legacy)

Notes:

  • SLACK_MCP_XOXB_TOKEN must be set on both the backend and worker. Docker-compose shares it automatically.
  • Slack endpoints use HMAC signature verification via SLACK_SIGNING_SECRET, independent of Firebase auth.

Email Integration

VariableDefaultRequiredDescription
SMTP_HOST--Yes (if sending email)SMTP server hostname (e.g., smtp.gmail.com)
SMTP_PORT465Yes (if sending email)SMTP server port
SMTP_USER--Yes (if sending/receiving email)SMTP/IMAP username (usually the email address)
SMTP_PASS--Yes (if sending/receiving email)SMTP/IMAP password or app password
IMAP_HOST--Yes (if receiving email)IMAP server hostname (e.g., imap.gmail.com)
IMAP_PORT993NoIMAP server port
IMAP_CHECK60NoEmail check interval in seconds

Note: SMTP_USER and SMTP_PASS are shared between SMTP (outbound) and IMAP (inbound) connections.


MCP (Model Context Protocol)

VariableDefaultRequiredDescription
MCP_CONFIG_JSON--NoFull MCP server configuration as a JSON string (preferred in production)
MCP_SERVERS--NoFile path to mcp-config.json (legacy alternative to MCP_CONFIG_JSON)
TAVILY_API_KEY--NoTavily API key, passed through to MCP server environment

MCP_CONFIG_JSON format example:

{
  "mcpServers": {
    "server-name": {
      "command": "npx",
      "args": ["-y", "@some/mcp-server"],
      "env": { "API_KEY": "..." }
    }
  }
}

Agent Customization

VariableDefaultRequiredDescription
SPECIALIZATIONGeneral AssistanceNoAgent specialization/persona (e.g., Marketing Assistant)
ADDITIONAL_INSTRUCTIONS--NoExtra instructions appended to the agent system prompt
OTTO_PERSONA_PATH--NoPath to a persona/SOUL.md file for custom agent persona
OTTO_PROJECTS_DIR--NoDirectory containing project-specific persona files

Note: When a SOUL.md file is loaded from OTTO_PERSONA_PATH, its specialization and instructions fields override SPECIALIZATION and ADDITIONAL_INSTRUCTIONS respectively.


Skills System

VariableDefaultRequiredDescription
SKILLS_REFRESH_INTERVAL60NoSeconds between skill directory rescans
OTTO_SKILL_THRESHOLD0.35NoMinimum similarity score for a skill to match user input
OTTO_MAX_SKILLS3NoMaximum number of skills to load per task
OTTO_SCRIPT_TIMEOUT120NoTimeout in seconds for skill script execution

Performance Tuning

VariableDefaultRequiredDescription
MAX_PARALLEL_TOOL_CALLS5NoMaximum tool calls the agent executes in parallel per turn
MEDIUM_RESULT_THRESHOLD4000NoCharacter count triggering medium-length result truncation
LARGE_RESULT_THRESHOLD12000NoCharacter count triggering large-result truncation (first 20 lines only)
ENABLE_INTENT_PREPROCESSINGfalseNoEnable semantic intent preprocessing for tool matching (experimental)

Hosted / Multi-Tenant

These variables only apply when DEPLOYMENT_MODE=hosted.

VariableDefaultRequiredDescription
MAX_USERS0 (unlimited)NoMaximum number of users allowed. 0 means unlimited
TIERself-hostedNoDeployment tier label returned in the team info endpoint
FIREBASE_PROJECT_ID--Yes (if DEPLOYMENT_MODE=hosted)Firebase project ID for authentication middleware
OTTO_VERSIONdevNoApplication version string reported in the health endpoint

LangSmith / LangChain Tracing

Both LANGCHAIN_* and LANGSMITH_* prefixes are supported. They are synced automatically on startup -- setting one sets both.

VariableDefaultRequiredDescription
LANGCHAIN_API_KEY--NoLangSmith API key. Enables tracing when set
LANGCHAIN_TRACING_V2falseNoEnable LangChain tracing v2
LANGCHAIN_ENDPOINThttps://api.smith.langchain.comNoLangSmith API endpoint URL
LANGCHAIN_PROJECTdefaultNoLangSmith project name for trace grouping
LANGSMITH_API_KEYSynced from LANGCHAIN_API_KEYNoAlias for LANGCHAIN_API_KEY
LANGSMITH_TRACINGfalseNoAlias for LANGCHAIN_TRACING_V2
LANGSMITH_ENDPOINTSynced from LANGCHAIN_ENDPOINTNoAlias for LANGCHAIN_ENDPOINT
LANGSMITH_PROJECTSynced from LANGCHAIN_PROJECTNoAlias for LANGCHAIN_PROJECT

Docker / Infrastructure

These variables are consumed by docker-compose or the otto CLI, not by Python application code directly.

VariableDefaultRequiredDescription
PYTHONPATH/appNoPython module search path inside the container
FASTAPI_ENVdevelopmentNoFastAPI environment hint (dev compose only)
BACKEND_IMAGE_TAGlatestNoDocker image tag for the backend container
FRONTEND_IMAGE_TAGlatestNoDocker image tag for the frontend container
GITHUB_TOKEN--NoGitHub PAT for authenticated image pulls during otto update
OTTO_MEMORY_DB_PATH/data/team_memory/otto_memory.dbNoDocker-level path for the team memory DB volume mount. Python reads OTTO_MEMORY_DB instead

Variables That Must Match Across Services

When running the backend API and ARQ worker as separate processes (the default in Docker), these variables must have identical values in both:

VariableWhy
REDIS_URLBoth use the same Redis for queues and checkpoints
DATABASE_URLBoth read/write the same task database
OPENAI_API_KEY / GOOGLE_API_KEYWorker makes LLM calls
OPENAI_MODEL / GEMINI_MODEL / OLLAMA_MODELModel must match between API and worker
USE_GEMINI / USE_OLLAMAProvider selection must match
SLACK_MCP_XOXB_TOKENWorker sends Slack notifications on task completion
STORAGE_BACKEND / LOCAL_STORAGE_PATHWorker reads/writes files
MCP_CONFIG_JSON / MCP_SERVERSWorker initializes MCP tool servers

Docker-compose passes these from a single .env file to both services automatically.