Knowledge Base Sections ▾

Navigation

▸ Start here By roles

Categories

Tools 52
Glossary 12

Tools

Goose + JoinGonka Gateway: your own provider and key in the keyring

Goose is an open, extensible AI agent that runs on your machine: a desktop app for macOS, Linux, and Windows, a CLI for the terminal, and an API for embedding. It reads and edits files, executes commands, and connects external services via MCP extensions. Written in Rust and distributed under the Apache 2.0 license. The project grew within the company Block and is now part of the Agentic AI Foundation under the Linux Foundation; the canonical repository is github.com/aaif-goose/goose, the old block/goose address redirects there.

Goose describes its providers declaratively: a JSON file in the custom_providers directory — and another source of models appears in the list. JoinGonka Gateway speaks OpenAI Chat Completions, so it connects with one installer command or one file. 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 price: $0.0069 per million input tokens.

It is best to know one feature of Goose in advance: it does not keep provider keys in the config, but in the system secrets storage. Whether such storage exists on your machine determines whether there will be one manual step left after the installer — a separate section is dedicated to this. The commands and messages below have been verified with a live run of goose 1.51.0 via the gateway on September 23, 2026. After confirming the address, 3M free tokens will be credited to the account — enough to repeat all this yourself.

Quick start: installation and one command

Step 1: install Goose. The official CLI methods from the project documentation:

# macOS and Linux: the script puts the binary in ~/.local/bin
curl -fsSL https://github.com/aaif-goose/goose/releases/download/stable/download_cli.sh | CONFIGURE=false bash

# macOS, Homebrew
brew install block-goose-cli

The CONFIGURE=false variable disables the goose configure wizard that the script would otherwise launch right after installation: the installer will set up the provider. If ~/.local/bin isn't in your PATH, the script will tell you. For Windows there's a download_cli.ps1 script in the same repository, and the desktop app can be downloaded from the documentation page; it and the CLI read the same settings, so everything below applies to both. To verify, run goose --version.

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. One key and one balance work for all models on the network.

Step 3: run the installer.

npx @joingonka/setup --tool goose

The installer will ask for the key — it isn't passed as a command-line argument so it doesn't end up in your shell history — and will do the following:

  • create the provider file custom_providers/custom_joingonka.json with the gateway address and three network models with real context windows, with 600 permissions. The names custom_joingonka and CUSTOM_JOINGONKA_API_KEY are the same ones Goose itself derives from the name "JoinGonka", so the key from the wizard will land where it should;
  • make JoinGonka the default provider with the DeepSeek V4 Flash model — but only if no provider has been chosen yet, or if ours was chosen with an empty or offline model. It won't touch someone else's choice, but will print a command to try: goose session --provider custom_joingonka --model …;
  • put the key into secrets.yaml, but only if Goose's secret storage is definitely file-based; otherwise it will say outright that one step remains — details in the section about the key;
  • back up the modified files and, at the end, send a live request to the gateway to immediately verify the key, address, and model.

The installer finds the config directory the same way Goose itself does: ~/.config/goose on Linux and macOS, %APPDATA%\Block\goose\config on Windows, <root>/config when GOOSE_PATH_ROOT is set. A different model is specified with the --model flag using the shorthand deepseek, glm, or minimax; an explicitly specified model is always written. The no-questions mode takes the key from an environment variable:

JOINGONKA_API_KEY=jg-your-key npx @joingonka/setup --tool goose --model glm --non-interactive

Manual configuration: provider file and config.yaml

Everything the installer does can be done manually. A provider is a separate JSON file ~/.config/goose/custom_providers/custom_joingonka.json; the file name must match the name field:

