rails_mcp_engine 0.2.0 → 0.3.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
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: f6c501b19758aada1c867684284621f255130d3d031aa39d4df44da9f3a79f93
|
|
4
|
+
data.tar.gz: e07a3da73bf2414648584e8a1eaa05b45e903d64151ec458dfd554c9ae15c0bd
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 6a4df6b3b995f865c86ed8d648d1629207ad9a603033f4b74ecbfff58c9913550b90588ae71952fbec505b3b4699e1c6247c4b310e7f777a60c3167c32aadb5b
|
|
7
|
+
data.tar.gz: 76372d4ad6346c20b65306dc277e7daba2921089fe808e721258b5b6ecb3bb72ba8d1caf16e57f7be728ad0e77a5131ad0b6cbe22d1adbf86dd2ec64a66ec345
|
|
@@ -50,7 +50,7 @@ module RailsMcpEngine
|
|
|
50
50
|
result = if schema.nil?
|
|
51
51
|
{ error: "Tool not found: #{tool_name}" }
|
|
52
52
|
else
|
|
53
|
-
delete_tool_from_registry(
|
|
53
|
+
delete_tool_from_registry(tool_name)
|
|
54
54
|
end
|
|
55
55
|
|
|
56
56
|
flash[:register_result] = result
|
|
@@ -139,8 +139,9 @@ module RailsMcpEngine
|
|
|
139
139
|
# The engine.rb defines ApplicationTool.
|
|
140
140
|
|
|
141
141
|
# Re-using the logic from ManualController but adapting for Engine.
|
|
142
|
-
::Tools::
|
|
142
|
+
::Tools::MetaToolWriteService.new.register_tool(
|
|
143
143
|
class_name,
|
|
144
|
+
source: source,
|
|
144
145
|
before_call: ->(args) { Rails.logger.info(" [MCP] Request #{class_name}: #{args.inspect}") },
|
|
145
146
|
after_call: ->(result) { Rails.logger.info(" [MCP] Response #{class_name}: #{result.inspect}") }
|
|
146
147
|
)
|
|
@@ -168,14 +169,8 @@ module RailsMcpEngine
|
|
|
168
169
|
{ error: e.message }
|
|
169
170
|
end
|
|
170
171
|
|
|
171
|
-
def delete_tool_from_registry(
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
# Also remove the RubyLLM tool class constant
|
|
175
|
-
tool_constant = ToolSchema::RubyLlmFactory.tool_class_name(service_class)
|
|
176
|
-
::Tools.send(:remove_const, tool_constant) if ::Tools.const_defined?(tool_constant, false)
|
|
177
|
-
|
|
178
|
-
{ success: 'Tool deleted successfully' }
|
|
172
|
+
def delete_tool_from_registry(tool_name)
|
|
173
|
+
::Tools::MetaToolWriteService.new.delete_tool(tool_name)
|
|
179
174
|
rescue StandardError => e
|
|
180
175
|
{ error: e.message }
|
|
181
176
|
end
|
|
@@ -44,26 +44,7 @@ module Tools
|
|
|
44
44
|
end
|
|
45
45
|
end
|
|
46
46
|
|
|
47
|
-
sig { params(class_name: T.nilable(String), before_call: T.nilable(Proc), after_call: T.nilable(Proc)).returns(T::Hash[Symbol, T.untyped]) }
|
|
48
|
-
def register_tool(class_name, before_call: nil, after_call: nil)
|
|
49
|
-
return { error: 'class_name is required for register' } if class_name.nil? || class_name.empty?
|
|
50
47
|
|
|
51
|
-
service_class = constantize(class_name)
|
|
52
|
-
return { error: "Could not find #{class_name}" } if service_class.nil?
|
|
53
|
-
return { error: "#{class_name} must extend ToolMeta" } unless service_class.respond_to?(:tool_metadata)
|
|
54
|
-
|
|
55
|
-
ToolMeta.registry << service_class unless ToolMeta.registry.include?(service_class)
|
|
56
|
-
|
|
57
|
-
schema = ToolSchema::Builder.build(service_class)
|
|
58
|
-
ToolSchema::RubyLlmFactory.build(service_class, schema, before_call: before_call, after_call: after_call)
|
|
59
|
-
ToolSchema::FastMcpFactory.build(service_class, schema, before_call: before_call, after_call: after_call)
|
|
60
|
-
|
|
61
|
-
{ status: 'registered', tool: summary_payload(schema) }
|
|
62
|
-
rescue ToolMeta::MissingSignatureError => e
|
|
63
|
-
{ error: e.message }
|
|
64
|
-
rescue NameError => e
|
|
65
|
-
{ error: "Could not find #{class_name}: #{e.message}" }
|
|
66
|
-
end
|
|
67
48
|
|
|
68
49
|
sig { params(tool_names: T::Array[String]).returns(T::Array[T.class_of(Object)]) }
|
|
69
50
|
def self.ruby_llm_tools(tool_names)
|
|
@@ -76,7 +57,6 @@ module Tools
|
|
|
76
57
|
end
|
|
77
58
|
end
|
|
78
59
|
|
|
79
|
-
private
|
|
80
60
|
|
|
81
61
|
sig { params(query: T.nilable(String)).returns(T::Hash[Symbol, T.untyped]) }
|
|
82
62
|
def search_tools(query)
|
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
# typed: strict
|
|
2
|
+
# frozen_string_literal: true
|
|
3
|
+
|
|
4
|
+
require 'sorbet-runtime'
|
|
5
|
+
require 'tool_meta'
|
|
6
|
+
require 'tool_schema/builder'
|
|
7
|
+
require 'tool_schema/ruby_llm_factory'
|
|
8
|
+
require 'tool_schema/fast_mcp_factory'
|
|
9
|
+
|
|
10
|
+
module Tools
|
|
11
|
+
class MetaToolWriteService
|
|
12
|
+
extend T::Sig
|
|
13
|
+
|
|
14
|
+
sig { params(class_name: T.nilable(String), source: T.nilable(String), before_call: T.nilable(Proc), after_call: T.nilable(Proc)).returns(T::Hash[Symbol, T.untyped]) }
|
|
15
|
+
def register_tool(class_name, source: nil, before_call: nil, after_call: nil)
|
|
16
|
+
return { error: 'class_name is required for register' } if class_name.nil? || class_name.empty?
|
|
17
|
+
|
|
18
|
+
# If source is provided, evaluate it first
|
|
19
|
+
if source
|
|
20
|
+
begin
|
|
21
|
+
Object.class_eval(source)
|
|
22
|
+
rescue StandardError => e
|
|
23
|
+
return { error: "Failed to evaluate source: #{e.message}" }
|
|
24
|
+
end
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
begin
|
|
28
|
+
service_class = meta_service.constantize(class_name)
|
|
29
|
+
rescue NameError
|
|
30
|
+
return { error: "Could not find #{class_name}" }
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
return { error: "#{class_name} must extend ToolMeta" } unless service_class.respond_to?(:tool_metadata)
|
|
34
|
+
|
|
35
|
+
ToolMeta.registry << service_class unless ToolMeta.registry.include?(service_class)
|
|
36
|
+
|
|
37
|
+
schema = ToolSchema::Builder.build(service_class)
|
|
38
|
+
ToolSchema::RubyLlmFactory.build(service_class, schema, before_call: before_call, after_call: after_call)
|
|
39
|
+
ToolSchema::FastMcpFactory.build(service_class, schema, before_call: before_call, after_call: after_call)
|
|
40
|
+
|
|
41
|
+
{ status: 'registered', tool: meta_service.summary_payload(schema) }
|
|
42
|
+
rescue ToolMeta::MissingSignatureError => e
|
|
43
|
+
{ error: e.message }
|
|
44
|
+
rescue NameError => e
|
|
45
|
+
{ error: "Could not find #{class_name}: #{e.message}" }
|
|
46
|
+
end
|
|
47
|
+
|
|
48
|
+
sig { params(tool_name: String).returns(T::Hash[Symbol, T.untyped]) }
|
|
49
|
+
def delete_tool(tool_name)
|
|
50
|
+
schema = meta_service.find_schema(tool_name)
|
|
51
|
+
return { error: "Tool not found: #{tool_name}" } unless schema
|
|
52
|
+
|
|
53
|
+
service_class = schema[:service_class]
|
|
54
|
+
ToolMeta.registry.delete(service_class)
|
|
55
|
+
|
|
56
|
+
tool_constant = ToolSchema::RubyLlmFactory.tool_class_name(service_class)
|
|
57
|
+
Tools.send(:remove_const, tool_constant) if Tools.const_defined?(tool_constant, false)
|
|
58
|
+
fast_mcp_constant = ToolSchema::FastMcpFactory.tool_class_name(service_class)
|
|
59
|
+
Mcp.send(:remove_const, fast_mcp_constant) if Mcp.const_defined?(fast_mcp_constant, false)
|
|
60
|
+
|
|
61
|
+
{ success: 'Tool deleted successfully' }
|
|
62
|
+
rescue StandardError => e
|
|
63
|
+
{ error: e.message }
|
|
64
|
+
end
|
|
65
|
+
|
|
66
|
+
private
|
|
67
|
+
|
|
68
|
+
def meta_service
|
|
69
|
+
@meta_service ||= Tools::MetaToolService.new
|
|
70
|
+
end
|
|
71
|
+
end
|
|
72
|
+
end
|
metadata
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: rails_mcp_engine
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.
|
|
4
|
+
version: 0.3.0
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Soonoh Jung
|
|
@@ -92,6 +92,7 @@ files:
|
|
|
92
92
|
- app/lib/tool_schema/ruby_llm_factory.rb
|
|
93
93
|
- app/lib/tool_schema/sorbet_type_mapper.rb
|
|
94
94
|
- app/services/tools/meta_tool_service.rb
|
|
95
|
+
- app/services/tools/meta_tool_write_service.rb
|
|
95
96
|
- app/views/rails_mcp_engine/chat/show.html.erb
|
|
96
97
|
- app/views/rails_mcp_engine/playground/show.html.erb
|
|
97
98
|
- config/routes.rb
|