actionmcp 0.1.2 → 0.2.3

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 (51) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +133 -30
  3. data/Rakefile +0 -2
  4. data/exe/actionmcp_cli +221 -0
  5. data/lib/action_mcp/capability.rb +52 -0
  6. data/lib/action_mcp/client.rb +249 -0
  7. data/lib/action_mcp/configuration.rb +55 -1
  8. data/lib/action_mcp/content/audio.rb +9 -0
  9. data/lib/action_mcp/content/image.rb +9 -0
  10. data/lib/action_mcp/content/resource.rb +13 -0
  11. data/lib/action_mcp/content/text.rb +8 -1
  12. data/lib/action_mcp/content.rb +13 -3
  13. data/lib/action_mcp/engine.rb +34 -0
  14. data/lib/action_mcp/gem_version.rb +2 -2
  15. data/lib/action_mcp/integer_array.rb +17 -0
  16. data/lib/action_mcp/json_rpc/json_rpc_error.rb +22 -1
  17. data/lib/action_mcp/json_rpc/notification.rb +13 -6
  18. data/lib/action_mcp/json_rpc/request.rb +26 -2
  19. data/lib/action_mcp/json_rpc/response.rb +42 -31
  20. data/lib/action_mcp/json_rpc.rb +1 -7
  21. data/lib/action_mcp/json_rpc_handler.rb +106 -0
  22. data/lib/action_mcp/logging.rb +19 -0
  23. data/lib/action_mcp/prompt.rb +33 -45
  24. data/lib/action_mcp/prompts_registry.rb +32 -1
  25. data/lib/action_mcp/registry_base.rb +72 -40
  26. data/lib/action_mcp/renderable.rb +54 -0
  27. data/lib/action_mcp/resource.rb +5 -3
  28. data/lib/action_mcp/server.rb +10 -0
  29. data/lib/action_mcp/string_array.rb +14 -0
  30. data/lib/action_mcp/tool.rb +112 -102
  31. data/lib/action_mcp/tools_registry.rb +28 -3
  32. data/lib/action_mcp/transport/capabilities.rb +21 -0
  33. data/lib/action_mcp/transport/messaging.rb +20 -0
  34. data/lib/action_mcp/transport/prompts.rb +19 -0
  35. data/lib/action_mcp/transport/sse_client.rb +309 -0
  36. data/lib/action_mcp/transport/stdio_client.rb +117 -0
  37. data/lib/action_mcp/transport/tools.rb +20 -0
  38. data/lib/action_mcp/transport/transport_base.rb +125 -0
  39. data/lib/action_mcp/transport.rb +1 -238
  40. data/lib/action_mcp/transport_handler.rb +54 -0
  41. data/lib/action_mcp/version.rb +4 -5
  42. data/lib/action_mcp.rb +40 -27
  43. data/lib/generators/action_mcp/install/install_generator.rb +2 -0
  44. data/lib/generators/action_mcp/prompt/templates/prompt.rb.erb +3 -1
  45. data/lib/generators/action_mcp/tool/templates/tool.rb.erb +5 -1
  46. data/lib/tasks/action_mcp_tasks.rake +28 -5
  47. metadata +68 -10
  48. data/exe/action_mcp_stdio +0 -0
  49. data/lib/action_mcp/json_rpc/base.rb +0 -12
  50. data/lib/action_mcp/railtie.rb +0 -27
  51. data/lib/action_mcp/resources_bank.rb +0 -96
@@ -1,13 +1,17 @@
1
1
  # frozen_string_literal: true
2
2
 
3
+ # Template for generating new tools.
3
4
  class <%= class_name %> < ApplicationTool
5
+ # Set the tool name.
4
6
  tool_name "<%= tool_name %>"
5
7
  description "Calculate the sum of two numbers"
6
8
 
9
+ # Define input properties.
7
10
  property :a, type: "number", description: "First number", required: true
8
11
  property :b, type: "number", description: "Second number", required: true
9
12
 
13
+ # Implement the tool's logic here.
10
14
  def call
11
- a + b
15
+ render_text(a + b)
12
16
  end
13
17
  end
@@ -1,6 +1,29 @@
1
- # frozen_string_literal: true
1
+ namespace :action_mcp do
2
+ desc "List all tools with their names and descriptions"
3
+ task list_tools: :environment do
4
+ # Ensure Rails eager loads all classes
5
+ Rails.application.eager_load!
2
6
 
