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.

Since 2.11 MTPLX reads opencode.json as JSONC, the way OpenCode does (comments and trailing commas), and merges its provider block into it. A file that still does not parse is left untouched with a message naming the file and position; a rewrite keeps the previous file as opencode.json.before-mtplx-<stamp>.bak, and connect prints where it wrote.

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.

No dead time between tool turns. A 43k-token OpenCode session on Flash-Next, measured on the live daemon before MTPLX 2.11 (M5 Max, 128 GB), spent 146 seconds of a 14-minute task waiting on the engine while its decode rounds ran 65 to 70 tok/s. 2.11 (4 Sep 2026) fixed the five engine defects behind that: the follow-up after a file write re-prefills 20 tokens in 0.12 s instead of 3,535 tokens in 3.7 s, the wait before a warm turn's first token is 0.01 s instead of 5 to 7.5 s, and a forced tool_choice round in a 41k-token session takes 0.58 s instead of 85 s. The release script replays this loop against a serving daemon and fails on warm-turn dead time over 1 s; at 40k tokens it passes at 0.15 s to first token and 66 to 84 tok/s.

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
Flash-decoding verify, 16k and 88k context+7% / +16%MTPLX 2.11, 4 Sep 2026, Qwen 3.8 27B Optimized Speed, M5 Max, decode gain on die-matched pairs against the 2.10.2 engine; +51% at 88k with two opt-in long-context settings
Flash Next, one OpenCode request125.8 tok/sMTPLX 2.11.3, 16 Sep 2026, Qwen 3.8 Flash Next Optimized Speed, M5 Max 128 GB, OpenCode Desktop: 1,301 tokens generated, 18,539-token prompt with 18,364 tokens served from cache. Real OpenCode coding tasks on the installed daemon ran 54.6 to 122.4 tok/s per model request with seven of eight requests served from the session cache
Flash Next, 109k and 200k-token OpenCode turns61.8 / 50.3 tok/sMTPLX 2.11.3, means of two runs each, M5 Max 128 GB; a 96,760-token conversation restored from the cache in 8 ms
Flash-Next, warm agent turns at 40k context66 to 84 tok/sMTPLX 2.11 agent-session gate on the live daemon, Qwen 3.8 Flash-Next, M5 Max 128 GB; 0.15 s to first token

The rewrite lane matters for agents, which spend much of their output reproducing text already in the context. On Flash Next, MTPLX 2.11.3 decodes 61.8 tok/s on a 109k-token OpenCode turn and 50.3 at 200k, and MTPLX 2.11 measured 68.4 tok/s at 16k context, 60.9 at 100k and 44.2 at 206k (M5 Max 128 GB, temperature 1, coding prompts). 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.