actionmcp 0.72.0 → 0.80.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (52) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +1 -1
  3. data/app/controllers/action_mcp/application_controller.rb +20 -12
  4. data/app/models/action_mcp/session/message.rb +31 -20
  5. data/app/models/action_mcp/session/resource.rb +35 -20
  6. data/app/models/action_mcp/session/sse_event.rb +23 -17
  7. data/app/models/action_mcp/session/subscription.rb +22 -15
  8. data/app/models/action_mcp/session.rb +42 -119
  9. data/config/routes.rb +0 -13
  10. data/db/migrate/20250727000001_remove_oauth_support.rb +59 -0
  11. data/lib/action_mcp/client/streamable_http_transport.rb +1 -46
  12. data/lib/action_mcp/client.rb +2 -25
  13. data/lib/action_mcp/configuration.rb +51 -24
  14. data/lib/action_mcp/engine.rb +0 -7
  15. data/lib/action_mcp/filtered_logger.rb +2 -6
  16. data/lib/action_mcp/gateway_identifier.rb +187 -3
  17. data/lib/action_mcp/gateway_identifiers/api_key_identifier.rb +56 -0
  18. data/lib/action_mcp/gateway_identifiers/devise_identifier.rb +34 -0
  19. data/lib/action_mcp/gateway_identifiers/request_env_identifier.rb +58 -0
  20. data/lib/action_mcp/gateway_identifiers/warden_identifier.rb +38 -0
  21. data/lib/action_mcp/gateway_identifiers.rb +26 -0
  22. data/lib/action_mcp/server/base_session.rb +2 -0
  23. data/lib/action_mcp/version.rb +1 -1
  24. data/lib/action_mcp.rb +1 -6
  25. data/lib/generators/action_mcp/identifier/identifier_generator.rb +189 -0
  26. data/lib/generators/action_mcp/identifier/templates/identifier.rb.erb +35 -0
  27. data/lib/generators/action_mcp/install/install_generator.rb +1 -1
  28. data/lib/generators/action_mcp/install/templates/application_gateway.rb +80 -31
  29. data/lib/generators/action_mcp/install/templates/mcp.yml +4 -21
  30. metadata +13 -97
  31. data/app/controllers/action_mcp/oauth/endpoints_controller.rb +0 -265
  32. data/app/controllers/action_mcp/oauth/metadata_controller.rb +0 -125
  33. data/app/controllers/action_mcp/oauth/registration_controller.rb +0 -201
  34. data/app/models/action_mcp/oauth_client.rb +0 -159
  35. data/app/models/action_mcp/oauth_token.rb +0 -142
  36. data/db/migrate/20250608112101_add_oauth_to_sessions.rb +0 -28
  37. data/db/migrate/20250708105124_create_action_mcp_oauth_clients.rb +0 -44
  38. data/db/migrate/20250708105226_create_action_mcp_oauth_tokens.rb +0 -39
  39. data/lib/action_mcp/client/jwt_client_provider.rb +0 -135
  40. data/lib/action_mcp/client/oauth_client_provider/memory_storage.rb +0 -47
  41. data/lib/action_mcp/client/oauth_client_provider.rb +0 -234
  42. data/lib/action_mcp/jwt_decoder.rb +0 -28
  43. data/lib/action_mcp/jwt_identifier.rb +0 -28
  44. data/lib/action_mcp/none_identifier.rb +0 -19
  45. data/lib/action_mcp/o_auth_identifier.rb +0 -34
  46. data/lib/action_mcp/oauth/active_record_storage.rb +0 -183
  47. data/lib/action_mcp/oauth/error.rb +0 -79
  48. data/lib/action_mcp/oauth/memory_storage.rb +0 -132
  49. data/lib/action_mcp/oauth/middleware.rb +0 -128
  50. data/lib/action_mcp/oauth/provider.rb +0 -406
  51. data/lib/action_mcp/oauth.rb +0 -12
  52. data/lib/action_mcp/omniauth/mcp_strategy.rb +0 -162
