Configuration Guide
Crucible uses TOML configuration files stored in ~/.config/crucible/.
Quick Start
Section titled “Quick Start”mkdir -p ~/.config/crucible# Create config.toml with your settingsFile Structure
Section titled “File Structure”~/.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)Dynamic Values
Section titled “Dynamic Values”Crucible supports dynamic value references that are resolved at config load time.
{env:VAR} Environment Variables
Section titled “{env:VAR} Environment Variables”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,
.envfile, or secret manager - Reference them in config with
{env:VAR}syntax - The config file itself contains no secrets
{file:path} File References
Section titled “{file:path} File References”Use {file:path} anywhere in your config to pull in external content:
# Include a whole section from a TOML filegateway = "{file:mcps.toml}"
# Include just a secret value (plain text file)[embedding]provider = "openai"api_key = "{file:~/.secrets/openai.key}"
# Works in arrays tooextra_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
.tomlextension → 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 directoryproviders = "{dir:~/.config/crucible/providers.d/}"
# Drop-in MCP server configsgateway = "{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
.tomlfiles are processed - Hidden files (starting with
.) are ignored - Later files override earlier ones for conflicting keys
- Tables are deep-merged, arrays are appended
Combining All Three
Section titled “Combining All Three”You can use {env:}, {file:}, and {dir:} references throughout your config:
[providers.cloud]backend = "openai"api_key = "{env:OPENAI_API_KEY}" # From environmentendpoint = "{file:~/.config/endpoint.txt}" # From file
# Modular provider configs[llm]providers = "{dir:~/.config/crucible/providers.d/}"[include] Section (Legacy)
Section titled “[include] Section (Legacy)”The [include] section merges files into top-level sections:
[include]gateway = "mcps.toml"embedding = "embedding.toml"Path Resolution
Section titled “Path Resolution”| Path Format | Example | Resolution |
|---|---|---|
| Relative | mcps.toml | Same directory as main config |
| Home | ~/crucible/mcps.toml | User’s home directory |
| Absolute | /etc/crucible/mcps.toml | Exact path |
Merge Behavior
Section titled “Merge Behavior”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
MCP Server Configuration
Section titled “MCP Server Configuration”Configure upstream MCP servers in mcps.toml. See MCP Gateway for details.
Stdio Transport (spawn a process)
Section titled “Stdio Transport (spawn a process)”[[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"SSE Transport (connect to HTTP endpoint)
Section titled “SSE Transport (connect to HTTP endpoint)”[[servers]]name = "remote-tools"prefix = "remote_"
[servers.transport]type = "sse"url = "https://mcp.example.com/sse"auth_header = "Bearer your-api-key"Tool Filtering
Section titled “Tool Filtering”Control which tools are exposed:
[[servers]]name = "github"allowed_tools = ["search_*", "get_*"] # Whitelist with glob patternsblocked_tools = ["delete_*"] # Blacklist (takes priority)Environment Variables
Section titled “Environment Variables”Crucible uses a minimal set of environment variables for system-level configuration:
| Variable | Description |
|---|---|
CRUCIBLE_CONFIG | Path to config file (default: ~/.config/crucible/config.toml) |
CRUCIBLE_CONFIG_DIR | Config directory path |
CRUCIBLE_LOG_LEVEL | Logging level (off, error, warn, info, debug, trace) |
CRUCIBLE_TEST_MODE | Enable 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 preferProfiles
Section titled “Profiles”Define multiple profiles for different environments:
profile = "development" # Active profile
[profiles.development]# Development-specific settings
[profiles.production]# Production-specific settingsStorage Modes
Section titled “Storage Modes”Crucible supports multiple storage modes that control how the CLI accesses data:
SQLite Mode (Default)
Section titled “SQLite Mode (Default)”[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
Daemon Mode
Section titled “Daemon Mode”[storage]mode = "daemon"idle_timeout_secs = 300 # Optional, default 5 minutesThe 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
Socket Location
Section titled “Socket Location”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)
Daemon Management
Section titled “Daemon Management”The daemon is managed automatically. For manual control:
# The daemon starts automatically when needed# To force shutdown:cru daemon stop- Secure API keys: Use
{env:VAR}syntax so secrets never appear in config files - Use file references for shared configs:
gateway = "{file:mcps.toml}" - Test your config: Run
cru config showto see effective configuration - Verify: Use
cru config showto confirm your changes took effect - Use daemon mode if you frequently run multiple cru commands at once