Discover / Development

Crush

by charmbraceletGo

Glamourous AI coding agent for your favourite terminal.

Agentexperimental

Maturity: experimental because latest release v0.87.0 is pre 1.0. Derived from release and commit history, not a rating.

Stars
27k
Forks
2.1k
Downloads / mo
Last commit
2026-08-03
License
NOASSERTION
Open issues
600

Market and trust evidence

Edition not yet matched

No exact skills.sh identity match is available for this repository. Repository adoption and freshness remain visible above; install momentum is not inferred.

Trust analysis is a screening signal, not a security warranty. Read the ranking and trust methodology.

In practice

Written by AI from this repository’s README · high confidence

Wanting an AI coding assistant inside the terminal without locking into one model provider or losing session context.

Use it when

Use it when you work in a terminal across macOS, Linux, Windows or BSD and want to switch LLM providers mid session.

Not the right pick when

Not a fit if you want a GUI editor experience, or if you cannot authenticate to any LLM provider.

Capabilities

  • choose from many LLMs or add OpenAI or Anthropic compatible APIs
  • switch LLMs mid session while preserving context
  • multiple work sessions and contexts per project
  • uses LSPs for additional code context
  • extensible through MCP servers over http, stdio and sse
  • runs in terminals on macOS, Linux, Windows and BSDs

Requirements

  • an LLM provider you can authenticate to, or an OpenAI or Anthropic compatible API

Cost: Cost not stated

Video walkthroughs

Third-party YouTube uploads matched to this tool by title, channel and repository name on 2026-08-03. Not made, reviewed or endorsed by SkillPilot. View counts and publish months are as of the match date and the month is approximate. Nothing loads from YouTube until you press play.

What the repository ships

Has docsCI configured

Detected from the actual files in the repository root.

Latest release v0.87.0

Published 2026-07-24

MCP OAuth, performance and more

Happy Friday everybody!

We're releasing some nice features for you so you can enjoy your weekend vibecoding. (Or not, stay outside :sun_with_face: and return to Crush on Monday! :smiley:).

MCP OAuth

That's it, it's finally here! Some of you have been asking for this for long.

This is required for some MCPs to work. Want to know to it set it up? Refer to this section into the README.

Thank @joestump and his agent @joestump-agent for this contribution. And of course, our favorite @taciturnaxolotl also helped.

Claude Channels MCP extension

@joestump (and his agent) _also_ added an initial implementation to support the Claude Channels MCP extension, which means MCPs can now send notifications to Crush when certain events happen.

Give this a try if you're interested, and let us know how well it works for you.

Restored MCP prompts

MCP prompts were unintentionally disabled in a previous release, but they were now added back!

LSP performance boost

Another cool contrib was made by @TheJhyeFactor, who vastly improved the CPU and memory usage on handling LSP servers in large repositories!

See #3370 for a more in-depth explanation of the optimizations.

Bang mode performance boost

@TheJhyeFactor _also_ improved performance of output streaming when running command in bang mode.

Check #3381 to see some benchmarking.

/etc/crush/crush.json

You read it right! Thank to @Muttaqin86 you can now have a system-wide Crush configuration on /etc/crush/crush.json.

The motivation for this was improving compatibility with NixOS.

Fixed Copilot + GPT-5.6

All three GPT-5.6 models (Sol, Terra and Luna) are now fixed when running via GitHub Copilot. Kudos to @nghiant03 for this!

That was a lot, but it's really fun to how much the community is enganged with Crush dev.

Keep Crushing! :tm:

Charm

Changelog

New!

  • 6f8a7fe8b2cd619e82683a70de252238f333052f: feat(client): reconnect the event stream after it drops (@meowgorithm)
  • d291d9f2c189d1d8c1c4a18d4b73650fc4d20ac9: feat(cmd): add --channels opt-in flag for MCP channel servers (@joestump)
  • 37fc995daca4486501acb6d03445a4bd6969d7f3: feat(mcp): OAuth 2.1 authorization for HTTP MCP servers (@taciturnaxolotl)
  • 1588ae868a8ae7a0f13738cf04542c466dd50f65: feat(mcp): SSE OAuth, metadata fixups, and resource param stripping (@taciturnaxolotl)
  • d338af88648a8f33f05624800013fcd11b0f1b97: feat(mcp): add OAuth support for HTTP MCP servers (@joestump)
  • a1cf002270dede2be0b415ace5e36b199cb5773e: feat(mcp): detect claude/channel capability and receive channel messages (@joestump)
  • b238696201229f30b073078b246c4f47416dd34c: feat(ui): tell a lost connection apart from an uninitialized agent (@meowgorithm)

