# How the Dream CLI Switches Between Local and Cloud AI Models

> Discover how the Dream CLI seamlessly switches between local and cloud AI models by managing the MODEL_PROVIDER variable and regenerating Docker Compose for your Light-Heart-Labs DreamServer.

- Repository: [Light Heart Labs/DreamServer](https://github.com/Light-Heart-Labs/DreamServer)
- Tags: how-to-guide
- Published: 2026-05-18

---

**The Dream CLI switches between local and cloud AI models by persisting the `MODEL_PROVIDER` variable to a `.env` file and dynamically regenerating the Docker Compose stack to either initialize local GPU containers or deploy a cloud-proxy service.**

The Dream CLI is the Bash-based command-line interface for the Light-Heart-Labs/DreamServer project. It enables seamless switching between self-hosted local models running on your own hardware and external cloud providers through a three-layer architecture involving environment configuration, compose-stack generation, and runtime flags.

## Architecture Overview

The CLI orchestrates model switching through three tightly coupled layers that work together to reconfigure the entire stack. When you change the model provider, the system validates the configuration, updates the environment file, and rebuilds the container orchestration to match the selected backend.

## Environment Configuration Layer

The foundation of model switching resides in the `.env` file located at `dream-server/.env.example`. This file stores the critical configuration keys that determine runtime behavior:

- **`MODEL_PROVIDER`**: Sets the active mode to `local` or `cloud`
- **`LLM_URL`**: Specifies the endpoint URL for cloud connections
- **`GPU_BACKEND`**: Declares the hardware acceleration type (AMD, NVIDIA, or Apple)
- **`CLOUD_FALLBACK`**: Enables automatic fallback to cloud when local resources are unavailable

The CLI loads these values on startup (lines 28-33 of `dream-server/dream-cli`) and exposes helper functions to manipulate them. The `_env_set` function writes key-value pairs to the environment file, while `_env_get_raw` retrieves current settings without default fallbacks.

## Dynamic Compose-Stack Generation

The [`scripts/resolve-compose-stack.sh`](https://github.com/Light-Heart-Labs/DreamServer/blob/main/scripts/resolve-compose-stack.sh) script acts as the orchestration engine that translates environment variables into running containers. This script evaluates the `MODEL_PROVIDER` value and conditionally assembles the Docker Compose configuration.

When `MODEL_PROVIDER=local`, the resolver merges [`docker-compose.base.yml`](https://github.com/Light-Heart-Labs/DreamServer/blob/main/docker-compose.base.yml) with GPU-specific overlays such as [`docker-compose.amd.yml`](https://github.com/Light-Heart-Labs/DreamServer/blob/main/docker-compose.amd.yml) or [`docker-compose.nvidia.yml`](https://github.com/Light-Heart-Labs/DreamServer/blob/main/docker-compose.nvidia.yml). When `MODEL_PROVIDER=cloud`, the script appends [`docker-compose.cloud-proxy.yml`](https://github.com/Light-Heart-Labs/DreamServer/blob/main/docker-compose.cloud-proxy.yml) to the stack, which defines a proxy container that forwards API calls to external providers like Claude-3-Opus.

```bash

# scripts/resolve-compose-stack.sh (simplified logic)

provider=$(grep '^MODEL_PROVIDER=' "$INSTALL_DIR/.env" | cut -d= -f2)
if [[ "$provider" == "cloud" ]]; then
    COMPOSE_FILES+=("-f" "docker-compose.cloud-proxy.yml")
fi
docker compose -f docker-compose.base.yml "${COMPOSE_FILES[@]}" up -d

```

## CLI Commands and Runtime Flags

The Dream CLI provides ergonomic commands to modify configuration without manual file editing.

### Permanent Provider Switching

Use the `config set` subcommand to persistently change the model provider. This invokes `_env_set` and automatically triggers the compose-stack resolver to recreate services:

```bash

# Switch to local model (e.g., Qwen-3-Coder-Next)

dream-cli config set MODEL_PROVIDER local

# Switch to cloud model (e.g., Claude-3-Opus)

dream-cli config set MODEL_PROVIDER cloud

```

Behind the scenes, the CLI executes:

```bash

# In dream-server/dream-cli

_env_set() {
    local key="$1" val="$2" file="$INSTALL_DIR/.env"
    # Writes key=value into .env

}

if [[ "$1" == "config" && "$2" == "set" ]]; then
    _env_set "$3" "$4"
    scripts/resolve-compose-stack.sh
fi

```

### Temporary Runtime Overrides

For experimental workflows, the `--cloud` flag temporarily overrides the stored configuration for a single command execution without persisting changes to the `.env` file:

```bash

# Execute against cloud backend without changing default configuration

dream-cli --cloud run-agent "Explain the code base"

```

### Configuration Inspection

Verify the current mode using the `config get` command:

```bash
dream-cli config get MODEL_PROVIDER

# Output: local   (or cloud)

```

## Error Handling and Validation

The Dream CLI is written in Bash with strict `set -euo pipefail` settings that ensure immediate failure on undefined variables or pipe errors. When you attempt to set an invalid provider, the built-in `error` helper aborts the process with a descriptive message, preventing accidental misconfiguration that could leave the system in an inconsistent state.

## Summary

- **Configuration-driven switching**: The Dream CLI uses a `.env` file with `MODEL_PROVIDER`, `LLM_URL`, and `GPU_BACKEND` keys to determine runtime behavior.
- **Dynamic container orchestration**: The [`scripts/resolve-compose-stack.sh`](https://github.com/Light-Heart-Labs/DreamServer/blob/main/scripts/resolve-compose-stack.sh) generates appropriate Docker Compose configurations, adding [`docker-compose.cloud-proxy.yml`](https://github.com/Light-Heart-Labs/DreamServer/blob/main/docker-compose.cloud-proxy.yml) for cloud mode or GPU-specific overlays for local mode.
- **Ergonomic CLI interface**: Commands like `dream-cli config set MODEL_PROVIDER local` modify configuration permanently, while the `--cloud` flag enables temporary overrides.
- **Strict validation**: The Bash implementation with `set -euo pipefail` and the `error` helper prevents invalid configuration states.

## Frequently Asked Questions

### How do I temporarily test a cloud model without changing my default configuration?

Use the `--cloud` runtime flag before any subcommand. This overrides the `MODEL_PROVIDER` value stored in `.env` for that single execution only. For example: `dream-cli --cloud run-agent "Analyze this function"`.

### What files control the container composition when switching providers?

The [`scripts/resolve-compose-stack.sh`](https://github.com/Light-Heart-Labs/DreamServer/blob/main/scripts/resolve-compose-stack.sh) script reads `MODEL_PROVIDER` from `.env` and assembles the appropriate stack. For local models, it combines [`docker-compose.base.yml`](https://github.com/Light-Heart-Labs/DreamServer/blob/main/docker-compose.base.yml) with GPU-specific files like [`docker-compose.nvidia.yml`](https://github.com/Light-Heart-Labs/DreamServer/blob/main/docker-compose.nvidia.yml). For cloud models, it additionally includes [`docker-compose.cloud-proxy.yml`](https://github.com/Light-Heart-Labs/DreamServer/blob/main/docker-compose.cloud-proxy.yml) to route API calls.

### Where does the Dream CLI store the current model provider setting?

The CLI stores the active provider in the `MODEL_PROVIDER` key within the `.env` file located in the installation directory. Helper functions `_env_set` and `_env_get_raw` in `dream-server/dream-cli` manage read and write operations to this file.

### What happens if I specify an invalid provider name?

The CLI validates inputs using strict Bash settings (`set -euo pipefail`). If you attempt to set an unrecognized provider, the `error` helper function prints a clear diagnostic message and terminates the process immediately, preventing the system from launching with misconfigured services.