Class: McpAuthenticator
- Inherits:
-
Object
- Object
- McpAuthenticator
- Defined in:
- app/mcp/mcp_authenticator.rb
Overview
Handles authentication for MCP (Model Context Protocol) requests.
Supports two authentication methods:
-
Doorkeeper OAuth tokens (preferred for Claude Desktop/native clients)
Obtained via the OAuth 2.1 authorization code flow with PKCE.
Service access is scoped by the OAuth application's permitted_services.
If permitted_services is empty, grants access to all services. -
ApiAuthentication bearer tokens (for Cursor/programmatic access)
Manual tokens created in CRM with per-token service scoping.
Security Requirements:
- Request must come from the MCP subdomain (mcp.warmlyyours.com)
- Client must send Bearer token in Authorization header
- Token must be valid and not expired/revoked
- Account must be an employee with 'mcp_access' role (admin has it by default)
Returns an AuthResult (or OAuthAuthResult) containing the account and auth info.
Defined Under Namespace
Classes: AuthResult, AuthenticationError, AuthorizationError, OAuthAuthResult
Constant Summary collapse
- REQUIRED_ROLE =
'mcp_access'- ALLOWED_SUBDOMAINS =
%w[mcp].freeze
- ENV_KEY =
Rack env key for storing auth result
'mcp.auth_result'
Class Method Summary collapse
-
.authenticate(request) ⇒ AuthResult, ...
Check if a request is authenticated (doesn't raise).
-
.authenticate!(request) ⇒ AuthResult, OAuthAuthResult
Authenticate a request and return an AuthResult.
Instance Method Summary collapse
- #authenticate ⇒ Object
- #authenticate! ⇒ Object
-
#initialize(request) ⇒ McpAuthenticator
constructor
A new instance of McpAuthenticator.
Constructor Details
#initialize(request) ⇒ McpAuthenticator
Returns a new instance of McpAuthenticator.
101 102 103 |
# File 'app/mcp/mcp_authenticator.rb', line 101 def initialize(request) @request = request end |
Class Method Details
.authenticate(request) ⇒ AuthResult, ...
Check if a request is authenticated (doesn't raise)
97 98 99 |
# File 'app/mcp/mcp_authenticator.rb', line 97 def self.authenticate(request) new(request).authenticate end |
.authenticate!(request) ⇒ AuthResult, OAuthAuthResult
Authenticate a request and return an AuthResult
90 91 92 |
# File 'app/mcp/mcp_authenticator.rb', line 90 def self.authenticate!(request) new(request).authenticate! end |
Instance Method Details
#authenticate ⇒ Object
112 113 114 115 116 117 118 119 120 121 122 123 124 125 |
# File 'app/mcp/mcp_authenticator.rb', line 112 def authenticate # Verify request is from allowed subdomain return nil unless valid_subdomain? token_string = extract_bearer_token return nil if token_string.blank? # Try Doorkeeper OAuth token first result = authenticate_doorkeeper(token_string) return result if result # Fall back to ApiAuthentication bearer token authenticate_api_token(token_string) end |
#authenticate! ⇒ Object
105 106 107 108 109 110 |
# File 'app/mcp/mcp_authenticator.rb', line 105 def authenticate! result = authenticate raise AuthenticationError, 'Invalid or missing authentication token' unless result result end |