3
- # desc "Explaining what the task does"
4
- # task :action_mcp do
5
- # # Task goes here
6
- # end
7
+ puts "\e[34mACTION MCP TOOLS\e[0m" # Blue
8
+ puts "\e[34m---------------\e[0m" # Blue
9
+ ActionMCP::Tool.descendants.each do |tool|
10
+ puts "\e[34m#{tool.capability_name}:\e[0m #{tool.description}" # Blue name
11
+ end
12
+ end
13
+
14
+ desc "List all prompts with their names and descriptions"
15
+ task list_prompts: :environment do
16
+ # Ensure Rails eager loads all classes
17
+ Rails.application.eager_load!
18
+
19
+ puts "\e[32mACTION MCP PROMPTS\e[0m" # Red
20
+ puts "\e[32m-----------------\e[0m" # Red
21
+ ActionMCP::Prompt.descendants.each do |prompt|
22
+ puts "\e[32m#{prompt.capability_name}:\e[0m #{prompt.description}" # Red name
23
+ end
24
+ end
25
+
26
+ desc "List all tools and prompts with their names and descriptions"
27
+ task list: [ :list_tools, :list_prompts ] do
28
+ end
29
+ end
metadata CHANGED
@@ -1,16 +1,16 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: actionmcp
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.2
4
+ version: 0.2.3
5
5
  platform: ruby
6
6
  authors:
7
7
  - Abdelkader Boudih
8
8
  bindir: exe
9
9
  cert_chain: []
10
- date: 2025-02-14 00:00:00.000000000 Z
10
+ date: 2025-03-11 00:00:00.000000000 Z
11
11
  dependencies:
12
12
  - !ruby/object:Gem::Dependency
13
- name: activemodel
13
+ name: railties
14
14
  requirement: !ruby/object:Gem::Requirement
15
15
  requirements:
16
16
  - - ">="
@@ -24,7 +24,21 @@ dependencies:
24
24
  - !ruby/object:Gem::Version
25
25
  version: 8.0.1
26
26
  - !ruby/object:Gem::Dependency
27
- name: activesupport
27
+ name: activerecord
28
+ requirement: !ruby/object:Gem::Requirement
29
+ requirements:
30
+ - - ">="
31
+ - !ruby/object:Gem::Version
32
+ version: 8.0.1
33
+ type: :runtime
34
+ prerelease: false
35
+ version_requirements: !ruby/object:Gem::Requirement
36
+ requirements:
37
+ - - ">="
38
+ - !ruby/object:Gem::Version
39
+ version: 8.0.1
40
+ - !ruby/object:Gem::Dependency
41
+ name: actioncable
28
42
  requirement: !ruby/object:Gem::Requirement
29
43
  requirements:
30
44
  - - ">="
@@ -51,42 +65,84 @@ dependencies:
51
65
  - - ">="
52
66
  - !ruby/object:Gem::Version
53
67
  version: '0'
68
+ - !ruby/object:Gem::Dependency
69
+ name: faraday
70
+ requirement: !ruby/object:Gem::Requirement
71
+ requirements:
72
+ - - "~>"
73
+ - !ruby/object:Gem::Version
74
+ version: '2.0'
75
+ type: :runtime
76
+ prerelease: false
77
+ version_requirements: !ruby/object:Gem::Requirement
78
+ requirements:
79
+ - - "~>"
80
+ - !ruby/object:Gem::Version
81
+ version: '2.0'
82
+ - !ruby/object:Gem::Dependency
83
+ name: zeitwerk
84
+ requirement: !ruby/object:Gem::Requirement
85
+ requirements:
86
+ - - "~>"
87
+ - !ruby/object:Gem::Version
88
+ version: '2.6'
89
+ type: :runtime
90
+ prerelease: false
91
+ version_requirements: !ruby/object:Gem::Requirement
92
+ requirements:
93
+ - - "~>"
94
+ - !ruby/object:Gem::Version
95
+ version: '2.6'
54
96
  description: It offers base classes and helpers for creating MCP applications, making
55
97
  it easier to integrate your Ruby/Rails application with the MCP standard
56
98
  email:
