Skip to content

[Client][Server] Negotiate 2026-07-28 across both eras on stdio and HTTP - #537

Closed
chr-hertel wants to merge 17 commits into
mainfrom
default-spec-version
Closed

chr-hertel wants to merge 17 commits into
mainfrom
default-spec-version

Conversation

@chr-hertel

@chr-hertel chr-hertel commented Oct 6, 2026 •

Copy link
Copy Markdown
Member

Defaults the client to 2026-07-28 and lets one client or server speak both eras on stdio and HTTP, following the backward compatibility rules of the spec.

  • Client probes with server/discover and falls back to initialize on 2025-11-25 unless the server proves to be modern - setFallbackProtocolVersion() picks the revision, null makes it modern-only
  • StdioTransport settles the era on the client's first request and serves 2026-07-28 incl. subscriptions/listen and notifications/cancelled
  • Refusals come back fast: request id on the missing-session error, -32022 naming the revisions on a bare initialize, HTTP error statuses and a dead stdio process fail the request at once
  • On a modern connection setLoggingLevel() rides on every request, ping() uses server/discover and the roots notification is skipped

[BC Break] A default client against a dual-era server now lands on 2026-07-28, so sampling and roots are gone there - pin setProtocolVersion(ProtocolVersion::V2025_11_25) to keep them.

Server conformance runs at 100% locally for both revisions, client baselines pass.

@chr-hertel chr-hertel changed the title [Client] Default to protocol version 2026-07-28 [Client][Server] Negotiate 2026-07-28 across both eras on stdio and HTTP Oct 6, 2026
@chr-hertel
chr-hertel marked this pull request as ready for review October 6, 2026 23:04
@chr-hertel chr-hertel added breaking change Breaking the Backwards Compatibility Promise Server Issues & PRs related to the Server component Client Issues & PRs related to the Client component improves spec compliance Improves consistency with other SDKs such as TyepScript 2026-07-28 All issues and PRs related to the spec release 2026-07-28 labels Oct 6, 2026
benjaminkott added a commit to TYPO3/dev-companion that referenced this pull request Oct 7, 2026
The Skills extension declares itself in the answer to server/discover,
which the server refused over stdio. The transport now takes the SDK's
modern dispatcher and settles the era on the first request.

It follows modelcontextprotocol/php-sdk#537 in behaviour and names, so
that release replaces the class. D-ANS-175 lists where it differs, and
revokes D-ANS-172.
@chr-hertel chr-hertel added this to the 0.9.0 milestone Oct 7, 2026
@chr-hertel
chr-hertel requested a balanced review from Copilot October 7, 2026 20:54

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🟡 Changes recommended

Transport correlation, pending-request cleanup, stream ID handling, and disconnected logging behavior contain unresolved bugs.

5 open findings
What changed in this PR

Adds dual-era MCP negotiation across stdio and HTTP, preferring 2026-07-28 while retaining handshake compatibility.

Changes:

  • Adds modern-protocol probing with configurable handshake fallback.
  • Enables dual-era stdio routing, streaming, and cancellation.
  • Updates client behavior, tests, fixtures, and documentation for both eras.
File Description
tests/​Unit/​Server/​Transport/​StdioDualEraTest.php Tests dual-era stdio routing and streams.
tests/​Unit/​Server/​Stateless/​StatelessProtocolTest.php Tests inline modern requests and refusals.
tests/​Unit/​Server/​ProtocolTest.php Verifies request IDs on session errors.
tests/​Unit/​Client/​Transport/​StdioTransportTest.php Tests dead-process handling.
tests/​Unit/​Client/​Transport/​HttpTransportTest.php Tests HTTP probe refusal handling.
tests/​Unit/​Client/​ProtocolTest.php Covers negotiation and fallback behavior.
tests/​Unit/​Client/​ConfigurationTest.php Tests new protocol defaults.
tests/​Integration/​SamplingToolsTest.php Pins sampling tools to handshake mode.
tests/​Integration/​SamplingTest.php Covers sampling across era boundaries.
tests/​Integration/​RootsTest.php Pins roots tests to handshake mode.
tests/​Integration/​NotificationTest.php Tests notifications across both eras.
tests/​Integration/​IntegrationTestCase.php Adds shared era datasets.
tests/​Integration/​HttpNegotiationTest.php Adds HTTP negotiation coverage.
tests/​Integration/​HandshakeTest.php Expands stdio negotiation coverage.
tests/​Integration/​Fixture/​http.php Adds dual-era HTTP fixture.
tests/​Integration/​Fixture/​handshake.php Adds handshake-only fixture mode.
tests/​Integration/​ElicitationTest.php Tests modern elicitation failures.
src/​Server/​Transport/​StdioTransport.php Routes stdio traffic by protocol era.
src/​Server/​Stateless/​StatelessProtocol.php Supports headerless inline dispatch.
src/​Server/​Protocol.php Correlates missing-session errors.
src/​Schema/​Result/​InitializeResult.php Retains handshake initialization default.
src/​Schema/​JsonRpc/​MessageInterface.php Changes the default protocol revision.
src/​Client/​Transport/​StdioTransport.php Detects terminated server processes.
src/​Client/​Transport/​HttpTransport.php Converts HTTP refusals into responses.
src/​Client/​Stateless/​RequestEnvelope.php Adds per-request logging level metadata.
src/​Client/​Protocol.php Implements probing and fallback negotiation.
src/​Client/​Configuration.php Adds modern defaults and fallback configuration.
src/​Client/​Builder.php Exposes fallback configuration.
src/​Client.php Adapts ping, logging, and roots behavior.
examples/​server/​bootstrap.php Documents dual-era stdio examples.
docs/​run/​protocol-eras.md Documents stdio era routing.
docs/​protocol-versions.md Documents client negotiation behavior.
docs/​client/​connecting.md Updates connection configuration guidance.
CHANGELOG.md Records behavior and compatibility changes.

🧠 Review effort: Balanced


💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.

Comment on lines +270 to +272
if (feof($this->stdout)) {
throw new ConnectionException('The server process closed its output; it is no longer running.');
}
Comment thread src/Client.php
Comment thread src/Client/Transport/HttpTransport.php Outdated
Comment on lines +211 to +215
if (\is_array($answer) && \array_key_exists('id', $answer) && null !== $answer['id']) {
$this->handleMessage($body);

return;
}
Comment thread src/Server/Transport/StdioTransport.php Outdated
Comment on lines +229 to +232
if ((\is_string($requestId) || \is_int($requestId)) && isset($this->streams[$requestId])) {
unset($this->streams[$requestId]);
$this->logger->debug('StdioTransport dropped a cancelled request.', ['request_id' => $requestId]);
}
Comment thread docs/client/connecting.md
Comment on lines +71 to +76
$client = Client::builder()
// Fall back to an older handshake revision instead of 2025-11-25…
->setFallbackProtocolVersion(ProtocolVersion::V2025_06_18)
// …or not at all, refusing servers without the modern era.
->setFallbackProtocolVersion(null)
->build();
@chr-hertel

Copy link
Copy Markdown
Member Author

Closed in favor of #546, #547, and #550

@chr-hertel chr-hertel closed this Oct 7, 2026
@chr-hertel
chr-hertel deleted the default-spec-version branch October 7, 2026 22:37
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

2026-07-28 All issues and PRs related to the spec release 2026-07-28 breaking change Breaking the Backwards Compatibility Promise Client Issues & PRs related to the Client component improves spec compliance Improves consistency with other SDKs such as TyepScript Server Issues & PRs related to the Server component

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants