You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
I have verified this feature I'm about to request 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.
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-initiated elicitation/create nested inside an already-running tools/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/create as a server-to-client request during tools/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 fallback
Why 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:
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/call without Mcp-Session-Id. The compatibility path keeps existing tool calls working, while the SDK path remains available for clients that advertise capabilities.elicitation and 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-client elicitation/create requests such as:
For this case, Approve always would 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, and cancel.
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 question tool.
This should not require exposing a model-callable approval tool.
Acceptance criteria
OpenCode advertises capabilities.elicitation only when it can actually handle elicitation.
OpenCode can receive and answer server-to-client elicitation/create while a tools/call is 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.
Activity
romanilyin commentedon May 31, 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:
Why pre-call approval is not enough
My internal Gateway exposes a small stable MCP tool surface such as:
The potentially sensitive operation is not the wrapper tool name. It is inside the arguments:
A pre-call prompt like this asks the wrong question:
That is too early and too coarse. At that point the Gateway has not yet:
allow,ask, ordeny;args_hashtied to this exact request;The user should instead see something like:
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:
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:
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:
The actions should be explicit:
For 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:
accept,decline, andcancel.questiontool.Acceptance criteria
capabilities.elicitationonly when it can actually handle elicitation.elicitation/createwhile atools/callis in progress.References
opencode: elicitation investigation — not supported (Step 10)
rekram1-node commentedon Jul 3, 2026
adding mcp elicitation support that will ship in opencode v2 soon
rekram1-node commentedon Jul 8, 2026
has been added to opencode v2 see v2 branch (will release opencode v2 in next week or so)
opencode: elicitation investigation — not supported (Step 10)