Skip to content

mcp: initialize sends capabilities.elicitation.form.applyDefaults, breaking strict MCP servers #52319

Closed

Description

@moujian421

Summary

When connecting to a remote MCP server, opencode sends capabilities.elicitation.form.applyDefaults in its initialize request. Servers built on strict JSON parsers (for example the official MCP Java SDK, which uses FAIL_ON_UNKNOWN_PROPERTIES) reject the whole handshake, so the server never connects and all of its tools are unavailable. There is no configuration option to disable the advertised elicitation capability, and no retry with a reduced capability set.

Environment

  • opencode version: 2.0.20
  • OS: Microsoft Windows 11, Microsoft Windows NT 10.0.26200.0 (win32 x64)
  • Terminal: TERM=xterm-256color, no TERM_PROGRAM / COLORTERM / WT_SESSION (OpenCode desktop app, not a shell TTY)
  • Shell: C:\WINDOWS\system32\cmd.exe (PowerShell 5.1.26100.9168 used for diagnostics)
  • Install/channel: OpenCode desktop app, bundled CLI at %APPDATA%\ai.opencode.desktop\cli\2.0.20\opencode-cli.exe; the opencode binary is not on PATH
  • Active plugins: none found in config

Reproduction

  1. Configure a remote MCP server whose implementation rejects unknown fields in ClientCapabilities:

    {
      "$schema": "https://opencode.ai/config.json",
      "mcp": {
        "servers": {
          "sellersprite-mcp": {
            "type": "remote",
            "url": "https://mcp.sellersprite.com/mcp",
            "oauth": false,
            "headers": { "secret-key": "<redacted>" }
          }
        }
      }
    }
  2. Run opencode mcp list.

  3. Observe the server reporting failed with the error below.

The server is reachable and the credential is valid: sending the same initialize with "capabilities": {} returns HTTP 200 and the full tool list. Only the presence of elicitation.form.applyDefaults triggers the rejection.

Expected Behavior

Either the client omits capability fields the server may not understand, or a failed handshake caused by unrecognized client capabilities is retried once with a minimal capability set, so that opencode interoperates with strict MCP implementations.

Actual Behavior

The handshake is rejected and the server is never connected. No tools from that server are exposed to the agent.

$ opencode mcp list
x sellersprite-mcp  failed: Unrecognized field "applyDefaults" (class io.modelcontextprotocol.spec.McpSchema$ClientCapabilities$Elicitation$Form), not marked as ignorable (0 known properties: ])
 at [Source: UNKNOWN; byte offset: #UNKNOWN] (through reference chain: io.modelcontextprotocol.spec.McpSchema$InitializeRequest["capabilities"]->io.modelcontextprotocol.spec.McpSchema$ClientCapabilities["elicitation"]->io.modelcontextprotocol.spec.McpSchema$ClientCapabilities$Elicitation["form"]->io.modelcontextprotocol.spec.McpSchema$ClientCapabilities$Elicitation$Form["applyDefaults"])
v sorftime-mcp      connected
v xydc-mcp          connected

The server side returns a JSON-RPC error for the initialize call:

{
  "jsonrpc": "2.0",
  "id": 1,
  "error": {
    "code": -32603,
    "message": "Unrecognized field \"applyDefaults\" (class io.modelcontextprotocol.spec.McpSchema$ClientCapabilities$Elicitation$Form), not marked as ignorable (0 known properties: ]) ..."
  }
}

Additional Context

A/B test against the same endpoint confirming the cause:

initialize params.capabilities Result
{} HTTP 200, 44 tools returned
{"roots":{"listChanged":true},"elicitation":{"form":{"applyDefaults":true}},"sampling":{}} HTTP 200 with JSON-RPC error -32603

Reproducible 100% of the time. Log entry from ~/.local/share/opencode/log/opencode.log:

level=WARN message="mcp connect failed" server=sellersprite-mcp status.status=failed status.error="Unrecognized field \"applyDefaults\" (class io.modelcontextprotocol.spec.McpSchema$ClientCapabilities$Elicitation$Form), not marked as ignorable ..."

Workaround used: a local stdio proxy that deletes params.capabilities.elicitation before forwarding initialize to the remote server, with the server reconfigured as type: "local". This works and the server then connects and exposes all 44 tools, but it requires an extra process and a hand-maintained script, and it does not help other strict servers.

Checked for a configuration escape hatch: neither the published config schema nor opencode mcp add --help exposes any way to control the client capabilities sent during initialize, so this cannot be worked around in configuration alone.

This looks like the same class of interoperability problem as #47502 (an injected ?codemode= query param breaking strict remote MCP servers).

Activity

  1. github-actions commented on Sep 30, 2026

    @github-actions
    Contributor

    This issue might be a duplicate of existing issues. Please check:

    • #47502: Its additional context reports the same elicitation.form.applyDefaults field being rejected by strict Java MCP servers during initialize.
  2. gudnithor commented on Oct 9, 2026

    @gudnithor

    Hi @nexxeln - #53196 has a fix for this bug. Is there any way to help reviewing and/or testing to get it merged?

    cc @donbowman

  3. rekram1-node commented on Oct 15, 2026

    @rekram1-node
    Collaborator

    fixed in next v2 release should go out later tonight.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

Labels

No labels
No labels

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions