Skip to content
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
32 changes: 1 addition & 31 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,36 +7,6 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0

## [Unreleased]

### Added
## [0.1.0] - 2026-09-07

- Initial release.

### Changed

- Identifier handling now preserves issuer and resource identity. Issuers are stored and compared
byte-for-byte (RFC 8414 §3.3) with no trailing-slash reconciliation; the terminating slash is
stripped only when *deriving* a `.well-known` discovery URL (RFC 8414/9728 §3.1). The resource
identifier is likewise preserved verbatim: deriving the Protected Resource Metadata path now
strips the terminating slash of the resource path (`/mcp/` →
`/.well-known/oauth-protected-resource/mcp`, RFC 9728 §3.1) without altering the resource
identifier itself.

**Migration:** If your configured issuer differs from your authorization server's actual
identifier by a trailing slash, correct the config — the SDK no longer silently reconciles them.

### Fixed

- Deriving a Protected Resource Metadata URL now requires the resource identifier to carry a
scheme. A scheme-relative reference such as `//api.example.com/mcp` is neither opaque nor
authority-less, so it cleared the derivation gate and produced
`null://api.example.com/.well-known/oauth-protected-resource/mcp` — a URL the SDK then published
in the `resource_metadata` parameter of the 401 `WWW-Authenticate` challenge, where no client
could resolve it. Such an identifier is now rejected at derivation, naming the missing
component. RFC 8707 §2 requires an absolute URI, which RFC 3986 §4.3 defines as always carrying
a scheme, so no valid identifier is affected.
- The derived Protected Resource Metadata URL now carries the resource identifier's authority
verbatim. It was built from `URI.getAuthority()`, which percent-decodes, so an identifier whose
userinfo contained an encoded `@` (`https://u%40b@api.example.com/mcp`) derived
`https://u@b@api.example.com/…` — an authority with two `@` delimiters where the identifier
names one. The raw authority is now used, matching the derived path, which already preserved
its percent-encoded octets.
Loading