makemode
opencode · eu models · your terminal

build from your terminal.

opencode is a full coding agent that runs in your terminal — it writes real multi-file projects, runs commands, and iterates. Point it at MakeMode and it builds on GLM-5.2, hosted in France. The model key never touches your machine; every request is metered through the MakeMode gateway and billed to your balance. Already use Claude Code? The same key drives it too.

every request runs through the gateway in france — nothing leaves the eu

four steps · about five minutes

sign in, get a key, run one command, build.

01

sign in

Go to account.makemode.eu and sign in with an email link. New accounts start with a small balance of EU credits.

02

create your key

On your account dashboard, under API keys, create a key and name it (e.g. “laptop”). You'll see the sk-gw-… key once — copy it now. That key is your identity and your wallet: every request it makes bills your balance.

03

run the setup command

Paste this into a terminal. It installs opencode if you don't have it, asks for your key, and configures opencode to use MakeMode — you never touch a config file.

$ curl -fsSL https://makemode.eu/setup.sh | sh
04

build

Open a project folder and run opencode. Describe what you want to make; it builds on GLM-5.2 in the EU.

$ cd my-project $ opencode
prefer to configure it by hand?

The script just writes two files. To do it yourself, create these (paste your own sk-gw-… key into the second one):

~/.config/opencode/opencode.json

{
  "$schema": "https://opencode.ai/config.json",
  "model": "makemode/glm-5.2",
  "provider": {
    "makemode": {
      "npm": "@ai-sdk/openai-compatible",
      "name": "MakeMode (EU, metered)",
      "options": { "baseURL": "https://api.makemode.eu/v1" },
      "models": {
        "mistral-small-3.2-24b-instruct-2506": { "name": "Mistral Small (EU, fast)", "limit": { "context": 128000, "output": 8192 } },
        "devstral-2-123b-instruct-2512": { "name": "Devstral 2 (EU, coding)", "limit": { "context": 128000, "output": 8192 } },
        "mistral-medium-3.5-128b": { "name": "Mistral Medium (EU, balanced)", "limit": { "context": 128000, "output": 8192 } },
        "glm-5.2": { "name": "GLM 5.2 (EU)", "limit": { "context": 128000, "output": 8192 } },
        "qwen3.5-397b-a17b": { "name": "Qwen 3.5 (EU, reasoning)", "limit": { "context": 256000, "output": 8192 } },
        "kimi-k2.6": { "name": "Kimi K2.6 (EU, reasoning)", "limit": { "context": 256000, "output": 8192 } },
        "kimi-k2.7-code": { "name": "Kimi K2.7 Code (EU, coding)", "limit": { "context": 256000, "output": 8192 } },
        "deepseek-v4-pro": { "name": "DeepSeek V4 Pro (EU, agentic)", "limit": { "context": 256000, "output": 8192 } }
      }
    }
  }
}

~/.local/share/opencode/auth.json

{ "makemode": { "type": "api", "key": "sk-gw-YOUR-KEY-HERE" } }
what's protecting you

your key is safe to use, and the rails are sovereign.

the model key stays server-side

You hold an sk-gw-… key, never the real provider key. The gateway injects that in France — it never reaches your machine.

your balance is the limit

Requests draw from prepaid EU credits. You can't overspend what you've bought — no debt, no surprise bill. Top up any time.

eu-only models

The gateway only routes EU-hosted models (GLM-5.2 today). It won't send your traffic to a non-European model, even by accident.

revoke any time

Lost a key, or done with a machine? Revoke it from your account dashboard and it stops working immediately.

one key, your choice of model

choosing which model builds.

Your sk-gw-… key is your identity and your wallet — it is not tied to a model. Which model runs is a per-request setting: the "model" line in your opencode config (opencode also has an in-session model switcher). One key runs any EU model MakeMode offers — switching never means a new key, a new sign-up, or a new vendor. The gateway routes each request to the right EU host and bills the same balance.

The setup script already wrote every EU model MakeMode offers into models — the default is GLM-5.2, hosted in France. Switch by pointing "model" at another entry in the same file:

{
  "model": "makemode/glm-5.2",
  "provider": {
    "makemode": {
      "options": { "baseURL": "https://api.makemode.eu/v1" },
      "models": {
        "mistral-small-3.2-24b-instruct-2506": { "name": "Mistral Small (EU, fast)", "limit": { "context": 128000, "output": 8192 } },
        "devstral-2-123b-instruct-2512": { "name": "Devstral 2 (EU, coding)", "limit": { "context": 128000, "output": 8192 } },
        "mistral-medium-3.5-128b": { "name": "Mistral Medium (EU, balanced)", "limit": { "context": 128000, "output": 8192 } },
        "glm-5.2": { "name": "GLM 5.2 (EU)", "limit": { "context": 128000, "output": 8192 } },
        "qwen3.5-397b-a17b": { "name": "Qwen 3.5 (EU, reasoning)", "limit": { "context": 256000, "output": 8192 } },
        "kimi-k2.6": { "name": "Kimi K2.6 (EU, reasoning)", "limit": { "context": 256000, "output": 8192 } },
        "kimi-k2.7-code": { "name": "Kimi K2.7 Code (EU, coding)", "limit": { "context": 256000, "output": 8192 } },
        "deepseek-v4-pro": { "name": "DeepSeek V4 Pro (EU, agentic)", "limit": { "context": 256000, "output": 8192 } }
      }
    }
  }
}

