Repository navigation
[FEATURE]: MCP elicitation support #23066
Description
Activity
- addeddiscussionUsed for feature requests, proposals, ideas, etc. Open discussionUsed for feature requests, proposals, ideas, etc. Open discussion
on Apr 17, 2026 - addedcoreAnything pertaining to core functionality of the application (opencode server stuff)Anything pertaining to core functionality of the application (opencode server stuff)
on Apr 17, 2026 - removeddiscussionUsed for feature requests, proposals, ideas, etc. Open discussionUsed for feature requests, proposals, ideas, etc. Open discussioncoreAnything pertaining to core functionality of the application (opencode server stuff)Anything pertaining to core functionality of the application (opencode server stuff)
on May 3, 2026 Adding a concrete use case here because this looks like the main OpenCode tracking issue for MCP elicitation support. I do not want to create duplicate issues; if maintainers prefer a separate issue for this specific case, I can open one and link it back here.
Important context: the MCP server below,
Unity MCP Gateway, is not a published public tool yet. It is currently an internal/private tool in my workflow. I am not asking maintainers to run or reproduce it directly. I am sharing the implementation shape because it exercises a specific MCP client capability: server-initiatedelicitation/createnested inside an already-runningtools/call.The Gateway uses CanonicalPath, a cross-language, cross-platform path canonicalization library, as the basis for consistent path identity and scoped filesystem safety across OSes/languages. That detail matters here because the approval prompt should be shown only after the server has canonicalized paths, evaluated policy, and computed the exact command scope/hash.
What I need
I need OpenCode to support MCP
elicitation/createas a server-to-client request duringtools/call, so an MCP server can ask the human user to approve one resolved command after the server has validated the request.The approval I need is not a broad pre-call permission for a wrapper MCP tool. It is a post-validation, one-shot approval for the concrete command resolved by the server.
Conceptually:
model asks to run a Unity action → OpenCode calls an MCP wrapper tool → Gateway parses args, canonicalizes paths, evaluates policy/risk/scope/hash → Gateway asks the human user to approve exactly this resolved command once → user accepts/declines/cancels in OpenCode UI → Gateway either continues once or returns its safe fallbackWhy pre-call approval is not enough
My internal Gateway exposes a small stable MCP tool surface such as:
sgg_unity_call(project, command, args_json, mode)The potentially sensitive operation is not the wrapper tool name. It is inside the arguments:
project = "..." command = "test.run" | "asset.write" | "package.change" | ... args_json = "..." mode = "wait" | ...A pre-call prompt like this asks the wrong question:
Allow MCP tool `sgg_unity_call`?That is too early and too coarse. At that point the Gateway has not yet:
- parsed the command-specific arguments;
- resolved the Unity project;
- canonicalized path inputs through CanonicalPath/CanonicalFs;
- rejected traversal, absolute path, symlink/reparse, or scope escape attempts;
- evaluated command policy as
allow,ask, ordeny; - computed the canonical scope summary;
- computed the
args_hashtied to this exact request; - created a one-shot pending approval.
The user should instead see something like:
Approve this resolved Unity Gateway command once? MCP server: sgg-unity-mcp-gateway Tool: sgg_unity_call Command: test.run Risk: ask Approval: one-shot Canonical scope: <scope summary> Args hash: <args_hash> Expires: <timestamp>This is why the approval needs to happen inside the command invocation, after server-side validation and policy evaluation, not before the wrapper tool is called.
Current internal Gateway behavior
This is the current implementation shape, not a public reproduction package.
When a command is policy-gated as
ask, the Gateway returns a structured fallback result:{ "status": "error", "error": { "code": "confirmation_required" }, "next_valid_actions": [ "ask_user_for_confirmation", "choose_safer_command" ], "details": { "approval_request": { "project": "<project>", "command": "<command>", "risk": "ask", "args_hash": "<hash>", "scope": "<canonical scope summary>", "expires_at": "<timestamp>" }, "pending_id": "<pending approval id>", "action_hint": "Ask the human user to approve this pending request, then retry the original sgg_unity_call." } }The Gateway deliberately keeps approvals outside the MCP tool surface:
- there is no model-callable `sgg_unity_approve` tool; - `confirmation_required` writes a pending approval request under the Gateway approval store; - the fallback response includes `pending_id` and an action hint; - a local human-only CLI/UI path can list and approve pending requests; - approval creates a one-shot approval token only; - the approval does not execute the command by itself; - the agent must repeat the original `sgg_unity_call` after human approval; - the one-shot approval is tied to the resolved project/command/scope/args_hash/expiry.That fallback is safe, but the UX is poor when the MCP client cannot render a native prompt. The agent only sees an MCP tool error JSON, and the human user does not get a first-class approve/decline/cancel UI.
Gateway-side MCP elicitation support already implemented
The Gateway also has a server-side MCP elicitation attempt for clients that advertise
capabilities.elicitation.Current server-side shape:
- the MCP server uses official SDK transports where possible; - if the handler receives `extra.sendRequest`; - and if dispatching the command returns `confirmation_required`; - and if `pending_id` is available; - the Gateway sends `elicitation/create` with a boolean `approve` field; - on `accept` with `approve: true`, it creates a one-shot approval and retries the original call once; - on `decline`, `cancel`, error, or unsupported elicitation, it returns the original `confirmation_required` fallback.For HTTP, the Gateway now has an SDK Streamable HTTP path for clients that support official sessions and a compatibility path for clients that still call
tools/list/tools/callwithoutMcp-Session-Id. The compatibility path keeps existing tool calls working, while the SDK path remains available for clients that advertisecapabilities.elicitationand support nested server-to-client requests.Expected OpenCode behavior
When OpenCode truly supports MCP elicitation, it should declare the client capability during MCP initialization:
{ "capabilities": { "elicitation": {} } }During a
tools/call, OpenCode should accept server-to-clientelicitation/createrequests such as:{ "jsonrpc": "2.0", "id": "approval-123", "method": "elicitation/create", "params": { "message": "Approve this Unity Gateway command once?", "requestedSchema": { "type": "object", "properties": { "approve": { "type": "boolean", "title": "Approve once", "description": "Approve exactly this resolved command once. This does not approve future calls.", "default": false } }, "required": ["approve"] } } }The OpenCode UI should render a native prompt/form and return one of the standard MCP responses.
Accept:
{ "jsonrpc": "2.0", "id": "approval-123", "result": { "action": "accept", "content": { "approve": true } } }Decline:
{ "jsonrpc": "2.0", "id": "approval-123", "result": { "action": "decline" } }Cancel:
{ "jsonrpc": "2.0", "id": "approval-123", "result": { "action": "cancel" } }UI expectations
For this use case, the prompt should clearly show:
MCP server: <server name> Tool call: sgg_unity_call Project: <project> Command: <command> Risk: ask Approval type: one-shot Canonical scope: <scope summary> Args hash: <args_hash> Expires: <timestamp>The actions should be explicit:
Approve once Decline CancelFor this case,
Approve alwayswould be unsafe unless the MCP server explicitly requests a broader approval scope. The Gateway is intentionally asking for a one-shot approval tied to the resolved command details.Security requirements
Please make sure the implementation preserves these properties:
- The model must not be able to approve its own request.
- The approval must come from the human user through the OpenCode client UI.
- The prompt must identify the requesting MCP server.
- The prompt must distinguish
accept,decline, andcancel. - The prompt should not collect secrets. In this Gateway case, it only asks for a boolean approval.
- The UI should show a safe summary and hash, not require displaying raw args.
- Repeated elicitation requests should be rate-limited or deduplicated.
- Non-interactive modes should fail deterministically instead of hanging forever.
- This should not be mapped to a model-callable
questiontool. - This should not require exposing a model-callable approval tool.
Acceptance criteria
- OpenCode advertises
capabilities.elicitationonly when it can actually handle elicitation. - OpenCode can receive and answer server-to-client
elicitation/createwhile atools/callis in progress. - Boolean-only flat JSON Schema forms are supported.
- The TUI/web/desktop UI clearly identifies the requesting MCP server.
- Users can explicitly accept, decline, or cancel.
- The original tool call continues or fails cleanly based on the user response.
- Non-interactive/headless modes do not hang indefinitely.
- The implementation does not introduce model self-approval.
- Streamable HTTP MCP and local stdio MCP are both considered.
- If elicitation is unsupported, the failure/fallback is explicit and discoverable.
References
- MCP elicitation spec: https://modelcontextprotocol.io/specification/2025-06-18/client/elicitation
- CanonicalPath: https://github.com/romanilyin/canonicalpath
- Related umbrella issue: [FEATURE]: Full MCP client capabilities #28567
Reacted by ANTVirGEO, Lateral Summer, Murad Khafizov, Evgeniy Sigitov, tyapichu, mlkhed, Benjamin Bartels and semidark- added a commit that references this issue
on Jul 1, 2026 adding mcp elicitation support that will ship in opencode v2 soon
Reacted by Brandon BayerReacted by Roman «Stinger» Ilyin, Jindřich Pilař, Benjamin Bartels and Josef Hoferhas been added to opencode v2 see v2 branch (will release opencode v2 in next week or so)
Reacted by Josef Hofer- added a commit that references this issue
on Sep 26, 2026
Feature hasn't been suggested before.
Describe the enhancement you want to request
Enable human-in-the-loop workflows for MCP tools by supporting the elicitation protocol. This allows MCP servers to request user input via forms during tool execution.
#8251
#21231
#11948
#8243
#14968