Class: MCP::Client::OAuth::Provider
- Inherits:
-
Object
- Object
- MCP::Client::OAuth::Provider
- Defined in:
- lib/mcp/client/oauth/provider.rb
Overview
Pluggable OAuth client configuration handed to ‘MCP::Client::HTTP` via the `oauth:` keyword. Inspired by the OAuthClientProvider in the TypeScript SDK and httpx.Auth-based provider in the Python SDK.
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
- #access_token ⇒ Object
- #clear_tokens! ⇒ Object
- #client_information ⇒ Object
-
#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.
- #save_client_information(info) ⇒ Object
- #save_tokens(tokens) ⇒ Object
- #tokens ⇒ Object
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.
67 68 69 70 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 |
# File 'lib/mcp/client/oauth/provider.rb', line 67 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.
59 60 61 |
# File 'lib/mcp/client/oauth/provider.rb', line 59 def callback_handler @callback_handler end |
#client_id_metadata_document_url ⇒ Object (readonly)
Returns the value of attribute client_id_metadata_document_url.
59 60 61 |
# File 'lib/mcp/client/oauth/provider.rb', line 59 def @client_id_metadata_document_url end |
#client_metadata ⇒ Object (readonly)
Returns the value of attribute client_metadata.
59 60 61 |
# File 'lib/mcp/client/oauth/provider.rb', line 59 def @client_metadata end |
#redirect_handler ⇒ Object (readonly)
Returns the value of attribute redirect_handler.
59 60 61 |
# File 'lib/mcp/client/oauth/provider.rb', line 59 def redirect_handler @redirect_handler end |
#redirect_uri ⇒ Object (readonly)
Returns the value of attribute redirect_uri.
59 60 61 |
# File 'lib/mcp/client/oauth/provider.rb', line 59 def redirect_uri @redirect_uri end |
#scope ⇒ Object (readonly)
Returns the value of attribute scope.
59 60 61 |
# File 'lib/mcp/client/oauth/provider.rb', line 59 def scope @scope end |
#storage ⇒ Object (readonly)
Returns the value of attribute storage.
59 60 61 |
# File 'lib/mcp/client/oauth/provider.rb', line 59 def storage @storage end |
Instance Method Details
#access_token ⇒ Object
105 106 107 |
# File 'lib/mcp/client/oauth/provider.rb', line 105 def access_token tokens&.dig("access_token") || tokens&.dig(:access_token) end |
#clear_tokens! ⇒ Object
125 126 127 |
# File 'lib/mcp/client/oauth/provider.rb', line 125 def clear_tokens! @storage.save_tokens(nil) end |
#client_information ⇒ Object
117 118 119 |
# File 'lib/mcp/client/oauth/provider.rb', line 117 def client_information @storage.client_information end |
#save_client_information(info) ⇒ Object
121 122 123 |
# File 'lib/mcp/client/oauth/provider.rb', line 121 def save_client_information(info) @storage.save_client_information(info) end |
#save_tokens(tokens) ⇒ Object
113 114 115 |
# File 'lib/mcp/client/oauth/provider.rb', line 113 def save_tokens(tokens) @storage.save_tokens(tokens) end |
#tokens ⇒ Object
109 110 111 |
# File 'lib/mcp/client/oauth/provider.rb', line 109 def tokens @storage.tokens end |