{
  "name": "custom_joingonka",
  "engine": "openai",
  "display_name": "JoinGonka",
  "description": "JoinGonka Gateway — Gonka AI inference (OpenAI-compatible)",
  "api_key_env": "CUSTOM_JOINGONKA_API_KEY",
  "base_url": "https://gate.joingonka.ai/v1/chat/completions",
  "models": [
    { "name": "deepseek-ai/DeepSeek-V4-Flash-0731", "context_limit": 380000 },
    { "name": "zai-org/GLM-5.3-Flash", "context_limit": 390000 },
    { "name": "MiniMaxAI/MiniMax-M2.7", "context_limit": 200000 }
  ],
  "supports_streaming": true,
  "requires_auth": true
}
FieldValueWhy it matters
namecustom_joingonkaThis is the file name and the --provider value
engineopenaiThe OpenAI Chat Completions format is the gateway's primary path. Goose also supports anthropic and ollama
api_key_envCUSTOM_JOINGONKA_API_KEYNot the key itself, but the secret name. The file contains no field for the key value — where Goose looks for it is covered in the next section
base_urlhttps://gate.joingonka.ai/v1/chat/completionsThe full address, as per the Goose documentation example: older builds understand this format too
modelsthree entries with context_limitWithout context_limit, Goose uses the window from its own model catalog, or 128,000 tokens for unknown models, and compresses history when it hits 80% of the window. The network models have windows from 200,000 to 390,000
supports_streaming, requires_authtrueThe response is streamed; requests require a key. Do not disable streaming: without it, and without a hard limit in the request, the gateway will truncate the response to a short default value

Goose does not provide a separate response limit for individual model entries. For such models, it doesn't send a limit in the request at all—we verified this via its request logs—and in streaming mode, the gateway limits the response to the model's native limit: 32,768 tokens for DeepSeek V4 Flash, 8,192 for GLM-5.3 Flash, and MiniMax M2.7. There is no need to set the global GOOSE_MAX_TOKENS variable for this: it applies to all providers at once.

Goose reads the provider file using strict JSON parsing: a comment or a trailing comma will cause the provider to disappear from the list. You can create it using the wizard (goose configure → Custom Providers), but the wizard does not ask for the context window — you will have to add it manually.

The default provider and model reside in ~/.config/goose/config.yaml. This is how Goose records them:

active_provider: custom_joingonka
providers:
  custom_joingonka:
    enabled: true
    model: deepseek-ai/DeepSeek-V4-Flash-0731
    configured: true

The old layout—flat GOOSE_PROVIDER and GOOSE_MODEL keys at the root of the file—still works: Goose reads it and converts it to the new format upon the first settings save, like in our case after goose configure. The installer writes flat keys on an empty file, which any version understands. Environment variables with the same names take precedence over the file: if they are set in the shell, the selection from config.yaml will not take effect, and the installer will warn you about this.

Where the key lives: keyring, secrets.yaml, or an environment variable

In Goose's provider file there is only the secret's name — CUSTOM_JOINGONKA_API_KEY. Goose looks up the value in order: in an environment variable with that name, then in the system secret store (keyring, on macOS — Keychain), then in the secrets.yaml file next to the config. Secrets end up in that file when Goose's storage is file-based, and they sit there in plain text, with 600 permissions. And in config.yaml Goose doesn't look for keys at all (documentation).

Storage becomes file-based if the keyring is disabled — via the GOOSE_DISABLE_KEYRING variable with any value or the string GOOSE_DISABLE_KEYRING: true in config.yaml — or unavailable: a server without a graphical session, a container, CI. In the second case Goose writes to the log “Keyring unavailable. Using file storage for secrets.” and switches to the file on its own — exactly what we saw in the container. The installer can't write to the keyring, and it won't disable it for you: Goose would stop seeing the secrets already stored there. Hence these scenarios:

SituationWhat the installer will doWhat's left for you
Desktop with keyring: macOS, Windows, Linux with a graphical sessionWill write the provider and model, won't write the key, and will say “ONE STEP LEFT”Save the key once with the wizard
Server or container without keyring, no secrets.yaml yetSame: file storage can't be guessed from indirect signsGo through the wizard — Goose will put the key into secrets.yaml itself, and from then on the installer will update it there
GOOSE_DISABLE_KEYRING is set or secrets.yaml already existsWill write the key to secrets.yaml with 600 permissions, preserving other secretsNothing
The provider's key is issued by a command (the auth field)Won't write the key: in Goose, auth and api_key_env are mutually exclusiveNothing

