v0.6.0
What's Changed
The tracked MCP specification moves from 2025-11-25 to 2026-07-28 with no compatibility layer, so this boundary is breaking throughout. BREAKING_CHANGES.md is the upgrade guide. The entries below are the inventory.
Added
- The Streamable HTTP server transport.
StreamableHttpServerTransportis a PSR-15 handler, andSecuredHttpEndpointwraps it in CORS, DNS-rebinding protection, a body size limit, header validation, and an optional authentication slot. Responses stream as SSE or buffer as JSON. - The Streamable HTTP client transport.
StreamableHttpClientTransportPOSTs one envelope per exchange and parses SSE frame by frame, so progress notifications arrive mid-call. Requests are bounded by a progress-aware deadline set viaClientBuilder::setRequestTimeout(). - The OAuth 2.1 client half.
AuthorizedHttpClientdiscovers metadata on a401, resolves a client identifier, runs the PKCE (S256) authorization-code exchange throughUserAuthorizationInterface, binds the token to the MCP server it was issued for, and replays the request. - The OAuth 2.1 resource-server half.
BearerAuthenticationMiddlewarevalidates bearer tokens, binds the audience, and enforces scopes.ProtectedResourceMetadataHandlerserves the RFC 9728 document. The validated token reaches handlers as$context->receiveContext->authInfo. JwksAccessTokenValidator, a JWT validator riding the suggestedfirebase/php-jwtpackage.subscriptions/listenon both sides.Client::listen()opens a notification stream, and the server serves it from aSubscriptionStore. The built-in stores became runtime-mutable and firelist_changednotifications.- The input-required flow.
callTool(),readResource()andgetPrompt()can answer with anInputRequiredResult, and the caller answers by calling again withinputResponses:and the echoedrequestState:. - Completion registration grew
ServerBuilder::addPromptCompletion()/addResourceTemplateCompletion()and the repeatable#[AsCompletion]attribute. - Stdio client supervision. A subprocess that exits unexpectedly is respawned behind the same transport under a restart budget, with lost read-only requests optionally retried.
- Server-side lifecycle guards and the new protocol error codes (
-32020 HeaderMismatch,-32021 MissingRequiredClientCapability,-32022 UnsupportedProtocolVersion). ServerBuilderconfiguration:setPageSize(),setTtlMs(),setCacheScope(),setMaxInFlightDispatches(),setServerInfoDisclosure(), and theget*Store()accessors.ClientBuilder::setClientCapabilities()declares the client's capabilities.- Tool schemas accept full JSON Schema 2020-12 (SEP-2106), every top-level keyword preserved verbatim.
- Streamable HTTP examples and a dockerised Keycloak end-to-end example (
examples/keycloak-e2e/).
Changed
Client::discover()(server/discover) replaces theinitializehandshake, and the SDK stamps the per-request_metalifecycle fields on every outbound request.- Every result carries the required
resultTypediscriminator, and cacheable results require the SEP-2549ttlMsandcacheScopehints. Client::sendRequest()takes the expected response-envelope class, an optionalSendContext, and an optional per-request timeout.- The
ServerRequestmarker is renamedInputRequest, and elicitation is remodelled as bareInputRequest/InputResponsebodies ridingInputRequiredResult. - A misrouted envelope is decided by its
idalone, never the method name, uniformly across every parse-failure arm. - Reading an unknown resource answers
-32602with the requested URI inerror.data.uri(SEP-2164) instead of an emptycontentslist.
Removed
- The
initialize/notifications/initializedhandshake andClient::initialize(). Sessions go with it: no session id onTransportInterface, noMcp-Session-Idheader. pingandClient::ping(), removed by the 2026-07-28 revision.- Roots, Sampling and the Logging emission path, deprecated by SEP-2577 and omitted per SEP-2596. The
LoggingLevelenum survives only to round-trip the deprecated_metalogLevelfield. resources/subscribeandresources/unsubscribe, replaced bysubscriptions/listen.- The task methods from core (they return as the tasks extension),
Tool.execution, theElicitationCompleteNotification, and theUrlElicitationRequiredError(-32042) mechanism.
Fixed
- A handler argument-binding failure on an attribute-discovered method is reported as
-32602naming the offending argument, instead of surfacing as an internal error. Resource::$sizeis typedintper the spec'sinteger, andNumberSchemabounds plusElicitResultnumeric content accept floats per the spec'snumber.
Full Changelog: v0.5.0...v0.6.0