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
Go to account.makemode.eu and sign in with an email link. New accounts start with a small balance of EU credits.
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.
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.
Open a project folder and run opencode. Describe what you want to make; it builds on GLM-5.2 in the EU.
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" } }
You hold an sk-gw-… key, never the real provider key. The gateway injects that in France — it never reaches your machine.
Requests draw from prepaid EU credits. You can't overspend what you've bought — no debt, no surprise bill. Top up any time.
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.
Lost a key, or done with a machine? Revoke it from your account dashboard and it stops working immediately.
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.
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:
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.
Two environment variables do the core of it:
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.
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:
See your balance → the key's good. See invalid_api_key → create a fresh key and re-run the setup command.
trace trap, or errors with no such columnopencode'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:
Then relaunch opencode; it rebuilds a fresh database. (On brew: brew upgrade opencode first is worth a try too.)
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.
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 installThe 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.