Skip to content

Legacy initialize responses drop capabilities.extensions (2025-11-25 and earlier) #3773

Open

Description

@sambhav

Initial Checks

Release line

2.x (current stable)

Description

What happens. On connections that negotiate 2025-11-25 or earlier, a server's initialize result loses capabilities.extensions. The public ServerCapabilities model exposes extensions, but serialize_server_result("initialize", version, ...) validates against the per-version wire model, and _v2025_11_25.ServerCapabilities has no extensions field and uses extra="ignore". Client advertisements survive, so negotiation is one-sided: the client offers an extension but never sees the server accept it.

Why it matters. Extensions became official in 2026-07-28, but they are widely negotiated through initialize on older versions. MCP Apps' stable spec advertises io.modelcontextprotocol/ui this way, and the TypeScript, Go, C#, Rust, Kotlin, Ruby, PHP, and Java SDKs all carry the field on legacy connections. modelcontextprotocol/modelcontextprotocol#3364 documents this and encourages SDKs that can carry the field to do so. Today, a Python server can't advertise MCP Apps (or any extension) to a 2025-11-25 client.

Expected. capabilities.extensions survives legacy initialize serialization in both directions, as it does for 2026-07-28.

Possible fix. Add an optional extensions: dict[str, dict[str, Any]] | None field to the legacy ClientCapabilities/ServerCapabilities wire models (or carve it out of the sieve), and add an initialize round-trip test per supported legacy version.

Related: #3640, which covers unknown capability keys more broadly. This issue is narrower: extensions is a known field that the SDK already models for 2026-07-28.

Example Code

from mcp_types.methods import serialize_server_result

data = {
    "protocolVersion": "2025-11-25",
    "capabilities": {"tools": {}, "extensions": {"io.modelcontextprotocol/ui": {}}},
    "serverInfo": {"name": "S", "version": "1"},
}
print(serialize_server_result("initialize", "2025-11-25", data)["capabilities"])
# {'tools': {}}  <- extensions dropped

Activity

  1. added
    bugSomething isn't working
    spec-2026-07-28Concerns the SDK's implementation of the 2026-07-28 MCP spec revision
    v2Affects the v2 line (2.x on main)
    on Oct 27, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't workingspec-2026-07-28Concerns the SDK's implementation of the 2026-07-28 MCP spec revisionv2Affects the v2 line (2.x on main)

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions