Class: Mcp::Auth::ScopeRegistry

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

Class Method Summary collapse

Class Method Details

.available_scopesObject

All available scopes If no scopes are registered, returns basic MCP scopes for backwards compatibility



25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
# File 'lib/mcp/auth/scope_registry.rb', line 25

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)



54
55
56
# File 'lib/mcp/auth/scope_registry.rb', line 54

def clear_scopes!
  @custom_scopes = {}
end

.custom_scopesObject

Custom scopes registered by the application



19
20
21
# File 'lib/mcp/auth/scope_registry.rb', line 19

def custom_scopes
  @custom_scopes ||= {}
end

.default_scope_stringObject

Get default scopes string for a client



106
107
108
109
# File 'lib/mcp/auth/scope_registry.rb', line 106

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



91
92
93
94
95
96
97
98
99
100
101
102
103
# File 'lib/mcp/auth/scope_registry.rb', line 91

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



45
46
47
48
49
50
51
# File 'lib/mcp/auth/scope_registry.rb', line 45

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

Returns:

  • (Boolean)


59
60
61
# File 'lib/mcp/auth/scope_registry.rb', line 59

def scope_exists?(scope)
  available_scopes.key?(scope.to_s)
end

.scope_metadata(scope) ⇒ Object

Get scope metadata



64
65
66
67
68
69
70
# File 'lib/mcp/auth/scope_registry.rb', line 64

def (scope)
  available_scopes[scope.to_s] || {
    name: scope,
    description: scope,
    required: false
  }
end

.validate_scopes(requested_scopes) ⇒ Object

Validate and filter requested scopes



73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
# File 'lib/mcp/auth/scope_registry.rb', line 73

def validate_scopes(requested_scopes)
  # If no scopes requested, return all required scopes
  if requested_scopes.blank?
    return available_scopes.select { |_, meta| meta[:required] }.keys
  end

  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 { |_, meta| meta[:required] }.keys

  (valid_scopes + required_scopes).uniq
end