Two ways in: let MTPLX launch OpenCode Desktop already configured, or print the provider config and wire it yourself. Either way the model runs on your Mac and OpenCode talks to it over the OpenAI-compatible API. Created by Youssof Altoukhi, who brought native MTP to the Mac in April 2026.
One command
Install MTPLX from the DMG or with Homebrew, then:
brew install youssofal/mtplx/mtplx
mtplx start opencode
mtplx start opencode loads the model, serves it on 127.0.0.1:8000, and launches
OpenCode Desktop already configured with the mtplx provider and the served model id. The app's
one-click OpenCode launch does the same thing. The app and the CLI share one server, so mtplx start
attaches to a model the app already has loaded instead of loading a second copy.
Manual setup
If you run OpenCode your own way, print the exact configuration for your install. The command also writes
the mtplx provider block into OpenCode's config file, so the served model id is in the provider's
model map before OpenCode starts.
mtplx connect opencode
What it prints on 3 Sep 2026, with Qwen 3.8 27B Optimized Speed loaded:
| Field | Value |
|---|---|
| Base URL | http://127.0.0.1:8000/v1 |
| Model | mtplx-qwen38-27b-optimized-speed |
| Config path | ~/.config/opencode/opencode.json |
| Provider | mtplx |
| Reasoning | controlled by MTPLX server settings |
The API key is any non-empty string for a localhost server. If you bind the server to a non-localhost address
you must start it with --api-key; the server then accepts the key as Authorization: Bearer
or X-API-Key.
What OpenCode gets
Warm prefix restore across tool turns. Since 2.0.0 (6 Jul 2026) MTPLX checkpoints the
attention KV cache plus the recurrent and conv GDN state at commit boundaries, with speculation on. An agent turn
that appends a tool result and resends the transcript restores the prefix instead of prefilling it again:
mid-session tool rounds restore warm in under 2 s, and a 100k-token session restores in about 2 s after a
restart instead of a five-minute cold prefill. Every response reports usage.cached_tokens, so you
can see the restore working.
Transcript passthrough. The messages OpenCode sends are the messages the model sees. MTPLX passes the transcript through unchanged; one that cannot fit the resolved context window is refused with HTTP 507 rather than trimmed.
Uncapped generation. MTPLX adds no hidden cap on output length, reasoning length or tool
steps. The request's own max_tokens is honored; the model runs to its own stop otherwise.
Tool calls in OpenAI style. When tools are active, Qwen XML tool calls are translated into
OpenAI delta.tool_calls chunks as the function name and arguments stream. Unknown or malformed
tool-shaped output falls back to assistant content rather than hanging or returning a server 500.
Concurrency. Since 2.6.0 (11 Aug 2026) two agents can decode at once with speculation on: 1.6 to 2.25x per lane versus the previous AR batch route on the Qwen 3.6 35B-A3B, M5 Max, sampled at shipped settings.
Reasoning effort
The reasoning dial lives on the MTPLX side, in the app or through mtplx settings get and
mtplx settings set; an effort picked inside OpenCode for a request overrides it for that request.
In 2.10.0 (29 Aug 2026) OpenCode and Pi began defaulting to the family's agent-lane reasoning effort, medium for
Flash-Next, instead of xhigh. On the multi-file agent task in that release note, wall clock went from 150.2 s to 44.2 s with the same correct output; the gain came from the lower reasoning-effort default rather than from decode speed.
What to expect
Decode on Qwen 3.8 27B Optimized Speed runs through the native MTP path: the model drafts three tokens ahead with its own MTP head, the target verifies them in one forward pass, and acceptance is exact rejection sampling at the model's shipped sampler (temperature 1.0, top-p 0.95, top-k 20 for Qwen 3.8). Measured on an M5 Max:
| Lane | Decode | Conditions |
|---|---|---|
| Coding task, medium reasoning, via mtplx serve | 58.7 tok/s | MTPLX 2.7.0, 15 Aug 2026, Qwen 3.8 27B Optimized Speed, M5 Max, fans verified at max, single stream, official Qwen 3.8 sampling |
| 3k-token chat answer | 64.3 tok/s | MTPLX 2.10.0, 29 Aug 2026, Qwen 3.8 27B Optimized Speed, M5 Max, stock settings |
| 88k context | 30.4 tok/s | MTPLX 2.10.0, 29 Aug 2026, Qwen 3.8 27B Optimized Speed, M5 Max, stock settings; prefill at 88k 535 tok/s |
| 147k context | 18.4 tok/s | MTPLX 2.10.0, 29 Aug 2026, Qwen 3.8 27B Optimized Speed, M5 Max, stock settings |
| Rewriting a file the model just wrote (cache-copy rewrite lane) | 87.6 tok/s | MTPLX 2.10.0, 29 Aug 2026, Qwen 3.8 27B Optimized Speed, M5 Max, stock settings; 73.8 in 2.9.2 |
The rewrite lane matters for agents, which spend much of their output reproducing text already in the context. The full set is on the benchmarks page.
Model ids
The served id follows the pack. mtplx connect opencode prints the one for the model you
loaded.
| Pack | Served id | RAM |
|---|---|---|
| Qwen 3.8 27B Optimized Speed (recommended for coding) | mtplx-qwen38-27b-optimized-speed | 32 GB+ |
| Qwen 3.8 27B Optimized Quality (8-bit) | mtplx-qwen38-27b-optimized-quality | 36 GB+ |
| Qwen 3.8 Flash-Next Optimized Speed (125B MoE) | mtplx-flash-next-optimized-speed | 96 GB+ |
| Qwen 3.5 9B Optimized Speed | mtplx-qwen35-9b-optimized-speed | 16 GB+ |
Details for each pack, including the quantization map and the measured speeds, are on the models pages.