ruby-sdk/docs
Repository files (latest commit first)
Filename Latest commit message Latest commit date
Koichi ITO f51ccfbe66 Let providers without a CIMD URL reader refresh their tokens
## Motivation and Context

`Flow#refresh!` reads `client_id_metadata_document_url` from the provider unconditionally, once to decide whether
a provider without stored `client_information` may still refresh and once to build the CIMD `client_id`.
Only `Provider` defines that reader: `CrossAppAccessProvider` and `ClientCredentialsProvider`
raise `NoMethodError` once a stored `refresh_token` is found. `MCP::Client::HTTP` calls `refresh!` on any `401` while
a `refresh_token` is stored, so a `jwt-bearer` client whose authorization server issued one fails with
`NoMethodError` on the first expired token instead of refreshing. The error is not an `AuthorizationError`,
so the transport does not fall back to the grant either. RFC 7521 Section 4.1 makes a refresh token unusual
for an assertion grant, not forbidden, and one in storage must not crash the client.

The flow now reads the URL through a duck-typed helper, like `authorization_flow` and `client_assertion`,
so a provider without the reader has no CIMD URL and refreshes with its stored `client_information`:
the `refresh_token` grant is sent with the stored client authentication, and no new ID-JAG assertion is obtained.
The authorization-code registration path reads the URL through the same helper.
The docs now say that a refresh token issued anyway is used on the next `401`, and that the assertion provider
is not called again on refresh.
A refresh token stored without the `issuer` the SDK records is refused for these two providers before any request:
unlike `Provider`, they have no tokens that predate the record, and a refresh asks no validator, so such a token
would be presented to whatever authorization server discovery names. The refusal is an `AuthorizationError`,
which sends the transport back through the grant, and the grant asks.

## How Has This Been Tested?

New tests in `test/mcp/client/oauth/flow_test.rb` refresh through a `CrossAppAccessProvider` and
a `ClientCredentialsProvider` holding a `refresh_token`, asserting the `refresh_token` grant, the Basic credentials,
and that the assertion provider is not called. A transport test in `test/mcp/client/oauth/http_oauth_test.rb` sends
a `401` to a `CrossAppAccessProvider` with a stored `refresh_token` and expects the refreshed bearer token on the retry.
All three raise `NoMethodError` against the previous library.
Further tests pin the issuer stamp on the refreshed tokens, the refusal of an authorization server that did not issue them
for a `CrossAppAccessProvider`, a clean `AuthorizationError` for a provider with neither the reader
nor stored `client_information`, and registration through DCR for a provider without the reader.
A refresh token without a recorded issuer is refused for both providers before any request is sent.

## Breaking Changes

None.
2026-09-18 11:17:21 +09:00
..
_client Let providers without a CIMD URL reader refresh their tokens 2026-09-18 11:17:21 +09:00
_extensions [Doc] Align the Docs Page Names With the MCP Specification 2026-08-22 18:07:38 +09:00
_includes [Doc] Replace the theme attribution in the nav footer 2026-08-24 16:45:55 +09:00
_preview Add a rake docs:preview task serving the docs site locally 2026-08-25 12:36:54 +09:00
_sass Move the Documentation From README.md to the Documentation Site 2026-08-21 13:24:04 +09:00
_server [Doc] State the Listen Stream Delivery Semantics 2026-09-13 17:10:12 +09:00
assets Move the Documentation From README.md to the Documentation Site 2026-08-21 13:24:04 +09:00
latest Add API documentation with GitHub Pages deployment 2025-11-21 12:21:38 -06:00
_config.yml Move the Documentation From README.md to the Documentation Site 2026-08-21 13:24:04 +09:00
CNAME [Doc] Add CNAME file to preserve custom domain across deployments 2026-03-30 13:27:58 +09:00
examples.md Move the Documentation From README.md to the Documentation Site 2026-08-21 13:24:04 +09:00
favicon.svg Move the Documentation From README.md to the Documentation Site 2026-08-21 13:24:04 +09:00
Gemfile Add a rake docs:preview task serving the docs site locally 2026-08-25 12:36:54 +09:00
index.md [Doc] Align the Docs Page Names With the MCP Specification 2026-08-22 18:07:38 +09:00
installation.md [Doc] Explain when the HTTP client needs event_stream_parser 2026-09-06 03:22:32 +09:00
protocol-versions.md [Doc] Align the Docs Page Names With the MCP Specification 2026-08-22 18:07:38 +09:00