Fixed

  • fbf59341beee53600e8e4f55b60d9392371dc22c: fix(agent): close dispatch completion-boundary cancel race (@joestump-agent)
  • ae9257b9cdce0dfc4afb6a5e7407d40e988c616c: fix(agent): serialize in-process run dispatch to prevent concurrent turns (@joestump)
  • a09cb3668c2871469250d42e1ced905fef84d820: fix(backend): log channel flag mismatch on duplicate workspace creation (@joestump-agent)
  • 086dc626c68292089fb1c7d7e0569dc7efa52005: fix(client): add MCP prompts to ui in client-server mode (@meowgorithm)
  • ca9ef6adeceed920f882a44f68b61ba9de2d9aba: fix(cmd): make --channels a persistent flag so crush run inherits it (@joestump-agent)
  • 213ad7945184fbbd5ae0830a8ffc313fd8f3722f: fix(config): load system-wide config from /etc/crush/crush.json (#2984) (@Muttaqin86)
  • 8ccf6945d6f9f0de98ed2e1f9900a322f7c91fab: fix(copilot): add additional responses models (#3416) (@nghiant03)
  • 26399fc2ef5968db46627d3bcb2c57d4d330472c: fix(mcp): address OAuth review findings (timeout, refresh, concurrency) (@joestump-agent)
  • bc8ff341a02f8d739dea37af2375f5dcde712474: fix(mcp): buffer cha

Tags

README

Crush

<p align="center">

<a href="https://stuff.charm.sh/crush/charm-crush.png"><img width="450" alt="Charm Crush Logo" src="https://github.com/user-attachments/assets/cf8ca3ce-8b02-43f0-9d0f-5a331488da4b" /></a><br />

<a href="https://github.com/charmbracelet/crush/releases"><img src="https://img.shields.io/github/release/charmbracelet/crush" alt="Latest Release"></a>

<a href="https://github.com/charmbracelet/crush/actions"><img src="https://github.com/charmbracelet/crush/actions/workflows/build.yml/badge.svg" alt="Build Status"></a>

</p>

<p align="center">Your new coding bestie, now available in your favourite terminal.<br />Your tools, your code, and your workflows, wired into your LLM of choice.</p>

<p align="center">终端里的编程新搭档,<br />无缝接入你的工具、代码与工作流,全面兼容主流 LLM 模型。</p>

<p align="center"><img width="800" alt="Crush Demo" src="https://github.com/user-attachments/assets/58280caf-851b-470a-b6f7-d5c4ea8a1968" /></p>

Features

  • Multi-Model: choose from a wide range of LLMs or add your own via OpenAI- or Anthropic-compatible APIs
  • Flexible: switch LLMs mid-session while preserving context
  • Session-Based: maintain multiple work sessions and contexts per project
  • LSP-Enhanced: Crush uses LSPs for additional context, just like you do
  • Extensible: add capabilities via MCPs (http, stdio, and sse)
  • Works Everywhere: first-class support in every terminal on macOS, Linux, Windows (PowerShell and WSL), Android, FreeBSD, OpenBSD, and NetBSD
  • Industrial Grade: built on the Charm ecosystem, powering 25k+ applications, from leading open source projects to business-critical infrastructure

Installation

Use a package manager:


# Homebrew
brew install charmbracelet/tap/crush

# NPM
npm install -g @charmland/crush

# Arch Linux (btw)
yay -S crush-bin

# Nix
nix run github:numtide/nix-ai-tools#crush

# FreeBSD
pkg install crush

Windows users:


# Winget
winget install charmbracelet.crush

# Scoop
scoop bucket add charm https://github.com/charmbracelet/scoop-bucket.git
scoop install crush

<details>

<summary><strong>Nix (NUR)</strong></summary>

Crush is available via the official Charm NUR in nur.repos.charmbracelet.crush, which is the most up-to-date way to get Crush in Nix.

You can also try out Crush via the NUR with nix-shell:


# Add the NUR channel.
nix-channel --add https://github.com/nix-community/NUR/archive/main.tar.gz nur
nix-channel --update

# Get Crush in a Nix shell.
nix-shell -p '(import <nur> { pkgs = import <nixpkgs> {}; }).repos.charmbracelet.crush'

NixOS & Home Manager Module Usage via NUR

Crush provides NixOS and Home Manager modules via NUR.

You can use these modules directly in your flake by importing them from NUR. Since it auto detects whether its a home manager or nixos context you can use the import the exact same way :)


{
  inputs = {
    nixpkgs.url = "github:NixOS/nixpkgs/nixos-unstable";
    nur.url = "github:nix-community/NUR";
  };

  outputs = { self, nixpkgs, nur, ... }: {
    nixosConfigurations.your-hostname = nixpkgs.lib.nixosSystem {
      system = "x86_64-linux";
      modules = [
        nur.modules.nixos.default
        nur.repos.charmbracelet.modules.crush
        {
          programs.crush = {
            enable = true;
            settings = {
              providers = {
                openai = {
                  id = "openai";
                  name = "OpenAI";
                  base_url = "https://api.openai.com/v1";
                  type = "openai";
                  api_key = "sk-fake123456789abcdef...";
                  models = [
                    {
                      id = "gpt-4";
                      name = "GPT-4";
                    }
                  ];
                };
              };
              lsp = {
                go = { command = "gopls"; enabled = true; };
                nix = { command = "nil"; enabled = true; };
              };
              options = {
                context_paths = [ "/etc/nixos/configuration.nix" ];
                tui = { compact_mode = true; };
                debug = false;
              };
            };
          };
        }
      ];
    };
  };
}

</details>

<details>

<summary><strong>Debian/Ubuntu</strong></summary>


sudo mkdir -p /etc/apt/keyrings
curl -fsSL https://repo.charm.sh/apt/gpg.key | sudo gpg --dearmor -o /etc/apt/keyrings/charm.gpg
echo "deb [signed-by=/etc/apt/keyrings/charm.gpg] https://repo.charm.sh/apt/ * *" | sudo tee /etc/apt/sources.list.d/charm.list
sudo apt update && sudo apt install crush

</details>

<details>

<summary><strong>Fedora/RHEL</strong></summary>


echo '[charm]
name=Charm
baseurl=https://repo.charm.sh/yum/
enabled=1
gpgcheck=1
gpgkey=https://repo.charm.sh/yum/gpg.key' | sudo tee /etc/yum.repos.d/charm.repo
sudo yum install crush

</details>

Or, download it:

  • [Packages][releases] are available in Debian and RPM formats
  • [Binaries][releases] are available for Linux, macOS, Windows, FreeBSD, OpenBSD, and NetBSD

[releases]: https://github.com/charmbracelet/crush/releases

Or just install it with Go:


go install github.com/charmbracelet/crush@latest

On illumos (OpenIndiana, OmniOS), the command above works as-is. Only native

OS notifications are unavailable there; terminal-based notifications (OSC) and

the terminal bell still work. On Oracle Solaris, add -tags sqlite3_dotlk so

the local database uses dot-file locking:


go install -tags sqlite3_dotlk github.com/charmbracelet/crush@latest

[!WARNING]

Productivity may increase when using Crush and you may find yourself nerd

sniped when first using the application. If the symptoms persist, join the

[Slack][slack] or [Discord][discord] and nerd snipe the rest of us.

Getting Started

The quickest way to get started is to choose a [Hyper][hyper] model from model

picker. Follow the steps to authenticate and you'll be good to go.

[Hyper], from Charm, is the official Crush provider. It’s subscription-based,

with a free tier, and optimized for Crush. It’s privacy focused, with zero data

retention (ZDR) is and designed to comply with GDPR. [More on Hyper][hyper].

<p><a href="https://hyper.charm.land"><img width="340" height="200" alt="Charm Hyper" src="https://github.com/user-attachments/assets/50875289-7992-454d-9f14-9f790413fb5e" /></a></p>

API Keys

You can also use Crush with many other providers such as Anthopic, OpenAI,

Gemini, OpenRouter and so on. Press <kbd>ctrl+l</kbd> to open the model picker,

choose the provider of your choice, and paste your API key.

That said, you can also set environment variables for preferred providers:

| Environment Variable | Provider |

| --------------------------- | -------------------------------------------------- |

| HYPER_API_KEY | [Charm Hyper][hyper] |

| ANTHROPIC_API_KEY | Anthropic |

| OPENAI_API_KEY | OpenAI |

| VERCEL_API_KEY | Vercel AI Gateway |

| GEMINI_API_KEY | Google Gemini |

| ZAI_API_KEY | Z.ai |

| MINIMAX_API_KEY | MiniMax |

| SYNTHETIC_API_KEY | Synthetic |

| HF_TOKEN | Hugging Face Inference |

| CEREBRAS_API_KEY | Cerebras |

| OPENROUTER_API_KEY | OpenRouter |

| IONET_API_KEY | io.net |

| ALIBABA_SINGAPORE_API_KEY | Alibaba (Singapore) |

| ALIBABA_US_API_KEY | Alibaba (United States) |

| GROQ_API_KEY | Groq |

| AVIAN_API_KEY | Avian |

| OPENCODE_API_KEY | OpenCode Zen & Go |

| VERTEXAI_PROJECT | Google Cloud VertexAI (Gemini) |

| VERTEXAI_LOCATION | Google Cloud VertexAI (Gemini) |

| AWS_ACCESS_KEY_ID | Amazon Bedrock (Claude) |

| AWS_SECRET_ACCESS_KEY | Amazon Bedrock (Claude) |

| AWS_REGION | Amazon Bedrock (Claude) |

| AWS_PROFILE | Amazon Bedrock (Custom Profile) |

| AWS_BEARER_TOKEN_BEDROCK | Amazon Bedrock |

| AZURE_OPENAI_API_ENDPOINT | Azure OpenAI models |

| AZURE_OPENAI_API_KEY | Azure OpenAI models (optional when using Entra ID) |

| AZURE_OPENAI_API_VERSION | Azure OpenAI models |

| MOONSHOT_API_KEY | Moonshot |

[hyper]: https://hyper.charm.land

Also note that Crush can support nearly any provider, including

Local Models. For more info see

Custom Providers below.

By the Way

Is there a provider you’d like to see in Crush? Is there an existing model that needs an update?

Crush’s default model listing is managed in Catwalk, a community-supported, open source repository of Crush-compatible models, and you’re welcome to contribute.

<a href="https://github.com/charmbracelet/catwalk"><img width="174" height="174" alt="Catwalk Badge" src="https://github.com/user-attachments/assets/95b49515-fe82-4409-b10d-5beb0873787d" /></a>

Configuration

[!TIP]

Crush ships with a builtin crush-config skill for configuring itself. In

many cases you can simply ask Crush to configure itself.

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

customize Crush, configuration can be added either local to the project itself,

or globally, with the following priority:

  1. .crush.json
  2. crush.json
  3. $HOME/.config/crush/crush.json

Configuration itself is stored as a JSON object:


{
  "this-setting": { "this": "that" },
  "that-setting": ["ceci", "cela"]
}

As an additional note, Crush also stores ephemeral data, such as application

state, in one additional location:


# Unix
$HOME/.local/share/crush/crush.json

# Windows
%LOCALAPPDATA%\crush\crush.json

[!TIP]

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

- CRUSH_GLOBAL_CONFIG

- CRUSH_GLOBAL_DATA

LSPs

Crush can use LSPs for additional context to help inform its decisions, just

like you would. LSPs can be added manually like so:


{
  "$schema": "https://charm.land/crush.json",
  "lsp": {
    "go": {
      "command": "gopls",
      "env": {
        "GOTOOLCHAIN": "go1.24.5"
      }
    },
    "typescript": {
      "command": "typescript-language-server",
      "args": ["--stdio"]
    },
    "nix": {
      "command": "nil"
    }
  }
}

MCPs

Crush also supports Model Context Protocol (MCP) servers through three transport

types: stdio for command-line servers, http for HTTP endpoints, and sse

for Server-Sent Events.

Shell-style value expansion ($VAR, ${VAR:-default}, $(command), quoting,

nesting) works in command, args, env, headers, and url, so

file-based secrets work out of the box. You can use values like "$TOKEN"

or "$(cat /path/to/secret/token)". Expansion runs through Crush's embedded

shell, so the same syntax works on every supported system, Windows included.

Unset variables expand to the empty string by default, matching bash. For

required credentials, use ${VAR:?message} so an unset variable fails loudly

at load time with message instead of silently resolving to empty:


{ "api_key": "${CODEBERG_TOKEN:?set CODEBERG_TOKEN}" }

Headers (both MCP headers and provider extra_headers) whose value

resolves to the empty string are dropped from the outgoing request rather

than sent as Header:. That keeps optional env-gated headers like

"OpenAI-Organization": "$OPENAI_ORG_ID" clean when the variable is unset.

Provider extra_body is a non-expanding JSON passthrough; put env-driven

values in extra_headers or the provider's api_key / base_url, all of

which do expand.

Security note: crush.json is trusted code. Any $(...) in it runs at

load time with your shell's privileges, before the UI appears. Don't launch

Crush in a directory whose crush.json you haven't reviewed.


{
  "$schema": "https://charm.land/crush.json",
  "mcp": {
    "filesystem": {
      "type": "stdio",
      "command": "node",
      "args": ["/path/to/mcp-server.js"],
      "timeout": 120,
      "disabled": false,
      "disabled_tools": ["some-tool-name"],
      "env": {
        "NODE_ENV": "production"
      }
    },
    "github": {
      "type": "http",
      "url": "https://api.githubcopilot.com/mcp/",
      "timeout": 120,
      "disabled": false,
      "disabled_tools": ["create_issue", "create_pull_request"],
      "headers": {
        "Authorization": "Bearer $GH_PAT"
      }
    },
    "streaming-service": {
      "type": "sse",
      "url": "https://example.com/mcp/sse",
      "timeout": 120,
      "disabled": false,
      "headers": {
        "API-Key": "$(echo $API_KEY)"
      }
    }
  }
}
MCP OAuth

HTTP and SSE MCP servers that require OAuth can use Crush's built-in

authorization-code flow instead of a static Authorization header. Set

"oauth": true to enable it:


{
  "mcp": {
    "linear": {
      "type": "http",

Truncated. Read the full README on GitHub ↗

Related tools