How the Agentsview Configuration System Loads Settings from config.toml and Environment Variables

The agentsview configuration system merges built-in defaults, environment variables, and TOML file settings through a four-layer precedence model implemented in internal/config/config.go, ensuring that CLI flags always override file-based and environment configurations.

The kenn-io/agentsview repository provides a flexible configuration architecture that combines compile-time defaults with runtime overrides. Understanding how the agentsview configuration system resolves competing settings across environment variables and config.toml files allows operators to deploy the application securely across development, staging, and production environments without code changes.

Configuration Loading Layers

The agentsview configuration system constructs the final Config struct through three successive merge operations, followed by optional CLI flag application.

Layer 1: Built-in Defaults

The foundation is established by the Default() function, which creates initial values for all configuration fields. This implementation populates default ports, host bindings, and data directory paths. You can find this initialization logic at internal/config/config.go lines 67-78.

Layer 2: Environment Variable Overrides

The (*Config).loadEnv() method applies the second layer, scanning for AGENTSVIEW_* prefixed variables such as AGENTSVIEW_DATA_DIR and AGENTSVIEW_PG_URL. This function also processes per-agent directory variables defined in internal/parser/registry.go. The environment loading implementation resides at internal/config/config.go lines 70-92.

Layer 3: User-Provided config.toml

Finally, the (*Config).loadFile() method parses the TOML configuration file by invoking applyConfigTOML. This step reads fields including host settings, proxy configurations, and database connection strings from the user-provided file. The file loading logic appears at internal/config/config.go lines 90-100, while the TOML application logic is implemented at lines 662-720.

Loading Order and Precedence

The agentsview configuration system strictly follows a hierarchical precedence where higher-numbered sources override lower-numbered ones:

  1. Built-in defaults (Default)
  2. Environment variables (loadEnv)
  3. config.toml file (loadFile → applyConfigTOML)
  4. CLI flags (applyFlags or applyPFlags)

Because environment variables are merged before the TOML file is parsed, any value set via AGENTSVIEW_* variables survives unless the configuration file explicitly defines the same field. When the file defines a field, that value takes precedence over the environment. This behavior is verified by the test suite in cases such as TestLoadEnv_OverridesDataDir, TestLoadMinimal_PreservesCursorAdminEnvOverFile, and TestLoad_PublicURLMergedIntoOrigins.

Key Loading Functions

Several top-level helpers orchestrate the configuration construction process:

  • Load(fs *flag.FlagSet): Executes the full loading chain—defaults, environment, config file, and command-line flags. Internally calls LoadMinimal followed by applyFlags.
  • LoadMinimal(): Loads defaults, environment variables, and the config file without processing CLI flags. Used when flag parsing is handled separately or unnecessary.
  • LoadPFlags(fs *pflag.FlagSet): Identical to Load but designed for Cobra/PFlag flag sets, calling applyPFlags instead of the standard flag application.
  • ResolveDataDir(): Returns the data directory after applying defaults and environment variables, used before any file read operations to determine where to look for config.toml.

Special Configuration Handling

Legacy JSON Migration

If the system detects a config.json file but no config.toml, the loadFileWithMigration function triggers migrateJSONToTOML. This migration runs under a file lock to prevent race conditions during concurrent startup attempts. The migration logic is located at internal/config/config.go lines 71-106.

Per-Agent Directory Resolution

The AgentDirs map supports granular directory overrides for individual agents through a chained precedence system:

  1. Root environment variables (e.g., *_CONFIG_DIR)
  2. Per-agent environment variables (e.g., CLAUDE_PROJECTS_DIR)
  3. TOML file arrays (e.g., claude_dirs)
  4. Built-in defaults

This logic, implemented at internal/config/config.go lines 746-784, tracks the source of each entry using markers (dirDefault, dirEnv, dirFile) to identify whether a value originated from user-provided sources.

Practical Implementation Examples

Loading Configuration Without Flags

package main

import (
	"fmt"
	"log"

	"go.kenn.io/agentsview/internal/config"
)

func main() {
	// Loads defaults + environment + config file
	cfg, err := config.LoadMinimal()
	if err != nil {
		log.Fatalf("config load failed: %v", err)
	}
	fmt.Printf("Data directory: %s\n", cfg.DataDir)
	fmt.Printf("Public URL: %s\n", cfg.PublicURL)
}

Overriding Settings via Environment

export AGENTSVIEW_DATA_DIR=/tmp/agentsview-data
export AGENTSVIEW_PG_URL=postgres://mydb.example.com/agents
go run ./cmd/agentsview

The application picks up the custom data directory and PostgreSQL URL because loadEnv executes before the TOML file is parsed.

Sample config.toml Structure


# ~/.agentsview/config.toml

host = "0.0.0.0"
port = 8081

public_url = "https://viewer.mycompany.com"

[proxy]
mode = "caddy"
bind_host = "0.0.0.0"
public_port = 8443
allowed_subnets = ["10.0.0.0/8", "192.168.0.0/16"]

Accessing Per-Agent Directories

cfg, _ := config.LoadMinimal()
claudeDirs := cfg.ResolveDirs(parser.AgentClaude)
fmt.Println("Claude session directories:", claudeDirs)

The result reflects the full precedence chain: environment variables override defaults, and TOML file entries override environment variables when explicitly defined.

Summary

  • The agentsview configuration system applies settings in four strict layers: defaults → environment variables → config.toml → CLI flags.
  • Environment variables use the AGENTSVIEW_* prefix and are processed by loadEnv() at internal/config/config.go lines 70-92.
  • The config.toml file is parsed by loadFile() and applyConfigTOML at lines 90-100 and 662-720, respectively.
  • Configuration files take precedence over environment variables only when explicitly defining the same field.
  • Per-agent directories support additional environment variables like CLAUDE_PROJECTS_DIR and TOML array overrides.
  • Legacy JSON configurations are automatically migrated to TOML under file locking to prevent race conditions.

Frequently Asked Questions

What happens when the same setting is defined in both environment variables and config.toml?

The agentsview configuration system merges environment variables before parsing the TOML file. If config.toml explicitly defines a field that exists as an environment variable, the file value wins. However, if the file omits that field, the environment variable persists. This precedence is verified by tests such as TestLoadMinimal_PreservesCursorAdminEnvOverFile.

How does agentsview handle legacy configuration.json files?

When loadFileWithMigration detects a config.json without a corresponding config.toml, it automatically invokes migrateJSONToTOML at internal/config/config.go lines 71-106. The migration executes under a file lock to prevent data corruption during concurrent access, converting the legacy JSON structure to the modern TOML format.

Can I configure agentsview using only environment variables without creating a config.toml file?

Yes. The LoadMinimal() and Load() functions do not require a config.toml to exist. If the file is missing, the system proceeds with built-in defaults and environment variables. Simply export AGENTSVIEW_* variables such as AGENTSVIEW_DATA_DIR and AGENTSVIEW_PG_URL before starting the application.

Which function should I use if my application does not need CLI flag parsing?

Use config.LoadMinimal() to initialize the configuration system without processing command-line flags. This function loads defaults, applies environment variable overrides via loadEnv(), and parses config.toml via loadFile(), returning a fully populated Config struct suitable for library usage or custom CLI implementations.

Have a question about this repo?

These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:

Share the following with your agent to get started:
curl -s "https://instagit.com/install.md"

Works with
Claude Codex Cursor VS Code OpenClaw Any MCP Client

Maintain an open-source project? Get it listed too →