Knowledge Base Sections ▾
Navigation
▸ Start here By rolesCategories
- Cursor + Gonka AI - cheap LLM for coding
- Claude Code + Gonka AI - LLM for the terminal
- OpenClaw + Gonka AI - affordable AI agents
- OpenCode: your own model in the terminal
- Continue.dev + Gonka AI - AI for VS Code/JetBrains
- Cline + Gonka AI - AI agent in VS Code
- Aider + Gonka AI - pair programming with AI
- LangChain + Gonka AI - AI applications for pennies
- n8n + Gonka AI - automation with cheap AI
- Open WebUI + Gonka AI - your own ChatGPT
- LibreChat + Gonka AI — open-source ChatGPT
- Hermes Agent + DeepSeek on the Gonka network — an autonomous agent for pennies
- Kilo Code + Gonka AI — AI-Agent in VS Code
- Roo Code + Gonka AI — Autonomous AI Agent in VS Code
- LlamaIndex + Gonka AI — RAG applications for pennies
- PydanticAI + Gonka — typed AI agents for pennies
- Vercel AI SDK + Gonka AI — AI applications in TypeScript for pennies
- TanStack AI + Gonka — AI applications in TypeScript for pennies
- API quick start — curl, Python, TypeScript
- JoinGonka Gateway — a full overview
- Management Keys — SaaS on Gonka
- Cheapest AI API: Provider Comparison 2026
- How to buy AI tokens and an API key: 3 methods in 2026
- Cursor Pro request limit reached — breakdown and cheaper alternative
- Claude Code is cheaper — bill breakdown and switching
- Cline is burning money — why the agent spends so much
- OpenClaw is expensive — why the agent burns through tokens and how to save
- OpenRouter: Cheap Alternative — Comparison with JoinGonka Gateway
- Best AI model for coding in 2026: comparison and prices
- Cheap alternative to GitHub Copilot without limits
- A cheap Windsurf alternative without credits or limits
- The cheapest API for AI agents in 2026
- ZCode: Cheap GLM inference instead of GLM Coding Plan
- JetBrains IDE + JoinGonka Gateway — your own endpoint instead of credits
- GitHub Copilot BYOK — own models instead of quotas
- Zed + JoinGonka Gateway — cheap inference in your editor
- Pi + JoinGonka Gateway — terminal agent on cheap inference
- Codex CLI: your own key instead of a subscription
- DeepSeek Harness: Your Own Provider via JoinGonka Gateway
- MiniMax Code: MiniMax agent with your own key via Gonka
- Warp + JoinGonka Gateway — terminal agent on your own endpoint
- Trae + JoinGonka Gateway — Gonka network models in AI-IDE
- Cherry Studio + JoinGonka Gateway — desktop AI client
- omp (Oh My Pi) + JoinGonka Gateway: an agent with model roles
- OpenHands + JoinGonka Gateway: agent on your own endpoint
- Qwen Code after the closure of qwen-oauth: working via JoinGonka Gateway
- Goose + JoinGonka Gateway: your own provider and key in the keyring
- Crush + JoinGonka Gateway: Charm agent on Gonka network models
- Zoo Code + JoinGonka Gateway: Migrating from Roo Code to Gonka models
- Kimi Code CLI: Moonshot AI agent on your key via Gonka
- Factory Droid + JoinGonka Gateway: BYOK on Gonka network models
- MiMo Code + JoinGonka Gateway: Xiaomi agent on Gonka network models
Tools
Crush + JoinGonka Gateway: Charm agent on Gonka network models
Crush is a terminal coding agent from Charm, the team whose libraries for console interfaces power tens of thousands of programs. It reads and edits project files, runs commands, retrieves context from language servers (LSP), connects external tools via MCP, and can switch models mid-session without losing context. It works in macOS, Linux, and Windows terminals, as well as on Android and BSD; the license is FSL-1.1-MIT. The project has a notable pedigree: the archive repository opencode-ai/opencode directly refers to Crush — the project was continued by its original author and the Charm team.
Crush accepts two types of third-party providers — those with OpenAI- and Anthropic-compatible APIs. JoinGonka Gateway connects as openai-compat: with a single installer command or a dozen lines of config. After that, the agent runs on models of the decentralized Gonka network — DeepSeek V4 Flash, GLM-5.3 Flash, and MiniMax M2.7 — at a flat rate: $0.0069 per million input tokens.
Two features of Crush are worth knowing before your first session: it distributes models into two slots, large and small, and the model chosen in the interface is stored in a separate state file that takes precedence over the config. A separate section is dedicated to this. The commands and messages below have been verified with a live run of Crush 0.96.1 via the gateway on September 23, 2026. After confirming the address, 3M free tokens will be credited to your account — enough to repeat all this yourself.
Quick start: installation and a single command
Step 1: install Crush. Official methods from the project README:
# Homebrew
brew install charmbracelet/tap/crush
# npm
npm install -g @charmland/crush
# Arch Linux
yay -S crush-bin
# Windows
winget install charmbracelet.crush
# Go
go install github.com/charmbracelet/crush@latestThe same README covers package repositories for Debian, Ubuntu, Fedora and RHEL, Nix and Scoop, and ready-made binaries are available on the releases page. To verify, run crush --version and you'll get a line like crush version v0.96.1.
Step 2: get a key. Sign up at gate.joingonka.ai/register, confirm your address, and create a key with the jg- prefix in the "API Keys" section. A single key and a single balance work for all models on the network.
Step 3: run the installer.
npx @joingonka/setup --tool crushThe installer will ask for your key — it isn't passed as a command-line argument so it doesn't end up in your shell history — and will do four things:
- write the
joingonkaprovider into~/.config/crush/crush.json: typeopenai-compat, the gateway address, the key as a literal, and three network models with context windows, response caps and prices per million tokens, which it pulls live from the gateway at install time — Crush uses these to calculate session cost. The file will be set to permissions600; - assign models: DeepSeek V4 Flash to the large slot, MiniMax M2.7 to small, and GLM-5.3 Flash will stay in the list for manual selection. It only does this if the large slot is empty or points to one of our models that has left the network; someone else's choice stays put, and the output will include a hint on how to switch;
- check that the choice takes effect: the model from the Crush interface is stored in a state file, and that file overrides the config — see the section on large and small;
- make a backup, leave the other providers and settings untouched, and finish with a live request to the gateway to immediately verify the key, address and model.
To set a different model, use the --model flag with the shorthand deepseek, glm or minimax; an explicitly specified model is always written. The installer handles non-standard directories the same way Crush itself does: CRUSH_GLOBAL_CONFIG for the config, CRUSH_GLOBAL_DATA for the state file, plus XDG_CONFIG_HOME and XDG_DATA_HOME. For servers and scripts there's a non-interactive mode, where the key is taken from an environment variable:
JOINGONKA_API_KEY=jg-your-key npx @joingonka/setup --tool crush --model glm --non-interactiveCrush's primary format is now crushrc, but the installer writes crush.json: all versions understand it. If you already have a crushrc, Crush will merge both files, crushrc wins on key conflicts, and the installer itself leaves it alone.
Manual configuration: crush.json or crushrc
Everything the installer does can be written by hand. Here's a working ~/.config/crush/crush.json — this is the file we ran through the gateway:
{
"$schema": "https://charm.land/crush.json",
"providers": {
"joingonka": {
"name": "JoinGonka (Gonka)",
"type": "openai-compat",
"base_url": "https://gate.joingonka.ai/v1",
"api_key": "jg-your-key",
"models": [
{ "id": "deepseek-ai/DeepSeek-V4-Flash-0731", "name": "DeepSeek V4 Flash (Gonka)",
"context_window": 380000, "default_max_tokens": 32768,
"can_reason": true, "supports_attachments": false },
{ "id": "MiniMaxAI/MiniMax-M2.7", "name": "MiniMax M2.7 (Gonka)",
"context_window": 200000, "default_max_tokens": 8192,
"can_reason": false, "supports_attachments": false },
{ "id": "zai-org/GLM-5.3-Flash", "name": "GLM-5.3 Flash (Gonka)",
"context_window": 390000, "default_max_tokens": 8192,
"can_reason": true, "supports_attachments": false }
]
}
},
"models": {
"large": { "provider": "joingonka", "model": "deepseek-ai/DeepSeek-V4-Flash-0731" },
"small": { "provider": "joingonka", "model": "MiniMaxAI/MiniMax-M2.7" }
}
}| Field | Value | Why it matters |
|---|---|---|
type | openai-compat | The type for third-party services with an OpenAI-compatible API. Crush's docs reserve the openai type for requests that go through OpenAI itself |
base_url | https://gate.joingonka.ai/v1 | With /v1 at the end: Crush appends the /chat/completions path itself |
api_key | your jg-… key | Crush runs the value through shell substitution, so instead of the key you can write $JOINGONKA_API_KEY — but then the variable must be exported in the environment Crush is launched from |
context_window | the model's window | Crush uses it to show how full the context is and to decide when to compress the history |
default_max_tokens | the response ceiling | Sent with every request as max_tokens. For reasoning models, the reasoning also counts against this budget |
Crush accepts only strict JSON: a comment or a trailing comma and it won't start. The pricing fields (cost_per_1m_in, cost_per_1m_out, and the two cache fields) are only needed for the cost counter: the installer fills in the gateway's live price there, and without them Crush still works and shows zero — only an editor with the schema from $schema will flag them as required.
The same provider in crushrc format — that's plain Bash with Crush's built-in commands. The file ~/.config/crush/crushrc:
provider add joingonka \
--name "JoinGonka (Gonka)" \
--type openai-compat \
--base-url "https://gate.joingonka.ai/v1" \
--api-key "${JOINGONKA_API_KEY:?set JOINGONKA_API_KEY}"
model add joingonka/deepseek-ai/DeepSeek-V4-Flash-0731 \
--name "DeepSeek V4 Flash (Gonka)" \
--context-window 380000 --default-max-tokens 32768 --can-reason true
model add joingonka/MiniMaxAI/MiniMax-M2.7 \
--name "MiniMax M2.7 (Gonka)" \
--context-window 200000 --default-max-tokens 8192
model add joingonka/zai-org/GLM-5.3-Flash \
--name "GLM-5.3 Flash (Gonka)" \
--context-window 390000 --default-max-tokens 8192 --can-reason true
model large joingonka/deepseek-ai/DeepSeek-V4-Flash-0731
model small joingonka/MiniMaxAI/MiniMax-M2.7Here a model is named in the provider/model-id form: the provider name comes before the first slash, and after it comes the network identifier exactly as is. The ${JOINGONKA_API_KEY:?…} form keeps the key out of the file, but without an exported variable Crush won't start — better an error at startup than requests with an empty key.
Large and small models and the state file
In Crush, you don't choose a single model for everything; you choose for two slots:
| Slot | Function | Installer Default | How to change |
|---|---|---|---|
large | Main agent: handles all turns involving file reading, editing, and command execution. | DeepSeek V4 Flash: 380K context window and the largest response limit in the network, 32768. | ctrl+l in the interface, -m for crush run, models.large in the config. |
small | Auxiliary tasks: session naming and a sub-agent that searches the web and reads web pages. If the small model fails to generate a title, Crush repeats the request with the large model. | MiniMax M2.7: has the largest capacity in the network. | --small-model for crush run, models.small in the config, model small in crushrc. |
The third network model, the reasoning-focused GLM-5.3 Flash, is chosen for complex logic, keeping in mind that its response limit is 8192 and part of that is used for reasoning — see details in the model overview. For a single run, the model is specified by its full name: crush run -m joingonka/zai-org/GLM-5.3-Flash "…". All available names can be listed via crush models joingonka.
State file. The model selected in the interface via ctrl+l is not saved by Crush in crush.json, but in a machine-specific state file: ~/.local/share/crush/crush.json, or on Windows — %LOCALAPPDATA%\crush\crush.json. This file takes precedence over both the user config and crushrc: Crush reads them in order: /etc/crush/crush.json → ~/.config/crush/crush.json → ~/.config/crush/crushrc → state file, with each subsequent one overriding the previous. Higher priority is given only to project-specific settings — crush.json or crushrc in the project directory. The command crush dirs will show where the files are located on your machine.
In our run, we opened the model selection menu — the “JoinGonka (Gonka)” provider appears there marked as “✓ Configured” — and selected MiniMax M2.7. Crush replied with “Large model changed to MiniMax M2.7 (Gonka)” and wrote to the state file:
{"models":{"large":{"model":"MiniMaxAI/MiniMax-M2.7","provider":"joingonka","max_tokens":8192}}, …}Now this model overrides what is written in crush.json. The installer recognizes this situation and behaves differently:
- without
--modelit does not touch the state file — that is your working selection — but explicitly warns which model Crush will actually start with:Heads-up: Crush will still start with joingonka/MiniMaxAI/MiniMax-M2.7, not joingonka/deepseek-ai/DeepSeek-V4-Flash-0731. It will do the same if GLM-5.3 Flash or another provider's model is selected in the interface; - with an explicit
--modelit modifies exactly one entry in the state file —models.large— after saving a backup, and reports the change. Otherwise, the flag would have no effect silently. After such a run, our Crush instance opened using the model specified in the flag.
Verification: what should happen
First, make sure Crush can see the provider:
crush models joingonkaYou should get three lines back:
joingonka/MiniMaxAI/MiniMax-M2.7
joingonka/deepseek-ai/DeepSeek-V4-Flash-0731
joingonka/zai-org/GLM-5.3-FlashNext, do a one-off run without the interface. Drop a file with an obvious bug into your project directory and ask it to find the bug:
crush run -q "Read calc.py and tell me in one sentence whether it has a bug."The agent should call the file-reading tool on its own and give a substantive answer, including the line number. In our run, all three models on the network found the bug, and the task took 20-40 seconds. The -q flag hides the waiting indicator. In crush run mode, all tool calls are approved automatically, so run it in your own project. In the regular interface (the crush command), the active model is visible in the status line: ◇ DeepSeek V4 Flash (Gonka) via JoinGonka (Gonka). Crush stores sessions and the log in the project's .crush directory, isolated from git by its own .gitignore; the log is printed by crush logs. On the gateway side, the request is visible in the dashboard: the "Usage" section, broken down by "By model" and "By key".
If something goes wrong, the diagnosis is usually readable straight from the message:
| What you see | What it means | What to do |
|---|---|---|
unauthorized: Invalid API key. | The gateway rejected the key | Check api_key: the whole key, no spaces. If it references a variable, that variable must be exported in this shell |
invalid JSON in config file …/crush.json | The file has a comment, a trailing comma, or a typo | Crush accepts only strict JSON: fix the file. The installer doesn't strip comments itself, but it does warn about them, and it won't touch a file that fails to parse at all — it will tell you why |
failed to load shell config …/crushrc: … exit status 1 | An error in crushrc, most often an unset variable with a key in the form ${…:?} | Export the variable before launching, or fix the line where the script fails |
Failed to override models: large model "…" not found | A typo in the model name passed to the -m flag | Copy the name from the output of crush models joingonka |
too many requests: Model "…" is currently overloaded in the Gonka network (rate limit) | The model has run out of free capacity on the network during peak hours | Crush retries the request on its own with growing pauses — about a minute in our run — and only then gives up. Switch to another model with ctrl+l or -m, or wait; the status is visible on the status page |
| Crush opened on a different model than the installer reported | The interface selection is stored in a state file and overrides the config | Pick a model with ctrl+l or rerun the installation with --model |
402 | The balance has run out of funds | Top up your account in the "Billing" section; the key itself is still valid |
How much does it cost
An agent spends tokens differently than a chat: for every phrase you send, Crush adds a system prompt and descriptions of its tools, and a task usually takes several turns. In our test run, each request to the model carried about 11,500 input tokens, and the task of "reading a file and finding an error" took two to three requests and 23,000–35,000 tokens, almost entirely input. Therefore, the price per token is the deciding factor here.
Via the JoinGonka Gateway, tokens cost $0.0069 per million on input and $0.021 per million on output—the price is the same for all network models and is fetched on this page from a live source.
| Scenario | Consumption | Via Gateway |
|---|---|---|
| One-time task: read a file, find an error | 23-35K tokens | hundredths of a cent |
| A day of active work | 3-7M tokens | a few cents |
| A month of active development | ~150M tokens | about a dollar |
The estimates in the right column are based on prices as of September 2026. For comparison—how you can pay for models in Crush:
| Method | Payment model | Limitations |
|---|---|---|
| Hyper — official Charm provider | subscription, free tier available | Terms of service on the Charm side |
| Direct vendor key | pay for tokens at vendor price | Bill grows with session length; price depends on the model |
| JoinGonka Gateway | pay-per-token, prepaid balance | Consumption visible in the dashboard; no subscriptions or monthly quotas |
The cost counter in the Crush interface calculates using price fields from the config. It captures the gateway price at the moment of installation, and the dollar price on the network fluctuates with the GNK exchange rate, so the counter is an approximation. Precise consumption and balance are available in the dashboard, under the "Usage" and "Billing" sections. Why DeepSeek V4 Flash is set to the large slot by default is explained in detail in the model review.
What to keep in mind
Permissions. By default, the Crush interface asks for permission before calling a tool. The --yolo flag turns off all prompts at once, while individually trusted tools are listed in the config:
# crushrc
permissions allow view ls grep
# crush.json
"permissions": { "allowed_tools": ["view", "ls", "grep"] }Recall that crush run approves everything on its own. This is a property of Crush and does not depend on the model provider.
Request timeout. Crush aborts a request if no fragment of the response arrives from the model for a long time: in version 0.96.1 that's two minutes of silence (the documentation says 60 seconds, but in the code and in our test it's two minutes). The keep-alive pings the gateway uses to hold the connection do not reset this counter — we verified this on a local test bench. Meanwhile, during peak hours the gateway waits up to 150 seconds for the first token from the network, so the margin is worth raising:
# crushrc
option request-timeout 300
# crush.json
"options": { "request_timeout": 300 }Commit signatures. Commits and pull requests created by Crush get the line Assisted-by: Crush:<model> and the note "Generated with Crush" by default. If you don't want that:
# crushrc
option attribution-trailer-style none
option attribution-generated-with false
# crush.json
"options": { "attribution": { "trailer_style": "none", "generated_with": false } }Metrics. Crush sends pseudonymous usage statistics to the developers — metadata only, no prompts or responses. It's disabled with the variable CRUSH_DISABLE_METRICS=1 or DO_NOT_TRACK=1. The gateway, for its part, does not store the contents of prompts or responses — only usage aggregates remain in the statistics.
The config is code. Crush executes both crushrc and crush.json with the privileges of your shell: $(…) in a key field will run on load, and a project-level crushrc will fire as soon as you open Crush in that directory. Don't run the agent in someone else's repository without reading its configs.
npx @joingonka/setup --tool crush — or by adding the providers.joingonka block to ~/.config/crush/crush.json: set type to openai-compat, address to https://gate.joingonka.ai/v1, key to jg-…, and models with honest context_window and default_max_tokens settings. The same can be written via multiple provider add and model add lines in crushrc. The large slot is provided by DeepSeek V4 Flash, small — by MiniMax M2.7, and GLM-5.3 Flash — for complex logic. The main trap is the state file: the model selected via ctrl+l takes precedence over the config, so the installer with an explicit --model flag updates it as well. To verify, run crush models joingonka and crush run; the request timeout should be increased to 300 seconds.Want to learn more?
Explore other sections or start earning GNK right now.
Get a key and free tokens →