You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Set OIDC application_type on Dynamic Client Registration per SEP-837
## Motivation and Context
SEP-837 (modelcontextprotocol/modelcontextprotocol#837, merged for the 2026-07-28 spec release)
updates the authorization spec to require MCP clients to specify an appropriate OIDC `application_type`
(`"native"` vs `"web"`) during Dynamic Client Registration, so the authorization server can apply
the matching redirect URI policy and native and web clients do not collide on redirect URI validation rules.
This mirrors the approach taken by the TypeScript SDK (typescript-sdk#2266) and the Python SDK (python-sdk#2784):
- `MCP::Client::OAuth::Discovery.infer_application_type(redirect_uris)` returns `"native"` when every redirect URI
is a native-app URI (a custom non-http(s) scheme per RFC 8252 Section 7.1, or an http(s) URI with a loopback host
per RFC 8252 Section 7.3) and `"web"` otherwise, including for nil, empty, or unparseable input.
Loopback detection reuses the existing `loopback_host?` helper, so lookalike hosts such as `localhost.example.com`
or `127.attacker.com` are not treated as native.
- `Flow#ensure_client_registered` now posts the metadata through the new `registration_client_metadata` helper,
which merges the inferred `application_type` into the DCR request body only when the user did not set
one explicitly (symbol or string key); an explicit value always wins.
Resolves#375.
## How Has This Been Tested?
New tests in `test/mcp/client/oauth/discovery_test.rb` cover the inference: loopback http URIs (IPv4, IPv6, `localhost`),
custom schemes, https URIs, mixed lists, the `localhost.example.com` lookalike, nil/empty input, and unparseable URIs.
New tests in `test/mcp/client/oauth/flow_test.rb` assert on the actual DCR request body via WebMock `assert_requested`:
loopback redirect URI registers `"application_type": "native"`, an HTTPS redirect URI registers `"web"`,
and an explicit `application_type` (symbol- or string-keyed) is never overridden.
## Breaking Changes
None. The DCR request body gains an `application_type` member only when the user has not specified one;
RFC 7591 requires authorization servers to accept and use known metadata fields, and OIDC-registration servers
already default this field to `"web"` when absent.
Copy file name to clipboardExpand all lines: README.md
+2Lines changed: 2 additions & 0 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -2029,6 +2029,8 @@ Required keyword arguments to `Provider.new`:
2029
2029
2030
2030
-`client_metadata`: Hash sent to the authorization server's Dynamic Client Registration endpoint. Must include `redirect_uris`, `grant_types`, `response_types`,
2031
2031
`token_endpoint_auth_method`. `redirect_uri` (below) must appear in this list, otherwise the constructor raises `Provider::UnregisteredRedirectURIError`.
2032
+
When `application_type` is omitted, the SDK infers `"native"` or `"web"` from `redirect_uris` per SEP-837 before registering (loopback or custom-scheme URIs are native);
2033
+
an explicit value always wins.
2032
2034
-`redirect_uri`: String. Must use HTTPS or be a loopback URL (`localhost`, `127.0.0.0/8`, `::1`); other values raise `Provider::InsecureRedirectURIError`.
2033
2035
-`redirect_handler`: Callable invoked with the fully-built authorization `URI`. Typically opens the user's browser.
2034
2036
-`callback_handler`: Callable that returns `[code, state]` after the user is redirected back to `redirect_uri`.
0 commit comments