Class: MCP::Client::OAuth::Provider

Inherits:
Object
  • Object
show all
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`.

Defined Under Namespace

Classes: InsecureRedirectURIError, UnregisteredRedirectURIError

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(client_metadata:, redirect_uri:, redirect_handler:, callback_handler:, scope: nil, storage: nil) ⇒ Provider

Returns a new instance of Provider.



48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
# File 'lib/mcp/client/oauth/provider.rb', line 48

def initialize(
  client_metadata:,
  redirect_uri:,
  redirect_handler:,
  callback_handler:,
  scope: nil,
  storage: 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

  @client_metadata = 
  @redirect_uri = redirect_uri
  @redirect_handler = redirect_handler
  @callback_handler = callback_handler
  @scope = scope
  @storage = storage || InMemoryStorage.new
end

Instance Attribute Details

#callback_handlerObject (readonly)

Returns the value of attribute callback_handler.



41
42
43
# File 'lib/mcp/client/oauth/provider.rb', line 41

def callback_handler
  @callback_handler
end

#client_metadataObject (readonly)

Returns the value of attribute client_metadata.



41
42
43
# File 'lib/mcp/client/oauth/provider.rb', line 41

def 
  @client_metadata
end

#redirect_handlerObject (readonly)

Returns the value of attribute redirect_handler.



41
42
43
# File 'lib/mcp/client/oauth/provider.rb', line 41

def redirect_handler
  @redirect_handler
end

#redirect_uriObject (readonly)

Returns the value of attribute redirect_uri.



41
42
43
# File 'lib/mcp/client/oauth/provider.rb', line 41

def redirect_uri
  @redirect_uri
end

#scopeObject (readonly)

Returns the value of attribute scope.



41
42
43
# File 'lib/mcp/client/oauth/provider.rb', line 41

def scope
  @scope
end

#storageObject (readonly)

Returns the value of attribute storage.



41
42
43
# File 'lib/mcp/client/oauth/provider.rb', line 41

def storage
  @storage
end

Instance Method Details

#access_tokenObject



77
78
79
# File 'lib/mcp/client/oauth/provider.rb', line 77

def access_token
  tokens&.dig("access_token") || tokens&.dig(:access_token)
end

#clear_tokens!Object



97
98
99
# File 'lib/mcp/client/oauth/provider.rb', line 97

def clear_tokens!
  @storage.save_tokens(nil)
end

#client_informationObject



89
90
91
# File 'lib/mcp/client/oauth/provider.rb', line 89

def client_information
  @storage.client_information
end

#save_client_information(info) ⇒ Object



93
94
95
# File 'lib/mcp/client/oauth/provider.rb', line 93

def save_client_information(info)
  @storage.save_client_information(info)
end

#save_tokens(tokens) ⇒ Object



85
86
87
# File 'lib/mcp/client/oauth/provider.rb', line 85

def save_tokens(tokens)
  @storage.save_tokens(tokens)
end

#tokensObject



81
82
83
# File 'lib/mcp/client/oauth/provider.rb', line 81

def tokens
  @storage.tokens
end