actionmcp 0.31.1 → 0.33.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 (40) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +143 -5
  3. data/app/controllers/action_mcp/mcp_controller.rb +13 -17
  4. data/app/controllers/action_mcp/messages_controller.rb +3 -1
  5. data/app/controllers/action_mcp/sse_controller.rb +22 -4
  6. data/app/controllers/action_mcp/unified_controller.rb +147 -52
  7. data/app/models/action_mcp/session/message.rb +1 -0
  8. data/app/models/action_mcp/session/sse_event.rb +55 -0
  9. data/app/models/action_mcp/session.rb +235 -12
  10. data/app/models/concerns/mcp_console_helpers.rb +68 -0
  11. data/app/models/concerns/mcp_message_inspect.rb +73 -0
  12. data/config/routes.rb +4 -2
  13. data/db/migrate/20250329120300_add_registries_to_sessions.rb +9 -0
  14. data/db/migrate/20250329150312_create_action_mcp_sse_events.rb +16 -0
  15. data/lib/action_mcp/capability.rb +16 -0
  16. data/lib/action_mcp/configuration.rb +16 -4
  17. data/lib/action_mcp/console_detector.rb +12 -0
  18. data/lib/action_mcp/engine.rb +3 -0
  19. data/lib/action_mcp/json_rpc_handler_base.rb +1 -1
  20. data/lib/action_mcp/resource_template.rb +11 -0
  21. data/lib/action_mcp/server/capabilities.rb +28 -22
  22. data/lib/action_mcp/server/configuration.rb +63 -0
  23. data/lib/action_mcp/server/json_rpc_handler.rb +35 -9
  24. data/lib/action_mcp/server/notifications.rb +14 -5
  25. data/lib/action_mcp/server/prompts.rb +18 -5
  26. data/lib/action_mcp/server/registry_management.rb +32 -0
  27. data/lib/action_mcp/server/resources.rb +3 -2
  28. data/lib/action_mcp/server/simple_pub_sub.rb +145 -0
  29. data/lib/action_mcp/server/solid_cable_adapter.rb +222 -0
  30. data/lib/action_mcp/server/tools.rb +50 -6
  31. data/lib/action_mcp/server.rb +84 -2
  32. data/lib/action_mcp/sse_listener.rb +6 -5
  33. data/lib/action_mcp/tagged_stream_logging.rb +47 -0
  34. data/lib/action_mcp/test_helper.rb +57 -34
  35. data/lib/action_mcp/tool.rb +45 -9
  36. data/lib/action_mcp/version.rb +1 -1
  37. data/lib/action_mcp.rb +4 -4
  38. data/lib/generators/action_mcp/config/config_generator.rb +29 -0
  39. data/lib/generators/action_mcp/config/templates/mcp.yml +36 -0
  40. metadata +23 -13
@@ -16,6 +16,7 @@ module ActionMCP
16
16
  # @return [Array<String>] The required properties of the tool.
17
17
  class_attribute :_schema_properties, instance_accessor: false, default: {}
18
18
  class_attribute :_required_properties, instance_accessor: false, default: []
19
+ class_attribute :_annotations, instance_accessor: false, default: {}
19
20
 
20
21
  # --------------------------------------------------------------------------
21
22
  # Tool Name and Description DSL
@@ -45,6 +46,29 @@ module ActionMCP
45
46
  def type
46
47
  :tool
47
48
  end
49
+
50
+ def annotate(key, value)
51
+ self._annotations = _annotations.merge(key.to_s => value)
52
+ end
53
+
54
+ # Convenience methods for common annotations
55
+ def destructive(enabled = true)
56
+ annotate(:destructive, enabled)
57
+ end
58
+
59
+ def read_only(enabled = true)
60
+ annotate(:readOnly, enabled)
61
+ end
62
+
63
+ # Return annotations based on protocol version
64
+ def annotations_for_protocol(protocol_version = nil)
65
+ # Only include annotations for 2025+ protocols
66
+ if protocol_version.nil? || protocol_version == "2024-11-05"
67
+ {}
68
+ else
69
+ _annotations
70
+ end
71
+ end
48
72
  end
49
73
 
50
74
  # --------------------------------------------------------------------------
@@ -114,14 +138,21 @@ module ActionMCP
114
138
  # Returns a hash representation of the tool definition including its JSON Schema.
115
139
  #
116
140
  # @return [Hash] The tool definition.
