Skip to content

Configuration Guide

Crucible uses TOML configuration files stored in ~/.config/crucible/.

Terminal window
mkdir -p ~/.config/crucible
# Create config.toml with your settings
~/.config/crucible/
├── config.toml # Main configuration file
├── mcps.toml # MCP server configurations (included)
├── embedding.toml # Embedding/API config (optional)
├── discovery.toml # Discovery paths (optional)
├── hooks.toml # Hook configs (optional)
└── profiles.toml # Environment profiles (optional)

Crucible supports dynamic value references that are resolved at config load time.

Use {env:VAR} to read values from environment variables:

[providers.openai]
backend = "openai"
api_key = "{env:OPENAI_API_KEY}"
[providers.anthropic]
backend = "anthropic"
api_key = "{env:ANTHROPIC_API_KEY}"

This is the recommended way to handle API keys and secrets:

  • Store secrets in your shell profile, .env file, or secret manager
  • Reference them in config with {env:VAR} syntax
  • The config file itself contains no secrets

Use {file:path} anywhere in your config to pull in external content:

# Include a whole section from a TOML file
gateway = "{file:mcps.toml}"
# Include just a secret value (plain text file)
[embedding]
provider = "openai"
api_key = "{file:~/.secrets/openai.key}"
# Works in arrays too
extra_paths = ["{file:paths.txt}", "/static/path"]
# Works at any nesting level
[deep.nested.config]
secret = "{file:secret.txt}"

How it works:

  • If the file has a .toml extension → parsed as structured TOML data
  • Otherwise → file content is used as a string (whitespace trimmed)

{dir:path} Directory References (config.d style)

Section titled “{dir:path} Directory References (config.d style)”

Use {dir:path} to merge all .toml files from a directory:

# Include all provider configs from a directory
providers = "{dir:~/.config/crucible/providers.d/}"
# Drop-in MCP server configs
gateway = "{dir:mcps.d/}"

Files are processed in sorted order (alphabetically), allowing predictable overrides:

~/.config/crucible/providers.d/
├── 00-base.toml # Processed first (defaults)
├── 10-local.toml # Local Ollama config
├── 20-cloud.toml # Cloud providers
└── 99-override.toml # Processed last (overrides)
  • Only .toml files are processed
  • Hidden files (starting with .) are ignored
  • Later files override earlier ones for conflicting keys
  • Tables are deep-merged, arrays are appended

You can use {env:}, {file:}, and {dir:} references throughout your config:

[providers.cloud]
backend = "openai"
api_key = "{env:OPENAI_API_KEY}" # From environment
endpoint = "{file:~/.config/endpoint.txt}" # From file
# Modular provider configs
[llm]
providers = "{dir:~/.config/crucible/providers.d/}"

The [include] section merges files into top-level sections:

[include]
gateway = "mcps.toml"
embedding = "embedding.toml"
Path FormatExampleResolution
Relativemcps.tomlSame directory as main config
Home~/crucible/mcps.tomlUser’s home directory
Absolute/etc/crucible/mcps.tomlExact path

When files are included:

  • TOML files are parsed and merged as structured data
  • Plain text files are used as string values (trimmed)
  • Tables are deep-merged (nested keys combined)
  • Arrays are appended

Configure upstream MCP servers in mcps.toml. See MCP Gateway for details.

[[servers]]
name = "github"
prefix = "gh_" # Tools become gh_search_code, gh_get_repo, etc.
[servers.transport]
type = "stdio"
command = "npx"
args = ["-y", "@modelcontextprotocol/server-github"]
[servers.transport.env]
GITHUB_TOKEN = "ghp_your_token_here"
[[servers]]
name = "remote-tools"
prefix = "remote_"
[servers.transport]
type = "sse"
url = "https://mcp.example.com/sse"
auth_header = "Bearer your-api-key"

Control which tools are exposed:

[[servers]]
name = "github"
allowed_tools = ["search_*", "get_*"] # Whitelist with glob patterns
blocked_tools = ["delete_*"] # Blacklist (takes priority)

Crucible uses a minimal set of environment variables for system-level configuration:

VariableDescription
CRUCIBLE_CONFIGPath to config file (default: ~/.config/crucible/config.toml)
CRUCIBLE_CONFIG_DIRConfig directory path
CRUCIBLE_LOG_LEVELLogging level (off, error, warn, info, debug, trace)
CRUCIBLE_TEST_MODEEnable test mode (for development)

For API keys and secrets, use {env:VAR} syntax in your config file instead of dedicated Crucible environment variables. This gives you full control over which environment variables to use:

[providers.openai]
api_key = "{env:OPENAI_API_KEY}" # or any env var you prefer

Define multiple profiles for different environments:

profile = "development" # Active profile
[profiles.development]
# Development-specific settings
[profiles.production]
# Production-specific settings

Crucible supports multiple storage modes that control how the CLI accesses data:

[storage]
mode = "sqlite"

The CLI uses SQLite for local storage. This is simple and fast for single-user use:

  • Pros: Fast startup, no extra processes, simple setup, reliable
  • Cons: Single-user only, file locked to one session

Use SQLite mode when:

  • Running a single CLI session at a time
  • Using scripts that call cru commands sequentially
  • Maximum simplicity is desired
[storage]
mode = "daemon"
idle_timeout_secs = 300 # Optional, default 5 minutes

The CLI connects through a shared daemon process that manages the database. The daemon is automatically started when needed and shuts down after idle_timeout_secs of inactivity with no connections.

  • Pros: Multiple concurrent CLI sessions, shared connection pooling, better for workflows
  • Cons: Slightly slower initial connection (may need to start daemon), extra process

Use daemon mode when:

  • Running multiple cru commands in parallel (e.g., in separate terminals)
  • Using editor integrations that query while you work
  • Running background processing while using the TUI

The daemon socket is created at:

  • $CRUCIBLE_SOCKET (if environment variable is set)
  • $XDG_RUNTIME_DIR/crucible.sock (if XDG_RUNTIME_DIR is set)
  • /tmp/crucible.sock (fallback)

The daemon is managed automatically. For manual control:

Terminal window
# The daemon starts automatically when needed
# To force shutdown:
cru daemon stop
  1. Secure API keys: Use {env:VAR} syntax so secrets never appear in config files
  2. Use file references for shared configs: gateway = "{file:mcps.toml}"
  3. Test your config: Run cru config show to see effective configuration
  4. Verify: Use cru config show to confirm your changes took effect
  5. Use daemon mode if you frequently run multiple cru commands at once