CLI Reference
The `otto` command is the primary interface for managing your Otto installation. It is a Bash script located at the project root and can be invoked as `./otto` from the project directory or simply ...
The otto command is the primary interface for managing your Otto installation. It is a Bash script located at the project root and can be invoked as ./otto from the project directory or simply otto if the symlink in /usr/local/bin has been set up (done automatically during installation and updates).
Commands
otto start
Start Otto in production mode.
Starts all services using pre-built container images from the GitHub Container Registry. On first run, or if the .env file is missing an LLM provider configuration, the interactive setup wizard runs automatically.
What it does:
- Checks that Docker is installed and running
- Ensures
.envexists and has an LLM provider configured (runsotto configureif not) - Creates data directories:
data/sqlite,data/redis,data/sandbox,data/uploads,data/team_memory,logs,skills - Runs
docker compose -f docker-compose.yml up -d - Reports that Otto is running at
http://localhost:3000
Services started: redis, backend, arq-worker, frontend
Example:
otto stop
Stop all Otto services.
Shuts down containers from both the production and development Compose files. Silently handles cases where one or both are not running.
Example:
otto restart
Restart all running services.
Restarts containers without recreating them. Tries the production Compose file first, then the development Compose file. Reports an error if no running containers are found.
Example:
otto dev
Start the development environment with hot reload.
Starts backend services in Docker (built from local source) and the frontend natively on the host. All Python code changes trigger automatic restarts. Press Ctrl+C to stop everything.
What it does:
- Checks that Docker, Node.js (18+), and npm are installed
- Ensures
.envexists and has an LLM provider configured - Creates data directories
- Installs frontend npm dependencies if
node_modules/is missing - Starts backend, arq-worker, and Redis via
docker-compose.dev.yml - Waits for backend health check at
http://localhost:8000/api/health(up to 60 seconds) - Streams backend and worker logs with color-coded prefixes (
[backend]in cyan,[worker]in yellow) - Starts the Next.js dev server natively on the host
- On
Ctrl+C: stops log streaming, runsdocker compose down, reports "Stopped."
Key differences from production:
- Backend is built from local
./backendsource - Backend runs with
uvicorn --reload - ARQ worker runs with
watchmedo auto-restart - Frontend runs natively (not in Docker)
- Redis port 6379 is exposed to the host
Example:
otto status
Show service status and health.
Displays the state of all running containers and checks whether the backend and frontend are responding.
What it does:
- Shows
docker compose psoutput for running containers - Checks backend health at
http://localhost:8000/api/health - Checks frontend availability at
http://localhost:3000 - Reports each as "healthy" or "not responding"
Example:
otto logs
Tail logs from running containers.
Streams live log output. When called without arguments, shows logs from all services. Specify a service name to filter.
Arguments:
| Argument | Description |
|---|---|
| (none) | Logs from all services |
otto-backend | Backend API server logs |
arq-worker | Async task worker logs |
redis | Redis server logs |
otto-frontend | Frontend nginx logs |
Examples:
otto configure
Interactive setup wizard for API keys and integrations.
Walks through each configuration section and writes the results to .env. If no .env file exists, it starts from .env.example as a template.
Configuration sections:
- LLM Provider (required) -- Gemini, OpenAI, or Ollama
- Web Search -- Tavily API key
- Specialization -- Agent focus area
- Slack Integration -- Bot token and signing secret
- Email Integration -- SMTP and IMAP settings
- Redis Password -- Authentication for Redis
- LangSmith Tracing -- Observability and debugging
At every prompt, the current value is shown in brackets. Press Enter to keep it. Secret values are masked, showing only the first and last 4 characters.
Example:
otto sync-settings
Merge your .env with the latest configuration template.
Reads .env.example line by line and produces an updated .env that:
- Keeps all your existing values for settings that exist in the template
- Adds new settings from the template with their default values
- Preserves any custom settings you have added that are not in the template (appended under a "Custom settings" section)
This command runs automatically as part of otto update, but you can run it manually after pulling new code.
Example:
otto update
Pull the latest version and restart.
Performs a complete in-place upgrade of your Otto installation.
Update steps:
- Downloads the latest CLI script, Compose files, and configuration templates from GitHub
- Sets executable permissions on scripts
- Updates default skills (without overwriting user-modified skills)
- Ensures the
/usr/local/bin/ottosymlink points to your installation - Syncs new configuration options into your
.env(preserves your values) - Pulls the latest Docker images from the container registry
- Recreates all containers with the new images
Your data is preserved. If GITHUB_TOKEN is set in the environment, it is used for authenticated downloads.
Example:
otto backup
Create a backup of all Otto data.
Otto must be running when you create a backup (the script needs access to the Redis container to trigger a snapshot).
What is backed up:
| File | Contents |
|---|---|
sqlite_data.tar.gz | SQLite database (users, tasks, logs, projects, schedules) |
redis_dump.rdb | Redis snapshot (queues, checkpoints, cached state) |
.env | Environment configuration and secrets |
Backup location: backups/YYYY-MM-DD_HH-MM-SS/ in the project root.
Example:
otto restore
Restore from a backup directory.
Restores data from a previously created backup. This command stops all running Otto containers before restoring and does not restart them automatically. You must start Otto manually after the restore completes.
Arguments:
| Argument | Description |
|---|---|
<backup-directory> | Path to the backup directory (e.g., backups/2026-02-19_14-30-00) |
What it does:
- Validates the backup directory exists
- Stops all running Otto containers
- Restores SQLite data from
sqlite_data.tar.gz - Restores Redis dump from
redis_dump.rdb - Restores
.env
Example:
otto help
Show available commands.
Prints a summary of all available commands and their descriptions.
Makefile Targets
The project includes a Makefile that wraps CLI commands and adds a few extras. All targets are run from the project root.
| Target | Equivalent | Description |
|---|---|---|
make dev | otto dev | Start development environment |
make dev-build | (direct docker compose) | Rebuild backend container from scratch (no cache) |
make start | otto start | Start production environment |
make stop | otto stop | Stop all containers |
make restart | otto restart | Restart all containers |
make update | otto update | Pull latest and restart |
make status | otto status | Show container status |
make health | (direct curl) | Check backend health with formatted JSON output |
make logs | otto logs | Show all container logs |
make logs-backend | otto logs otto-backend | Backend logs only |
make logs-redis | otto logs redis | Redis logs only |
make backup | otto backup | Create backup |
make restore FILE=<dir> | otto restore <dir> | Restore from backup |
make clean | (direct commands) | Remove all data files, keep directory structure |
make export-traces | (direct python) | Export LangSmith traces to JSON |
The export-traces target accepts optional parameters:
Common Workflows
First Installation
Open http://localhost:3000 and follow the onboarding flow.