117
- def self.to_h
141
+ def self.to_h(protocol_version: nil)
118
142
  schema = { type: "object", properties: _schema_properties }
119
143
  schema[:required] = _required_properties if _required_properties.any?
120
- {
144
+
145
+ result = {
121
146
  name: tool_name,
122
147
  description: description.presence,
123
148
  inputSchema: schema
124
149
  }.compact
150
+
151
+ # Add annotations if protocol supports them
152
+ annotations = annotations_for_protocol(protocol_version)
153
+ result[:annotations] = annotations if annotations.any?
154
+
155
+ result
125
156
  end
126
157
 
127
158
  # --------------------------------------------------------------------------
@@ -131,24 +162,29 @@ module ActionMCP
131
162
  # Public entry point for executing the tool
132
163
  # Returns an array of Content objects collected from render calls
133
164
  def call
134
- @response = ToolResponse.new # Create a new response for each invocation
165
+ @response = ToolResponse.new
166
+ performed = false # ← track execution
135
167
 
136
- # Check validations before proceeding
137
168
  if valid?
138
169
  begin
139
170
  run_callbacks :perform do
140
- perform # Invoke the subclass-specific logic if valid
171
+ performed = true # set if we reach the block
172
+ perform
141
173
  end
142
174
  rescue StandardError => e
143
- # Handle exceptions during execution
144
175
  @response.mark_as_error!(:internal_error, message: e.message)
145
176
  end
146
177
  else
147
- # Handle validation failure
148
- @response.mark_as_error!(:invalid_request, message: "Invalid input", data: errors.full_messages)
178
+ @response.mark_as_error!(:invalid_request,
179
+ message: "Invalid input",
180
+ data: errors.full_messages)
149
181
  end
150
182
 
151
- @response # Return the response with collected content
183
+ # If callbacks halted execution (`performed` still false) and
184
+ # nothing else marked an error, surface it as invalid_request.
185
+ @response.mark_as_error!(:invalid_request, message: "Aborted by callback") if !performed && !@response.error?
186
+
187
+ @response
152
188
  end
153
189
 
154
190
  def inspect
@@ -2,7 +2,7 @@
2
2
 
3
3
  require_relative "gem_version"
4
4
  module ActionMCP
5
- VERSION = "0.31.1"
5
+ VERSION = "0.33.0"
6
6
 
7
7
  class << self
8
8
  alias version gem_version
data/lib/action_mcp.rb CHANGED
@@ -34,11 +34,11 @@ module ActionMCP
34
34
  require_relative "action_mcp/version"
35
35
  require_relative "action_mcp/client"
36
36
  include Logging
37
- PROTOCOL_VERSION = "2024-11-05"
38
-
37
+ PROTOCOL_VERSION = "2024-11-05" # Default version
38
+ CURRENT_VERSION = "2025-03-26" # Current version for the /mcp endpoint
39
+ SUPPORTED_VERSIONS = %w[2024-11-05 2025-03-26].freeze
39
40
  class << self
40
- attr_accessor :server
41
-
41
+ delegate :server, to: "ActionMCP::Server"
42
42
  # Returns the configuration instance.
43
43
  #
44
44
  # @return [Configuration] the configuration instance
@@ -0,0 +1,29 @@
1
+ # frozen_string_literal: true
2
+
3
+ module ActionMCP
4
+ module Generators
5
+ class ConfigGenerator < Rails::Generators::Base
6
+ source_root File.expand_path("templates", __dir__)
7
+
8
+ desc "Creates ActionMCP configuration file (config/mcp.yml)"
9
+
10
+ def create_mcp_yml
11
+ template "mcp.yml", "config/mcp.yml"
12
+ end
13
+
14
+ def show_instructions
15
+ say "ActionMCP configuration file created at config/mcp.yml"
16
+ say "You can customize your PubSub adapters and other settings in this file."
17
+ say ""
18
+ say "Available adapters:"
19
+ say " - simple : In-memory adapter for development"
20
+ say " - test : Test adapter"
21
+ say " - solid_cable : Database-backed adapter (requires solid_cable gem)"
22
+ say " - redis : Redis-backed adapter (requires redis gem)"
23
+ say ""
24
+ say "Example usage:"
25
+ say " rails g action_mcp:install # Main generator"
26
+ end
27
+ end
28
+ end
29
+ end
@@ -0,0 +1,36 @@
1
+ # ActionMCP Configuration
2
+ # This file contains configuration for the ActionMCP pub/sub system.
3
+ # Different environments can use different adapters.
4
+
5
+ development:
6
+ # In-memory adapter for development
7
+ adapter: simple
8
+ # Thread pool configuration (optional)
9
+ # min_threads: 5 # Minimum number of threads in the pool
10
+ # max_threads: 10 # Maximum number of threads in the pool
11
+ # max_queue: 100 # Maximum number of tasks that can be queued
12
+
13
+ test:
14
+ # Test adapter for testing
15
+ adapter: test
16
+
17
+ production:
18
+ # Choose one of the following adapters:
19
+
20
+ # 1. Database-backed adapter (recommended)
21
+ adapter: solid_cable
22
+ polling_interval: 0.5.seconds
23
+ # connects_to: cable # Optional: specify a different database connection
24
+
25
+ # Thread pool configuration (optional)
26
+ min_threads: 10 # Minimum number of threads in the pool
27
+ max_threads: 20 # Maximum number of threads in the pool
28
+ max_queue: 500 # Maximum number of tasks that can be queued
29
+
30
+ # 2. Redis-backed adapter (alternative)
31
+ # adapter: redis
32
+ # url: <%= ENV.fetch("REDIS_URL") { "redis://localhost:6379/1" } %>
33
+ # channel_prefix: <%= Rails.application.class.module_parent_name.underscore %>_production
34
+ # min_threads: 10 # Minimum number of threads in the pool
35
+ # max_threads: 20 # Maximum number of threads in the pool
36
+ # max_queue: 500 # Maximum number of tasks that can be queued
metadata CHANGED
@@ -1,17 +1,16 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: actionmcp
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.31.1
4
+ version: 0.33.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Abdelkader Boudih
8
- autorequire:
9
8
  bindir: exe
10
9
  cert_chain: []
11
- date: 2025-04-14 00:00:00.000000000 Z
10
+ date: 1980-01-02 00:00:00.000000000 Z
12
11
  dependencies:
13
12
  - !ruby/object:Gem::Dependency
14
- name: actioncable
13
+ name: activerecord
15
14
  requirement: !ruby/object:Gem::Requirement
16
15
  requirements:
17
16
  - - ">="
@@ -25,19 +24,19 @@ dependencies:
25
24
  - !ruby/object:Gem::Version
26
25
  version: 8.0.1
27
26
  - !ruby/object:Gem::Dependency
28
- name: activerecord
27
+ name: jsonrpc-rails
29
28
  requirement: !ruby/object:Gem::Requirement
30
29
  requirements:
31
30
  - - ">="
32
31
  - !ruby/object:Gem::Version
33
- version: 8.0.1
32
+ version: 0.5.1
34
33
  type: :runtime
35
34
  prerelease: false
36
35
  version_requirements: !ruby/object:Gem::Requirement
37
36
  requirements:
38
37
  - - ">="
39
38
  - !ruby/object:Gem::Version
40
- version: 8.0.1
39
+ version: 0.5.1
41
40
  - !ruby/object:Gem::Dependency
42
41
  name: multi_json
43
42
  requirement: !ruby/object:Gem::Requirement
@@ -81,19 +80,19 @@ dependencies:
81
80
  - !ruby/object:Gem::Version
82
81
  version: '2.6'
83
82
  - !ruby/object:Gem::Dependency
84
- name: jsonrpc-rails
83
+ name: concurrent-ruby
85
84
  requirement: !ruby/object:Gem::Requirement
86
85
  requirements:
87
86
  - - ">="
88
87
  - !ruby/object:Gem::Version
89
- version: '0'
88
+ version: 1.3.1
90
89
  type: :runtime
91
90
  prerelease: false
92
91
  version_requirements: !ruby/object:Gem::Requirement
93
92
  requirements:
94
93
  - - ">="
95
94
  - !ruby/object:Gem::Version
96
- version: '0'
95
+ version: 1.3.1
97
96
  description: It offers base classes and helpers for creating MCP applications, making
98
97
  it easier to integrate your Ruby/Rails application with the MCP standard
99
98
  email:
@@ -115,7 +114,10 @@ files:
115
114
  - app/models/action_mcp/session.rb
116
115
  - app/models/action_mcp/session/message.rb
117
116
  - app/models/action_mcp/session/resource.rb
117
+ - app/models/action_mcp/session/sse_event.rb
118
118
  - app/models/action_mcp/session/subscription.rb
119
+ - app/models/concerns/mcp_console_helpers.rb
120
+ - app/models/concerns/mcp_message_inspect.rb
119
121
  - config/routes.rb
120
122
  - db/migrate/20250308122801_create_action_mcp_sessions.rb
121
123
  - db/migrate/20250314230152_add_is_ping_to_session_message.rb
@@ -123,6 +125,8 @@ files:
123
125
  - db/migrate/20250316005649_create_action_mcp_session_resources.rb
124
126
  - db/migrate/20250324203409_remove_session_message_text.rb
125
127
  - db/migrate/20250327124131_add_sse_event_counter_to_action_mcp_sessions.rb
128
+ - db/migrate/20250329120300_add_registries_to_sessions.rb
129
+ - db/migrate/20250329150312_create_action_mcp_sse_events.rb
126
130
  - exe/actionmcp_cli
127
131
  - lib/action_mcp.rb
128
132
  - lib/action_mcp/base_response.rb
@@ -147,6 +151,7 @@ files:
147
151
  - lib/action_mcp/client/toolbox.rb
148
152
  - lib/action_mcp/client/tools.rb
149
153
  - lib/action_mcp/configuration.rb
154
+ - lib/action_mcp/console_detector.rb
150
155
  - lib/action_mcp/content.rb
151
156
  - lib/action_mcp/content/audio.rb
152
157
  - lib/action_mcp/content/image.rb
@@ -172,18 +177,23 @@ files:
172
177
  - lib/action_mcp/resource_templates_registry.rb
173
178
  - lib/action_mcp/server.rb
174
179
  - lib/action_mcp/server/capabilities.rb
180
+ - lib/action_mcp/server/configuration.rb
175
181
  - lib/action_mcp/server/json_rpc_handler.rb
176
182
  - lib/action_mcp/server/messaging.rb
177
183
  - lib/action_mcp/server/notifications.rb
178
184
  - lib/action_mcp/server/prompts.rb
185
+ - lib/action_mcp/server/registry_management.rb
179
186
  - lib/action_mcp/server/resources.rb
180
187
  - lib/action_mcp/server/roots.rb
181
188
  - lib/action_mcp/server/sampling.rb
182
189
  - lib/action_mcp/server/sampling_request.rb
190
+ - lib/action_mcp/server/simple_pub_sub.rb
191
+ - lib/action_mcp/server/solid_cable_adapter.rb
183
192
  - lib/action_mcp/server/tools.rb
184
193
  - lib/action_mcp/server/transport_handler.rb
185
194
  - lib/action_mcp/sse_listener.rb
186
195
  - lib/action_mcp/string_array.rb
196
+ - lib/action_mcp/tagged_stream_logging.rb
187
197
  - lib/action_mcp/test_helper.rb
188
198
  - lib/action_mcp/tool.rb
189
199
  - lib/action_mcp/tool_response.rb
@@ -192,6 +202,8 @@ files:
192
202
  - lib/action_mcp/uri_ambiguity_checker.rb
193
203
  - lib/action_mcp/version.rb
194
204
  - lib/actionmcp.rb
205
+ - lib/generators/action_mcp/config/config_generator.rb
206
+ - lib/generators/action_mcp/config/templates/mcp.yml
195
207
  - lib/generators/action_mcp/install/install_generator.rb
196
208
  - lib/generators/action_mcp/install/templates/application_mcp_prompt.rb
197
209
  - lib/generators/action_mcp/install/templates/application_mcp_res_template.rb
@@ -212,7 +224,6 @@ metadata:
212
224
  source_code_uri: https://github.com/seuros/action_mcp
213
225
  changelog_uri: https://github.com/seuros/action_mcp/blob/master/CHANGELOG.md
214
226
  rubygems_mfa_required: 'true'
215
- post_install_message:
216
227
  rdoc_options: []
217
228
  require_paths:
218
229
  - lib
@@ -227,8 +238,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
227
238
  - !ruby/object:Gem::Version
228
239
  version: '0'
229
240
  requirements: []
230
- rubygems_version: 3.5.22
231
- signing_key:
241
+ rubygems_version: 3.6.7
232
242
  specification_version: 4
233
243
  summary: Provides essential tooling for building Model Context Protocol (MCP) capable
234
244
  servers