> ## Documentation Index
> Fetch the complete documentation index at: https://mintlify.com/block/goose/llms.txt
> Use this file to discover all available pages before exploring further.

# Config

> Configuration management system for Goose

The Config system provides flexible configuration management with environment variable overrides, YAML persistence, and secure secret storage.

## Overview

Goose's configuration system supports:

* Dynamic configuration keys
* Type-safe value retrieval via serde
* Environment variable overrides
* YAML-based persistence (`~/.config/goose/config.yaml`)
* Secure secret storage in system keyring
* File-based secret fallback
* Configuration migrations

## Configuration Precedence

Values are loaded in order:

1. **Environment variables** (exact key match, e.g., `OPENAI_API_KEY`)
2. **Configuration file** (`~/.config/goose/config.yaml`)
3. **Default values** (from `defaults.yaml` or built-in defaults)

## Secret Precedence

1. **Environment variables** (exact key match)
2. **System keyring** (macOS Keychain, Windows Credential Manager, Linux Secret Service)
3. **Secrets file** (`~/.config/goose/secrets.yaml`, if keyring disabled via `GOOSE_DISABLE_KEYRING`)

## Config Struct

```rust theme={null}
pub struct Config {
    config_path: PathBuf,
    defaults_path: Option<PathBuf>,
    secrets: SecretStorage,
    guard: Mutex<()>,
    secrets_cache: Arc<Mutex<Option<HashMap<String, Value>>>>,
}
```

**Source:** `crates/goose/src/config/base.rs:103-109`

## Constructor Methods

### global()

Get the global Config instance.

```rust theme={null}
pub fn global() -> &'static Config
```

**Returns:** Reference to the global singleton Config

**Source:** `crates/goose/src/config/base.rs:237-239`

**Example:**

```rust theme={null}
let config = Config::global();
let api_key: String = config.get_param("OPENAI_API_KEY")?;
```

### new()

Create a Config with custom paths (primarily for testing).

```rust theme={null}
pub fn new<P: AsRef<Path>>(config_path: P, service: &str) -> Result<Self, ConfigError>
```

<ParamField path="config_path" type="P: AsRef<Path>" required>
  Path to YAML config file
</ParamField>

<ParamField path="service" type="&str" required>
  Keyring service name
</ParamField>

**Source:** `crates/goose/src/config/base.rs:245-255`

### new\_with\_file\_secrets()

Create Config using file-based secrets.

```rust theme={null}
pub fn new_with_file_secrets<P1: AsRef<Path>, P2: AsRef<Path>>(
    config_path: P1,
    secrets_path: P2,
) -> Result<Self, ConfigError>
```

<ParamField path="config_path" type="P1: AsRef<Path>" required>
  Path to config YAML
</ParamField>

<ParamField path="secrets_path" type="P2: AsRef<Path>" required>
  Path to secrets YAML
</ParamField>

**Source:** `crates/goose/src/config/base.rs:261-274`

## Reading Configuration

### get\_param()

Get a configuration parameter with type inference.

```rust theme={null}
pub fn get_param<T: DeserializeOwned>(&self, key: &str) -> Result<T, ConfigError>
```

<ParamField path="key" type="&str" required>
  Configuration key (e.g., "openai\_api\_key")
</ParamField>

**Returns:** Deserialized value of type T

**Errors:**

* `ConfigError::NotFound` - Key not found in config, env, or defaults
* `ConfigError::DeserializeError` - Value cannot be deserialized to type T

**Example:**

```rust theme={null}
use goose::config::Config;

let config = Config::global();

// Get string
let api_key: String = config.get_param("OPENAI_API_KEY")?;

// Get number
let max_retries: u32 = config.get_param("max_retries")?;

// Get complex type
#[derive(serde::Deserialize)]
struct ServerConfig {
    host: String,
    port: u16,
}
let server: ServerConfig = config.get_param("server")?;
```

### all\_values()

Get all configuration values as a HashMap.

```rust theme={null}
pub fn all_values(&self) -> Result<HashMap<String, Value>, ConfigError>
```

**Returns:** All config keys and values

**Source:** `crates/goose/src/config/base.rs:338-347`

## Writing Configuration

### set\_param()

Set a configuration parameter.

```rust theme={null}
pub fn set_param<T: Serialize>(&self, key: &str, value: &T) -> Result<(), ConfigError>
```

<ParamField path="key" type="&str" required>
  Configuration key
</ParamField>

<ParamField path="value" type="&T" required>
  Value to store (must be Serialize)
</ParamField>

**Example:**

```rust theme={null}
let config = Config::global();

// Set string
config.set_param("model_name", &"gpt-4o")?;

// Set number
config.set_param("timeout_seconds", &30)?;

// Set complex type
#[derive(serde::Serialize)]
struct Settings {
    enabled: bool,
    threshold: f64,
}
config.set_param("my_settings", &Settings {
    enabled: true,
    threshold: 0.95,
})?;
```

