Repository navigation
docs(mcp): document the text-only knob for OpenCode 2; fix the mcp.text_only description - #311
Conversation
…hake OpenCode 2.x reports clientInfo.name as "cli": its default is `process.env.OPENCODE_CLIENT ?? "cli"` and the serve service never sets the variable, so every default install says cli (dondai44423#306). The text-only client list from dondai44423#27 matched "opencode", so 2.x got the split shape; with Code Mode on by default it keeps structuredContent and drops content, and the model saw `{"content_ok": true, "url": ...}` and none of the page text. "cli" alone is anyone's name, so the name list does not grow. The 2.x handshake is recognised by its fingerprint instead: a version whose major is 2 or more together with the `capabilities.elicitation.form.applyDefaults` field, which no other client sends. A bare "cli" without it, the same capability on a 1.x version, and opencode-web all keep the default split, as the report's table has them. Also: `mcp.text_only` was described as "strip image blocks from tool output"; the fold never touched image blocks. It is described as what it does now. README names OpenCode 2 among the clients that show one surface and how it is detected. Test: opencode_2_is_recognised_by_its_handshake_not_its_name (the captured 2.0.16 initialize; red: left Default).
Mart-Bogdan
left a comment
There was a problem hiding this comment.
I firmly object to this change!
Name cli is too generaic, and there can be bunch of different software that have major version of 2.
This is:
- Upstream bug (OpenCode)
- We have configuration knob for this case.
Other way around can be to isntead default to text mode and enable dual mode for clients that we know are good, but with current setup I consider current implementation of probe harmful.
Better fix would be to just change README to add isntruction how to configure for such clietnts.
|
Regarding readme, I saw you edited readme a bit, we can instead expand it into proper section with better instruction how to enable this. P.S. AFAIK only lients that benefit from dual mode are ones like OMP (perhaps Pi) who allows model to use code mode to inspect raw MCP response, so we might think on flipping default resonse mode and instead use knob/detection for clients that accept both fields. But that different story, and it doesn't change fact that OpenCode v2 sends bad "UserAgent" and detecting it by signature of how elicitation is implemented + major version is not so good ideal. |
|
Some background on
Consequences for this probe:
The underlying defect is OpenCode reporting One thing to keep from this PR regardless: the server must stay lenient on unknown keys under |
…dai44423#306) The fingerprint (name "cli" plus major >= 2 plus elicitation.form.applyDefaults) is a coincidence of three facts none of which OpenCode owns: the capability is a TypeScript-SDK opt-in any SDK-based client can send and future clients will, so the match would misfire on later clients while claiming a certainty the handshake does not carry. compat.rs documents its layers; the manual override is layer 3, designed for exactly this case ("fixed today without waiting for a release"), and the list stays name-based with its exit plan. Kept from the original: the mcp.text_only description fix and the README coverage of OpenCode 2. An upstream report for the actual defect (clientInfo.name defaults to "cli") is drafted. compat.rs is back at master; no behavioral change ships in it.
|
Reworked on this branch per the review: the fingerprint and its test are gone; the description fix and the README coverage are kept, with the README now documenting the knob explicitly (toml form, new-style env name, legacy-name note). @mnaza the write-up and the description fix ship as-is, thanks. @Mart-Bogdan your read decided it: the capability is an SDK opt-in, not an OpenCode signature, and the compat layer already has the designed path for this case. The actual defect is upstream. compat.rs is back at master, byte-identical; the diff is README + CHANGELOG + one description line. |
Reworked on the branch per this review: the handshake fingerprint is dropped, the mcp.text_only description fix and the README coverage stay, and the upstream defect is noted as an OpenCode report. compat.rs is back at master.
|
@Mart-Bogdan agreed, and thanks for the SDK background: I took |
Closes #306. Reworked from the original handshake-probe revision after review; compat.rs is no longer touched by this PR.
What ships
mcp.text_onlyis described as what it does: foldstructuredContentinto a leading[meta]text block for every client. It never stripped image blocks, andweb_screenshotreturning its PNG with the knob on is correct.clientInfo.nameascli(itsprocess.env.OPENCODE_CLIENT ?? "cli"default, whichservenever overrides), too generic to match in the text-only list, and its Code Mode shows the modelstructuredContentonly. Set[mcp] text_only = true(orDONSETCH_MCP__TEXT_ONLY=1) for it until OpenCode restores a usable name upstream.What was dropped, and why
The earlier revision recognized OpenCode 2 by handshake fingerprint (name
cli, major version >= 2,elicitation.form.applyDefaults).applyDefaultsis a TypeScript-SDK opt-in (SEP-1036), not an OpenCode signature: any SDK-based client can send it, later ones will, and the match would misfire silently while claiming a certainty the handshake does not carry. The compat layer's designed path for a newly-discovered broken host is the manual override (layer 3, "fixed today without waiting for a release"), and the name list stays name-based with its exit plan.Upstream
The defect is OpenCode's: v2 regressed
clientInfo.name, undoing the intent of anomalyco/opencode#2289, which hardcodedopencodeprecisely so MCP servers could identify the client.Tests: the fingerprint and its test are removed; existing compat coverage is unchanged. Local: fmt + check + scoped nextest; CI is the gate.