Repository navigation
Description
Feature hasn't been suggested before.
- I have verified this feature I'm about to request hasn't been suggested before.
Describe the enhancement you want to request
OpenCode's MCP client features are way behind the latest MCP standard. The gaps below were touched across many issues and PRs (see list below). I myself also encountered many difficulties due to the incomplete capability while developing MCP extensions for OpenCode. A one-time implementation is probably the cleanest fix to all of them and leaves no technical debt. This should also bring architectural advantages by flattening skills and tasks into the MCP layer.
I know this proposal for a project of this size might be a bit unrealistic. Rewriting the MCP client would definitely break loads of plugins and dependencies, and the migration wouldn't be easy. Even so, the count of issues on this is large enough that I think the discussion is at least worth having.
Behavioral gaps
Missing entirely:
- ❌
sampling/createMessageand thesamplingcapability1 - ❌
elicitation/create(form + URL modes),notifications/elicitation/complete,URLElicitationRequiredError -32042, and theelicitationcapability2 - ❌
roots/list,notifications/roots/list_changed, and therootscapability3 - ❌
resources/subscribe/resources/unsubscribe/notifications/resources/updated/notifications/resources/list_changed4 - ❌
resources/templates/list5 - ❌
completion/complete6 ⚠️ logging/setLevelandnotifications/message7 — inboundnotifications/messageis now handled; outboundlogging/setLevelis still missing- ❌
ping8 - ❌ The entire experimental
tasks/*system from2025-11-259 - ❌ No
capabilitiesobject passed tonew Client(...)— opencode advertises nothing atinitialize10
Partial or incorrect:
- ✅ Progress:
Progress reports now reset the tool call timeout timer. Long-running MCP tools that report progress will not be timed out. fix(mcp): enable progress timeout resets #32477resetTimeoutOnProgress: trueis passed tocallTooland works at the SDK level for timeout resets, butonprogressis never wired through, so no progress token is sent and progress events are not surfaced to the user. 11 - ❌ Cancellation:
notifications/cancelledis never sent when a user aborts a tool call12 - ✅
Pagination:— resolved: generictools/list,resources/list,prompts/listare called without cursors; large lists silently truncatepaginate()with cursor support, cycle detection, and 1000-page max is implemented13 - ✅
Tool results:— resolved: now JSON-stringified to text content14structuredContentis ignored - ❌
outputSchemais tolerated duringtools/listfallback by stripping it rather than validated or consumed15 - ✅
— resolved: handled as 'resource' content type in session/tools.ts16resource_linkcontent type is dropped - ❌
audiocontent type is dropped17 - ❌
isErrorflag in tool results is not checked - ❌ Tool annotations (
readOnlyHint,destructiveHint,idempotentHint,openWorldHint)18 andicons[]19 are not consumed - ❌
tools/list_changedis the only notification handled;resources/list_changedandprompts/list_changedare missing20 - ❌ The server's
InitializeResult.instructionsdoes not appear to be captured from MCP initialization or threaded into the LLM context, so the server's own usage hints are lost21
Authorization:
- ✅
Token refresh:— resolved: SDK v1.29.0 executes token refresh viarefreshTokenis stored but never executed — tokens silently expirerefreshAuthorization()22 - ✅
RFC 8707 resource indicators: not sent— resolved: implemented by SDK23 - ✅
RFC 9728 protected resource metadata: no explicit— resolved: implemented by SDK24WWW-Authenticateresource_metadataparsing - ✅
OpenID Connect Discovery 1.0: not implemented— resolved: SDK falls back from RFC 8414 to OIDC Discovery25 ⚠️ Client ID Metadata Documents: SDK supports it, but OpenCode'sMcpOAuthProviderdoes not supplyclientMetadataUrl26- ✅
Step-up authorization (— resolved: SDK handles with loop protection27insufficient_scopere-auth): not implemented - ❌ OAuth callback server (port
19876) is not stopped after auth completes - ❌ OAuth callback page has unescaped
errorquery parameter (XSS / CWE-79) - ✅
— resolvedheadersconfig is not sent duringmcp auth/mcp debug
Networking:
- ✅
Streamable HTTP— resolved: SDK sends correct Accept header28Acceptheader doesn't always list bothapplication/jsonandtext/event-stream ⚠️ MCP-Protocol-Versionheader: SDK dynamically negotiates correctly during normal operation, butopencode mcp debugstill hardcodesprotocolVersion: "2024-11-05"(three revisions behind)29- ✅
— resolved: SDK stores and sends session ID30Mcp-Session-Idis not handled; session loss permanently breaks the connection - ✅
— resolved: SDK implements resumption31Last-Event-IDresumption is not implemented - ✅
No transport-level auto-reconnect on socket errors— resolved: SDK auto-reconnects with exponential backoff28 ⚠️ Local stdio servers still have incomplete lifecycle cleanup coverage on disconnect / replace / rollback32- ❌ Origin header validation, SSRF protection, and session-hijacking mitigations from the spec's Security Best Practices are not implemented33
Related issues and PRs
Sampling:
Elicitation / roots / initialize instructions:
- [FEATURE]: MCP elicitation support #23066
- Add MCP elicitation support #8251
- feat(mcp): add elicitation request handling #8243
- [Feature Request] Native Elicitation support for MCP tools (Commit Message Refinement) #21231
- feat: Implement MCP server instruction fetching and integration #7334
- [FEATURE]: MCP Server instructions exposure #7373
- Support MCP Roots #2308
Resources and resource content:
- feat(mcp): add resource subscription API with autoprompt #29355
- [FEATURE]: Support MCP Resources (resources/read) in addition to MCP Tools #15535
- [FEATURE]:Resource subscription #12092
- feat: add MCP resource subscription support #20682
- Bug: MCP resource @mention dispatches local file read instead of resources/read RPC #17543
Prompts:
- Regression: MCP prompts are no longer listed after connecting MCP server #28579
- Feature: Support MCP Prompt content injection as system message (hidden from user) #23480
- fix(mcp): cache unsupported prompt lists #28301
Progress and cancellation:
- fix(mcp): add onprogress callback so resetTimeoutOnProgress actually works #21701
- MCP client doesn't pass
onprogresstocallTool, so progress notifications can't extend the request timeout #28186 - [BUG]: opencode doesn't receive progress notifications from MCP servers #24965
- BUG-001: MCP tool call missing progressToken injection causing timeout on long reviews (-32001) #14499
- Implement MCP progress notifications #2101
- [FEATURE]: MCP progress events via server/sdk #11821
- fix(mcp): pass onprogress so resetTimeoutOnProgress actually works #24964
- fix: pass onprogress to callTool so progressToken is set and long-run… #28246
Tool result schemas, structured content, and content types:
- MCP tool parameters of type "object" are serialized as strings instead of being passed as objects #28472
- Non-vision models blocked from passing images to vision-capable MCP tools #29216
- [FEATURE]: outputSchema for mcp tools should be exposed to LLM #27577
- MCP servers with outputSchema in tools/list break tool discovery #21591
- "Failed to get tools" when MCP server returns outputSchema in tools/list response #21373
OAuth / auth:
- MCP OAuth scope from config is ignored for pre-registered remote servers #28895
- fix(mcp): include scope in OAuth authorization URL for pre-registered clients #29219
- fix(mcp): invalidate stale credentials before re-authentication #29521
- Unexpected status: needs_auth when trying to authenticate MCP after changing account (already authenticated) #29227
- feat(mcp): expose synthetic authenticate tool for needs_auth MCPs #27725
- fix(mcp): authenticate on toggle in TUI MCP picker #27704
- MCP OAuth scope config is not applied to authorization flow #26301
- opencode mcp auth fails to open browser for OAuth flow (Google Drive MCP) #26195
- [FEATURE]: Support for MCP Support Client ID Metadata Document (CIMD) #25961
- Agents have no awareness of MCPs that need auth #27724
opencode mcp authdoes not print authorize URL to terminal, making it unusable over SSH #23951- [Bug]: OAuth callback server (port 19876) not stopped after authentication, causing cross-instance CSRF failures #23568
- [Bug]: OAuth callback server (port 19876) not stopped after authentication completes #23563
- [Bug]: OAuth callback server not stopped after authentication, causing cross-instance CSRF failures #23562
- MCP OAuth: opencode mcp auth doesn't refresh token in active sessions #21702
- Remote MCP OAuth browser flow never triggered - Datadog MCP silently fails to authenticate #18130
- fix(mcp): OAuth callback error page XSS via unescaped error parameter (CWE-79) #17364
- Remote MCP OAuth: browser never opens for re-authentication after session loss #16893
- Entra Authentication for MCP doesn't work #12308
- Oath MCP always using root level even though my rul is .../xmcp/mcp #7135
- Reauthentication with Jira MCP via Oauth doesn't work #5953
- MCP with oauth doesn't work #5444
Transport / Streamable HTTP / SSE:
- MCP remote type: Accept header missing for Streamable HTTP servers (HTTP 400) #25650
- MCP streamable-HTTP transport: 'Session not found' from server permanently breaks tool calls (no auto-reconnect) #25137
- MCP client sends deprecated protocol version causing GitLab MCP server to fail (401) #20239
- Unauthenticated streamable HTTP MCP servers are reported as SSE errors instead of missing auth #16247
- fix(opencode): reconnect MCP transport on session-expiration error and retry once #25135
Connection lifecycle / reconnect / stdio:
- MCP config using type "stdio" causes opaque TUI bootstrap server errors in 1.15.x #28625
- Local stdio MCP servers leak processes on disconnect / replace / rollback #26714
- MCP remote client has no transport-level retry on socket/connection errors #25287
- MCP client connection status goes stale after initial connect #25682
- fix(mcp): MCP status shows connected green after server reconnect even though server is down #24855
- fix(mcp): MCP server loses connection mid-session causing intermittent failures #23997
- MCP stdio transport sends batched requests without proper flush, breaking local servers #21516
Custom / dynamic headers:
- [FEATURE]: add dynamic MCP headersHelper support for remote authentication #27161
- [FEATURE]: add mcp.call.before plugin hook for per-call MCP request headers (e.g. sessionID forwarding) #28225
- feat(mcp): add mcp.call.before plugin hook for per-call MCP request headers #28319
Tool invocation and tool management:
- MCP tool wrappers send extra
_placeholderparam causing ZodError in Supabase MCP + empty response in PythonAnywhere MCP #15041 - [FEATURE]: Per-agent MCP tool filtering to stay within model tool limits #28662
Server notifications, _meta, logging, and schema compatibility:
- Surface upstream HTTP response headers from remote MCP tool calls (e.g. pagination, rate-limit) via CallToolResult._meta #29665
- [FEATURE]: Support _meta when calling downstream MCP tools #17084
- feat(mcp): forward session ID and plugin _meta to MCP tool calls #21624
- [MCP] Schema validation fails for tools with multiple discriminated-union/nested-object parameters (e.g. obsidian-mcp-server patch_note, append_to_note) #26277
- OpenCode warns on nonstandard MCP schema formats before jsonSchema() #20749
- MCP tool schema resolution: RecursionError on circular schema references #16899
TLS / mTLS / certificate validation:
- [FEATURE]: Mutual TLS / client-side certificate support for remote MCP #26862
- [FEATURE]: Add MCP client support for skipping certificate validation #23506
Stdio / platform transport compatibility:
- Python FastMCP server (STDIO) exits immediately on Windows — Not connected #26128
- fix: local MCP servers fail on Windows without native shell context #25904
- Local MCP server always times out on Windows #22310
- MCP Subsystem entirely unresponsive on Windows Desktop App (/config loads, but /mcp times out) #16449
Footnotes
-
https://modelcontextprotocol.io/specification/2025-11-25/client/sampling ↩
-
https://modelcontextprotocol.io/specification/2025-11-25/client/elicitation ↩
-
https://modelcontextprotocol.io/specification/2025-11-25/client/roots ↩
-
https://modelcontextprotocol.io/specification/2025-11-25/server/resources#subscriptions ↩
-
https://modelcontextprotocol.io/specification/2025-11-25/server/resources#resource-templates ↩
-
https://modelcontextprotocol.io/specification/2025-11-25/server/utilities/completion ↩
-
https://modelcontextprotocol.io/specification/2025-11-25/server/utilities/logging ↩
-
https://modelcontextprotocol.io/specification/2025-11-25/basic/utilities/ping ↩
-
https://modelcontextprotocol.io/specification/2025-11-25/basic/utilities/tasks ↩
-
https://modelcontextprotocol.io/specification/2025-11-25/basic/lifecycle#capability-negotiation ↩
-
https://modelcontextprotocol.io/specification/2025-11-25/basic/utilities/progress ↩
-
https://modelcontextprotocol.io/specification/2025-11-25/basic/utilities/cancellation ↩
-
https://modelcontextprotocol.io/specification/2025-11-25/server/utilities/pagination ↩
-
https://modelcontextprotocol.io/specification/2025-11-25/server/tools#structured-content ↩
-
https://modelcontextprotocol.io/specification/2025-11-25/server/tools#output-schema ↩
-
https://modelcontextprotocol.io/specification/2025-11-25/server/tools#resource-links ↩
-
https://modelcontextprotocol.io/specification/2025-11-25/server/tools#tool-result ↩
-
https://modelcontextprotocol.io/specification/2025-11-25/server/tools#tool ↩
-
https://modelcontextprotocol.io/specification/2025-11-25/basic#icons ↩
-
https://modelcontextprotocol.io/specification/2025-11-25/server/tools#list-changed-notification ↩
-
https://modelcontextprotocol.io/specification/2025-11-25/basic/lifecycle#initialization ↩
-
https://modelcontextprotocol.io/specification/2025-11-25/basic/authorization ↩
-
https://modelcontextprotocol.io/specification/2025-11-25/basic/authorization#resource-parameter-implementation ↩
-
https://modelcontextprotocol.io/specification/2025-11-25/basic/authorization#authorization-server-discovery ↩
-
https://modelcontextprotocol.io/specification/2025-11-25/basic/authorization#authorization-server-metadata-discovery ↩
-
https://modelcontextprotocol.io/specification/2025-11-25/basic/authorization#client-id-metadata-documents ↩
-
https://modelcontextprotocol.io/specification/2025-11-25/basic/authorization#scope-challenge-handling ↩
-
https://modelcontextprotocol.io/specification/2025-11-25/basic/transports#streamable-http ↩ ↩2
-
https://modelcontextprotocol.io/specification/2025-11-25/basic/transports#protocol-version-header ↩
-
https://modelcontextprotocol.io/specification/2025-11-25/basic/transports#session-management ↩
-
https://modelcontextprotocol.io/specification/2025-11-25/basic/transports#resumability-and-redelivery ↩
-
https://modelcontextprotocol.io/specification/2025-11-25/basic/transports#stdio ↩
-
https://modelcontextprotocol.io/specification/2025-11-25/basic/security_best_practices ↩
Activity
[-][FEATURE]: Complete MCP client implementation[/-][+][FEATURE]: Full MCP client capabilities[/+]Arcadi4 commentedon May 27, 2026
Edit: update according to the latest
devbranch (ata1a401dc9b69).oauth.scopenot being threaded into client metadata. Current source now passes configured scope through OAuth provider/client metadata.outputSchema: discovery failures are now tolerated by a fallback that stripsoutputSchema, but schemas still are not validated or consumed.rekram1-node commentedon May 28, 2026
yeah mcp needs a major pass, thanks for aggregating all this
romanilyin commentedon May 31, 2026
Adding a concrete use case here because this issue tracks the broader MCP client capability gap. I do not want to create duplicate issues; I plan to keep the detailed write-up in the main elicitation issue (#23066), but I think this use case is also relevant to this umbrella tracker. If maintainers prefer a separate issue, I can open one and link it from both places.
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, so this is not a runnable public reproduction. I am sharing the implementation shape because it depends on the exact MCP client capabilities discussed here.The Gateway uses CanonicalPath, a cross-language, cross-platform path canonicalization library, so it can ask the user to approve a canonicalized, scoped operation rather than raw/ambiguous path input.
The relevant capability gap is
elicitation/createnested insidetools/call.My internal MCP server exposes a wrapper-style tool surface like:
A broad pre-call prompt for the wrapper tool is not enough, because the Gateway only knows whether a command needs human approval after it has:
The desired flow is:
For MCP
2025-06-18, the client should advertise:{ "capabilities": { "elicitation": {} } }The Gateway-side implementation already has this shape for capable clients:
This use case also touches the Streamable HTTP/session part of this issue: capable clients should preserve the MCP session and support nested server-to-client requests during
tools/call. Compatibility paths that calltools/list/tools/callwithout session support can still work for ordinary tools, but they cannot provide this native prompt UX.The key requirement from this use case: OpenCode should support real MCP elicitation semantics rather than mapping this to a model-callable
questiontool or to coarse pre-call tool approval.References:
rekram1-node commentedon Jun 9, 2026
Started chipping away at all this, should have a lot of it knocked out soon
Arcadi4 commentedon Jun 13, 2026
Update (
dbbe67f066fe)13 items are now resolved (mostly via SDK v1.29.0), 5 are partially resolved, and the rest confirmed still missing.
Resolved
paginate()with cursors, cycle detection, 1000-page capstructuredContentandresource_linkare handledheadersconfig is now sent inmcp auth/mcp debugsignal: options.abortSignalis passed through, SDK sendsnotifications/cancelledon abortStill missing
capabilitiesobject at initializeInitializeResult.instructionsnot capturedonprogresscallback never wired tocallTool, so no progressToken sent and no events surfacedisErrornot checked,audiodropped, tool annotations ignoredmcp debugstill hardcodes protocol version2024-11-05Clean up
Removed 56 resolved closed issues/PRs from the related list. Re-added 17 that were closed but never actually implemented (sampling, elicitation, roots, instructions, resource subscriptions, progress).
rekram1-node commentedon Jun 14, 2026
Idk if we wanna add anything experimental like tasks but everything else will be added i believe, at least till we hit parity with other coding agents
Arcadi4 commentedon Jun 14, 2026
Is elicitation planned? If so, will we reuse the current form UI? And would it just reject subagents right away?
Arcadi4 commentedon Jun 14, 2026
Resource notifications also need more consideration if ever planned. Currently, there's no suitable UI component to fit it, which can be a gap. Introducing a new UI primitive for it should also benefit the plugin ecosystem, given that many plugins are using user messages as a workaround (I opened an issue to justify this #29633).
Nomadcxx commentedon Jun 14, 2026
This is excellent
rekram1-node commentedon Jun 15, 2026
Is elicitation experimental? My understanding was that it wasnt maybe im wrong but elicitation is planned yes
rekram1-node commentedon Jun 15, 2026
im prioritizing the lowest hanging fruit in terms of easy fixes / additions and then I do fixes on critical existing paths, and then I do the bigger newer features like elicitation. Making progress almost there
Arcadi4 commentedon Jun 15, 2026
Sounds like a good prioritization strategy. I’ve also noticed there are already several smaller UX PRs from the community that may not need much review.
On elicitation: it is new (introduced in version 2025-06-18) but not experimental. For the TODOs/skills, do you think it would make sense to merge them into a built-in MCP? MCP-based skill seems to be trending. That might also expose more capability for plugins to extend or modify them over time.
Nomadcxx commentedon Jun 15, 2026
I had a good look at this today and I think @rekram1-node small-fixes-first path makes sense.
What's landed so far:
notifications/resources/list_changed→mcp.resources.changed). This is the next one I'd like to land.Parallel to that resource work, #32480 is open for progress/status plumbing. I reworked it after feedback on the thread so mcp progress uses
session.next.tool.progress.reportinstead of the partial-output path. Happy to defer broader UI if that's not the shape you want.After #32478, the resource chain is stacked in order:
notifications/resources/updated, no auto-inject into contextresources/templates/listandcompletion/completeat the service layer, plus error-path tests for the new methods (folded into that PR rather than a separate follow-up)Still on the roadmap after that:
InitializeResult.instructionsinto model contextThis split keeps the early PRs low-risk while still giving a path toward fuller MCP client support.
Arcadi4 commentedon Jun 16, 2026
Also created a small PR #32490 on MCP server instructions. There are already many issues complaining that server instructions are not being injected. PRs with the same fix were opened as well, but they might be stale.
rekram1-node commentedon Jun 16, 2026
thx yall prolly gonna tweak these, not so sure about that mcp tool progress ideally if u make ui changes there is also a video attached
Nomadcxx commentedon Jun 17, 2026
I have a little more to do on another project but can return to this soon @rekram1-node so let me know if you want me to finish with the split PRs above and/or whether you are happy with that split or not.
Nomadcxx commentedon Jun 19, 2026
yeah makes sense.
I reworked #32480 so it no longer pushes mcp progress into the existing
session.next.tool.progressoutput path. It now usessession.next.tool.progress.report, so mcp progress stays as status/report data rather than partial tool output.I also avoided making a bigger UI call there for now. If you already have a preferred progress/status surface from the video, I’m happy to keep #32480 as the event/plumbing slice and leave the UI shape for your tweak or a follow-up.
Nomadcxx commentedon Jun 25, 2026
quick update @rekram1-node: I rebased the split mcp PRs onto current dev and cleaned up the conflicts from the recent event/schema moves.
McpEvent.ResourcesChangedpath instead of a local event definitionresources/subscribe,resources/unsubscribe, andnotifications/resources/updatedcompletion/completeplus the error-path testssession.next.tool.progress.reporton the newer schema/sdk/tui event shapeChecks are green on all four now. After this stack, the next pieces I had in mind are initialize instructions, elicitation, and sampling. Elicitation probably needs the most care because it touches UI, permissions, accept/decline/cancel behaviour, and subagents.
Nomadcxx commentedon Jun 25, 2026
Opened the first MCP elicitation slice here: #33748
I looked at the earlier attempts before cutting this down:
I kept #33748 to the smallest useful MCP path:
elicitation/createduring tool callsaccept,decline, andcancelthrough MCP, events, HTTP, SDK, and TUIcancelfor URL mode, unsupported schemas, auth probe clients, timeouts, disconnects, and shutdown cleanupelicitation.formonly for normal clients with the handler wiredLeft out on purpose: URL mode, web/desktop UI, plugin UI primitives, broader schema forms, and sampling.
Manual dev-build check: I started the rebuilt TUI from this branch, connected a repo-local stdio MCP demo server, called
elicitation-demo_request_approval, confirmed the live prompt rendered with the requesting server and checkbox label, accepted the prompt, and verified the MCP tool returned{"action":"accept","content":{"allowDemo":false}}.Live TUI prompt from the dev build:
Manual round trip with a repo-local stdio MCP demo server:
Review before opening caught one cleanup bug: cancel paths could resolve the MCP request without sending the TUI a
mcp.elicitation.repliedevent. #33748 fixes that. Timeout, interrupt, instance disposal, server close, disconnect, and client replacement now publishcancelreplies so the TUI clears the prompt.Checks run locally:
bun run typecheckcd packages/opencode && bun test --timeout 30000 test/mcp/elicitation.test.ts test/mcp/lifecycle.test.ts test/mcp/oauth-auto-connect.test.ts test/mcp/oauth-browser.test.ts test/server/httpapi-mcp-elicitation.test.ts test/server/httpapi-mcp-oauth.test.tscd packages/tui && bun test --timeout 30000 test/cli/cmd/tui/sync.test.tsxbun run --filter @opencode-ai/tui typecheckbun run --cwd packages/opencode buildelicitation-demo_request_approvalgit diff --checkIf this direction looks okay, I’d expect follow-up PRs in this order:
Sampling should stay separate from elicitation.
Also @rekram1-node for the next elicitation slice after #33748 if it lands would you prefer:
venkman-del commentedon Jun 27, 2026
Any updates on these? @rekram1-node above approach seems reasonably solid.
rekram1-node commentedon Jun 29, 2026
I already stated for bigger UI things we won't accept prs so while I appreciate it, I will be doing a separate pr.
rekram1-node commentedon Jul 8, 2026
All core mcp functionality that we hope to support is there on dev/v2 branches