actionmcp 0.50.13 → 0.52.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.
- checksums.yaml +4 -4
- data/README.md +83 -0
- data/app/controllers/action_mcp/application_controller.rb +12 -6
- data/app/models/action_mcp/session.rb +5 -1
- data/lib/action_mcp/client/base.rb +88 -82
- data/lib/action_mcp/client/json_rpc_handler.rb +42 -5
- data/lib/action_mcp/client/session_store.rb +231 -0
- data/lib/action_mcp/client/streamable_http_transport.rb +291 -0
- data/lib/action_mcp/client/transport.rb +107 -0
- data/lib/action_mcp/client.rb +45 -5
- 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/capabilities.rb +23 -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 +30 -6
@@ -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,14 +1,13 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: actionmcp
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.52.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Abdelkader Boudih
|
8
|
-
autorequire:
|
9
8
|
bindir: exe
|
10
9
|
cert_chain: []
|
11
|
-
date:
|
10
|
+
date: 1980-01-02 00:00:00.000000000 Z
|
12
11
|
dependencies:
|
13
12
|
- !ruby/object:Gem::Dependency
|
14
13
|
name: activerecord
|
@@ -94,6 +93,20 @@ dependencies:
|
|
94
93
|
- - "~>"
|
95
94
|
- !ruby/object:Gem::Version
|
96
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'
|
97
110
|
description: It offers base classes and helpers for creating MCP applications, making
|
98
111
|
it easier to integrate your Ruby/Rails application with the MCP standard
|
99
112
|
email:
|
@@ -137,9 +150,12 @@ files:
|
|
137
150
|
- lib/action_mcp/client/resources.rb
|
138
151
|
- lib/action_mcp/client/roots.rb
|
139
152
|
- lib/action_mcp/client/server.rb
|
153
|
+
- lib/action_mcp/client/session_store.rb
|
140
154
|
- lib/action_mcp/client/sse_client.rb
|
155
|
+
- lib/action_mcp/client/streamable_http_transport.rb
|
141
156
|
- lib/action_mcp/client/toolbox.rb
|
142
157
|
- lib/action_mcp/client/tools.rb
|
158
|
+
- lib/action_mcp/client/transport.rb
|
143
159
|
- lib/action_mcp/configuration.rb
|
144
160
|
- lib/action_mcp/console_detector.rb
|
145
161
|
- lib/action_mcp/content.rb
|
@@ -148,13 +164,17 @@ files:
|
|
148
164
|
- lib/action_mcp/content/image.rb
|
149
165
|
- lib/action_mcp/content/resource.rb
|
150
166
|
- lib/action_mcp/content/text.rb
|
167
|
+
- lib/action_mcp/current.rb
|
168
|
+
- lib/action_mcp/current_helpers.rb
|
151
169
|
- lib/action_mcp/engine.rb
|
170
|
+
- lib/action_mcp/gateway.rb
|
152
171
|
- lib/action_mcp/gem_version.rb
|
153
172
|
- lib/action_mcp/instrumentation/controller_runtime.rb
|
154
173
|
- lib/action_mcp/instrumentation/instrumentation.rb
|
155
174
|
- lib/action_mcp/instrumentation/resource_instrumentation.rb
|
156
175
|
- lib/action_mcp/integer_array.rb
|
157
176
|
- lib/action_mcp/json_rpc_handler_base.rb
|
177
|
+
- lib/action_mcp/jwt_decoder.rb
|
158
178
|
- lib/action_mcp/log_subscriber.rb
|
159
179
|
- lib/action_mcp/logging.rb
|
160
180
|
- lib/action_mcp/prompt.rb
|
@@ -167,6 +187,7 @@ files:
|
|
167
187
|
- lib/action_mcp/resource_template.rb
|
168
188
|
- lib/action_mcp/resource_templates_registry.rb
|
169
189
|
- lib/action_mcp/server.rb
|
190
|
+
- lib/action_mcp/server/base_messaging.rb
|
170
191
|
- lib/action_mcp/server/capabilities.rb
|
171
192
|
- lib/action_mcp/server/configuration.rb
|
172
193
|
- lib/action_mcp/server/error_aware.rb
|
@@ -180,9 +201,11 @@ files:
|
|
180
201
|
- lib/action_mcp/server/prompts.rb
|
181
202
|
- lib/action_mcp/server/registry_management.rb
|
182
203
|
- lib/action_mcp/server/resources.rb
|
204
|
+
- lib/action_mcp/server/response_collector.rb
|
183
205
|
- lib/action_mcp/server/roots.rb
|
184
206
|
- lib/action_mcp/server/sampling.rb
|
185
207
|
- lib/action_mcp/server/sampling_request.rb
|
208
|
+
- lib/action_mcp/server/session_store.rb
|
186
209
|
- lib/action_mcp/server/simple_pub_sub.rb
|
187
210
|
- lib/action_mcp/server/solid_cable_adapter.rb
|
188
211
|
- lib/action_mcp/server/tools.rb
|
@@ -191,6 +214,8 @@ files:
|
|
191
214
|
- lib/action_mcp/string_array.rb
|
192
215
|
- lib/action_mcp/tagged_stream_logging.rb
|
193
216
|
- lib/action_mcp/test_helper.rb
|
217
|
+
- lib/action_mcp/test_helper/progress_notification_assertions.rb
|
218
|
+
- lib/action_mcp/test_helper/session_store_assertions.rb
|
194
219
|
- lib/action_mcp/tool.rb
|
195
220
|
- lib/action_mcp/tool_response.rb
|
196
221
|
- lib/action_mcp/tools_registry.rb
|
@@ -201,6 +226,7 @@ files:
|
|
201
226
|
- lib/generators/action_mcp/config/config_generator.rb
|
202
227
|
- lib/generators/action_mcp/config/templates/mcp.yml
|
203
228
|
- lib/generators/action_mcp/install/install_generator.rb
|
229
|
+
- lib/generators/action_mcp/install/templates/application_gateway.rb
|
204
230
|
- lib/generators/action_mcp/install/templates/application_mcp_prompt.rb
|
205
231
|
- lib/generators/action_mcp/install/templates/application_mcp_res_template.rb
|
206
232
|
- lib/generators/action_mcp/install/templates/application_mcp_tool.rb
|
@@ -220,7 +246,6 @@ metadata:
|
|
220
246
|
source_code_uri: https://github.com/seuros/action_mcp
|
221
247
|
changelog_uri: https://github.com/seuros/action_mcp/blob/master/CHANGELOG.md
|
222
248
|
rubygems_mfa_required: 'true'
|
223
|
-
post_install_message:
|
224
249
|
rdoc_options: []
|
225
250
|
require_paths:
|
226
251
|
- lib
|
@@ -235,8 +260,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
235
260
|
- !ruby/object:Gem::Version
|
236
261
|
version: '0'
|
237
262
|
requirements: []
|
238
|
-
rubygems_version: 3.
|
239
|
-
signing_key:
|
263
|
+
rubygems_version: 3.6.9
|
240
264
|
specification_version: 4
|
241
265
|
summary: Provides essential tooling for building Model Context Protocol (MCP) capable
|
242
266
|
servers
|