Configuration

Crush is configured with Bash via a set of Crush-specific builtin commands.

Note

Crush can configure itself via a builtin config skill. That is to say, can generally just tell Crush want you want to configure using natural language.

If you're migrating from the old JSON format, you can also ask Crush to convert the config for you.

Crush runs great with no configuration. That said, if you do need or want to customize Crush, you can, with a crushrc.

Crush is configured with Bash via a set of Crush-specific builtin commands. By default, global config lives at ~/.config/crush/crushrc on Unix-like systems and %USERPROFILE%\.config\crush\crushrc on Windows. It works like a .bashrc: it runs when Crush starts and configures the agent.

# Add Ollama.provider add ollama --type ollama --base-url "http://localhost:11434/v1" # Register a model on Ollama.model add ollama/llama3.3 --name "Llama 3.3" --context-window 128000 # Auto-approve some tools.permissions allow view edit # Add an MCP server, with a GitHub API token stored in 1Password.mcp add github \  --type http \  --url "https://api.github.com/mcp/" \  --header Authorization "Bearer $(op read 'op://my-secret-key')"

Since it's Bash, so you can use logic, source other files, and so on. It's really handy.

# Change config based on the machine you're on.if [[ $HOSTNAME == "babysquid" ]]; then    option skill-path "$HOME/squid-skills"fi # Load some extra configsource "$XDG_CONFIG_HOME/squid-config.sh" # Get API keys from your password manager.provider add my-secret-provider \  --type completions \  --base-url "https://api.example.com/v1" \  --api-key "$(op read my-secret-key)"

Because Crush has a native, built-in Bash interpreter, Bash-based config works identically across all platforms, including Windows.

Why Bash?

Two reasons:

  1. Crush ships with a first-class Bash interpreter, so we get the logic for free.

  2. Ultimately, Crush needs to be able to configure itself, and command-based config allows both users and the agent to use the same tools.

What about JSON?

JSON is still supported but is deprecated and, while it's supported, it won't be receiving new features. For more see Legacy JSON.

Config versioning

Not breaking the config API is really important to us! That said, you can target specific Crush versions with $CRUSH_VERSION:

if [[ $CRUSH_VERSION == "0.85.*" ]]; then    option debug truefi

Security

Just like crush.json, crushrc is a trusted file. Guard it carefully and don't download random configs without reading them first.

Where config lives

Crush looks for config in the following places, with lower numbers taking precedence:

PriorityUnix-likeWindows
1./.crushrc.\.crushrc
2./crushrc.\crushrc
3$XDG_CONFIG_HOME/crush/crushrc%USERPROFILE%\.config\crush\crushrc

Legacy JSON uses .crush.json / crush.json in the same directories as the above. Everything found is merged, with project settings overriding global ones and crushrc overriding JSON in the same directory. If a folder has both, they merge and Crush logs a warning.

Data directories (~/.local/share/crush on Unix-like systems and %LOCALAPPDATA%\crush on Windows) contain machine-owned JSON state. Crush does not discover or execute a crushrc from those locations.

Note

Crush also stores ephemeral data, such as application state, in crush.json: $XDG_DATA_HOME/crush/crush.json (~/.local/share/crush/crush.json by default) on Unix-like systems and %LOCALAPPDATA%\crush\crush.json on Windows. This is application state, and should not be edited by hand.

Crush respects the XDG Base Directory Specification, so your paths may differ depending on your XDG_CONFIG_HOME value.

Note

You can override the user and data config locations by setting:

  • CRUSH_GLOBAL_CONFIG

  • CRUSH_GLOBAL_DATA

  • CRUSH_DATA_DIR (overrides the per-project .crush directory)

Command Reference

The sections below read like CLI help. Entity commands use add to create or update something and remove (or rm) to delete it. Booleans accept true/false/1/0/yes/no, in any case.

Available Commands:  provider      Manage model providers  model         Manage models and model selection  mcp           Manage MCP servers  lsp           Manage language servers  hook          Manage hooks  permissions   Configure tool permissions  option        Configure general Crush behavior

Detailed references live on their own pages:

CommandWhere
providerProviders
modelModels
mcpMCPs
lspLSPs
hookHooks
permissionsPermissions
optionOptions

Composing configs

Because it's Bash, a shared base config is just a source:

# Unix-like: ~/.config/crush/crushrc# Windows:   %USERPROFILE%\.config\crush\crushrcsource ~/team/crush-base.sh    # sets up providers, a few skills # …but on this machine, drop a skill path the base added and add my own.option reset skill-pathoption skill-path ~/my/skills

remove, rm, and option reset all act on whatever was set earlier in the script or pulled in via source. Later lines win, just like a shell.

Legacy JSON

crush.json is the original format and is now deprecated. We plan to support it for the foreseeable future, but new configuration options will only be added to Bash-based config.

{    "$schema": "https://charm.land/crush.json",    "providers": {        "anthropic": { "api_key": "$ANTHROPIC_API_KEY" },    },    "models": {        "large": {            "provider": "anthropic",            "model": "claude-sonnet-4-20250514",        },    },    "permissions": { "allowed_tools": ["view", "ls", "grep"] },}

For a full reference, see the JSON schema.

In JSON, only selected string fields (API keys, URLs, MCP/LSP commands and args, headers) are shell-expanded at load time. In crushrc there's no such list — it's all just Bash.

Both formats are trusted code: they run with your shell privileges before the UI appears. Don't launch Crush in a directory whose config you haven't read.

Environment variables

The top-level env field sets environment variables at startup, before providers are configured. This is useful for variables that affect provider authentication (e.g. the AWS SDK credential chain) without wrapping the crush command in a shell script or exporting them in your shell profile:

{    "$schema": "https://charm.land/crush.json",    "env": {        "AWS_PROFILE": "my-sso-profile"    }}

Values support the same $VAR and $(command) expansion as other config fields, so you can reference existing environment variables or shell out for a value.

Read this post in your terminal with glow:glow -p https://crush.charm.land/configuration/index.md

EOF