[BUG] MCP elicitation: capability is declared but requests are auto-declined ("print mode") in interactive VSCode sessions
Preflight Checklist
- [x] I have searched existing issues and this hasn't been reported yet
- [x] This is a single bug report (please file separate reports for different bugs)
- [x] I am using the latest version of Claude Code
What's Wrong?
In an interactive VSCode-extension session, Claude Code declares the MCP elicitation capability during initialize, but auto-declines every elicitation/create request without showing any UI. The same session can render permission prompts and AskUserQuestion option dialogs, so it is clearly capable of interactive prompting — only the MCP elicitation path is unwired and silently rejected.
Because the capability is declared, servers cannot detect the situation:
- ServerSession.check_client_capability(ClientCapabilities(elicitation=...)) returns true
- ctx.elicit(...) does not raise; it returns a normal non-accept result
- From the server's perspective this is indistinguishable from a human explicitly declining the dialog
What Should Happen?
Any MCP server that implements a two-phase destructive operation ("show dialog → proceed on accept, abort on decline") dead-ends: the auto-decline is interpreted as a user cancellation, and the operation becomes impossible from Claude Code while working fine from elicitation-capable clients (e.g. Claude Desktop). We had to patch our server to treat decline as "declined or unavailable" and fall back to a confirmation-token flow, which weakens the semantics of a real user decline for every other client.
Error Messages/Logs
Steps to Reproduce
- Minimal Python MCP stdio server (FastMCP / mcp SDK) with a tool that calls ctx.elicit(message=..., schema=...).
- Register it in .mcp.json, run a Claude Code session from the VSCode extension.
- Ask Claude to call the tool.
- The tool returns immediately with a non-accept elicitation result; no dialog is shown.
MCP log (~/Library/Caches/claude-cli-nodejs/<project>/mcp-logs-<server>/*.jsonl):
{"debug":"Elicitation request received in print mode: {\"method\":\"elicitation/create\",\"params\":{\"mode\":\"form\", ... }}", ...}
Note the log says "print mode" even though the session is interactive (permission prompts and AskUserQuestion render fine in the very same session).
Claude Model
Opus
Is this a regression?
No, this never worked
Last Working Version
_No response_
Claude Code Version
claude: 2.1.284, vscode extension: 2.1.284
Platform
AWS Bedrock
Operating System
macOS
Terminal/Shell
VS Code integrated terminal
Additional Information
The original issue was erroneously closed by bot: https://github.com/anthropics/claude-code/issues/79174
Showing cached comments. Read the full discussion on GitHub ↗
3 Comments
Peer note — elicitation declared but declined as print mode
Thanks for the clear repro and the MCP log line (
Elicitation request received in print modewhile the same VS Code session still shows permission prompts / AskUserQuestion). That mismatch is the useful signal.What the log implies
Claude Code’s MCP client is advertising
elicitationininitialize(socheck_client_capabilityis true), but the elicitation handler path is still taking the non-interactive / print-mode branch and auto-decliningelicitation/createwith a normal non-accept result. From the server’s side that is indistinguishable from a human clicking Decline — which is why a two-phase “elicit → proceed” tool dead-ends, and why patching the server to treat decline as “declined or unavailable” weakens real declines for other clients.Narrow workarounds while the handler is unwired
-p/ print) in the report — your log already shows the print-mode branch firing in an interactive extension session, which is the bug to fix on the host side.What would fix it for server authors
elicitation/createto the same interactive prompt path used by AskUserQuestion / permissions in the VS Code extension.No product pitch — just aligning the capability advertisement with the handler so MCP servers can branch correctly.
Adding a control comparison, which might help pin this on the client.
I maintain may-i, an MCP proxy that gates tool calls behind a human approval sent as
elicitation/create(form mode). I ran the same proxy, policy, and wrapped server (@modelcontextprotocol/server-filesystem) with Cursor as the MCP client:initialize, and may-i logselicitation: supported (form).write_filethat hits an ask rule sendselicitation/create. Cursor shows the approval dialog, and the accept comes back about 1.8s later, which is human click time. The audit entry is{"tool":"write_file","verdict":"ask→approved"}.So the server side and the form schema are fine, and another client handles the identical request correctly. The same request is what gets auto-declined with no UI in the VS Code extension, per the "print mode" log in the original report.
A workaround for other server authors until this is fixed: may-i treats a decline or cancel that arrives faster than a person could click (under 250ms by default) as "client can't ask" and falls back to a terminal prompt. It never falls back to allow (code). That's a heuristic, not a fix. The rmcp report on #79174 measured about 400ms in a headless setup, which would slip past a 250ms threshold. Option 3 from the original report, a distinguishable "not supported" response instead of a synthetic decline, would let servers handle this properly.
Same behaviour here on a newer build and a different platform, in case that helps narrow it down.
Environment
linux-arm64, VS Code Remote)2026-07-28What happens
The tool calls a form-mode
elicitation/createwith a single boolean field:In the same interactive session, the normal tool-permission prompt shows up and I approve it (the extension log shows
tool_permission_response→behavior: "allow"). Then the elicitation arrives and gets declined without any UI. The webview never sends or receives an elicitation message. I got the same result 4 times in a row, with and without expanding the permission prompt's details, and with message lengths from ~900 to ~2,900 characters:| Elicitation received → decline returned |
|---|
| 44 ms |
| 7 ms |
| 8 ms |
| 8 ms |
MCP log (
~/.cache/claude-cli-nodejs/<project>/mcp-logs-<server>/*.jsonl), trimmed:About 1 s later, a
Notification:elicitation_responsehook fires, so the client does emit a response event. It just never asks the user.The client-side log doesn't record the capabilities the client advertised, so I can't confirm that part myself. But the server did go ahead and send
elicitation/create, and all it got back was an ordinarydecline, which it can't tell apart from a real one.---