57
99
  - terminale@gmail.com
58
100
  executables:
59
- - action_mcp_stdio
101
+ - actionmcp_cli
60
102
  extensions: []
61
103
  extra_rdoc_files: []
62
104
  files:
63
105
  - MIT-LICENSE
64
106
  - README.md
65
107
  - Rakefile
66
- - exe/action_mcp_stdio
108
+ - exe/actionmcp_cli
67
109
  - lib/action_mcp.rb
110
+ - lib/action_mcp/capability.rb
111
+ - lib/action_mcp/client.rb
68
112
  - lib/action_mcp/configuration.rb
69
113
  - lib/action_mcp/content.rb
70
114
  - lib/action_mcp/content/audio.rb
71
115
  - lib/action_mcp/content/image.rb
72
116
  - lib/action_mcp/content/resource.rb
73
117
  - lib/action_mcp/content/text.rb
118
+ - lib/action_mcp/engine.rb
74
119
  - lib/action_mcp/gem_version.rb
120
+ - lib/action_mcp/integer_array.rb
75
121
  - lib/action_mcp/json_rpc.rb
76
- - lib/action_mcp/json_rpc/base.rb
77
122
  - lib/action_mcp/json_rpc/json_rpc_error.rb
78
123
  - lib/action_mcp/json_rpc/notification.rb
79
124
  - lib/action_mcp/json_rpc/request.rb
80
125
  - lib/action_mcp/json_rpc/response.rb
126
+ - lib/action_mcp/json_rpc_handler.rb
127
+ - lib/action_mcp/logging.rb
81
128
  - lib/action_mcp/prompt.rb
82
129
  - lib/action_mcp/prompts_registry.rb
83
- - lib/action_mcp/railtie.rb
84
130
  - lib/action_mcp/registry_base.rb
131
+ - lib/action_mcp/renderable.rb
85
132
  - lib/action_mcp/resource.rb
86
- - lib/action_mcp/resources_bank.rb
133
+ - lib/action_mcp/server.rb
134
+ - lib/action_mcp/string_array.rb
87
135
  - lib/action_mcp/tool.rb
88
136
  - lib/action_mcp/tools_registry.rb
89
137
  - lib/action_mcp/transport.rb
138
+ - lib/action_mcp/transport/capabilities.rb
139
+ - lib/action_mcp/transport/messaging.rb
140
+ - lib/action_mcp/transport/prompts.rb
141
+ - lib/action_mcp/transport/sse_client.rb
142
+ - lib/action_mcp/transport/stdio_client.rb
143
+ - lib/action_mcp/transport/tools.rb
144
+ - lib/action_mcp/transport/transport_base.rb
145
+ - lib/action_mcp/transport_handler.rb
90
146
  - lib/action_mcp/version.rb
91
147
  - lib/actionmcp.rb
92
148
  - lib/generators/action_mcp/install/install_generator.rb
@@ -103,6 +159,8 @@ licenses:
103
159
  metadata:
104
160
  homepage_uri: https://github.com/seuros/action_mcp
105
161
  source_code_uri: https://github.com/seuros/action_mcp
162
+ changelog_uri: https://github.com/seuros/action_mcp/blob/master/CHANGELOG.md
163
+ rubygems_mfa_required: 'true'
106
164
  rdoc_options: []
107
165
  require_paths:
108
166
  - lib
@@ -117,7 +175,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
117
175
  - !ruby/object:Gem::Version
118
176
  version: '0'
119
177
  requirements: []
120
- rubygems_version: 3.6.2
178
+ rubygems_version: 3.6.5
121
179
  specification_version: 4
122
180
  summary: Provides essential tooling for building Model Context Protocol (MCP) capable
123
181
  servers
