Skip to content

v0.9.0

Choose a tag to compare

@paulbalandan paulbalandan released this 06 Aug 09:45
· 251 commits to 1.x since this release
Immutable release. Only release title and notes can be modified.
v0.9.0
239d26a

What's Changed

Closes the extensions backlog with the two ratified OAuth extensions, completing the 2026-07-28 migration. Three breaking changes are listed in BREAKING_CHANGES.md.

Added

  • The OAuth client credentials extension (io.modelcontextprotocol/oauth-client-credentials, SEP-1046) under Nexus\Mcp\Extension\Auth\ClientCredentials, authenticating with HTTP Basic or an RFC 7523 client assertion.
  • The enterprise-managed authorization extension (io.modelcontextprotocol/enterprise-managed-authorization, SEP-990) under Nexus\Mcp\Extension\Auth\Enterprise, exchanging a sign-on assertion for an ID-JAG and redeeming it at the resource authorization server.
  • A public grant-strategy seam. AuthorizedHttpClient takes a grantStrategy:, so an OAuth grant the SDK does not model can be written by a consumer. See docs/auth/extension-grants.md.
  • AuthorizationServerMetadata reads the four *_supported discovery fields, and TokenEndpointAuthMethod gained private_key_jwt.
  • The three referee scenarios for these extensions, run via composer conformance:extensions:client.

Changed

  • AuthorizationOptions::$redirectUri is nullable, for grants that never visit an authorization endpoint. A client built with a user authorization is still held to carrying one.
  • An unattended grant is rerun on expiry whether or not the token carried a refresh token.
  • MissingSuggestedDependencyException moved from Nexus\Mcp\Server\Exception to Nexus\Mcp\Core\Exception (see BREAKING_CHANGES.md).
  • Constructor parameters carry the narrow type their property always had. Nothing changes at runtime, but PHPStan now reports a plain string passed where a non-empty-string is required (see BREAKING_CHANGES.md).
  • ResourceRequestParams and ReadResourceRequestParams hold uri to the RFC 3986 shape the spec's format: uri fixes, matching what Resource already enforced (see BREAKING_CHANGES.md).
  • ScopeSet rejects an element that is not a non-empty string.
  • A schema payload missing a value now fails at the decoder as must be a non-empty string. Messages sit outside the compatibility promise, but tests pinning them need updating.

Full Changelog: v0.8.0...v0.9.0