MTPLX/Docs/OpenCode

OpenCode on a local model.

MTPLX serves an OpenAI-compatible /v1 endpoint on your Mac. OpenCode was the first agent harness MTPLX supported, in 0.3.2 on 11 May 2026. One command launches it against Qwen 3.8 27B running on Apple Silicon with native MTP speculative decoding. Nothing leaves the machine.

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:

FieldValue
Base URLhttp://127.0.0.1:8000/v1
Modelmtplx-qwen38-27b-optimized-speed
Config path~/.config/opencode/opencode.json
Providermtplx
Reasoningcontrolled 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:

LaneDecodeConditions
Coding task, medium reasoning, via mtplx serve58.7 tok/sMTPLX 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 answer64.3 tok/sMTPLX 2.10.0, 29 Aug 2026, Qwen 3.8 27B Optimized Speed, M5 Max, stock settings
88k context30.4 tok/sMTPLX 2.10.0, 29 Aug 2026, Qwen 3.8 27B Optimized Speed, M5 Max, stock settings; prefill at 88k 535 tok/s
147k context18.4 tok/sMTPLX 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/sMTPLX 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.

Memory. The memory governor (2.10.0) sizes the context window to what your Mac can hold and prints the plan in the serve banner: a 48 GB Mac serving the 27B Speed pack resolves 196,608 tokens instead of the nominal 262,144, and at 42k context that seat measured 33 tok/s decode and 645 tok/s prefill. A request that cannot fit is refused up front with HTTP 507 (2.10.2, 1 Sep 2026) instead of dying mid-stream.

Model ids

The served id follows the pack. mtplx connect opencode prints the one for the model you loaded.

PackServed idRAM
Qwen 3.8 27B Optimized Speed (recommended for coding)mtplx-qwen38-27b-optimized-speed32 GB+
Qwen 3.8 27B Optimized Quality (8-bit)mtplx-qwen38-27b-optimized-quality36 GB+
Qwen 3.8 Flash-Next Optimized Speed (125B MoE)mtplx-flash-next-optimized-speed96 GB+
Qwen 3.5 9B Optimized Speedmtplx-qwen35-9b-optimized-speed16 GB+

Details for each pack, including the quantization map and the measured speeds, are on the models pages.