data/exe/action_mcp_stdio DELETED
File without changes
@@ -1,12 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module ActionMCP
4
- module JsonRpc
5
- private
6
-
7
- def validate_id(id)
8
- raise Error, "ID must be a string or number" unless id.is_a?(String) || id.is_a?(Numeric)
9
- raise Error, "ID must not be null" if id.nil?
10
- end
11
- end
12
- end
@@ -1,27 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- require "rails"
4
- require "active_model/railtie"
5
-
6
- module ActionMCP
7
- class Railtie < Rails::Railtie # :nodoc:
8
- # Provide a configuration namespace for ActionMCP
9
- config.action_mcp = ActiveSupport::OrderedOptions.new
10
-
11
- config.after_initialize do |app|
12
- options = app.config.action_mcp.to_h.symbolize_keys
13
-
14
- # Override the default configuration if specified in the Rails app.
15
- ActionMCP.configuration.name = options[:name] if options.key?(:name)
16
- ActionMCP.configuration.version = options[:version] if options.key?(:version)
17
- ActionMCP.configuration.logging_enabled = options.fetch(:logging_enabled, true)
18
- end
19
-
20
- initializer "action_mcp.clear_registry" do |app|
21
- app.config.to_prepare do
22
- ActionMCP::ToolsRegistry.clear!
23
- ActionMCP::PromptsRegistry.clear!
24
- end
25
- end
26
- end
27
- end
@@ -1,96 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- # frozen_string_literal: true
4
-
5
- module ActionMCP
6
- module ResourcesBank
7
- @resources = {} # { uri => content_object }
8
- @templates = {} # { uri => template_object }
9
- @watchers = {} # { source_uri => watcher }
10
-
11
- class << self
12
- # Basic resource registration.
13
- def register_resource(uri, content)
14
- @resources[uri] = content
15
- end
16
-
17
- def all_resources
18
- @resources.values
19
- end
20
-
21
- def read(uri)
22
- @resources[uri]
23
- end
24
-
25
- def register_template(uri, template)
26
- @templates[uri] = template
27
- end
28
-
29
- def all_templates
30
- @templates.values
31
- end
32
-
33
- # Registers a source (file or directory) for resources.
34
- #
35
- # @param source_uri [String] An identifier for this source.
36
- # @param path [String] Filesystem path to the source.
37
- # @param watch [Boolean] Whether to watch the source for changes.
38
- def register_source(source_uri, path, watch: false)
39
- reload_source(source_uri, path) # Initial load
40
-
41
- return unless watch
42
-
43
- require "active_support/evented_file_update_checker"
44
- # Watch all files under the given path (recursive)
45
- file_paths = Dir.glob("#{path}/**/*")
46
- watcher = ActiveSupport::EventedFileUpdateChecker.new(file_paths) do |modified, added, removed|
47
- Rails.logger.info("Files changed in #{path} - Modified: #{modified.inspect}, Added: #{added.inspect}, Removed: #{removed.inspect}")
48
- # Reload resources for this source when changes occur.
49
- reload_source(source_uri, path)
50
- end
51
- @watchers[source_uri] = { path: path, watcher: watcher }
52
- end
53
-
54
- # Unregisters a source and stops watching it.
55
- #
56
- # @param source_uri [String] The identifier for the source.
57
- def unregister_source(source_uri)
58
- @watchers.delete(source_uri)
59
- # Optionally, remove any resources associated with this source.
60
- @resources.reject! { |uri, _| uri.start_with?("#{source_uri}://") }
61
- end
62
-
63
- # Reloads (or loads) all resources from the given directory.
64
- #
65
- # @param source_uri [String] The identifier for the source.
66
- # @param path [String] Filesystem path to the source.
67
- def reload_source(source_uri, path)
68
- Rails.logger.info("Reloading resources from #{path} for #{source_uri}")
69
- Dir.glob("#{path}/**/*").each do |file|
70
- next unless File.file?(file)
71
-
72
- # Create a resource URI from the source and file path.
73
- relative_path = file.sub(%r{\A#{Regexp.escape(path)}/?}, "")
74
- resource_uri = "#{source_uri}://#{relative_path}"
75
- # For this example, we assume text files.
76
- begin
77
- text = File.read(file)
78
- content = ActionMCP::Content::Text.new(text)
79
- register_resource(resource_uri, content)
80
- Rails.logger.info("Registered resource: #{resource_uri}")
81
- rescue StandardError => e
82
- Rails.logger.error("Error reading file #{file}: #{e.message}")
83
- end
84
- end
85
- end
86
-
87
- # This method should be called periodically (e.g. via a background thread)
88
- # to check if any watched files have changed.
89
- def run_watchers
90
- @watchers.each_value do |data|
91
- data[:watcher].execute_if_updated
92
- end
93
- end
94
- end
95
- end
96
- end