It's the same choice the web app puts behind its model picker — the picker just sets that model value for you. Every option runs on EU infrastructure, so your data never leaves whichever you pick; see how the models compare.

already work in claude code?

point claude code at the same key.

Claude Code speaks Anthropic's API, and the gateway serves that dialect at api.makemode.eu. So the coding agent you already use can run on GLM-5.2, hosted in France — same sk-gw-… key, same balance, same EU-only routing. No proxy to install, no new account. One command sets it up:

$ curl -fsSL https://makemode.eu/setup.sh | sh -s -- --claude $ claude

The script asks for your key and writes ~/.claude/settings.json (if you already have one, it prints the exact block to merge instead of touching your file). It points model traffic at France, pins the status line to glm-5.2 — the model actually serving, not a Claude model it isn't — routes Claude Code's background chores to the cheapest fast EU model, and sets CLAUDE_CODE_DISABLE_NONESSENTIAL_TRAFFIC=1: moving the base URL only relocates model calls, and without this flag Claude Code still sends telemetry and error reports to US endpoints.

prefer to set it by hand?

Two environment variables do the core of it:

$ export ANTHROPIC_BASE_URL=https://api.makemode.eu $ export ANTHROPIC_AUTH_TOKEN=sk-gw-YOUR-KEY-HERE $ claude

Whatever model name Claude Code asks for is served by GLM-5.2 — except haiku-class names (Claude Code uses those for quick background chores), which go to Mistral Small so the cheap-and-fast request actually gets a cheap, fast model. Prefer another EU model from the table above? Set ANTHROPIC_MODEL to its id. To make the setup permanent, put the variables in your shell profile, or in ~/.claude/settings.json under "env" — that's all the script does. Every request is metered against your balance and stays inside the EU.

Good to know: GLM-5.2 runs 128k tokens of context here (Claude Code assumes more, so trim very long sessions), and image pasting isn't supported on this endpoint yet.

The API response and your usage page always record the model that really served the request. Claude Code's status line is the one place that doesn't — it shows the name it was configured with, so set ANTHROPIC_MODEL=glm-5.2 if you want the UI to say what's true.

One feature won't come along: Claude Code's built-in web search runs on Anthropic's servers, not in the model, so it doesn't work through the gateway. If a search tool call fails, that's why — nothing is broken.

And a word on cost: we measured it, and a Claude Code session bills roughly 2.4× the same work in opencode here. Claude Code resends its large system prompt and tool catalog on every turn; on Anthropic's servers prompt caching absorbs most of that, but the EU models behind this gateway don't offer caching yet, so every resent token bills at full input price. Fine for real work — just worth knowing before a long session.

if something looks wrong

troubleshooting — most of these look scary but aren't.

“Forbidden / blocked by a gateway or proxy” or “token expired or incorrect”

That's opencode's wording for a rejected key — not a network or permissions problem. Usually the key was mis-copied: the full sk-gw-… key is shown once, on the “key created” screen. The value in your account's key list is only a short prefix — don't copy that. Check a key in two seconds:

$ curl -s https://api.makemode.eu/v1/balance -H "authorization: Bearer sk-gw-YOURKEY"

See your balance → the key's good. See invalid_api_key → create a fresh key and re-run the setup command.

opencode crashes with trace trap, or errors with no such column

opencode's local state database got out of sync (usually after an app upgrade). Reset it — your key is safe, it lives in a separate file:

$ mv ~/.local/share/opencode/opencode.db{,.bak}

Then relaunch opencode; it rebuilds a fresh database. (On brew: brew upgrade opencode first is worth a try too.)

your terminal is spewing gibberish like 35;86;21M…

A crashed full-screen app left mouse-tracking on. It's harmless. Type reset and press Enter (it'll look messy as you type — that's fine) to restore the terminal.

“Too Many Requests — quota of tokens per minute”

A shared per-minute rate limit on the EU model, not your balance. opencode retries automatically with a short backoff, so it recovers on its own — just pause a moment if a big build keeps hitting it.

opencode: command not found after a fresh install

The install script now checks this for you: it verifies opencode actually runs, and if a brand-new terminal wouldn't find it on PATH, it adds the fix itself to ~/.zshrc (or ~/.bashrc) and tells you so at the end. If you still see this, either open a new terminal (the fix only applies to shells started after the script ran) or add the line it printed by hand, then re-run the setup command — it's safe to run more than once.