Model nested experimental values and extensions in Client.Capabilities - #276
Open
nstrm wants to merge 1 commit into
Open
Conversation
Type experimental as [String: Value] per the spec and add the extensions capability map, so initialize requests carrying nested JSON (e.g. ChatGPT's) decode instead of failing with -32603. Fixes modelcontextprotocol#262
|
Second reproducer for #262: Codex CLI 0.154.0 (released 2026-09-09) sends |
3 tasks
ianegordon
added a commit
to ianegordon/swift-sdk
that referenced
this pull request
Sep 11, 2026
…nt.Capabilities (upstream modelcontextprotocol#276, nstrm) Manifest entry 7. Upstream refs/pull/276/head at f7077e0, unmodified. Client.Capabilities.experimental was typed [String: String], but the 2025-11-25 schema defines it as a map of arbitrary objects. A ChatGPT-shaped initialize carrying {"openai/visibility": {"enabled": true}} failed to decode and the server answered -32603 to a valid request. Reproduced before the merge and confirmed fixed after. experimental becomes [String: Value]; extensions is added as [String: Value]. Note that extensions is a draft-schema capability, absent from 2025-11-25 — an unmodeled key already decoded fine, so that half is a feature, not a fix. This is a source-breaking public type change: dictionary literals with string values still compile, but a typed [String: String] variable and reading a value back as String do not. A deprecated compatibility initializer follows as entry 7a. Fixes modelcontextprotocol#262. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Eb9yGSXH1TVkg5Afsu9phk
ianegordon
added a commit
to ianegordon/swift-sdk
that referenced
this pull request
Sep 11, 2026
modelcontextprotocol#276 changes Client.Capabilities.experimental from [String: String] to [String: Value], which is source-breaking: a dictionary literal with string values still compiles because Value is ExpressibleByStringLiteral, but a typed [String: String] variable does not. This restores that call site behind a deprecation warning. experimental is deliberately non-optional and without a default: with every parameter defaulted, overload resolution routes the bare Client.Capabilities() call to this initializer and warns on it, which is noise unrelated to experimental. Requiring the parameter keeps that call on the designated initializer. Reading a value back as String is not restored — experimental is a stored property and Swift has no second property of the same name, so consumers that read values out still need updating. Follows the deprecated compatibility factories in Sources/MCP/Server/Tools.swift. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Eb9yGSXH1TVkg5Afsu9phk
ianegordon
added a commit
to ianegordon/swift-sdk
that referenced
this pull request
Sep 11, 2026
…nt.Capabilities Manifest entry 7a. Fork addition at 604afd2, one clean commit stacked on modelcontextprotocol#276's f7077e0, offerable upstream as submitted. modelcontextprotocol#276's public type change is source-breaking for a typed [String: String] variable. This restores that call site behind a deprecation warning, with experimental required and undefaulted so the bare Client.Capabilities() call stays on the designated initializer instead of warning. Reading a value back as String is still unsupported and cannot be shimmed by an initializer. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Eb9yGSXH1TVkg5Afsu9phk
ianegordon
added a commit
to ianegordon/swift-sdk
that referenced
this pull request
Sep 11, 2026
… as entry 7a
Client.Capabilities.experimental was [String: String] where the 2025-11-25
schema defines a map of arbitrary objects, so a ChatGPT-shaped initialize
carrying {"openai/visibility": {"enabled": true}} failed to decode and the
server answered -32603 to a valid request. Reproduced on the wire before the
merge and confirmed fixed after.
The entry records what the PR description understates: the type change is
source-breaking for a typed [String: String] variable and for reading a value
back as String, and the extensions field it adds is a draft-schema capability
absent from 2025-11-25 — an unmodeled key already decoded fine, so that half
is a feature rather than a fix.
7a restores the typed-variable call site behind a deprecation warning. The
read direction cannot be shimmed by an initializer and still needs updating
downstream.
Remaining candidate modelcontextprotocol#278 renumbered 7 to 6.
Tracking: fork issue #11.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Eb9yGSXH1TVkg5Afsu9phk
ianegordon
added a commit
to ianegordon/swift-sdk
that referenced
this pull request
Sep 11, 2026
First fork tag carrying a library change since .5: modelcontextprotocol#276 fixes the -32603 a server returns to a ChatGPT-shaped initialize, and 7a adds the deprecated [String: String] compatibility initializer. Tags .5 and .6 differ only in the conformance harness, so this is the first tag downstream has a reason to move to since .5. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Eb9yGSXH1TVkg5Afsu9phk
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Fixes #262.
Client.Capabilities.experimentalis typed[String: String]?, but the spec defines it as a map of arbitrary objects. Clients that send nested values there — ChatGPT sends{"openai/visibility": {"enabled": true}}— fail decoding insideTypedRequestHandler, and the server returns JSON-RPC-32603to a validinitialize. Theextensionscapability map was also unmodeled (ignored on decode).experimentalis now[String: Value]?;extensionsis added as[String: Value]?.initialize(experimentaltyped[String: String],extensionsunmodeled); error is returned inside an HTTP 200 #262 and an encode/decode round-trip test. Full suite passes (553 tests).Note for reviewers: this changes the public type of
experimental. Dictionary literals with string values still compile (ValueisExpressibleByStringLiteral); no call sites in the repo needed updating.