Class: Mcp::Auth::ScopeRegistry
- Inherits:
-
Object
- Object
- Mcp::Auth::ScopeRegistry
- Defined in:
- lib/mcp/auth/scope_registry.rb
Overview
ScopeRegistry manages OAuth scopes for MCP Auth
By default, provides basic MCP scopes (mcp:read, mcp:write) automatically. Applications can register custom scopes which will replace the defaults.
Example:
Mcp::Auth::ScopeRegistry.register_scope('mcp:tools',
name: 'Tool Execution',
description: 'Execute tools and actions',
required: false
)
Constant Summary collapse
- STANDARD_OIDC_SCOPES =
Standard OpenID Connect scopes. These are not application resource scopes (so they are not registered or shown as consent checkboxes) but are recognized when present so OIDC discovery/id_token issuance works.
%w[openid profile email].freeze
Class Method Summary collapse
-
.available_scopes ⇒ Object
All available scopes If no scopes are registered, returns basic MCP scopes for backwards compatibility.
-
.clear_scopes! ⇒ Object
Clear all registered scopes (useful for testing).
-
.custom_scopes ⇒ Object
Custom scopes registered by the application.
-
.default_scope_string ⇒ Object
Get default scopes string for a client.
-
.format_for_display(requested_scopes) ⇒ Object
Format scopes for consent screen display.
-
.register_scope(scope_key, name:, description:, required: false) ⇒ Object
Register a custom scope.
-
.scope_exists?(scope) ⇒ Boolean
Check if a scope exists.
-
.scope_metadata(scope) ⇒ Object
Get scope metadata.
-
.validate_scopes(requested_scopes) ⇒ Object
Validate and filter requested scopes.
Class Method Details
.available_scopes ⇒ Object
All available scopes If no scopes are registered, returns basic MCP scopes for backwards compatibility
30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 |
# File 'lib/mcp/auth/scope_registry.rb', line 30 def available_scopes return custom_scopes unless custom_scopes.empty? # Fallback: If no scopes registered, use basic MCP scopes # This ensures backwards compatibility { 'mcp:read' => { name: 'Read Access', description: 'Read your data and resources', required: true }, 'mcp:write' => { name: 'Write Access', description: 'Create and modify data on your behalf', required: false } } end |
.clear_scopes! ⇒ Object
Clear all registered scopes (useful for testing)
59 60 61 |
# File 'lib/mcp/auth/scope_registry.rb', line 59 def clear_scopes! @custom_scopes = {} end |
.custom_scopes ⇒ Object
Custom scopes registered by the application
24 25 26 |
# File 'lib/mcp/auth/scope_registry.rb', line 24 def custom_scopes @custom_scopes ||= {} end |
.default_scope_string ⇒ Object
Get default scopes string for a client
109 110 111 112 |
# File 'lib/mcp/auth/scope_registry.rb', line 109 def default_scope_string # Return all registered scopes, or empty string if none available_scopes.keys.join(' ') end |
.format_for_display(requested_scopes) ⇒ Object
Format scopes for consent screen display
94 95 96 97 98 99 100 101 102 103 104 105 106 |
# File 'lib/mcp/auth/scope_registry.rb', line 94 def format_for_display(requested_scopes) scopes = requested_scopes.is_a?(String) ? requested_scopes.split : requested_scopes scopes.map do |scope| = (scope) { key: scope, name: [:name], description: [:description], required: [:required] } end end |
.register_scope(scope_key, name:, description:, required: false) ⇒ Object
Register a custom scope
50 51 52 53 54 55 56 |
# File 'lib/mcp/auth/scope_registry.rb', line 50 def register_scope(scope_key, name:, description:, required: false) custom_scopes[scope_key.to_s] = { name: name, description: description, required: required } end |
.scope_exists?(scope) ⇒ Boolean
Check if a scope exists
64 65 66 |
# File 'lib/mcp/auth/scope_registry.rb', line 64 def scope_exists?(scope) available_scopes.key?(scope.to_s) end |
.scope_metadata(scope) ⇒ Object
Get scope metadata
69 70 71 72 73 74 75 |
# File 'lib/mcp/auth/scope_registry.rb', line 69 def (scope) available_scopes[scope.to_s] || { name: scope, description: scope, required: false } end |
.validate_scopes(requested_scopes) ⇒ Object
Validate and filter requested scopes
78 79 80 81 82 83 84 85 86 87 88 89 90 91 |
# File 'lib/mcp/auth/scope_registry.rb', line 78 def validate_scopes(requested_scopes) # If no scopes requested, return all required scopes return available_scopes.select { |_, | [:required] }.keys if requested_scopes.blank? scopes = requested_scopes.is_a?(String) ? requested_scopes.split : requested_scopes # Filter to only valid registered scopes valid_scopes = scopes.select { |scope| scope_exists?(scope) } # Always include required scopes required_scopes = available_scopes.select { |_, | [:required] }.keys (valid_scopes + required_scopes).uniq end |