Class: MCP::Client::OAuth::Provider
- Inherits:
-
Object
- Object
- MCP::Client::OAuth::Provider
- Includes:
- StorageBackedProvider
- Defined in:
- lib/mcp/client/oauth/provider.rb
Overview
Pluggable OAuth client configuration for the OAuth 2.1 Authorization Code + PKCE flow, handed to ‘MCP::Client::HTTP` via the `oauth:` keyword. Inspired by the OAuthClientProvider in the TypeScript SDK and the httpx.Auth-based provider in the Python SDK. For the non-interactive machine-to-machine `client_credentials` grant, use `ClientCredentialsProvider` instead.
Required keyword arguments:
-
‘client_metadata` - Hash sent to the authorization server’s Dynamic Client Registration endpoint. Must include at minimum ‘redirect_uris`, `grant_types`, `response_types`, and `token_endpoint_auth_method`.
-
‘redirect_uri` - String: the redirect URI used for the authorization request. Must be one of `redirect_uris` in `client_metadata`.
-
‘redirect_handler` - Callable invoked with the fully-built authorization URL (a `URI`). Implementations typically open the user’s browser.
-
‘callback_handler` - Callable invoked after `redirect_handler`. Returns `[code, state]` where `code` is the authorization code and `state` is the `state` parameter received on the redirect URI.
Optional keyword arguments:
-
‘scope` - String of space-separated scopes to request when the server’s ‘WWW-Authenticate` does not specify one.
-
‘storage` - Object responding to `tokens`, `save_tokens(tokens)`, `client_information`, and `save_client_information(info)`. Defaults to an `InMemoryStorage`.
-
‘client_id_metadata_document_url` - URL where the client publishes its Client ID Metadata Document (`draft-ietf-oauth-client-id-metadata-document-00` and the MCP authorization specification). When the authorization server advertises `client_id_metadata_document_supported: true`, the SDK uses this URL as the OAuth `client_id` and skips Dynamic Client Registration. Spec-required: `https://` scheme, a non-root path, and no fragment, userinfo, or `.`/`..` segments. The SDK additionally refuses to send query strings (the draft marks them only SHOULD NOT include, but different encodings of the same query would yield different `client_id` strings for the same document). The document served at the URL is a separate JSON artifact from the `client_metadata` keyword: DCR `client_metadata` MUST NOT include `client_id`, while the CIMD document MUST include `client_id` set to the URL, `client_name`, and `redirect_uris` covering `redirect_uri`.
Defined Under Namespace
Classes: InsecureRedirectURIError, InvalidClientIDMetadataDocumentURLError, UnregisteredRedirectURIError
Instance Attribute Summary collapse
-
#callback_handler ⇒ Object
readonly
Returns the value of attribute callback_handler.
-
#client_id_metadata_document_url ⇒ Object
readonly
Returns the value of attribute client_id_metadata_document_url.
-
#client_metadata ⇒ Object
readonly
Returns the value of attribute client_metadata.
-
#redirect_handler ⇒ Object
readonly
Returns the value of attribute redirect_handler.
-
#redirect_uri ⇒ Object
readonly
Returns the value of attribute redirect_uri.
-
#scope ⇒ Object
readonly
Returns the value of attribute scope.
-
#storage ⇒ Object
readonly
Returns the value of attribute storage.
Instance Method Summary collapse
-
#authorization_flow ⇒ Object
Identifies the OAuth flow this provider drives.
-
#initialize(client_metadata:, redirect_uri:, redirect_handler:, callback_handler:, scope: nil, storage: nil, client_id_metadata_document_url: nil) ⇒ Provider
constructor
A new instance of Provider.
Methods included from StorageBackedProvider
#access_token, #clear_tokens!, #client_information, #save_client_information, #save_tokens, #tokens
Constructor Details
#initialize(client_metadata:, redirect_uri:, redirect_handler:, callback_handler:, scope: nil, storage: nil, client_id_metadata_document_url: nil) ⇒ Provider
Returns a new instance of Provider.
71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 |
# File 'lib/mcp/client/oauth/provider.rb', line 71 def initialize( client_metadata:, redirect_uri:, redirect_handler:, callback_handler:, scope: nil, storage: nil, client_id_metadata_document_url: nil ) unless Discovery.secure_url?(redirect_uri) raise InsecureRedirectURIError, "redirect_uri #{redirect_uri.inspect} must use https or be a loopback http URL " \ "(localhost, 127.0.0.0/8, or ::1) per the MCP authorization Communication Security requirement." end registered = Array([:redirect_uris] || ["redirect_uris"]) unless registered.include?(redirect_uri) raise UnregisteredRedirectURIError, "redirect_uri #{redirect_uri.inspect} must be listed in client_metadata[:redirect_uris] " \ "(got #{registered.inspect}); otherwise the authorization server will reject the authorization request." end if && !Discovery.() raise InvalidClientIDMetadataDocumentURLError, "client_id_metadata_document_url #{.inspect} must be an https URL " \ "with a non-root path and no fragment, query, userinfo, or `.`/`..` segments, " \ "per the MCP authorization specification and `draft-ietf-oauth-client-id-metadata-document`." end @client_metadata = @redirect_uri = redirect_uri @redirect_handler = redirect_handler @callback_handler = callback_handler @scope = scope @storage = storage || InMemoryStorage.new @client_id_metadata_document_url = end |
Instance Attribute Details
#callback_handler ⇒ Object (readonly)
Returns the value of attribute callback_handler.
63 64 65 |
# File 'lib/mcp/client/oauth/provider.rb', line 63 def callback_handler @callback_handler end |
#client_id_metadata_document_url ⇒ Object (readonly)
Returns the value of attribute client_id_metadata_document_url.
63 64 65 |
# File 'lib/mcp/client/oauth/provider.rb', line 63 def @client_id_metadata_document_url end |
#client_metadata ⇒ Object (readonly)
Returns the value of attribute client_metadata.
63 64 65 |
# File 'lib/mcp/client/oauth/provider.rb', line 63 def @client_metadata end |
#redirect_handler ⇒ Object (readonly)
Returns the value of attribute redirect_handler.
63 64 65 |
# File 'lib/mcp/client/oauth/provider.rb', line 63 def redirect_handler @redirect_handler end |
#redirect_uri ⇒ Object (readonly)
Returns the value of attribute redirect_uri.
63 64 65 |
# File 'lib/mcp/client/oauth/provider.rb', line 63 def redirect_uri @redirect_uri end |
#scope ⇒ Object (readonly)
Returns the value of attribute scope.
63 64 65 |
# File 'lib/mcp/client/oauth/provider.rb', line 63 def scope @scope end |
#storage ⇒ Object (readonly)
Returns the value of attribute storage.
63 64 65 |
# File 'lib/mcp/client/oauth/provider.rb', line 63 def storage @storage end |
Instance Method Details
#authorization_flow ⇒ Object
Identifies the OAuth flow this provider drives. ‘Flow` dispatches on this rather than inspecting `client_metadata`, which is protocol metadata for the authorization server, not an SDK control signal.
112 113 114 |
# File 'lib/mcp/client/oauth/provider.rb', line 112 def :authorization_code end |