@@ -1,162 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- require "omniauth-oauth2"
4
-
5
- module ActionMCP
6
- module Omniauth
7
- # MCP-specific Omniauth strategy for OAuth 2.1 authentication
8
- # This strategy integrates with ActionMCP's configuration system and provider interface
9
- class MCPStrategy < ::OmniAuth::Strategies::OAuth2
10
- # Strategy name used in configuration
11
- option :name, "mcp"
12
-
13
- # Default OAuth options with MCP-specific settings
14
- option :client_options, {
15
- authorize_url: "/oauth/authorize",
16
- token_url: "/oauth/token",
17
- auth_scheme: :request_body
18
- }
19
-
20
- # OAuth 2.1 compliance - PKCE is required
21
- option :pkce, true
22
-
23
- # Default scopes for MCP access
24
- option :scope, "mcp:tools mcp:resources mcp:prompts"
25
-
26
- # Use authorization code grant flow
27
- option :response_type, "code"
28
-
29
- # OAuth server metadata discovery
30
- option :discovery, true
31
-
32
- def initialize(app, *args, &block)
33
- super
34
-
35
- # Load configuration from ActionMCP if available
36
- configure_from_mcp_config if defined?(ActionMCP)
37
- end
38
-
39
- # User info from OAuth token response or userinfo endpoint
40
- def raw_info
41
- @raw_info ||= if options.userinfo_url
42
- access_token.get(options.userinfo_url).parsed
43
- else
44
- # Extract user info from token response or use minimal info
45
- access_token.token
46
- {
47
- "sub" => access_token.params["user_id"] || access_token.token,
48
- "scope" => access_token.params["scope"] || options.scope
49
- }
50
- end
51
- rescue ::OAuth2::Error => e
52
- log(:error, "Failed to fetch user info: #{e.message}")
53
- {}
54
- end
55
-
56
- # User ID for Omniauth
57
- uid { raw_info["sub"] || raw_info["user_id"] }
58
-
59
- # User info hash
60
- info do
61
- {
62
- name: raw_info["name"],
63
- email: raw_info["email"],
64
- username: raw_info["username"] || raw_info["preferred_username"]
65
- }
66
- end
67
-
68
- # Extra credentials and token info
69
- extra do
70
- {
71
- "raw_info" => raw_info,
72
- "scope" => access_token.params["scope"],
73
- "token_type" => access_token.params["token_type"] || "Bearer"
74
- }
75
- end
76
-
77
- # OAuth server metadata discovery
78
- def discovery_info
79
- @discovery_info ||= begin
80
- if options.discovery && options.client_options.site
81
- discovery_url = "#{options.client_options.site}/.well-known/oauth-authorization-server"
82
- response = client.request(:get, discovery_url)
83
- JSON.parse(response.body)
84
- end
85
- rescue StandardError => e
86
- log(:warn, "OAuth discovery failed: #{e.message}")
87
- {}
88
- end
89
- end
90
-
91
- # Override client to use discovered endpoints if available
92
- def client
93
- @client ||= begin
94
- if discovery_info.any? && discovery_info["authorization_endpoint"] && discovery_info["token_endpoint"]
95
- options.client_options.merge!(
96
- authorize_url: discovery_info["authorization_endpoint"],
97
- token_url: discovery_info["token_endpoint"]
98
- )
99
- end
100
- super
101
- end
102
- end
103
-
104
- # Token validation for API requests (not callback flow)
105
- def self.validate_token(token, options = {})
106
- strategy = new(nil, options)
107
- strategy.validate_token(token)
108
- end
109
-
110
- def validate_token(token)
111
- # Validate access token with OAuth server
112
- return nil unless token
113
-
114
- begin
115
- response = client.request(:post, options.introspection_url || "/oauth/introspect", {
116
- body: { token: token },
117
- headers: { "Content-Type" => "application/x-www-form-urlencoded" }
118
- })
119
-
120
- token_info = JSON.parse(response.body)
121
- return nil unless token_info["active"]
122
-
123
- token_info
124
- rescue StandardError => e
125
- log(:error, "Token validation failed: #{e.message}")
126
- nil
127
- end
128
- end
129
-
130
- private
131
-
132
- # Configure strategy from ActionMCP configuration
133
- def configure_from_mcp_config
134
- oauth_config = ActionMCP.configuration.oauth_config
135
- return unless oauth_config.is_a?(Hash)
136
-
137
- # Set client options from MCP config
138
- options.client_options[:site] = oauth_config["issuer_url"] if oauth_config["issuer_url"]
139
-
140
- options.client_id = oauth_config["client_id"] if oauth_config["client_id"]
141
-
142
- options.client_secret = oauth_config["client_secret"] if oauth_config["client_secret"]
143
-
144
- options.scope = Array(oauth_config["scopes_supported"]).join(" ") if oauth_config["scopes_supported"]
145
-
146
- # Enable PKCE if required (OAuth 2.1 compliance)
147
- options.pkce = true if oauth_config["pkce_required"]
148
-
149
- # Set userinfo endpoint if provided
150
- options.userinfo_url = oauth_config["userinfo_endpoint"] if oauth_config["userinfo_endpoint"]
151
-
152
- # Set token introspection endpoint
153
- return unless oauth_config["introspection_endpoint"]
154
-
155
- options.introspection_url = oauth_config["introspection_endpoint"]
156
- end
157
- end
158
- end
159
- end
160
-
161
- # Register the strategy with Omniauth
162
- OmniAuth.config.add_camelization "mcp", "MCP"