Crush
CLICharm
Charm's open-source terminal coding agent with multi-model support, LSP-enhanced context, MCP extensibility, and first-class support on every major platform.
MCP
SupportedConfigure MCP servers under the mcp key in crush.json. Supports stdio, HTTP, and SSE transports with shell-style value expansion for secrets.
Config files
| Path | Scope | Format | Key |
|---|---|---|---|
crush.json.crush.json takes precedence over crush.json. | Project | json | mcp |
~/.config/crush/crush.json | Global | json | mcp |
Fields
| Field | Type | Description |
|---|---|---|
type* | "stdio" | "http" | "sse" | Transport type: stdio for command-line servers, http for HTTP endpoints, sse for Server-Sent Events. |
command* | string | For stdio servers: the command to run. |
args | string[] | Arguments passed to the stdio command. |
env | record<string, string> | Environment variables for stdio servers. Supports shell-style expansion. |
url* | string | For http/sse servers: the endpoint URL. |
headers | record<string, string> | HTTP headers for http/sse servers, e.g. Authorization: Bearer $GH_PAT. |
timeout | number | Timeout in seconds for the server. |
disabled | boolean | Disable the server without removing it from config. |
disabled_tools | string[] | Tool names from this server to hide from the agent. |
Capabilities
Examples
{
"$schema": "https://charm.land/crush.json",
"mcp": {
"filesystem": {
"type": "stdio",
"command": "node",
"args": ["/path/to/mcp-server.js"],
"env": { "NODE_ENV": "production" }
},
"github": {
"type": "http",
"url": "https://api.githubcopilot.com/mcp/",
"disabled_tools": ["create_issue"],
"headers": { "Authorization": "Bearer $GH_PAT" }
},
"streaming-service": {
"type": "sse",
"url": "https://example.com/mcp/sse"
}
}
}- •Shell-style expansion ($VAR, ${VAR:-default}, ${VAR:?message}, $(command)) works in command, args, env, headers, and url, via Crush's embedded shell on all platforms including Windows.
- •Headers whose value resolves to the empty string are dropped from the outgoing request.
- •crush.json is trusted code: any $(...) in it runs at load time with your shell's privileges.
- •Individual server tools can be hidden with disabled_tools; MCP tools are named mcp_<server>_<tool> and can be allowlisted in permissions.allowed_tools.
Skills
SupportedSKILL.md skills following the Agent Skills open standard, discovered from many global and project paths and activated on demand; user-invocable skills appear in the command palette.
Config files
| Path | Scope | Format | Key |
|---|---|---|---|
.crush/skills/<name>/SKILL.md | Project | markdown | — |
~/.config/crush/skills/<name>/SKILL.md | Global | markdown | — |
Fields
| Field | Type | Description |
|---|---|---|
name* | string | Skill identifier (required by the Agent Skills standard). |
description* | string | What the skill does and when to use it. |
user-invocable | boolean | Make the skill invocable as a command from the command palette (Ctrl+P). |
disable-model-invocation | boolean | Prevent the model from auto-triggering the skill while still allowing user invocation. |
license | string | Optional license identifier. |
compatibility | string | Optional compatibility hint. |
metadata | record<string, string> | Optional string-to-string metadata map. |
Examples
---
name: my-skill
description: A skill that can be invoked as a command.
user-invocable: true
---
Instructions the agent loads when the skill is activated.{
"$schema": "https://charm.land/crush.json",
"options": {
"skills_paths": ["~/.config/crush/skills", "./project-skills"]
}
}- •Additional global search paths: $CRUSH_SKILLS_DIR, ~/.config/agents/skills/, ~/.claude/skills/, ~/.agents/skills/, Windows %LOCALAPPDATA% equivalents, and any paths in options.skills_paths.
- •Additional project search paths: .agents/skills/, .claude/skills/, and .cursor/skills/.
- •User-invocable skills show in the palette as user:skill-name (global) or project:skill-name (project).
- •disable-model-invocation hides a skill from the model's available skills list while keeping it user-invocable.
- •Hide specific skills (including builtins like crush-config) with options.disabled_skills.
- •Crush ships builtin skills including crush-config and crush-hooks for configuring itself.
Rules
SupportedProject context files (AGENTS.md, CRUSH.md, and compatible variants) plus global context files in ~/.config, with configurable paths.
Config files
| Path | Scope | Format | Key |
|---|---|---|---|
AGENTS.mdDefault file created by project initialization; CRUSH.md and other case variants are also read. | Project | markdown | — |
CRUSH.mdCrush-specific project rules; .local and lowercase variants are also read. | Project | markdown | — |
~/.config/crush/CRUSH.mdGlobal Crush-specific rules. | Global | markdown | — |
~/.config/AGENTS.mdGlobal generic instructions shared with other agentic coding tools. | Global | markdown | — |
Fields
| Field | Type | Description |
|---|---|---|
options.context_paths | string[] | Additional project context file paths, appended to the built-in defaults. |
options.global_context_paths | string[] | Global context file or folder paths. Folders load all .md files recursively. Defaults to ~/.config/crush/CRUSH.md and ~/.config/AGENTS.md. |
options.initialize_as | string | Name of the context file created/updated during project initialization. Default AGENTS.md. |
Examples
{
"$schema": "https://charm.land/crush.json",
"options": {
"global_context_paths": [
"~/path/to/custom/context/file.md",
"/full/path/to/folder/of/files/"
]
}
}- •Default project context paths also include compatible files from other tools: .github/copilot-instructions.md, .cursorrules, .cursor/rules/, CLAUDE.md, CLAUDE.local.md, GEMINI.md, and case variants of CRUSH.md/AGENTS.md (verified in source).
- •Project initialization analyzes the codebase and writes a context file, AGENTS.md by default; customize the name/location with options.initialize_as.
- •Add extra project context files with options.context_paths and replace the global defaults with options.global_context_paths (directories load all .md files recursively).
- •Use ~/.config/crush/CRUSH.md for Crush-specific rules and ~/.config/AGENTS.md for generic instructions shared with other agentic tools.
Hooks
PartialShell-command hooks configured under the hooks key in crush.json. Preliminary support: currently only PreToolUse fires, with plans to add more events.
Config files
| Path | Scope | Format | Key |
|---|---|---|---|
crush.jsonRelative command paths resolve against the working directory. | Project | json | hooks |
~/.config/crush/crush.jsonUse absolute paths or inline commands; relative paths resolve against the working directory, not the config file. | Global | json | hooks |
Fields
| Field | Type | Description |
|---|---|---|
name | string | Friendly display name shown in the TUI. Falls back to command. |
matcher | string | Regex tested against the tool name (e.g. ^bash$, ^mcp_). Omit to match all tools. |
command* | string | Shell command or script path to run. Executed through Crush's embedded POSIX shell on all platforms. |
timeout | number | Seconds before the hook is killed. Defaults to 30. |
Examples
{
"hooks": {
"PreToolUse": [
{
"name": "no-rm-rf",
"matcher": "^bash$",
"command": "./hooks/no-rm-rf.sh",
"timeout": 10
}
]
}
}{
"hooks": {
"PreToolUse": [
{
"matcher": "^(view|ls|grep|glob)$",
"command": "echo '{\"decision\":\"allow\"}'"
}
]
}
}- •Hooks are broadly Claude Code-compatible: the config shape, stdin payload, output envelope, and exit codes line up.
- •Hooks run in parallel through Crush's embedded POSIX shell but results compose in config order: deny wins over allow, updated_input patches shallow-merge in order.
- •Exit codes: 0 = success (stdout parsed as JSON envelope), 2 = block the tool call (stderr is the deny reason), 49 = halt the whole turn, anything else = non-blocking error.
- •The JSON output envelope supports decision (allow/deny), halt, reason, context, and updated_input; decision allow pre-approves the call and skips the permission prompt.
- •Hooks receive event data via stdin JSON and env vars like CRUSH_EVENT, CRUSH_TOOL_NAME, CRUSH_TOOL_INPUT_COMMAND, and CRUSH_TOOL_INPUT_FILE_PATH.
- •PreToolUse only fires on the top-level agent's tool calls; sub-agent tool calls are not intercepted.
- •Crush ships a builtin crush-hooks skill for writing and configuring hooks.
Commands
SupportedCustom commands (saved prompts) as plain markdown files, invoked from the command palette with user:/project: prefixes and $NAME argument placeholders.
Config files
| Path | Scope | Format | Key |
|---|---|---|---|
.crush/commands/<name>.mdLocation follows options.data_directory (default .crush). | Project | markdown | — |
~/.config/crush/commands/<name>.md$XDG_CONFIG_HOME/crush/commands/; Windows: %USERPROFILE%\AppData\Local\crush\commands\. | Global | markdown | — |
~/.crush/commands/<name>.md | Global | markdown | — |
Examples
# Fetch Context for Issue $ISSUE_NUMBER
RUN gh issue view $ISSUE_NUMBER --json title,body,comments
RUN grep -R "$SEARCH_PATTERN" $DIRECTORY- •The docs URL is the official repo's draft COMMANDS.md, confirmed by maintainers in issue #2219; paths and behavior verified against the main-branch source (internal/commands).
- •The whole markdown file is the prompt; the file name (without extension) becomes the command name, prefixed with user: or project:.
- •Sub-directories namespace commands with colons, e.g. commands/git/commit.md becomes user:git:commit.
- •$NAME placeholders (uppercase letters, numbers, underscores) become required arguments that Crush prompts for when the command runs.
- •Prompts from connected MCP servers also appear as commands in the palette, and user-invocable skills surface alongside them.
Settings
Supportedcrush.json configures providers, models, LSPs, MCP servers, hooks, permissions, and options, at project and global scope with a published JSON schema.
Config files
| Path | Scope | Format | Key |
|---|---|---|---|
.crush.jsonHighest priority. | Project | json | — |
crush.json | Project | json | — |
~/.config/crush/crush.jsonWindows: %LOCALAPPDATA%\crush\crush.json equivalent via env overrides. | Global | json | — |
Fields
| Field | Type | Description |
|---|---|---|
providers | object | Custom provider configs (openai, openai-compat, anthropic, ollama, llamacpp, lmstudio, litellm, omlx) with base_url, api_key, and model definitions. |
lsp | object | Language servers Crush uses for extra context, e.g. { "go": { "command": "gopls" } }. |
mcp | object | MCP server definitions (see MCP surface). |
hooks | object | Lifecycle hook configuration (see Hooks surface). |
permissions | { allowed_tools?: string[] } | Tools allowed to run without a permission prompt, e.g. view, ls, grep, or mcp_<server>_<tool>. |
options.context_paths | string[] | Additional context file paths (see Rules surface). |
options.global_context_paths | string[] | Global context file/folder paths (see Rules surface). |
options.initialize_as | string | Context file name created during project initialization. Default AGENTS.md. |
options.disabled_tools | string[] | Built-in tools to disable and hide from the agent entirely. |
options.disabled_skills | string[] | Skills (builtin or discovered) to hide from the agent. |
options.skills_paths | string[] | Additional skill discovery paths. |
options.data_directory | string | Directory for per-project state such as the SQLite database. Default .crush. |
options.attribution | { trailer_style?: string, generated_with?: boolean } | Git commit/PR attribution. trailer_style: assisted-by (default), co-authored-by, or none. |
options.disable_notifications | boolean | Disable desktop notifications for permission requests and finished turns. |
options.disable_provider_auto_update | boolean | Disable automatic provider/model list updates from Catwalk. |
options.disable_metrics | boolean | Opt out of pseudonymous usage metrics. |
options.debug | boolean | Enable debug logging (also available via --debug). |
Examples
{
"$schema": "https://charm.land/crush.json",
"lsp": {
"go": { "command": "gopls" },
"typescript": { "command": "typescript-language-server", "args": ["--stdio"] }
},
"permissions": {
"allowed_tools": ["view", "ls", "grep", "edit"]
},
"options": {
"disabled_tools": ["sourcegraph"]
}
}- •Config priority: .crush.json, then crush.json, then $HOME/.config/crush/crush.json. Schema: https://charm.land/crush.json.
- •Override the global config and data locations with CRUSH_GLOBAL_CONFIG and CRUSH_GLOBAL_DATA; ephemeral app state lives in ~/.local/share/crush/crush.json.
- •The --yolo flag skips all permission prompts entirely.
- •A .crushignore file (gitignore syntax) excludes additional files from context.
- •Opt out of pseudonymous metrics with options.disable_metrics, CRUSH_DISABLE_METRICS=1, or DO_NOT_TRACK=1.
- •Crush ships a builtin crush-config skill, so you can ask Crush to configure itself.