### remove\_param()

Remove a configuration parameter.

```rust theme={null}
pub fn remove_param(&self, key: &str) -> Result<(), ConfigError>
```

<ParamField path="key" type="&str" required>
  Configuration key to remove
</ParamField>

## Secret Management

### set\_secret()

Store a secret securely.

```rust theme={null}
pub fn set_secret(&self, key: &str, value: &str) -> Result<(), ConfigError>
```

<ParamField path="key" type="&str" required>
  Secret key
</ParamField>

<ParamField path="value" type="&str" required>
  Secret value
</ParamField>

**Storage:** Uses system keyring by default, falls back to encrypted file if keyring unavailable.

**Example:**

```rust theme={null}
config.set_secret("OPENAI_API_KEY", "sk-...")?;
```

### get\_secret()

Retrieve a secret.

```rust theme={null}
pub fn get_secret(&self, key: &str) -> Result<String, ConfigError>
```

<ParamField path="key" type="&str" required>
  Secret key
</ParamField>

**Returns:** Secret value

**Example:**

```rust theme={null}
let api_key = config.get_secret("OPENAI_API_KEY")?;
```

### remove\_secret()

Delete a secret.

```rust theme={null}
pub fn remove_secret(&self, key: &str) -> Result<(), ConfigError>
```

<ParamField path="key" type="&str" required>
  Secret key to remove
</ParamField>

### all\_secrets()

Get all secret keys (not values).

```rust theme={null}
pub fn all_secrets(&self) -> Result<Vec<String>, ConfigError>
```

**Returns:** Vector of secret key names

## File Operations

### path()

Get the config file path.

```rust theme={null}
pub fn path(&self) -> String
```

**Returns:** Path to config.yaml

**Source:** `crates/goose/src/config/base.rs:300-302`

### exists()

Check if config file exists.

```rust theme={null}
pub fn exists(&self) -> bool
```

**Source:** `crates/goose/src/config/base.rs:292-294`

### clear()

Delete the config file.

```rust theme={null}
pub fn clear(&self) -> Result<(), ConfigError>
```

**Source:** `crates/goose/src/config/base.rs:296-298`

## Built-in Configuration Keys

Goose recognizes several standard configuration keys:

### get\_goose\_mode()

Get the operating mode.

```rust theme={null}
pub fn get_goose_mode(&self) -> Result<GooseMode, ConfigError>
```

**Returns:** `GooseMode::Auto`, `GooseMode::Chat`, or `GooseMode::Agentic`

### GooseMode

```rust theme={null}
pub enum GooseMode {
    Auto,    // Automatically choose based on context
    Chat,    // Chat mode (no autonomous tool execution)
    Agentic, // Agentic mode (autonomous tool execution)
}
```

**Source:** `crates/goose/src/config/goose_mode.rs`

### Other Built-in Keys

* `GOOSE_DISABLE_SESSION_NAMING` - Disable auto-generated session names
* `GOOSE_TOOL_CALL_CUTOFF` - Max tool calls before summarization (default: 10)
* `GOOSE_AUTO_COMPACT_THRESHOLD` - Context percentage to trigger auto-compaction (default: 0.8)

## Error Types

### ConfigError

```rust theme={null}
pub enum ConfigError {
    NotFound(String),
    DeserializeError(String),
    FileError(std::io::Error),
    DirectoryError(String),
    KeyringError(String),
    LockError(String),
    FallbackToFileStorage,
}
```

**Source:** `crates/goose/src/config/base.rs:21-37`

<ResponseField name="NotFound" type="String">
  Configuration key not found
</ResponseField>

<ResponseField name="DeserializeError" type="String">
  Value cannot be deserialized to requested type
</ResponseField>

<ResponseField name="FileError" type="std::io::Error">
  I/O error reading/writing config file
</ResponseField>

<ResponseField name="KeyringError" type="String">
  Error accessing system keyring
</ResponseField>

## Naming Conventions

Goose recommends:

* Use `snake_case` for configuration keys
* Prefix Goose-specific keys with `goose_` (e.g., `goose_mode`)
* Environment variables use `UPPERCASE` (e.g., `OPENAI_API_KEY`)
* The system automatically converts `snake_case` → `UPPERCASE` when checking environment variables

**Example:**

```rust theme={null}
// Config file: openai_api_key: "sk-..."
// Environment: OPENAI_API_KEY="sk-..."
// Both work:
let key: String = config.get_param("openai_api_key")?;
```

## Related Types

* [Agent](/api/core/agent) - Uses Config for provider settings
* [Session](/api/core/session) - Session-specific configuration