The remaining step. Run goose configure and answer the wizard's questions — this is how they looked in our run:

  • What would you like to configure? → Configure Providers;
  • Which model provider should we use? → JoinGonka (in our case it was first);
  • Would you like to set CUSTOM_JOINGONKA_API_KEY? (optional) → Yes, then at Enter value for CUSTOM_JOINGONKA_API_KEY paste the key — squares will appear instead of characters. The key is saved immediately;
  • Would you like to configure advanced settings? → No;
  • Select a model — Goose gets the list from the gateway: MiniMaxAI/MiniMax-M2.7, deepseek-ai/DeepSeek-V4-Flash-0731, zai-org/GLM-5.3-Flash. The cursor is on the first line — to keep the model chosen by the installer, use the arrows to select DeepSeek V4 Flash. After a test request the wizard will finish with “Configuration saved successfully”.

In Goose Desktop the path is: Settings → Models → Configure providers → JoinGonka → key → Submit. Don't want to paste the key by hand — put it in a variable and run the wizard from the same shell: Goose will print “CUSTOM_JOINGONKA_API_KEY is set via environment variable” and offer to save the value:

read -s CUSTOM_JOINGONKA_API_KEY && export CUSTOM_JOINGONKA_API_KEY
goose configure

And for a single run you can pass the key without saving it at all: CUSTOM_JOINGONKA_API_KEY=jg-your-key goose session, in PowerShell — $env:CUSTOM_JOINGONKA_API_KEY = "jg-your-key"; goose session. The environment variable takes precedence over the saved value, but lives only until the shell is closed.

Verification: what should happen

First, check which settings Goose actually sees:

goose info -v

The "goose Configuration" block should contain lines GOOSE_PROVIDER: custom_joingonka and GOOSE_MODEL with the model identifier. Then run a one-off, non-interactive session: put a file with an obvious bug into an empty directory and ask Goose to find it.

goose run --no-session -t "Read calc.py and tell me in one sentence whether it has a bug."

The --no-session flag keeps the run out of history. A header line like ● new session · custom_joingonka deepseek-ai/DeepSeek-V4-Flash-0731 will appear, followed by a tool call — ▸ shell with the command cat calc.py — and a reply pointing out the bug. You can set a different model for a single run with --model: zai-org/GLM-5.3-Flash or MiniMaxAI/MiniMax-M2.7. In our run on September 23, 2026, all three models on the network completed the "request → tool → result → answer" cycle. By default, the Goose CLI hides model reasoning; you can show it with the GOOSE_CLI_SHOW_THINKING=1 variable when output goes to the terminal. On the gateway side, the request is visible in your dashboard: under "Usage", with breakdowns by "Models" and by "Keys".

If something goes wrong, the diagnosis can usually be read directly from the message:

What you seeWhat it meansWhat to do
Error missing required key CUSTOM_JOINGONKA_API_KEY: Configuration value not foundGoose found the key neither in the environment nor in the secret storeSave the key with the wizard. If the key is in secrets.yaml and the error persists, Goose now keeps secrets in the keyring — save the key with the wizard again
Authentication failed … Status: 401 Unauthorized. Response: Invalid API key.The gateway rejected the keySave the key again — in full, without spaces. Remember that the CUSTOM_JOINGONKA_API_KEY environment variable takes precedence over the saved value
Error Unknown provider: custom_joingonkaThe provider file couldn't be read: a comment, trailing comma, or typo in the JSONFix the file, or delete it and run the installer again: the installer won't overwrite a broken file, it will only name it
Bad request (400): Model "…" not found. Available: …A typo in the model nameThe gateway lists the available identifiers — copy the one you need
Rate limit exceeded: Model "…" is currently overloaded in the Gonka network (rate limit)The model ran out of free capacity on the network during peak hoursGoose retries the request itself, but with short pauses. Switch models — /model in the session or --model on launch — or wait a minute; network status is on the status page
402Your balance ran out of fundsTop up your account under "Billing"; the key itself is still valid

