Client support
What we measured per client, what other people report, and what is untested.
The matrix, honestly
Two different questions get conflated in client matrices: does the client render the challenge, and does the model retry after the user pays. Only the second closes the loop, and it is a behaviour, not a capability flag. This table separates what we measured from what others report and from what is unknown.
| client | renders structured + text | retries after payment | basis |
|---|---|---|---|
| Claude Code (headless) | yes | 18/18 structured · 41/43 text | measured · 2026-09-07 |
| Claude Code (interactive) | yes | not separately measured | unresolved |
| Claude Desktop | expected — it is a plain tool result | not measured | unresolved |
| Cursor | expected — it is a plain tool result | not measured | unresolved |
| VS Code Copilot, ChatGPT, others | expected — it is a plain tool result | not measured | unresolved |
Claude Code
Measured with a blind two-turn harness: a headless session with only the test server attached, a task that needs the paid tool, then “I’ve paid, please continue.” Retry and token fidelity come from the server log. Full numbers and method on the results page; the harness is in the repository and runs against the shipped renderers.
URL-mode elicitation scored 0/10 in the same harness, and for a structural reason rather than a client gap — the results page has the exact tool_result the model received. Tollbooth does not ship it.
Claude Desktop
DESKTOP-TEST.md) with a paste-ready config for the deployed server, the two prompts verbatim, and a command that reads the server log and answers the retry question objectively. If Desktop will not render a clickable link or will not retry, that changes the product, not the code — and this page will say so.What is known from public reporting, not measured by us: Desktop does not implement MCP elicitation at all (either mode). That does not affect Tollbooth, which never uses it.
Cursor and the rest
Cursor is listed by third parties as having partial elicitation support and as supporting the MCP Apps extension. Neither is relevant to the shipped path: Cursor receives the same structured-plus-text tool result as every other client. Whether its model retries is unmeasured, and we are not going to infer it from a capability column.
Why the default is safe everywhere
Negotiation is deny-by-default: every client — named, unnamed or unrecognised — gets structured content plus text, which is an ordinary tool result any client can display. Nothing is selected on the strength of an advertised capability, because the SDK does not gate mechanism on capability: a server can throw a -32042URL elicitation at a client that has never heard of one, and the user trying to pay sees a raw protocol error. Choosing the mechanism is the library’s job, so it makes the safe choice unless told otherwise in writing.