MCPcopy
hub / github.com/charmbracelet/crush

github.com/charmbracelet/crush @v0.81.0 sqlite

repository ↗ · DeepWiki ↗ · release v0.81.0 ↗
5,138 symbols 21,447 edges 485 files 2,812 documented · 55%
README

Crush

<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>


<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>

Your new coding bestie, now available in your favourite terminal.

Your tools, your code, and your workflows, wired into your LLM of choice.

终端里的编程新搭档,

无缝接入你的工具、代码与工作流,全面兼容主流 LLM 模型。

Crush Demo

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

Nix (NUR)

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;
              };
            };
          };
        }
      ];
    };
  };
}

Debian/Ubuntu

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

Fedora/RHEL

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

Or, download it:

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

Or just install it with Go:

go install 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 grab an API key for your preferred provider such as Anthropic, OpenAI, Groq, OpenRouter, or Vercel AI Gateway and just start Crush. You'll be prompted to enter your API key.

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

Environment Variable Provider
HYPER_API_KEY Charm Hyper
ANTHROPIC_API_KEY Anthropic
OPENAI_API_KEY OpenAI
VERCEL_API_KEY Vercel AI Gateway
GEMINI_API_KEY Google Gemini
SYNTHETIC_API_KEY Synthetic
ZAI_API_KEY Z.ai
MINIMAX_API_KEY MiniMax
HF_TOKEN Hugging Face Inference
CEREBRAS_API_KEY Cerebras
OPENROUTER_API_KEY OpenRouter
IONET_API_KEY io.net
ALIBABA_SINGAPORE_API_KEY Alibaba (Singapore)
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

Subscriptions

If you prefer subscription-based usage, here are some plans that work well in Crush:

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.

Catwalk Badge

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)"
      }
    }
  }
}

Hooks

Crush has preliminary support for hooks. For details, see the hook guide.

Sharing a workspace across clients

When Crush is run against a shared backend (for example two TUIs talking to the same crush serve), clients are grouped into workspaces keyed by their resolved --cwd. Two clients with the same --cwd join the same underlying workspace, so they share the session list, message history, permission queue, LSP, and MCP state.

Joining is implicit: pointing a second client at the same working directory attaches it to the existing workspace. Each new invocation, however, starts in its own fresh session by default. To pick up the conversation another client already has open, use the session manager (the session picker) and select it. Sessions surface two signals there:

  • IsBusy is set while an agent turn is in flight for that session.
  • AttachedClients reports how many clients are currently viewing it.

A non-zero AttachedClients (often combined with IsBusy) is the cue that a session is "in progress" on another client and joining it will mirror that view live.

The first client to create a workspace fixes its process-wide flags. In particular, --yolo and `

Extension points exported contracts — how you extend this code

ContentPart (Interface)
ContentPart is a part of a message's content. [16 implementers]
internal/proto/message.go
ToolRenderer (Interface)
ToolRenderer represents an interface for rendering tool calls. [25 implementers]
internal/ui/chat/tools.go
Enricher (Interface)
Enricher fills in model metadata (context window, max tokens, pricing, etc.) for discovered models. Providers that expos [5 …
internal/discover/enricher.go
Event (Interface)
Event is the herdr-specific event vocabulary. Each type maps to a distinct state transition in the agent lifecycle. Call [5 …
internal/herdr/client.go
Subscriber (Interface)
Subscriber can subscribe to events of type T. [4 implementers]
internal/pubsub/events.go
ContentPart (Interface)
(no doc) [16 implementers]
internal/message/content.go
Coordinator (Interface)
(no doc) [6 implementers]
internal/agent/coordinator.go
VariableResolver (Interface)
(no doc) [5 implementers]
internal/config/resolve.go

Core symbols most depended-on inside this repo

Errorf
called by 786
internal/event/logger.go
Render
called by 526
internal/ui/list/item.go
Run
called by 491
internal/agent/agent.go
WriteString
called by 250
internal/shell/background.go
Set
called by 249
internal/csync/maps.go
Len
called by 247
internal/csync/maps.go
Get
called by 164
internal/env/env.go
Config
called by 160
internal/workspace/workspace.go

Shape

Function 2,197
Method 2,138
Struct 664
TypeAlias 67
Interface 54
FuncType 18

Languages

Go100%
TypeScript1%

Modules by API surface

internal/ui/model/ui.go110 symbols
internal/ui/chat/tools.go85 symbols
internal/workspace/client_workspace.go80 symbols
internal/workspace/workspace.go69 symbols
internal/agent/agent.go69 symbols
internal/proto/message.go68 symbols
internal/workspace/app_workspace.go67 symbols
internal/ui/model/chat.go63 symbols
internal/agent/coordinator.go63 symbols
internal/config/config.go58 symbols
internal/ui/list/list.go56 symbols
internal/message/content.go56 symbols

Dependencies from manifests, versioned

charm.land/bubbles/v2v2.1.0 · 1×
charm.land/bubbletea/v2v2.0.7 · 1×
charm.land/catwalkv0.45.8 · 1×
charm.land/fang/v2v2.0.1 · 1×
charm.land/fantasyv0.34.0 · 1×
charm.land/glamour/v2v2.0.1 · 1×
charm.land/lipgloss/v2v2.0.4 · 1×
charm.land/log/v2v2.0.0 · 1×
charm.land/x/vcrv0.1.1 · 1×
cloud.google.com/gov0.123.0 · 1×
cloud.google.com/go/auth/oauth2adaptv0.2.8 · 1×

For agents

$ claude mcp add crush \
  -- python -m otcore.mcp_server <graph>

⬇ download graph artifact