How much does it cost

An agent spends tokens differently than a chat. Even in the standard configuration, Goose sends the model descriptions of eighteen built-in tools, and in our run, each turn carried about 4.6 thousand input tokens even before your question. The task of "reading a file and finding an error" took two to three turns and 10-15 thousand tokens, almost all of it input; Goose performs another short request itself to come up with a session title. Unnecessary extensions are turned off in goose configure → Toggle Extensions — this is the easiest way to reduce input.

Through JoinGonka Gateway, tokens cost $0.0069 per million for input and $0.021 per million for output — the price is the same for all models in the network and is pulled onto this page from a live source.

ScenarioConsumptionVia Gateway
One-off task: read a file, find an error10-15K tokensfractions of a cent
A day of active work3-7M tokensa few cents
A month of active development~150M tokensabout a dollar

The estimates in the right column are based on September 2026 prices. For comparison, how you can pay for models in Goose in general:

MethodPayment modelWhat it limits
Claude, ChatGPT, or Gemini subscription via ACPfixed amount per monthquotas and rate limit refresh windows on the vendor side
Vendor key directlyper token at vendor pricebill grows with session length
JoinGonka Gatewayper token, prepaid balanceusage is visible in the dashboard; no subscriptions or monthly quotas

Exact consumption and balance are in the dashboard, in the "Usage" and "Billing" sections. Why DeepSeek V4 Flash is the default — with the largest output ceiling in the network — is detailed in the model overview.

What to keep in mind

Confirmation mode. By default, Goose runs in auto mode — fully autonomous: it edits and deletes files, runs commands and uses extensions on its own, without asking anything. On your own project that's convenient, but on someone else's code it's better to tighten the mode:

# inside a session
/mode smart_approve

# permanently, as a line in config.yaml
GOOSE_MODE: smart_approve
ModeHow Goose behaves
autoActs without confirmations — the default mode
smart_approveAutomatically skips low-risk actions, asks about the rest
approveAsks before every tool call
chatOnly talks: no tools, no edits

This is a property of Goose itself; it doesn't depend on the model provider.

Switching models. Inside a session — the /model command with an identifier, for example /model zai-org/GLM-5.3-Flash; for a single run — the --model flag on goose run and goose session; permanently — goose configure or the model line in config.yaml. The provider stays the same. The reasoning GLM-5.3 Flash is great for tangled logic, but its answer ceiling is 8192 tokens, and part of that goes to reasoning — details in the model review.

Unattended runs. goose run is great for scripts and CI: the -q flag leaves only the model's answer in the output, --output-format json returns the result for parsing. The limiters --max-turns (how many turns the agent takes without human involvement) and --max-tool-repetitions (how many times in a row one tool can be called with the same arguments) guard against looping.

Privacy. Anonymous usage statistics in Goose are off by default (GOOSE_TELEMETRY_ENABLED). The gateway doesn't store the contents of prompts and responses — only aggregate usage stats remain.

Goose connects to JoinGonka Gateway with a single command — npx @joingonka/setup --tool goose — or a single file: the custom_joingonka provider in custom_providers (engine: openai, address https://gate.joingonka.ai/v1/chat/completions, models with honest context_limit) plus the default provider and model in config.yaml. Goose stores the key not in the config, but in the keyring or secrets.yaml: on a machine with a keyring, only one step remains — goose configure → Configure Providers → JoinGonka → key, and when choosing a model, you should leave DeepSeek V4 Flash. Verification — goose run and the "Usage" section in your account; the price for DeepSeek V4 Flash, GLM-5.3 Flash, and MiniMax M2.7 is the same, so the model is chosen based on behavior, not budget.

Want to learn more?

Explore other sections or start earning GNK right now.

Get key and free tokens →