actionmcp 0.51.0 → 0.52.1
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.
- checksums.yaml +4 -4
- data/README.md +192 -0
- data/app/controllers/action_mcp/application_controller.rb +12 -6
- data/lib/action_mcp/client/active_record_session_store.rb +57 -0
- data/lib/action_mcp/client/session_store.rb +2 -103
- data/lib/action_mcp/client/session_store_factory.rb +36 -0
- data/lib/action_mcp/client/test_session_store.rb +84 -0
- data/lib/action_mcp/client/volatile_session_store.rb +38 -0
- data/lib/action_mcp/configuration.rb +16 -1
- data/lib/action_mcp/current.rb +19 -0
- data/lib/action_mcp/current_helpers.rb +19 -0
- data/lib/action_mcp/gateway.rb +85 -0
- data/lib/action_mcp/json_rpc_handler_base.rb +6 -1
- data/lib/action_mcp/jwt_decoder.rb +26 -0
- data/lib/action_mcp/prompt.rb +1 -0
- data/lib/action_mcp/resource_template.rb +1 -0
- data/lib/action_mcp/server/base_messaging.rb +14 -0
- data/lib/action_mcp/server/error_aware.rb +8 -1
- data/lib/action_mcp/server/handlers/tool_handler.rb +2 -1
- data/lib/action_mcp/server/json_rpc_handler.rb +12 -4
- data/lib/action_mcp/server/messaging.rb +12 -1
- data/lib/action_mcp/server/registry_management.rb +0 -1
- data/lib/action_mcp/server/response_collector.rb +40 -0
- data/lib/action_mcp/server/session_store.rb +762 -0
- data/lib/action_mcp/server/tools.rb +14 -3
- data/lib/action_mcp/server/transport_handler.rb +9 -5
- data/lib/action_mcp/server.rb +7 -0
- data/lib/action_mcp/tagged_stream_logging.rb +0 -4
- data/lib/action_mcp/test_helper/progress_notification_assertions.rb +105 -0
- data/lib/action_mcp/test_helper/session_store_assertions.rb +130 -0
- data/lib/action_mcp/test_helper.rb +4 -0
- data/lib/action_mcp/tool.rb +1 -0
- data/lib/action_mcp/version.rb +1 -1
- data/lib/action_mcp.rb +0 -1
- data/lib/generators/action_mcp/install/install_generator.rb +4 -0
- data/lib/generators/action_mcp/install/templates/application_gateway.rb +40 -0
- metadata +29 -1
@@ -39,14 +39,25 @@ module ActionMCP
|
|
39
39
|
tool_class = session.registered_tools.find { |t| t.tool_name == tool_name }
|
40
40
|
|
41
41
|
if tool_class
|
42
|
-
# Create tool and set execution context
|
42
|
+
# Create tool and set execution context with request info
|
43
43
|
tool = tool_class.new(arguments)
|
44
|
-
tool.with_context({
|
44
|
+
tool.with_context({
|
45
|
+
session: session,
|
46
|
+
request: {
|
47
|
+
params: {
|
48
|
+
name: tool_name,
|
49
|
+
arguments: arguments,
|
50
|
+
_meta: _meta
|
51
|
+
}
|
52
|
+
}
|
53
|
+
})
|
45
54
|
|
46
55
|
result = tool.call
|
47
56
|
|
48
57
|
if result.is_error
|
49
|
-
|
58
|
+
# Convert ToolResponse error to proper JSON-RPC error format
|
59
|
+
error_hash = result.to_h
|
60
|
+
send_jsonrpc_response(request_id, error: error_hash)
|
50
61
|
else
|
51
62
|
send_jsonrpc_response(request_id, result: result)
|
52
63
|
end
|
@@ -1,5 +1,8 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
+
require_relative "response_collector"
|
4
|
+
require_relative "base_messaging"
|
5
|
+
|
3
6
|
module ActionMCP
|
4
7
|
module Server
|
5
8
|
class TransportHandler
|
@@ -9,6 +12,7 @@ module ActionMCP
|
|
9
12
|
delegate :read, :write, to: :session
|
10
13
|
include Logging
|
11
14
|
|
15
|
+
include BaseMessaging # Provides basic write_message
|
12
16
|
include Messaging
|
13
17
|
include Capabilities
|
14
18
|
include Tools
|
@@ -17,10 +21,14 @@ module ActionMCP
|
|
17
21
|
include Notifications
|
18
22
|
include Sampling
|
19
23
|
include Roots
|
24
|
+
include ResponseCollector # Must be included last to override write_message
|
20
25
|
|
21
26
|
# @param [ActionMCP::Session] session
|
22
|
-
|
27
|
+
# @param messaging_mode [:write, :return] The mode for message handling
|
28
|
+
def initialize(session, messaging_mode: :write)
|
23
29
|
@session = session
|
30
|
+
@messaging_mode = messaging_mode
|
31
|
+
initialize_response_collector if messaging_mode == :return
|
24
32
|
end
|
25
33
|
|
26
34
|
def send_pong(request_id)
|
@@ -29,10 +37,6 @@ module ActionMCP
|
|
29
37
|
|
30
38
|
private
|
31
39
|
|
32
|
-
def write_message(data)
|
33
|
-
session.write(data)
|
34
|
-
end
|
35
|
-
|
36
40
|
def format_registry_items(registry)
|
37
41
|
registry.map { |item| item.klass.to_h }
|
38
42
|
end
|
data/lib/action_mcp/server.rb
CHANGED
@@ -28,6 +28,13 @@ module ActionMCP
|
|
28
28
|
@server = nil
|
29
29
|
end
|
30
30
|
|
31
|
+
# Access the session store
|
32
|
+
def session_store
|
33
|
+
@session_store ||= SessionStoreFactory.create(
|
34
|
+
ActionMCP.configuration.session_store_type
|
35
|
+
)
|
36
|
+
end
|
37
|
+
|
31
38
|
# Available pubsub adapter types
|
32
39
|
ADAPTERS = {
|
33
40
|
"test" => "SimplePubSub",
|
@@ -0,0 +1,105 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module ActionMCP
|
4
|
+
module TestHelper
|
5
|
+
module ProgressNotificationAssertions
|
6
|
+
# Assert that at least one progress notification was sent with the given token
|
7
|
+
def assert_progress_notification_sent(token, message = nil)
|
8
|
+
notifications = get_progress_notifications(token)
|
9
|
+
assert notifications.any?,
|
10
|
+
message || "Expected at least one progress notification with token #{token}, but none were sent"
|
11
|
+
end
|
12
|
+
|
13
|
+
# Assert that no progress notifications were sent with the given token
|
14
|
+
def assert_no_progress_notification_sent(token, message = nil)
|
15
|
+
notifications = get_progress_notifications(token)
|
16
|
+
assert notifications.empty?,
|
17
|
+
message || "Expected no progress notifications with token #{token}, but #{notifications.size} were sent"
|
18
|
+
end
|
19
|
+
|
20
|
+
# Assert that progress values increase monotonically
|
21
|
+
def assert_progress_sequence_valid(token, message = nil)
|
22
|
+
notifications = get_progress_notifications(token)
|
23
|
+
progress_values = notifications.map { |n| n.params[:progress] }
|
24
|
+
|
25
|
+
assert progress_values.each_cons(2).all? { |a, b| b > a },
|
26
|
+
message || "Progress values must increase monotonically, but got: #{progress_values.inspect}"
|
27
|
+
end
|
28
|
+
|
29
|
+
# Assert specific fields in the latest progress notification
|
30
|
+
def assert_progress_notification_includes(token, expected, message = nil)
|
31
|
+
notifications = get_progress_notifications(token)
|
32
|
+
assert notifications.any?, "No progress notifications found for token #{token}"
|
33
|
+
|
34
|
+
notification = notifications.last
|
35
|
+
expected.each do |key, value|
|
36
|
+
actual = notification.params[key]
|
37
|
+
assert_equal value, actual,
|
38
|
+
message || "Expected notification to have #{key}: #{value.inspect}, but got: #{actual.inspect}"
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
42
|
+
# Assert the total count of progress notifications for a token
|
43
|
+
def assert_progress_notification_count(token, expected_count, message = nil)
|
44
|
+
notifications = get_progress_notifications(token)
|
45
|
+
actual_count = notifications.size
|
46
|
+
|
47
|
+
assert_equal expected_count, actual_count,
|
48
|
+
message || "Expected #{expected_count} progress notifications for token #{token}, but got #{actual_count}"
|
49
|
+
end
|
50
|
+
|
51
|
+
# Assert notification follows MCP spec structure
|
52
|
+
def assert_progress_notification_valid(notification, message = nil)
|
53
|
+
# Convert to hash if it's a notification object
|
54
|
+
data = notification.respond_to?(:to_h) ? notification.to_h : notification
|
55
|
+
|
56
|
+
# Verify JSON-RPC structure
|
57
|
+
assert_equal "2.0", data["jsonrpc"] || data[:jsonrpc],
|
58
|
+
message || "Notification must have jsonrpc: 2.0"
|
59
|
+
assert_equal "notifications/progress", data[:method],
|
60
|
+
message || "Notification method must be notifications/progress"
|
61
|
+
assert_nil data[:id],
|
62
|
+
message || "Notifications must not have an id field"
|
63
|
+
|
64
|
+
# Verify params
|
65
|
+
params = data[:params]
|
66
|
+
assert params, "Notification must have params"
|
67
|
+
assert params[:progressToken], "Notification must have progressToken"
|
68
|
+
assert params[:progress], "Notification must have progress value"
|
69
|
+
|
70
|
+
# Type checks
|
71
|
+
assert [ String, Integer ].include?(params[:progressToken].class),
|
72
|
+
"progressToken must be string or integer"
|
73
|
+
assert params[:progress].is_a?(Numeric),
|
74
|
+
"progress must be numeric"
|
75
|
+
|
76
|
+
# Optional field type checks if present
|
77
|
+
if params.key?(:total)
|
78
|
+
assert params[:total].is_a?(Numeric),
|
79
|
+
"total must be numeric when present"
|
80
|
+
end
|
81
|
+
|
82
|
+
if params.key?(:message)
|
83
|
+
assert params[:message].is_a?(String),
|
84
|
+
"message must be string when present"
|
85
|
+
end
|
86
|
+
end
|
87
|
+
|
88
|
+
# Get the current session store (with helpful error if not using test store)
|
89
|
+
def progress_session_store
|
90
|
+
store = ActionMCP::Server.session_store
|
91
|
+
unless store.respond_to?(:notifications_for_token)
|
92
|
+
raise "Session store #{store.class} does not support notification tracking. " \
|
93
|
+
"Use TestSessionStore for progress notification tests."
|
94
|
+
end
|
95
|
+
store
|
96
|
+
end
|
97
|
+
|
98
|
+
private
|
99
|
+
|
100
|
+
def get_progress_notifications(token)
|
101
|
+
progress_session_store.notifications_for_token(token)
|
102
|
+
end
|
103
|
+
end
|
104
|
+
end
|
105
|
+
end
|
@@ -0,0 +1,130 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module ActionMCP
|
4
|
+
module TestHelper
|
5
|
+
module SessionStoreAssertions
|
6
|
+
# Server session store assertions
|
7
|
+
def assert_session_created(session_id, message = nil)
|
8
|
+
assert server_session_store.session_created?(session_id),
|
9
|
+
message || "Expected session #{session_id} to have been created"
|
10
|
+
end
|
11
|
+
|
12
|
+
def assert_session_not_created(session_id, message = nil)
|
13
|
+
assert_not server_session_store.session_created?(session_id),
|
14
|
+
message || "Expected session #{session_id} not to have been created"
|
15
|
+
end
|
16
|
+
|
17
|
+
def assert_session_loaded(session_id, message = nil)
|
18
|
+
assert server_session_store.session_loaded?(session_id),
|
19
|
+
message || "Expected session #{session_id} to have been loaded"
|
20
|
+
end
|
21
|
+
|
22
|
+
def assert_session_not_loaded(session_id, message = nil)
|
23
|
+
assert_not server_session_store.session_loaded?(session_id),
|
24
|
+
message || "Expected session #{session_id} not to have been loaded"
|
25
|
+
end
|
26
|
+
|
27
|
+
def assert_session_saved(session_id, message = nil)
|
28
|
+
assert server_session_store.session_saved?(session_id),
|
29
|
+
message || "Expected session #{session_id} to have been saved"
|
30
|
+
end
|
31
|
+
|
32
|
+
def assert_session_not_saved(session_id, message = nil)
|
33
|
+
assert_not server_session_store.session_saved?(session_id),
|
34
|
+
message || "Expected session #{session_id} not to have been saved"
|
35
|
+
end
|
36
|
+
|
37
|
+
def assert_session_deleted(session_id, message = nil)
|
38
|
+
assert server_session_store.session_deleted?(session_id),
|
39
|
+
message || "Expected session #{session_id} to have been deleted"
|
40
|
+
end
|
41
|
+
|
42
|
+
def assert_session_not_deleted(session_id, message = nil)
|
43
|
+
assert_not server_session_store.session_deleted?(session_id),
|
44
|
+
message || "Expected session #{session_id} not to have been deleted"
|
45
|
+
end
|
46
|
+
|
47
|
+
def assert_session_operation_count(expected, type = nil, message = nil)
|
48
|
+
actual = server_session_store.operation_count(type)
|
49
|
+
type_desc = type ? " of type #{type}" : ""
|
50
|
+
assert_equal expected, actual,
|
51
|
+
message || "Expected #{expected} session operations#{type_desc}, got #{actual}"
|
52
|
+
end
|
53
|
+
|
54
|
+
# Client session store assertions
|
55
|
+
def assert_client_session_saved(session_id, message = nil)
|
56
|
+
assert client_session_store.session_saved?(session_id),
|
57
|
+
message || "Expected client session #{session_id} to have been saved"
|
58
|
+
end
|
59
|
+
|
60
|
+
def assert_client_session_not_saved(session_id, message = nil)
|
61
|
+
assert_not client_session_store.session_saved?(session_id),
|
62
|
+
message || "Expected client session #{session_id} not to have been saved"
|
63
|
+
end
|
64
|
+
|
65
|
+
def assert_client_session_loaded(session_id, message = nil)
|
66
|
+
assert client_session_store.session_loaded?(session_id),
|
67
|
+
message || "Expected client session #{session_id} to have been loaded"
|
68
|
+
end
|
69
|
+
|
70
|
+
def assert_client_session_not_loaded(session_id, message = nil)
|
71
|
+
assert_not client_session_store.session_loaded?(session_id),
|
72
|
+
message || "Expected client session #{session_id} not to have been loaded"
|
73
|
+
end
|
74
|
+
|
75
|
+
def assert_client_session_updated(session_id, message = nil)
|
76
|
+
assert client_session_store.session_updated?(session_id),
|
77
|
+
message || "Expected client session #{session_id} to have been updated"
|
78
|
+
end
|
79
|
+
|
80
|
+
def assert_client_session_not_updated(session_id, message = nil)
|
81
|
+
assert_not client_session_store.session_updated?(session_id),
|
82
|
+
message || "Expected client session #{session_id} not to have been updated"
|
83
|
+
end
|
84
|
+
|
85
|
+
def assert_client_session_deleted(session_id, message = nil)
|
86
|
+
assert client_session_store.session_deleted?(session_id),
|
87
|
+
message || "Expected client session #{session_id} to have been deleted"
|
88
|
+
end
|
89
|
+
|
90
|
+
def assert_client_session_not_deleted(session_id, message = nil)
|
91
|
+
assert_not client_session_store.session_deleted?(session_id),
|
92
|
+
message || "Expected client session #{session_id} not to have been deleted"
|
93
|
+
end
|
94
|
+
|
95
|
+
def assert_client_session_operation_count(expected, type = nil, message = nil)
|
96
|
+
actual = client_session_store.operation_count(type)
|
97
|
+
type_desc = type ? " of type #{type}" : ""
|
98
|
+
assert_equal expected, actual,
|
99
|
+
message || "Expected #{expected} client session operations#{type_desc}, got #{actual}"
|
100
|
+
end
|
101
|
+
|
102
|
+
def assert_client_session_data_includes(session_id, expected_data, message = nil)
|
103
|
+
saved_data = client_session_store.last_saved_data(session_id)
|
104
|
+
assert saved_data, "No saved data found for session #{session_id}"
|
105
|
+
|
106
|
+
expected_data.each do |key, value|
|
107
|
+
assert_equal value, saved_data[key],
|
108
|
+
message || "Expected session #{session_id} data to include #{key}: #{value}"
|
109
|
+
end
|
110
|
+
end
|
111
|
+
|
112
|
+
private
|
113
|
+
|
114
|
+
def server_session_store
|
115
|
+
store = ActionMCP::Server.session_store
|
116
|
+
raise "Server session store is not a TestSessionStore" unless store.is_a?(ActionMCP::Server::TestSessionStore)
|
117
|
+
store
|
118
|
+
end
|
119
|
+
|
120
|
+
def client_session_store
|
121
|
+
# This would need to be set by the test or could use a thread-local variable
|
122
|
+
# For now, we'll assume it's available as an instance variable
|
123
|
+
store = @client_session_store || Thread.current[:test_client_session_store]
|
124
|
+
raise "Client session store not set. Set @client_session_store or Thread.current[:test_client_session_store]" unless store
|
125
|
+
raise "Client session store is not a TestSessionStore" unless store.is_a?(ActionMCP::Client::TestSessionStore)
|
126
|
+
store
|
127
|
+
end
|
128
|
+
end
|
129
|
+
end
|
130
|
+
end
|
@@ -1,6 +1,8 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
3
|
require "active_support/testing/assertions"
|
4
|
+
require_relative "test_helper/session_store_assertions"
|
5
|
+
require_relative "test_helper/progress_notification_assertions"
|
4
6
|
|
5
7
|
module ActionMCP
|
6
8
|
#---------------------------------------------------------------------------
|
@@ -23,6 +25,8 @@ module ActionMCP
|
|
23
25
|
#---------------------------------------------------------------------------
|
24
26
|
module TestHelper
|
25
27
|
include ActiveSupport::Testing::Assertions
|
28
|
+
include SessionStoreAssertions
|
29
|
+
include ProgressNotificationAssertions
|
26
30
|
|
27
31
|
# ──── Registry assertions ────────────────────────────────────────────────
|
28
32
|
def assert_mcp_tool_findable(name, msg = nil)
|
data/lib/action_mcp/tool.rb
CHANGED
@@ -7,6 +7,7 @@ module ActionMCP
|
|
7
7
|
# Tools are registered automatically in the ToolsRegistry unless marked as abstract.
|
8
8
|
class Tool < Capability
|
9
9
|
include ActionMCP::Callbacks
|
10
|
+
include ActionMCP::CurrentHelpers
|
10
11
|
# --------------------------------------------------------------------------
|
11
12
|
# Class Attributes for Tool Metadata and Schema
|
12
13
|
# --------------------------------------------------------------------------
|
data/lib/action_mcp/version.rb
CHANGED
data/lib/action_mcp.rb
CHANGED
@@ -23,6 +23,10 @@ module ActionMcp
|
|
23
23
|
def create_mcp_profile_file
|
24
24
|
template "mcp.yml", File.join("config", "mcp.yml")
|
25
25
|
end
|
26
|
+
|
27
|
+
def create_application_gateway_file
|
28
|
+
template "application_gateway.rb", File.join("app/mcp", "application_gateway.rb")
|
29
|
+
end
|
26
30
|
end
|
27
31
|
end
|
28
32
|
end
|
@@ -0,0 +1,40 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
class ApplicationGateway < ActionMCP::Gateway
|
4
|
+
# Specify what attributes identify a connection
|
5
|
+
# Multiple identifiers can be used (e.g., user, account, organization)
|
6
|
+
identified_by :user
|
7
|
+
|
8
|
+
protected
|
9
|
+
|
10
|
+
# Override this method to implement your authentication logic
|
11
|
+
# Must return a hash with keys matching the identified_by attributes
|
12
|
+
# or raise ActionMCP::UnauthorizedError
|
13
|
+
def authenticate!
|
14
|
+
# Example using JWT:
|
15
|
+
token = extract_bearer_token
|
16
|
+
raise ActionMCP::UnauthorizedError, "Missing token" unless token
|
17
|
+
|
18
|
+
payload = ActionMCP::JwtDecoder.decode(token)
|
19
|
+
user = resolve_user(payload)
|
20
|
+
|
21
|
+
raise ActionMCP::UnauthorizedError, "Unauthorized" unless user
|
22
|
+
|
23
|
+
# Return a hash with all identified_by attributes
|
24
|
+
{ user: user }
|
25
|
+
rescue ActionMCP::JwtDecoder::DecodeError => e
|
26
|
+
raise ActionMCP::UnauthorizedError, e.message
|
27
|
+
end
|
28
|
+
|
29
|
+
private
|
30
|
+
|
31
|
+
# Example method to resolve user from JWT payload
|
32
|
+
def resolve_user(payload)
|
33
|
+
return nil unless payload.is_a?(Hash)
|
34
|
+
user_id = payload["user_id"] || payload["sub"]
|
35
|
+
return nil unless user_id
|
36
|
+
|
37
|
+
# Replace with your User model lookup
|
38
|
+
User.find_by(id: user_id)
|
39
|
+
end
|
40
|
+
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: actionmcp
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.52.1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Abdelkader Boudih
|
@@ -93,6 +93,20 @@ dependencies:
|
|
93
93
|
- - "~>"
|
94
94
|
- !ruby/object:Gem::Version
|
95
95
|
version: '2.6'
|
96
|
+
- !ruby/object:Gem::Dependency
|
97
|
+
name: jwt
|
98
|
+
requirement: !ruby/object:Gem::Requirement
|
99
|
+
requirements:
|
100
|
+
- - "~>"
|
101
|
+
- !ruby/object:Gem::Version
|
102
|
+
version: '2.10'
|
103
|
+
type: :runtime
|
104
|
+
prerelease: false
|
105
|
+
version_requirements: !ruby/object:Gem::Requirement
|
106
|
+
requirements:
|
107
|
+
- - "~>"
|
108
|
+
- !ruby/object:Gem::Version
|
109
|
+
version: '2.10'
|
96
110
|
description: It offers base classes and helpers for creating MCP applications, making
|
97
111
|
it easier to integrate your Ruby/Rails application with the MCP standard
|
98
112
|
email:
|
@@ -123,6 +137,7 @@ files:
|
|
123
137
|
- lib/action_mcp/callbacks.rb
|
124
138
|
- lib/action_mcp/capability.rb
|
125
139
|
- lib/action_mcp/client.rb
|
140
|
+
- lib/action_mcp/client/active_record_session_store.rb
|
126
141
|
- lib/action_mcp/client/base.rb
|
127
142
|
- lib/action_mcp/client/blueprint.rb
|
128
143
|
- lib/action_mcp/client/catalog.rb
|
@@ -137,11 +152,14 @@ files:
|
|
137
152
|
- lib/action_mcp/client/roots.rb
|
138
153
|
- lib/action_mcp/client/server.rb
|
139
154
|
- lib/action_mcp/client/session_store.rb
|
155
|
+
- lib/action_mcp/client/session_store_factory.rb
|
140
156
|
- lib/action_mcp/client/sse_client.rb
|
141
157
|
- lib/action_mcp/client/streamable_http_transport.rb
|
158
|
+
- lib/action_mcp/client/test_session_store.rb
|
142
159
|
- lib/action_mcp/client/toolbox.rb
|
143
160
|
- lib/action_mcp/client/tools.rb
|
144
161
|
- lib/action_mcp/client/transport.rb
|
162
|
+
- lib/action_mcp/client/volatile_session_store.rb
|
145
163
|
- lib/action_mcp/configuration.rb
|
146
164
|
- lib/action_mcp/console_detector.rb
|
147
165
|
- lib/action_mcp/content.rb
|
@@ -150,13 +168,17 @@ files:
|
|
150
168
|
- lib/action_mcp/content/image.rb
|
151
169
|
- lib/action_mcp/content/resource.rb
|
152
170
|
- lib/action_mcp/content/text.rb
|
171
|
+
- lib/action_mcp/current.rb
|
172
|
+
- lib/action_mcp/current_helpers.rb
|
153
173
|
- lib/action_mcp/engine.rb
|
174
|
+
- lib/action_mcp/gateway.rb
|
154
175
|
- lib/action_mcp/gem_version.rb
|
155
176
|
- lib/action_mcp/instrumentation/controller_runtime.rb
|
156
177
|
- lib/action_mcp/instrumentation/instrumentation.rb
|
157
178
|
- lib/action_mcp/instrumentation/resource_instrumentation.rb
|
158
179
|
- lib/action_mcp/integer_array.rb
|
159
180
|
- lib/action_mcp/json_rpc_handler_base.rb
|
181
|
+
- lib/action_mcp/jwt_decoder.rb
|
160
182
|
- lib/action_mcp/log_subscriber.rb
|
161
183
|
- lib/action_mcp/logging.rb
|
162
184
|
- lib/action_mcp/prompt.rb
|
@@ -169,6 +191,7 @@ files:
|
|
169
191
|
- lib/action_mcp/resource_template.rb
|
170
192
|
- lib/action_mcp/resource_templates_registry.rb
|
171
193
|
- lib/action_mcp/server.rb
|
194
|
+
- lib/action_mcp/server/base_messaging.rb
|
172
195
|
- lib/action_mcp/server/capabilities.rb
|
173
196
|
- lib/action_mcp/server/configuration.rb
|
174
197
|
- lib/action_mcp/server/error_aware.rb
|
@@ -182,9 +205,11 @@ files:
|
|
182
205
|
- lib/action_mcp/server/prompts.rb
|
183
206
|
- lib/action_mcp/server/registry_management.rb
|
184
207
|
- lib/action_mcp/server/resources.rb
|
208
|
+
- lib/action_mcp/server/response_collector.rb
|
185
209
|
- lib/action_mcp/server/roots.rb
|
186
210
|
- lib/action_mcp/server/sampling.rb
|
187
211
|
- lib/action_mcp/server/sampling_request.rb
|
212
|
+
- lib/action_mcp/server/session_store.rb
|
188
213
|
- lib/action_mcp/server/simple_pub_sub.rb
|
189
214
|
- lib/action_mcp/server/solid_cable_adapter.rb
|
190
215
|
- lib/action_mcp/server/tools.rb
|
@@ -193,6 +218,8 @@ files:
|
|
193
218
|
- lib/action_mcp/string_array.rb
|
194
219
|
- lib/action_mcp/tagged_stream_logging.rb
|
195
220
|
- lib/action_mcp/test_helper.rb
|
221
|
+
- lib/action_mcp/test_helper/progress_notification_assertions.rb
|
222
|
+
- lib/action_mcp/test_helper/session_store_assertions.rb
|
196
223
|
- lib/action_mcp/tool.rb
|
197
224
|
- lib/action_mcp/tool_response.rb
|
198
225
|
- lib/action_mcp/tools_registry.rb
|
@@ -203,6 +230,7 @@ files:
|
|
203
230
|
- lib/generators/action_mcp/config/config_generator.rb
|
204
231
|
- lib/generators/action_mcp/config/templates/mcp.yml
|
205
232
|
- lib/generators/action_mcp/install/install_generator.rb
|
233
|
+
- lib/generators/action_mcp/install/templates/application_gateway.rb
|
206
234
|
- lib/generators/action_mcp/install/templates/application_mcp_prompt.rb
|
207
235
|
- lib/generators/action_mcp/install/templates/application_mcp_res_template.rb
|
208
236
|
- lib/generators/action_mcp/install/templates/application_mcp_tool.rb
|