# Configuration Files for Goose: A Complete Guide to YAML Setup and Management

> Explore Goose YAML configuration files for runtime settings and defaults. Learn setup and management with automatic migration for schema updates. Master your Goose setup now.

- Repository: [goose/goose](https://github.com/aaif-goose/goose)
- Tags: how-to-guide
- Published: 2026-04-07

---

**Goose uses YAML configuration files stored in platform-specific directories, primarily [`config.yaml`](https://github.com/aaif-goose/goose/blob/main/config.yaml) for runtime settings and [`init-config.yaml`](https://github.com/aaif-goose/goose/blob/main/init-config.yaml) for defaults, with automatic migration support for schema updates.**

The open-source AI agent platform Goose (aaif-goose/goose) relies on plain-text YAML files to manage runtime behavior, provider settings, and extension loading. Understanding the configuration files for Goose is essential for customizing models, enabling telemetry, and managing MCP extensions across CLI and desktop environments.

## Where Goose Stores Configuration Files

Goose follows platform conventions for locating its runtime configuration, ensuring compatibility across development environments.

### Default File Locations

The primary [`config.yaml`](https://github.com/aaif-goose/goose/blob/main/config.yaml) lives in different paths depending on your operating system:

- **Linux and macOS**: `~/.config/goose/config.yaml`
- **Windows**: `%APPDATA%\Block\goose\config\config.yaml`

### Config Directory Resolution

The library determines the config directory via the `Paths::config_dir()` helper, implemented in [`crates/goose/src/config/paths.rs`](https://github.com/aaif-goose/goose/blob/main/crates/goose/src/config/paths.rs). This function returns a platform-specific `PathBuf` that points to the appropriate user configuration folder, handling OS-specific conventions automatically.

## Core Configuration Files Explained

Goose utilizes several distinct files to manage defaults, user preferences, and extension manifests.

### config.yaml (Primary Runtime Configuration)

The [`config.yaml`](https://github.com/aaif-goose/goose/blob/main/config.yaml) file stores all user-defined settings, including the selected **provider**, **model**, **extension list**, **telemetry flag**, and other runtime options. This file is read on every Goose startup and modified by both the CLI and desktop UI when settings change.

### init-config.yaml (Default Values Template)

Located in the same directory as [`config.yaml`](https://github.com/aaif-goose/goose/blob/main/config.yaml), the [`init-config.yaml`](https://github.com/aaif-goose/goose/blob/main/init-config.yaml) file supplies default values that are merged into a fresh [`config.yaml`](https://github.com/aaif-goose/goose/blob/main/config.yaml) when no existing configuration is detected. According to the source code in [`crates/goose/src/config/base.rs`](https://github.com/aaif-goose/goose/blob/main/crates/goose/src/config/base.rs) around line 400, Goose copies this template to create a new user configuration if the main file is missing.

### Extension Manifests

Goose ships with two JSON files that define available extensions:

- **[`ui/desktop/src/built-in-extensions.json`](https://github.com/aaif-goose/goose/blob/main/ui/desktop/src/built-in-extensions.json)**: Lists extensions that ship with Goose; they are merged into the user's configuration if not already present.
- **[`ui/desktop/src/components/settings/extensions/bundled-extensions.json`](https://github.com/aaif-goose/goose/blob/main/ui/desktop/src/components/settings/extensions/bundled-extensions.json)**: Used by the desktop UI to display extensions bundled with the app and to seed a new [`config.yaml`](https://github.com/aaif-goose/goose/blob/main/config.yaml).

## How Goose Loads and Parses Configuration

The configuration loading process follows a strict pipeline defined in [`crates/goose/src/config/base.rs`](https://github.com/aaif-goose/goose/blob/main/crates/goose/src/config/base.rs):

1. **Path resolution**: The library calls `Paths::config_dir()` to determine the platform-specific configuration directory.
2. **File discovery**: The code looks for `CONFIG_YAML_NAME` (defined as `"config.yaml"` in lines 39-40 of [`base.rs`](https://github.com/aaif-goose/goose/blob/main/base.rs)) in that directory.
3. **Initialization**: If the file does not exist, Goose copies [`init-config.yaml`](https://github.com/aaif-goose/goose/blob/main/init-config.yaml) into the config directory, creating a fresh [`config.yaml`](https://github.com/aaif-goose/goose/blob/main/config.yaml) with sensible defaults.
4. **Parsing**: The YAML is deserialized into the `Config` struct defined across several modules including [`crates/goose/src/config/mod.rs`](https://github.com/aaif-goose/goose/blob/main/crates/goose/src/config/mod.rs), [`crates/goose/src/config/extensions.rs`](https://github.com/aaif-goose/goose/blob/main/crates/goose/src/config/extensions.rs), and [`crates/goose/src/config/experiments.rs`](https://github.com/aaif-goose/goose/blob/main/crates/goose/src/config/experiments.rs).
5. **Migrations**: When the on-disk format changes, [`crates/goose/src/config/migrations.rs`](https://github.com/aaif-goose/goose/blob/main/crates/goose/src/config/migrations.rs) runs versioned migration steps to keep older files compatible with the current schema.

These steps are exercised by the CLI (`goose info` prints the resolved path) and by the desktop UI (see [`ui/desktop/src/components/ConfigContext.tsx`](https://github.com/aaif-goose/goose/blob/main/ui/desktop/src/components/ConfigContext.tsx) lines 53-55 for the UI-side handling).

## Configuration File Format and Options

A typical [`config.yaml`](https://github.com/aaif-goose/goose/blob/main/config.yaml) contains the following top-level keys:

```yaml

# Provider & model selection

provider: openrouter
model: gpt-4o-mini

# Telemetry

telemetry_enabled: true   # can also be set via GOOSE_TELEMETRY_ENABLED env var

# Context limits

max_turns: 20
context_limit: 1000000    # can also be set via GOOSE_CONTEXT_LIMIT env var

# Extensions (list of enabled MCP extensions)

extensions:
  - name: code-analyzer
    enabled: true
  - name: web-search
    enabled: false

# Experiment flags (feature toggles)

experiments:
  prompt_injection_detection: true

```

All keys are optional; missing entries fall back to the defaults supplied by [`init-config.yaml`](https://github.com/aaif-goose/goose/blob/main/init-config.yaml).

## Working with Goose Configuration

### Viewing Configuration via CLI

Use the `info` command to display the current configuration file location and active settings:

```bash
goose info --verbose

```

This command uses `CONFIG_YAML_NAME` defined in [`crates/goose-cli/src/commands/info.rs`](https://github.com/aaif-goose/goose/blob/main/crates/goose-cli/src/commands/info.rs) (lines 41-45) to locate and display the resolved [`config.yaml`](https://github.com/aaif-goose/goose/blob/main/config.yaml) path, provider, model, and enabled extensions.

### Creating Configurations Manually

You can create a minimal configuration file manually before running Goose:

```bash

# Create a minimal config.yaml in the default location

cat > ~/.config/goose/config.yaml <<'EOF'
provider: openrouter
model: gpt-4o-mini
telemetry_enabled: false
EOF

```

When Goose next starts, it will read this file directly. Any missing sections will be populated from [`init-config.yaml`](https://github.com/aaif-goose/goose/blob/main/init-config.yaml).

### Accessing Config Programmatically in Rust

Extensions and custom tools can access the configuration using the `Config` struct and `Paths` helper:

```rust
use goose::config::Config;          // the Config struct
use goose::paths::Paths;            // helper to locate the config dir

fn load_config() -> anyhow::Result<Config> {
    let config_path = Paths::config_dir().join("config.yaml");
    let contents = std::fs::read_to_string(&config_path)?;
    let cfg: Config = serde_yaml::from_str(&contents)?;
    Ok(cfg)
}

```

The `Config` struct lives in [`crates/goose/src/config/mod.rs`](https://github.com/aaif-goose/goose/blob/main/crates/goose/src/config/mod.rs), providing typed access to all configuration fields including extensions and experiment flags.

## Summary

- Goose stores runtime configuration in **YAML files** located in platform-specific directories (`~/.config/goose/` on Unix, `%APPDATA%\Block\goose\config\` on Windows).
- The main [`config.yaml`](https://github.com/aaif-goose/goose/blob/main/config.yaml) holds user settings, while [`init-config.yaml`](https://github.com/aaif-goose/goose/blob/main/init-config.yaml) provides default templates for new installations.
- Configuration loading is handled by [`crates/goose/src/config/base.rs`](https://github.com/aaif-goose/goose/blob/main/crates/goose/src/config/base.rs), with automatic **schema migrations** managed by [`crates/goose/src/config/migrations.rs`](https://github.com/aaif-goose/goose/blob/main/crates/goose/src/config/migrations.rs).
- All settings—including provider, model, extensions, and telemetry—can be viewed via `goose info` or accessed programmatically through the Rust `Config` API.

## Frequently Asked Questions

### Where is the Goose configuration file located?

On Linux and macOS, the file is at `~/.config/goose/config.yaml`. On Windows, it is stored at `%APPDATA%\Block\goose\config\config.yaml`. The `Paths::config_dir()` function in [`crates/goose/src/config/paths.rs`](https://github.com/aaif-goose/goose/blob/main/crates/goose/src/config/paths.rs) determines this path dynamically based on the operating system.

### What happens if I delete my config.yaml?

If [`config.yaml`](https://github.com/aaif-goose/goose/blob/main/config.yaml) is missing, Goose automatically creates a new one by copying [`init-config.yaml`](https://github.com/aaif-goose/goose/blob/main/init-config.yaml) from the same directory. This initialization logic runs around line 400 of [`crates/goose/src/config/base.rs`](https://github.com/aaif-goose/goose/blob/main/crates/goose/src/config/base.rs), ensuring users always start with valid default settings.

### Can I use environment variables instead of config files?

Yes. Specific settings can be overridden using environment variables. For example, `GOOSE_TELEMETRY_ENABLED` controls telemetry, and `GOOSE_CONTEXT_LIMIT` sets the context window size. These variables take precedence over values defined in [`config.yaml`](https://github.com/aaif-goose/goose/blob/main/config.yaml).

### How do I migrate configuration when upgrading Goose?

Goose handles migrations automatically through [`crates/goose/src/config/migrations.rs`](https://github.com/aaif-goose/goose/blob/main/crates/goose/src/config/migrations.rs). When the application starts and detects an older configuration schema, it runs versioned migration steps to update the file format while preserving your existing settings. No manual intervention is required.